kramdown-1.17.0/0000755000004100000410000000000013321140127013444 5ustar www-datawww-datakramdown-1.17.0/COPYING0000644000004100000410000000243713321140127014505 0ustar www-datawww-datakramdown - fast, pure-Ruby Markdown-superset converter Copyright (C) 2009-2013 Thomas Leitner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Some test cases and the benchmark files are based on test cases from the MDTest test suite: MDTest Copyright (c) 2007 Michel Fortin kramdown-1.17.0/test/0000755000004100000410000000000013321140127014423 5ustar www-datawww-datakramdown-1.17.0/test/test_files.rb0000644000004100000410000007373113321140127017124 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'minitest/autorun' require 'kramdown' require 'yaml' require 'tmpdir' begin require 'kramdown/converter/syntax_highlighter/rouge' Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class.send(:define_method, :format) do |tokens, &b| super(tokens, &b).sub(/<\/code><\/pre>\n?/, "\n") end # custom formatter for tests class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class tag 'rouge_html_formatters' def stream(tokens, &b) yield %(
) super yield %(
) end end rescue LoadError, SyntaxError, NameError end Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9' class TestFiles < Minitest::Test MATHJAX_NODE_AVAILABLE = begin require 'kramdown/converter/math_engine/mathjaxnode' Kramdown::Converter::MathEngine::MathjaxNode::AVAILABLE or warn("Skipping MathjaxNode tests as MathjaxNode is not available") end SSKATEX_AVAILABLE = begin / class="katex"/ === Kramdown::Document. new('$$a$$', {:math_engine => :sskatex}).to_html or warn("Skipping SsKaTeX tests as SsKaTeX is not available.") rescue warn("Skipping SsKaTeX tests as default SsKaTeX config does not work.") end or warn("Run \"rake dev:test_sskatex_deps\" to see why.") KATEX_AVAILABLE = RUBY_VERSION >= '2.3' EXCLUDE_KD_FILES = [('test/testcases/block/04_header/with_auto_ids.text' if RUBY_VERSION <= '1.8.6'), # bc of dep stringex not working ('test/testcases/span/03_codespan/rouge/' if RUBY_VERSION < '2.0'), #bc of rouge ('test/testcases/block/06_codeblock/rouge/' if RUBY_VERSION < '2.0'), #bc of rouge ('test/testcases/block/15_math/itex2mml.text' if RUBY_PLATFORM == 'java'), # bc of itextomml ('test/testcases/span/math/itex2mml.text' if RUBY_PLATFORM == 'java'), # bc of itextomml ('test/testcases/block/15_math/mathjaxnode.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/block/15_math/mathjaxnode_notexhints.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/block/15_math/mathjaxnode_semantics.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/span/math/mathjaxnode.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/block/15_math/sskatex.text' unless SSKATEX_AVAILABLE), ('test/testcases/span/math/sskatex.text' unless SSKATEX_AVAILABLE), ('test/testcases/block/15_math/katex.text' unless KATEX_AVAILABLE), ('test/testcases/span/math/katex.text' unless KATEX_AVAILABLE), ].compact # Generate test methods for kramdown-to-xxx conversion Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| next if EXCLUDE_KD_FILES.any? {|f| text_file =~ /#{f}/} basename = text_file.sub(/\.text$/, '') opts_file = text_file.sub(/\.text$/, '.options') (Dir[basename + ".*"] - [text_file, opts_file]).each do |output_file| next if (RUBY_VERSION >= '1.9' && File.exist?(output_file + '.19')) || (RUBY_VERSION < '1.9' && output_file =~ /\.19$/) output_format = File.extname(output_file.sub(/\.19$/, ''))[1..-1] next if !Kramdown::Converter.const_defined?(output_format[0..0].upcase + output_format[1..-1]) define_method('test_' + text_file.tr('.', '_') + "_to_#{output_format}") do opts_file = File.join(File.dirname(text_file), 'options') if !File.exist?(opts_file) options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} doc = Kramdown::Document.new(File.read(text_file), options) assert_equal(File.read(output_file), doc.send("to_#{output_format}")) end end end # Generate test methods for html-to-{html,kramdown} conversion `tidy -v 2>&1` if $?.exitstatus != 0 warn("Skipping html-to-{html,kramdown} tests because tidy executable is missing") else EXCLUDE_HTML_FILES = ['test/testcases/block/06_codeblock/whitespace.html', # bc of span inside pre 'test/testcases/block/09_html/simple.html', # bc of xml elements 'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element 'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option 'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option 'test/testcases/block/06_codeblock/rouge/simple.html', # bc of double surrounding
'test/testcases/block/06_codeblock/rouge/multiple.html', # bc of double surrounding
('test/testcases/span/03_codespan/rouge/simple.html' if RUBY_VERSION < '2.0'), ('test/testcases/span/03_codespan/rouge/disabled.html' if RUBY_VERSION < '2.0'), 'test/testcases/block/14_table/empty_tag_in_cell.html', # bc of tidy 'test/testcases/block/15_math/ritex.html', # bc of tidy 'test/testcases/span/math/ritex.html', # bc of tidy 'test/testcases/block/15_math/itex2mml.html', # bc of tidy 'test/testcases/span/math/itex2mml.html', # bc of tidy 'test/testcases/block/15_math/mathjaxnode.html', # bc of tidy 'test/testcases/block/15_math/mathjaxnode_notexhints.html', # bc of tidy 'test/testcases/block/15_math/mathjaxnode_semantics.html', # bc of tidy 'test/testcases/span/math/mathjaxnode.html', # bc of tidy 'test/testcases/block/15_math/mathjax_preview.html', # bc of mathjax preview 'test/testcases/block/15_math/mathjax_preview_simple.html', # bc of mathjax preview 'test/testcases/block/15_math/mathjax_preview_as_code.html', # bc of mathjax preview 'test/testcases/span/math/sskatex.html', # bc of tidy 'test/testcases/block/15_math/sskatex.html', # bc of tidy 'test/testcases/span/math/katex.html', # bc of tidy 'test/testcases/block/15_math/katex.html', # bc of tidy 'test/testcases/span/05_html/mark_element.html', # bc of tidy 'test/testcases/block/09_html/xml.html', # bc of tidy 'test/testcases/span/05_html/xml.html', # bc of tidy ].compact EXCLUDE_HTML_TEXT_FILES = ['test/testcases/block/09_html/parse_as_span.htmlinput', 'test/testcases/block/09_html/parse_as_raw.htmlinput', ].compact Dir[File.dirname(__FILE__) + '/testcases/**/*.{html,html.19,htmlinput,htmlinput.19}'].each do |html_file| next if EXCLUDE_HTML_FILES.any? {|f| html_file =~ /#{f}(\.19)?$/} next if (RUBY_VERSION >= '1.9' && File.exist?(html_file + '.19')) || (RUBY_VERSION < '1.9' && html_file =~ /\.19$/) out_files = [] out_files << [(html_file =~ /\.htmlinput(\.19)?$/ ? html_file.sub(/input(\.19)?$/, '') : html_file), :to_html] if html_file =~ /\.htmlinput(\.19)?$/ && !EXCLUDE_HTML_TEXT_FILES.any? {|f| html_file =~ /#{f}/} out_files << [html_file.sub(/htmlinput(\.19)?$/, 'text'), :to_kramdown] end out_files.select {|f, _| File.exist?(f)}.each do |out_file, out_method| define_method('test_' + html_file.tr('.', '_') + "_to_#{File.extname(out_file)}") do opts_file = html_file.sub(/\.html(input)?(\.19)?$/, '.options') opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file) options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} doc = Kramdown::Document.new(File.read(html_file), options.merge(:input => 'html')) if out_method == :to_html assert_equal(tidy_output(File.read(out_file)), tidy_output(doc.send(out_method))) else assert_equal(File.read(out_file), doc.send(out_method)) end end end end end def tidy_output(out) cmd = "tidy -q --doctype omit #{RUBY_VERSION >= '1.9' ? '-utf8' : '-raw'} 2>/dev/null" result = IO.popen(cmd, 'r+') do |io| io.write(out) io.close_write io.read end if $?.exitstatus == 2 raise "Problem using tidy" end result end # Generate test methods for text-to-latex conversion and compilation `latex -v 2>&1` if $?.exitstatus != 0 warn("Skipping latex compilation tests because latex executable is missing") else EXCLUDE_LATEX_FILES = ['test/testcases/span/01_link/image_in_a.text', # bc of image link 'test/testcases/span/01_link/imagelinks.text', # bc of image links 'test/testcases/span/01_link/empty_title.text', 'test/testcases/span/04_footnote/markers.text', # bc of footnote in header 'test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text', 'test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text', ].compact Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| next if EXCLUDE_LATEX_FILES.any? {|f| text_file =~ /#{f}$/} define_method('test_' + text_file.tr('.', '_') + "_to_latex_compilation") do latex = Kramdown::Document.new(File.read(text_file), :auto_ids => false, :footnote_nr => 1, :template => 'document').to_latex Dir.mktmpdir do |tmpdir| result = IO.popen("latex -output-directory='#{tmpdir}' 2>/dev/null", 'r+') do |io| io.write(latex) io.close_write io.read end assert($?.exitstatus == 0, result.scan(/^!(.*\n.*)/).join("\n")) end end end end # Generate test methods for text->kramdown->html conversion `tidy -v 2>&1` if $?.exitstatus != 0 warn("Skipping text->kramdown->html tests because tidy executable is missing") else EXCLUDE_TEXT_FILES = ['test/testcases/span/05_html/markdown_attr.text', # bc of markdown attr 'test/testcases/block/09_html/markdown_attr.text', # bc of markdown attr 'test/testcases/span/extension/options.text', # bc of parse_span_html option 'test/testcases/block/12_extension/options.text', # bc of options option 'test/testcases/block/12_extension/options3.text', # bc of options option 'test/testcases/block/09_html/content_model/tables.text', # bc of parse_block_html option 'test/testcases/block/09_html/html_to_native/header.text', # bc of auto_ids option that interferes 'test/testcases/block/09_html/html_to_native/table_simple.text', # bc of tr style attr getting removed 'test/testcases/block/09_html/simple.text', # bc of webgen:block elements 'test/testcases/block/11_ial/simple.text', # bc of change of ordering of attributes in header 'test/testcases/span/extension/comment.text', # bc of comment text modifications (can this be avoided?) 'test/testcases/block/04_header/header_type_offset.text', # bc of header_offset being applied twice ('test/testcases/block/04_header/with_auto_ids.text' if RUBY_VERSION <= '1.8.6'), # bc of dep stringex not working ('test/testcases/span/03_codespan/rouge/simple.text' if RUBY_VERSION < '2.0'), #bc of rouge ('test/testcases/span/03_codespan/rouge/disabled.text' if RUBY_VERSION < '2.0'), #bc of rouge 'test/testcases/block/06_codeblock/rouge/simple.text', 'test/testcases/block/06_codeblock/rouge/multiple.text', # check, what document contain more, than one code block 'test/testcases/block/14_table/empty_tag_in_cell.text', # bc of tidy 'test/testcases/block/15_math/ritex.text', # bc of tidy 'test/testcases/span/math/ritex.text', # bc of tidy 'test/testcases/block/15_math/itex2mml.text', # bc of tidy 'test/testcases/span/math/itex2mml.text', # bc of tidy 'test/testcases/block/15_math/mathjaxnode.text', # bc of tidy 'test/testcases/block/15_math/mathjaxnode_notexhints.text', # bc of tidy 'test/testcases/block/15_math/mathjaxnode_semantics.text', # bc of tidy 'test/testcases/span/math/mathjaxnode.text', # bc of tidy 'test/testcases/block/15_math/sskatex.text', # bc of tidy 'test/testcases/span/math/sskatex.text', # bc of tidy 'test/testcases/block/15_math/katex.text', # bc of tidy 'test/testcases/span/math/katex.text', # bc of tidy 'test/testcases/span/01_link/link_defs_with_ial.text', # bc of attribute ordering 'test/testcases/span/05_html/mark_element.text', # bc of tidy 'test/testcases/block/09_html/xml.text', # bc of tidy 'test/testcases/span/05_html/xml.text', # bc of tidy ].compact Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| next if EXCLUDE_TEXT_FILES.any? {|f| text_file =~ /#{f}$/} html_file = text_file.sub(/\.text$/, '.html') html_file += '.19' if RUBY_VERSION >= '1.9' && File.exist?(html_file + '.19') next unless File.exist?(html_file) define_method('test_' + text_file.tr('.', '_') + "_to_kramdown_to_html") do opts_file = text_file.sub(/\.text$/, '.options') opts_file = File.join(File.dirname(text_file), 'options') if !File.exist?(opts_file) options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} kdtext = Kramdown::Document.new(File.read(text_file), options).to_kramdown html = Kramdown::Document.new(kdtext, options).to_html assert_equal(tidy_output(File.read(html_file)), tidy_output(html)) end end end # Generate test methods for html-to-kramdown-to-html conversion `tidy -v 2>&1` if $?.exitstatus != 0 warn("Skipping html-to-kramdown-to-html tests because tidy executable is missing") else EXCLUDE_HTML_KD_FILES = ['test/testcases/span/extension/options.html', # bc of parse_span_html option 'test/testcases/span/05_html/normal.html', # bc of br tag before closing p tag 'test/testcases/block/12_extension/nomarkdown.html', # bc of nomarkdown extension 'test/testcases/block/09_html/simple.html', # bc of webgen:block elements 'test/testcases/block/09_html/markdown_attr.html', # bc of markdown attr 'test/testcases/block/09_html/html_to_native/table_simple.html', # bc of invalidly converted simple table 'test/testcases/block/06_codeblock/whitespace.html', # bc of entity to char conversion 'test/testcases/block/06_codeblock/rouge/simple.html', # bc of double surrounding
'test/testcases/block/06_codeblock/rouge/multiple.html', # bc of double surrounding
'test/testcases/block/11_ial/simple.html', # bc of change of ordering of attributes in header 'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element 'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option 'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option 'test/testcases/block/16_toc/toc_exclude.html', # bc of different attribute ordering 'test/testcases/span/autolinks/url_links.html', # bc of quot entity being converted to char ('test/testcases/span/03_codespan/rouge/simple.html' if RUBY_VERSION < '2.0'), ('test/testcases/span/03_codespan/rouge/disabled.html' if RUBY_VERSION < '2.0'), 'test/testcases/block/14_table/empty_tag_in_cell.html', # bc of tidy 'test/testcases/block/15_math/ritex.html', # bc of tidy 'test/testcases/span/math/ritex.html', # bc of tidy 'test/testcases/block/15_math/itex2mml.html', # bc of tidy 'test/testcases/span/math/itex2mml.html', # bc of tidy 'test/testcases/block/15_math/mathjaxnode.html', # bc of tidy 'test/testcases/block/15_math/mathjaxnode_notexhints.html', # bc of tidy 'test/testcases/block/15_math/mathjaxnode_semantics.html', # bc of tidy 'test/testcases/span/math/mathjaxnode.html', # bc of tidy 'test/testcases/block/15_math/sskatex.html', # bc of tidy 'test/testcases/span/math/sskatex.html', # bc of tidy 'test/testcases/block/15_math/katex.html', # bc of tidy 'test/testcases/span/math/katex.html', # bc of tidy 'test/testcases/block/15_math/mathjax_preview.html', # bc of mathjax preview 'test/testcases/block/15_math/mathjax_preview_simple.html', # bc of mathjax preview 'test/testcases/block/15_math/mathjax_preview_as_code.html', # bc of mathjax preview 'test/testcases/span/01_link/link_defs_with_ial.html', # bc of attribute ordering 'test/testcases/span/05_html/mark_element.html', # bc of tidy 'test/testcases/block/09_html/xml.html', # bc of tidy 'test/testcases/span/05_html/xml.html', # bc of tidy ].compact Dir[File.dirname(__FILE__) + '/testcases/**/*.{html,html.19}'].each do |html_file| next if EXCLUDE_HTML_KD_FILES.any? {|f| html_file =~ /#{f}(\.19)?$/} next if (RUBY_VERSION >= '1.9' && File.exist?(html_file + '.19')) || (RUBY_VERSION < '1.9' && html_file =~ /\.19$/) define_method('test_' + html_file.tr('.', '_') + "_to_kramdown_to_html") do kd = Kramdown::Document.new(File.read(html_file), :input => 'html', :auto_ids => false, :footnote_nr => 1).to_kramdown opts_file = html_file.sub(/\.html(\.19)?$/, '.options') opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file) options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} doc = Kramdown::Document.new(kd, options) assert_equal(tidy_output(File.read(html_file)), tidy_output(doc.to_html)) end end end # Generate test methods for text-manpage conversion Dir[File.dirname(__FILE__) + '/testcases/man/**/*.text'].each do |text_file| define_method('test_' + text_file.tr('.', '_') + "_to_man") do man_file = text_file.sub(/\.text$/, '.man') doc = Kramdown::Document.new(File.read(text_file)) assert_equal(File.read(man_file), doc.to_man) end end EXCLUDE_GFM_FILES = [ 'test/testcases/block/03_paragraph/no_newline_at_end.text', 'test/testcases/block/03_paragraph/indented.text', 'test/testcases/block/03_paragraph/two_para.text', 'test/testcases/block/03_paragraph/line_break_last_line.text', 'test/testcases/block/04_header/atx_header.text', 'test/testcases/block/04_header/setext_header.text', 'test/testcases/block/04_header/with_auto_ids.text', # bc of ID generation difference 'test/testcases/block/04_header/with_auto_id_prefix.text', # bc of ID generation difference 'test/testcases/block/05_blockquote/indented.text', 'test/testcases/block/05_blockquote/lazy.text', 'test/testcases/block/05_blockquote/nested.text', 'test/testcases/block/05_blockquote/no_newline_at_end.text', 'test/testcases/block/06_codeblock/error.text', 'test/testcases/block/07_horizontal_rule/error.text', 'test/testcases/block/08_list/escaping.text', 'test/testcases/block/08_list/item_ial.text', 'test/testcases/block/08_list/lazy.text', 'test/testcases/block/08_list/list_and_others.text', 'test/testcases/block/08_list/other_first_element.text', 'test/testcases/block/08_list/simple_ul.text', 'test/testcases/block/08_list/special_cases.text', 'test/testcases/block/08_list/lazy_and_nested.text', # bc of change in lazy line handling 'test/testcases/block/09_html/comment.text', 'test/testcases/block/09_html/html_to_native/code.text', 'test/testcases/block/09_html/html_to_native/emphasis.text', 'test/testcases/block/09_html/html_to_native/typography.text', 'test/testcases/block/09_html/parse_as_raw.text', 'test/testcases/block/09_html/simple.text', 'test/testcases/block/12_extension/comment.text', 'test/testcases/block/12_extension/ignored.text', 'test/testcases/block/12_extension/nomarkdown.text', 'test/testcases/block/13_definition_list/item_ial.text', 'test/testcases/block/13_definition_list/multiple_terms.text', 'test/testcases/block/13_definition_list/no_def_list.text', 'test/testcases/block/13_definition_list/simple.text', 'test/testcases/block/13_definition_list/with_blocks.text', 'test/testcases/block/14_table/errors.text', 'test/testcases/block/14_table/escaping.text', 'test/testcases/block/14_table/simple.text', 'test/testcases/block/15_math/normal.text', 'test/testcases/block/16_toc/toc_with_footnotes.text', # bc of ID generation difference 'test/testcases/encoding.text', 'test/testcases/span/01_link/inline.text', 'test/testcases/span/01_link/link_defs.text', 'test/testcases/span/01_link/reference.text', 'test/testcases/span/02_emphasis/normal.text', 'test/testcases/span/03_codespan/normal.text', 'test/testcases/span/04_footnote/definitions.text', 'test/testcases/span/04_footnote/markers.text', 'test/testcases/span/05_html/across_lines.text', 'test/testcases/span/05_html/markdown_attr.text', 'test/testcases/span/05_html/normal.text', 'test/testcases/span/05_html/raw_span_elements.text', 'test/testcases/span/autolinks/url_links.text', 'test/testcases/span/extension/comment.text', 'test/testcases/span/ial/simple.text', 'test/testcases/span/line_breaks/normal.text', 'test/testcases/span/math/normal.text', 'test/testcases/span/text_substitutions/entities_as_char.text', 'test/testcases/span/text_substitutions/entities.text', 'test/testcases/span/text_substitutions/typography.text', ('test/testcases/span/03_codespan/rouge/simple.text' if RUBY_VERSION < '2.0'), ('test/testcases/span/03_codespan/rouge/disabled.text' if RUBY_VERSION < '2.0'), ('test/testcases/block/06_codeblock/rouge/simple.text' if RUBY_VERSION < '2.0'), #bc of rouge ('test/testcases/block/06_codeblock/rouge/disabled.text' if RUBY_VERSION < '2.0'), #bc of rouge ('test/testcases/block/06_codeblock/rouge/multiple.text' if RUBY_VERSION < '2.0'), #bc of rouge ('test/testcases/block/15_math/itex2mml.text' if RUBY_PLATFORM == 'java'), # bc of itextomml ('test/testcases/span/math/itex2mml.text' if RUBY_PLATFORM == 'java'), # bc of itextomml ('test/testcases/block/15_math/mathjaxnode.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/block/15_math/mathjaxnode_notexhints.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/block/15_math/mathjaxnode_semantics.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/span/math/mathjaxnode.text' unless MATHJAX_NODE_AVAILABLE), ('test/testcases/block/15_math/sskatex.text' unless SSKATEX_AVAILABLE), ('test/testcases/span/math/sskatex.text' unless SSKATEX_AVAILABLE), ('test/testcases/block/15_math/katex.text' unless KATEX_AVAILABLE), ('test/testcases/span/math/katex.text' unless KATEX_AVAILABLE), ].compact # Generate test methods for gfm-to-html conversion Dir[File.dirname(__FILE__) + '/{testcases,testcases_gfm}/**/*.text'].each do |text_file| next if EXCLUDE_GFM_FILES.any? {|f| text_file =~ /#{f}$/} basename = text_file.sub(/\.text$/, '') html_file = [(".html.19" if RUBY_VERSION >= '1.9'), ".html"].compact. map {|ext| basename + ext }. detect {|file| File.exist?(file) } next unless html_file define_method('test_gfm_' + text_file.tr('.', '_') + "_to_html") do opts_file = basename + '.options' opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file) options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} doc = Kramdown::Document.new(File.read(text_file), options.merge(:input => 'GFM')) assert_equal(File.read(html_file), doc.to_html) end end EXCLUDE_PDF_MODIFY = ['test/testcases/span/text_substitutions/entities.text', 'test/testcases/span/text_substitutions/entities_numeric.text', 'test/testcases/span/text_substitutions/entities_as_char.text', 'test/testcases/span/text_substitutions/entities_as_input.text', 'test/testcases/span/text_substitutions/entities_symbolic.text', 'test/testcases/block/04_header/with_auto_ids.text', ].compact EXCLUDE_MODIFY = ['test/testcases/block/06_codeblock/rouge/multiple.text', # bc of HTMLFormater in options ('test/testcases/block/15_math/sskatex.text' unless SSKATEX_AVAILABLE), ('test/testcases/span/math/sskatex.text' unless SSKATEX_AVAILABLE), ('test/testcases/block/15_math/katex.text' unless KATEX_AVAILABLE), ('test/testcases/span/math/katex.text' unless KATEX_AVAILABLE), ].compact # Generate test methods for asserting that converters don't modify the document tree. Dir[File.dirname(__FILE__) + '/testcases/**/*.text'].each do |text_file| opts_file = text_file.sub(/\.text$/, '.options') options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} (Kramdown::Converter.constants.map {|c| c.to_sym} - [:Base, :RemoveHtmlTags, :MathEngine, :SyntaxHighlighter]).each do |conv_class| next if EXCLUDE_MODIFY.any? {|f| text_file =~ /#{f}$/} next if conv_class == :Pdf && (RUBY_VERSION < '2.0' || EXCLUDE_PDF_MODIFY.any? {|f| text_file =~ /#{f}$/}) define_method("test_whether_#{conv_class}_modifies_tree_with_file_#{text_file.tr('.', '_')}") do doc = Kramdown::Document.new(File.read(text_file), options) options_before = Marshal.load(Marshal.dump(doc.options)) tree_before = Marshal.load(Marshal.dump(doc.root)) Kramdown::Converter.const_get(conv_class).convert(doc.root, doc.options) assert_equal(options_before, doc.options) assert_tree_not_changed(tree_before, doc.root) end end end def assert_tree_not_changed(old, new) assert_equal(old.type, new.type, "type mismatch") if old.value.kind_of?(Kramdown::Element) assert_tree_not_changed(old.value, new.value) else assert(old.value == new.value, "value mismatch") end assert_equal(old.attr, new.attr, "attr mismatch") assert_equal(old.options, new.options, "options mismatch") assert_equal(old.children.length, new.children.length, "children count mismatch") old.children.each_with_index do |child, index| assert_tree_not_changed(child, new.children[index]) end end end kramdown-1.17.0/test/run_tests.rb0000644000004100000410000000252613321140127017003 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # $:.unshift File.dirname(__FILE__) + '/../lib' require 'kramdown' require 'test/unit/assertions' require 'yaml' include Test::Unit::Assertions arg = ARGV[0] || File.join(File.dirname(__FILE__), 'testcases') arg = if File.directory?(arg) File.join(arg, '**/*.text') else arg + '.text' end width = ((size = %x{stty size 2>/dev/null}).length > 0 ? size.split.last.to_i : 72) rescue 72 width -= 8 fwidth = 0 Dir[arg].each {|f| fwidth = [fwidth, f.length + 10].max }.each do |file| print(('Testing ' + file + ' ').ljust([fwidth, width].min)) $stdout.flush html_file = file.sub('.text', '.html') opts_file = file.sub('.text', '.options') opts_file = File.join(File.dirname(file), 'options') if !File.exist?(opts_file) options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1} doc = Kramdown::Document.new(File.read(file), options) begin assert_equal(File.read(html_file), doc.to_html) puts 'PASSED' rescue Exception => e puts ' FAILED' puts $!.message if $VERBOSE puts $!.backtrace if $DEBUG end puts "Warnings:\n" + doc.warnings.join("\n") if !doc.warnings.empty? && $VERBOSE end kramdown-1.17.0/test/testcases_gfm/0000755000004100000410000000000013321140127017252 5ustar www-datawww-datakramdown-1.17.0/test/testcases_gfm/task_list.text0000644000004100000410000000057313321140127022162 0ustar www-datawww-dataunordered task list - [ ] first ul task item - [x] second ul task item - [X] third ul task item - [ ] fourth ul task item [ ] next unordered list - > first ul item - - test - second ul item ordered list 1. first ol item 2. second ol item ordered task list 1. [ ] first ol task item 2. [x] second ol task item 3. [X] third ol task item 4. [ ] fourth ol task item kramdown-1.17.0/test/testcases_gfm/header_ids_with_prefix.html0000644000004100000410000000010313321140127024631 0ustar www-datawww-data

Header 1

123

kramdown-1.17.0/test/testcases_gfm/codeblock_fenced.text0000644000004100000410000000034513321140127023413 0ustar www-datawww-datanormal ```ruby require 'kramdown' Kramdown::Document.new(text).to_html ``` indent with tab ```ruby require 'kramdown' Kramdown::Document.new(text).to_html ``` indent with 2 spaces ```js console.log("hello"); ``` kramdown-1.17.0/test/testcases_gfm/header_ids.html0000644000004100000410000000122613321140127022230 0ustar www-datawww-data

test

variable_name

abc def öúß

192 abc 192

;.;;

variable_name

variable_name

;;

before after tab

with code

with  ä space

With “smart” quotes

with — « typographic » … symbols

with

kramdown-1.17.0/test/testcases_gfm/atx_header.html0000644000004100000410000000004313321140127022241 0ustar www-datawww-data

header

#no header

kramdown-1.17.0/test/testcases_gfm/backticks_disable_highlighting.text0000644000004100000410000000007213321140127026325 0ustar www-datawww-data```ruby Kramdown::Document.new(text, :input => 'GFM') ``` kramdown-1.17.0/test/testcases_gfm/two_para_hard_line_breaks.text0000644000004100000410000000012013321140127025321 0ustar www-datawww-dataThis is just a normal paragraph. Containing a line break. Another paragraph. kramdown-1.17.0/test/testcases_gfm/backticks_disable_highlighting.html0000644000004100000410000000014013321140127026301 0ustar www-datawww-data
Kramdown::Document.new(text, :input => 'GFM')
kramdown-1.17.0/test/testcases_gfm/codeblock_fenced.options0000644000004100000410000000002713321140127024117 0ustar www-datawww-data:enable_coderay: false kramdown-1.17.0/test/testcases_gfm/hard_line_breaks.html0000644000004100000410000000005213321140127023411 0ustar www-datawww-data

one
two
three

kramdown-1.17.0/test/testcases_gfm/no_typographic.html.190000644000004100000410000000023013321140127023410 0ustar www-datawww-data

Header with --ndash

with --- << typographic >> ... symbols

kramdown-1.17.0/test/testcases_gfm/paragraph_end.text0000644000004100000410000000030313321140127022747 0ustar www-datawww-dataA - b This is a list - or is it blockquote > text header # text codeblock fenced ``` puts hello world ``` * level 1 some text begin level 2 * level 2 * level 2 # h1 ## h2 ### h3 kramdown-1.17.0/test/testcases_gfm/no_typographic.options0000644000004100000410000000004313321140127023711 0ustar www-datawww-data:gfm_quirks: [no_auto_typographic] kramdown-1.17.0/test/testcases_gfm/backticks_syntax.text0000644000004100000410000000023313321140127023522 0ustar www-datawww-data``` Three backticks ``` ```` Four backticks ```` ``` Unbalanced bottom heavy `````` ````ruby language no space ```` ```` ruby language with space ```` kramdown-1.17.0/test/testcases_gfm/two_para_hard_line_breaks.html0000644000004100000410000000014413321140127025307 0ustar www-datawww-data

This is just a normal paragraph.
Containing a line break.

Another paragraph.

kramdown-1.17.0/test/testcases_gfm/paragraph_end-disabled.html0000644000004100000410000000054213321140127024501 0ustar www-datawww-data

A
- b

This is a list
- or is it

blockquote
> text

header
# text

codeblock fenced
puts hello world

  • level 1
    some text

    begin level 2
    * level 2
    * level 2

h1

## h2
### h3

kramdown-1.17.0/test/testcases_gfm/header_ids.text0000644000004100000410000000044213321140127022247 0ustar www-datawww-data### test {#myid} ### variable_name ### abc def öúß ### 192 abc 192 ### ;.;; ### variable_name ### variable_name ### ;; ### before after tab ### with `code` ### with  ä space ### With "smart" quotes ### with --- << typographic >> ... symbols ### with $$m=5$$ kramdown-1.17.0/test/testcases_gfm/strikethrough.html0000644000004100000410000000121213321140127023036 0ustar www-datawww-data

This is a test

~This is another test~

This is yet another test~

~~ This is a test of it NOT working ~~

~~
This
is
a
multiline
test
~~

This is an inline strikethrough test

This is an ~~escaped~~ strikethrough.

This is a strikethrough with a ~ in the middle

I don’t even~ have an extra tilde.

This should ~~not be struck.

This is a complex strike through *test ~~with nesting involved* here~~.

kramdown-1.17.0/test/testcases_gfm/no_typographic.text0000644000004100000410000000010413321140127023200 0ustar www-datawww-data### Header with --ndash ### with --- << typographic >> ... symbols kramdown-1.17.0/test/testcases_gfm/paragraph_end-disabled.options0000644000004100000410000000002013321140127025217 0ustar www-datawww-data:gfm_quirks: [] kramdown-1.17.0/test/testcases_gfm/backticks_syntax.html0000644000004100000410000000103413321140127023502 0ustar www-datawww-data
Three backticks
Four backticks
Unbalanced bottom heavy
1language no space
1language with space
kramdown-1.17.0/test/testcases_gfm/header_ids.options0000644000004100000410000000002013321140127022746 0ustar www-datawww-data:auto_ids: true kramdown-1.17.0/test/testcases_gfm/hard_line_breaks_off.text0000644000004100000410000000011113321140127024257 0ustar www-datawww-dataThis is just a normal paragraph. Containing a manual line break above. kramdown-1.17.0/test/testcases_gfm/hard_line_breaks_off.options0000644000004100000410000000002213321140127024767 0ustar www-datawww-data:hard_wrap: false kramdown-1.17.0/test/testcases_gfm/paragraph_end.html0000644000004100000410000000066113321140127022736 0ustar www-datawww-data

A

  • b

This is a list

  • or is it

blockquote

text

header

text

codeblock fenced

puts hello world
  • level 1
    some text

    begin level 2

    • level 2
    • level 2

h1

h2

h3

kramdown-1.17.0/test/testcases_gfm/strikethrough.text0000644000004100000410000000067313321140127023070 0ustar www-datawww-data~~This is a test~~ ~~~This is another test~~~ ~~This is yet another test~~~ ~~ This is a test of it NOT working ~~ ~~ This is a **multiline** test ~~ This is an ~~_inline_ **strikethrough**~~ test This is an \~~escaped~~ strikethrough. This is a ~~strikethrough with a ~ in the middle~~ I ~~don't even~~~ have an extra tilde. This should ~~not be struck. This ~~is a complex *strike* through *test ~~with nesting~~ involved* here~~. kramdown-1.17.0/test/testcases_gfm/no_typographic.html0000644000004100000410000000023013321140127023160 0ustar www-datawww-data

Header with --ndash

with --- << typographic >> ... symbols

kramdown-1.17.0/test/testcases_gfm/header_ids.html.190000644000004100000410000000116213321140127022457 0ustar www-datawww-data

test

variable_name

abc def öúß

192 abc 192

;.;;

variable_name

variable_name

;;

before after tab

with code

with  ä space

With “smart” quotes

with — « typographic » … symbols

with

kramdown-1.17.0/test/testcases_gfm/backticks_disable_highlighting.options0000644000004100000410000000002713321140127027034 0ustar www-datawww-data:enable_coderay: false kramdown-1.17.0/test/testcases_gfm/header_ids_with_prefix.text0000644000004100000410000000002213321140127024651 0ustar www-datawww-data# Header 1 # 123 kramdown-1.17.0/test/testcases_gfm/task_list.html0000644000004100000410000000276113321140127022143 0ustar www-datawww-data

unordered task list

  • first ul task item
  • second ul task item
  • third ul task item
  • fourth ul task item [ ] next

unordered list

  • first ul item

  • test
    
  • second ul item

ordered list

  1. first ol item
  2. second ol item

ordered task list

  1. first ol task item
  2. second ol task item
  3. third ol task item
  4. fourth ol task item
kramdown-1.17.0/test/testcases_gfm/paragraph_end-disabled.text0000644000004100000410000000030313321140127024514 0ustar www-datawww-dataA - b This is a list - or is it blockquote > text header # text codeblock fenced ``` puts hello world ``` * level 1 some text begin level 2 * level 2 * level 2 # h1 ## h2 ### h3 kramdown-1.17.0/test/testcases_gfm/header_ids_with_prefix.options0000644000004100000410000000005013321140127025361 0ustar www-datawww-data:auto_ids: true :auto_id_prefix: hallo- kramdown-1.17.0/test/testcases_gfm/hard_line_breaks_off.html0000644000004100000410000000012413321140127024243 0ustar www-datawww-data

This is just a normal paragraph.
Containing a manual line break above.

kramdown-1.17.0/test/testcases_gfm/strikethrough.html.190000644000004100000410000000120613321140127023271 0ustar www-datawww-data

This is a test

~This is another test~

This is yet another test~

~~ This is a test of it NOT working ~~

~~
This
is
a
multiline
test
~~

This is an inline strikethrough test

This is an ~~escaped~~ strikethrough.

This is a strikethrough with a ~ in the middle

I don’t even~ have an extra tilde.

This should ~~not be struck.

This is a complex strike through *test ~~with nesting involved* here~~.

kramdown-1.17.0/test/testcases_gfm/codeblock_fenced.html0000644000004100000410000000052113321140127023367 0ustar www-datawww-data

normal

require 'kramdown'

Kramdown::Document.new(text).to_html

indent with tab

```ruby
require 'kramdown'

Kramdown::Document.new(text).to_html
```

indent with 2 spaces

  console.log("hello");
kramdown-1.17.0/test/testcases_gfm/hard_line_breaks.text0000644000004100000410000000002013321140127023424 0ustar www-datawww-dataone _two_ three kramdown-1.17.0/test/testcases_gfm/atx_header.text0000644000004100000410000000002513321140127022261 0ustar www-datawww-data# header #no header kramdown-1.17.0/test/test_string_scanner_kramdown.rb0000644000004100000410000000145113321140127022731 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'minitest/autorun' require 'kramdown/utils/string_scanner' describe Kramdown::Utils::StringScanner do [ ["...........X............", [/X/], 1], ["1\n2\n3\n4\n5\n6X", [/X/], 6], ["1\n2\n3\n4\n5\n6X\n7\n8X", [/X/,/X/], 8], [(".\n" * 1000) + 'X', [/X/], 1001] ].each_with_index do |test_data, i| test_string, scan_regexes, expect = test_data it "computes the correct current_line_number for example ##{i+1}" do str_sc = Kramdown::Utils::StringScanner.new(test_string) scan_regexes.each { |scan_re| str_sc.scan_until(scan_re) } str_sc.current_line_number.must_equal expect end end end kramdown-1.17.0/test/testcases/0000755000004100000410000000000013321140127016421 5ustar www-datawww-datakramdown-1.17.0/test/testcases/man/0000755000004100000410000000000013321140127017174 5ustar www-datawww-datakramdown-1.17.0/test/testcases/man/heading-name-description.text0000644000004100000410000000013713321140127024741 0ustar www-datawww-data# name description {: data-section="1" data-date="November 2016" data-extra="Something extra"} kramdown-1.17.0/test/testcases/man/heading-name-dash-description.man0000644000004100000410000000010613321140127025441 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "7" .SH NAME name \- description kramdown-1.17.0/test/testcases/man/sections.man0000644000004100000410000000007513321140127021522 0ustar www-datawww-data.\" generated by kramdown .SH "NAME" works .SS "Sub section" kramdown-1.17.0/test/testcases/man/heading-name.text0000644000004100000410000000000713321140127022414 0ustar www-datawww-data# name kramdown-1.17.0/test/testcases/man/example.text0000644000004100000410000000344013321140127021536 0ustar www-datawww-data# name(1) - description {: data-date="November 2016" data-extra="Some extra data"} ## SYNOPSIS `name` \[`OPTIONS`\] *arguments*... ## DESCRIPTION This is a normal paragraph. * A * compact * list * with multiple * items and * nested * as well {:.compact} > blockquotes are fine > > 1. numbered lists > > 2. work too > 1. and they > 2. can be > 1. nested > > 3. again ~~~ Some fancy code going on here ~~~ `-o` `--option` : Description lists : are useful as well And compact definition lists: `o` : Option `k` : Key `v` : Value {:.compact} | tables | can | be | centered | {:.center} |-----------------+------------+-----------------+----------------| | Default aligned |Left aligned| Center aligned | Right aligned | |-----------------|:-----------|:---------------:|---------------:| | First body part |Second cell | Third cell | fourth cell | | Second *line* |foo | **strong** | baz | | Third line |`quux` | baz | bar | |-----------------+------------+-----------------+----------------| | Second body | | | | | 2nd line | | | | |=================+============+=================+================| | Footer row one | | | | | Footer row two | | | | |-----------------+------------+-----------------+----------------| Inline formatting like *emphasis*, **strong** and `code span` work as ususal. [Links](are_well.html) work, too! As do\\ line breaks. Abbreviations like MD can be used but the abbreviation title is ignored. *[MD]: Markdown Math elements work $$\l = 5$$ inline and in block form: $$\lambda_5 = \alpha + 4$$ kramdown-1.17.0/test/testcases/man/example.man0000644000004100000410000000272713321140127021334 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" "November 2016" "Some extra data" .SH NAME name \- description .SH "SYNOPSIS" \fBname\fP [\fBOPTIONS\fP] \fIarguments\fP\.\.\. .SH "DESCRIPTION" This is a normal paragraph\. .sp .PD 0 .IP \(bu 4 A .IP \(bu 4 compact .IP \(bu 4 list .IP \(bu 4 with multiple .RS .IP \(bu 4 items and .RS .IP \(bu 4 nested .RE .RE .IP \(bu 4 as well .PD .RS .P blockquotes are fine .IP 1. 4 numbered lists .IP 2. 4 work too .RS .IP 1. 4 and they .IP 2. 4 can be .RS .IP 1. 4 nested .RE .RE .IP 3. 4 again .RE .sp .RS 4 .EX Some fancy code going on here .EE .RE .TP \fB\-o\fP .TQ \fB\-\-option\fP Description lists .sp are useful as well .P And compact definition lists: .sp .PD 0 .TP \fBo\fP Option .TP \fBk\fP Key .TP \fBv\fP Value .PD .TS box center ; l l l l . tables can be centered .TE .sp .TS box ; lb lb cb rb . Default aligned Left aligned Center aligned Right aligned = .T& l l c r . First body part Second cell Third cell fourth cell Second \fIline\fP foo \fBstrong\fP baz Third line \fBquux\fP baz bar _ .T& l l c r . Second body 2nd line = Footer row one Footer row two .TE .sp .P Inline formatting like \fIemphasis\fP, \fBstrong\fP and \fBcode span\fP work as ususal\. .UR are_well\.html Links .UE work, too! As do .br line breaks\. .P Abbreviations like MD can be used but the abbreviation title is ignored\. .P Math elements work \fB\el = 5\fP inline and in block form: .sp .RS 4 .EX \elambda_5 = \ealpha + 4 .EE .RE kramdown-1.17.0/test/testcases/man/heading-name.man0000644000004100000410000000005113321140127022202 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "7" kramdown-1.17.0/test/testcases/man/text-escaping.man0000644000004100000410000000021213321140127022437 0ustar www-datawww-data.\" generated by kramdown \&\. at the start of the line .P line with \efB backslash symbol .P some \. other \- escaped \' symbols .P \&\. kramdown-1.17.0/test/testcases/man/heading-name-section.text0000644000004100000410000000001213321140127024052 0ustar www-datawww-data# name(1) kramdown-1.17.0/test/testcases/man/heading-name-section.man0000644000004100000410000000005113321140127023644 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" kramdown-1.17.0/test/testcases/man/heading-name-section-description.man0000644000004100000410000000010613321140127026166 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" .SH NAME name \- description kramdown-1.17.0/test/testcases/man/heading-name-description.man0000644000004100000410000000015013321140127024523 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" "November 2016" "Something extra" .SH NAME name \- description kramdown-1.17.0/test/testcases/man/heading-name-section-description.text0000644000004100000410000000003113321140127026374 0ustar www-datawww-data# name(1) -- description kramdown-1.17.0/test/testcases/man/text-escaping.text0000644000004100000410000000014113321140127022651 0ustar www-datawww-data. at the start of the line line with \fB backslash symbol some . other - escaped \' symbols . kramdown-1.17.0/test/testcases/man/heading-name-dash-description.text0000644000004100000410000000002613321140127025653 0ustar www-datawww-data# name -- description kramdown-1.17.0/test/testcases/man/sections.text0000644000004100000410000000011513321140127021726 0ustar www-datawww-data## NAME works ### Sub section #### Ignored ##### Ignored ###### Ignored kramdown-1.17.0/test/testcases/encoding.text0000644000004100000410000000120213321140127021110 0ustar www-datawww-dataDas ist gewöhnlich *ein* [Über-Problem](http://example.org) mit manchen Sälen und anderen Dinge. Siehe ![Über mich](http://example.org)! > Vielleicht *höre*{:.red} ich nicht richtig? {:.test} * Sollten wir uns das überl*egen*? *Verhöhne* mich nicht! * Ho ho höher! Sind \*wir\* da? Titel sind urschön ================== ## Manche mögens *ärmer* {#hot} öha was nun? Töne : Laute Geräusche : vielleicht noch was ä*hnliches* | hoch | höher | am höchsten | |----------------------------| | über | drüber | müde |

Das ist schön gemacht

kramdown-1.17.0/test/testcases/block/0000755000004100000410000000000013321140127017513 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/16_toc/0000755000004100000410000000000013321140127020606 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/16_toc/toc_levels.text0000644000004100000410000000030713321140127023653 0ustar www-datawww-data* Here comes the table of content {:toc} # Header level 1 ## Header \\\` level 2 ### Header level 3 #### Header level 4 # Other header level 1 ## Other header level 2 ### Other header level 3 kramdown-1.17.0/test/testcases/block/16_toc/toc_levels.html0000644000004100000410000000147713321140127023644 0ustar www-datawww-data

Header level 1

Header \` level 2

Header level 3

Header level 4

Other header level 1

Other header level 2

Other header level 3

kramdown-1.17.0/test/testcases/block/16_toc/toc_with_links.options0000644000004100000410000000005113321140127025237 0ustar www-datawww-data:auto_ids: true :auto_id_stripping: true kramdown-1.17.0/test/testcases/block/16_toc/toc_levels.options0000644000004100000410000000004213321140127024356 0ustar www-datawww-data:toc_levels: 2..3 :auto_ids: true kramdown-1.17.0/test/testcases/block/16_toc/toc_with_footnotes.html0000644000004100000410000000062013321140127025412 0ustar www-datawww-data

Header1 level 1

  1. Some footnote content here 

kramdown-1.17.0/test/testcases/block/16_toc/toc_with_footnotes.text0000644000004100000410000000014113321140127025430 0ustar www-datawww-data* Here comes the table of content {:toc} # Header[^1] level 1 [^1]: Some footnote content here kramdown-1.17.0/test/testcases/block/16_toc/toc_exclude.html0000644000004100000410000000241613321140127023775 0ustar www-datawww-data

Contents

Header level 1

Header level 2

Header level 3

Header level 4

Other header level 1

Other header level 2

Other header level 3

kramdown-1.17.0/test/testcases/block/16_toc/toc_exclude.text0000644000004100000410000000033113321140127024007 0ustar www-datawww-data# Contents {:.no_toc} * Here comes the table of content {:toc} # Header level 1 ## Header level 2 ### Header level 3 #### Header level 4 # Other header level 1 ## Other header level 2 ### Other header level 3 kramdown-1.17.0/test/testcases/block/16_toc/toc_exclude.options0000644000004100000410000000002013321140127024511 0ustar www-datawww-data:auto_ids: true kramdown-1.17.0/test/testcases/block/16_toc/toc_with_footnotes.options0000644000004100000410000000002013321140127026133 0ustar www-datawww-data:auto_ids: true kramdown-1.17.0/test/testcases/block/16_toc/toc_with_links.html0000644000004100000410000000041713321140127024516 0ustar www-datawww-data

Header

Header

kramdown-1.17.0/test/testcases/block/16_toc/no_toc.text0000644000004100000410000000030213321140127022770 0ustar www-datawww-data* Here comes the table of content {:toc} # Header level 1 ## Header level 2 ### Header level 3 #### Header level 4 # Other header level 1 ## Other header level 2 ### Other header level 3 kramdown-1.17.0/test/testcases/block/16_toc/toc_with_links.text0000644000004100000410000000007213321140127024533 0ustar www-datawww-data# [Header] # [Header] [header]: test.html * toc {:toc} kramdown-1.17.0/test/testcases/block/16_toc/no_toc.html0000644000004100000410000000030113321140127022747 0ustar www-datawww-data

Header level 1

Header level 2

Header level 3

Header level 4

Other header level 1

Other header level 2

Other header level 3

kramdown-1.17.0/test/testcases/block/13_definition_list/0000755000004100000410000000000013321140127023201 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/13_definition_list/with_blocks.text0000644000004100000410000000025013321140127026414 0ustar www-datawww-datakram : this is some text : this is some more text kram : > blockquote kram : code kram : kram : down kram : # header kram : * list * items kramdown-1.17.0/test/testcases/block/13_definition_list/too_much_space.html0000644000004100000410000000004413321140127027055 0ustar www-datawww-data

para

: no definition

kramdown-1.17.0/test/testcases/block/13_definition_list/para_wrapping.text0000644000004100000410000000005613321140127026742 0ustar www-datawww-dataterm : definition : definition : definition kramdown-1.17.0/test/testcases/block/13_definition_list/definition_at_beginning.html0000644000004100000410000000002713321140127030722 0ustar www-datawww-data

: no definition

kramdown-1.17.0/test/testcases/block/13_definition_list/item_ial.html0000644000004100000410000000054513321140127025656 0ustar www-datawww-data
item
definition continued
another {:.cls}
code
IAL at last no code bc of text
term
definition
term1
term2
definition
kramdown-1.17.0/test/testcases/block/13_definition_list/separated_by_eob.html0000644000004100000410000000012613321140127027355 0ustar www-datawww-data
kram
down
kram
down
kramdown-1.17.0/test/testcases/block/13_definition_list/styled_terms.html0000644000004100000410000000006413321140127026605 0ustar www-datawww-data
kram
down
kramdown-1.17.0/test/testcases/block/13_definition_list/definition_at_beginning.text0000644000004100000410000000002013321140127030733 0ustar www-datawww-data: no definition kramdown-1.17.0/test/testcases/block/13_definition_list/deflist_ial.text0000644000004100000410000000006313321140127026365 0ustar www-datawww-data{:.dl-horizontal} item : definition {:.dl-other} kramdown-1.17.0/test/testcases/block/13_definition_list/auto_ids.text0000644000004100000410000000015013321140127025712 0ustar www-datawww-data{:auto_ids} item : def item2 : def ^ {:auto_ids-prefix-} item : def item2 : def {:#id} item3 : def kramdown-1.17.0/test/testcases/block/13_definition_list/auto_ids.html0000644000004100000410000000036513321140127025702 0ustar www-datawww-data
item
def
item2
def
item
def
item2
def
item3
def
kramdown-1.17.0/test/testcases/block/13_definition_list/multiple_terms.text0000644000004100000410000000011713321140127027153 0ustar www-datawww-datakram *down* now : definition 1 : definition 2 : definition 3 : definition 4 kramdown-1.17.0/test/testcases/block/13_definition_list/separated_by_eob.text0000644000004100000410000000003213321140127027371 0ustar www-datawww-datakram : down ^ kram : down kramdown-1.17.0/test/testcases/block/13_definition_list/deflist_ial.html0000644000004100000410000000012013321140127026337 0ustar www-datawww-data
item
definition
kramdown-1.17.0/test/testcases/block/13_definition_list/para_wrapping.html0000644000004100000410000000017313321140127026722 0ustar www-datawww-data
term

definition

definition

definition

kramdown-1.17.0/test/testcases/block/13_definition_list/simple.text0000644000004100000410000000006313321140127025377 0ustar www-datawww-datakram : down novalue : kram : down kram : down kramdown-1.17.0/test/testcases/block/13_definition_list/styled_terms.text0000644000004100000410000000001613321140127026622 0ustar www-datawww-data*kram* : down kramdown-1.17.0/test/testcases/block/13_definition_list/too_much_space.text0000644000004100000410000000002713321140127027076 0ustar www-datawww-datapara : no definition kramdown-1.17.0/test/testcases/block/13_definition_list/no_def_list.text0000644000004100000410000000005413321140127026373 0ustar www-datawww-dataThis is a para \: and not a definition list kramdown-1.17.0/test/testcases/block/13_definition_list/simple.html0000644000004100000410000000017713321140127025365 0ustar www-datawww-data
kram
down
novalue
kram
down kram
down
kramdown-1.17.0/test/testcases/block/13_definition_list/no_def_list.html0000644000004100000410000000006213321140127026352 0ustar www-datawww-data

This is a para : and not a definition list

kramdown-1.17.0/test/testcases/block/13_definition_list/item_ial.text0000644000004100000410000000032213321140127025667 0ustar www-datawww-dataitem : {:.cls} definition continued : another {:.cls} : {:.class} code : {:.cls} IAL at last no code bc of text {:.class} term : definition {:.class1} term1 {:.class2} term2 : definition kramdown-1.17.0/test/testcases/block/13_definition_list/with_blocks.html0000644000004100000410000000075413321140127026405 0ustar www-datawww-data
kram
this is some text

this is some more text

kram

blockquote

kram
code
kram
kram
down
kram

header

kram
  • list
  • items
kramdown-1.17.0/test/testcases/block/13_definition_list/multiple_terms.html0000644000004100000410000000030113321140127027126 0ustar www-datawww-data
kram
down
now
definition 1
definition 2

definition 3

definition 4

kramdown-1.17.0/test/testcases/block/01_blank_line/0000755000004100000410000000000013321140127022111 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/01_blank_line/tabs.html0000644000004100000410000000000113321140127023717 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/01_blank_line/tabs.text0000644000004100000410000000001613321140127023745 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/01_blank_line/spaces.text0000644000004100000410000000002013321140127024265 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/01_blank_line/spaces.html0000644000004100000410000000000113321140127024244 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/05_blockquote/0000755000004100000410000000000013321140127022167 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/05_blockquote/indented.html0000644000004100000410000000052613321140127024652 0ustar www-datawww-data

A normal blockquote.

A normal blockquote.

A normal blockquote.

A normal blockquote.

> A codeblock

Blockquote with mixed indents.

kramdown-1.17.0/test/testcases/block/05_blockquote/with_code_blocks.text0000644000004100000410000000020613321140127026375 0ustar www-datawww-data>Example: > > sub status { > print "working"; > } > > Or: > > sub status { > return "working"; > } kramdown-1.17.0/test/testcases/block/05_blockquote/lazy.text0000644000004100000410000000033113321140127024051 0ustar www-datawww-data> This is a long long line. > > Nested quote inside > still inside > > This is a subquote. > > over multipline lines. > continuing here > This is a quote no code > This is a quote {: #id} > This is a quote ^ kramdown-1.17.0/test/testcases/block/05_blockquote/no_newline_at_end.html0000644000004100000410000000011313321140127026517 0ustar www-datawww-data

This is a block quote with no newline.

kramdown-1.17.0/test/testcases/block/05_blockquote/no_newline_at_end.text0000644000004100000410000000005213321140127026541 0ustar www-datawww-data> This is a block quote > with no newline.kramdown-1.17.0/test/testcases/block/05_blockquote/nested.text0000644000004100000410000000004013321140127024351 0ustar www-datawww-data> foo > > > bar >> baz > > foo kramdown-1.17.0/test/testcases/block/05_blockquote/with_code_blocks.html0000644000004100000410000000027413321140127026362 0ustar www-datawww-data

Example:

sub status {
    print "working";
}

Or:

sub status {
    return "working";
}
kramdown-1.17.0/test/testcases/block/05_blockquote/very_long_line.text0000644000004100000410000001576213321140127026123 0ustar www-datawww-data> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. kramdown-1.17.0/test/testcases/block/05_blockquote/very_long_line.html0000644000004100000410000001602413321140127026073 0ustar www-datawww-data

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

kramdown-1.17.0/test/testcases/block/05_blockquote/lazy.html0000644000004100000410000000073113321140127024035 0ustar www-datawww-data

This is a long long line.

Nested quote inside still inside

This is a subquote. over multipline lines. continuing here

This is a quote no code

This is a quote

This is a quote

kramdown-1.17.0/test/testcases/block/05_blockquote/nested.html0000644000004100000410000000015213321140127024335 0ustar www-datawww-data

foo

bar baz

foo

kramdown-1.17.0/test/testcases/block/05_blockquote/indented.text0000644000004100000410000000024213321140127024665 0ustar www-datawww-data> A normal blockquote. > A normal blockquote. > A normal blockquote. > A normal blockquote. > A codeblock > Blockquote > with >mixed > indents. kramdown-1.17.0/test/testcases/block/12_extension/0000755000004100000410000000000013321140127022031 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/12_extension/options3.text0000644000004100000410000000026013321140127024513 0ustar www-datawww-data x = Class.new {: .language-ruby} {::options coderay_wrap="span" coderay_line_numbers="" coderay_css="class" coderay_tab_width="4" /} x = Class.new {: .language-ruby} kramdown-1.17.0/test/testcases/block/12_extension/ignored.text0000644000004100000410000000011613321140127024364 0ustar www-datawww-dataparagraph {::something} anotherthing {:/something} {::something/} paragraph kramdown-1.17.0/test/testcases/block/12_extension/options2.html0000644000004100000410000000036113321140127024474 0ustar www-datawww-data

Some text1.

  1. Some text. 

kramdown-1.17.0/test/testcases/block/12_extension/nomarkdown.text0000644000004100000410000000046613321140127025124 0ustar www-datawww-dataThis is a simple paragraph. {::nomarkdown} This *is* not processed {:/nomarkdown} And another paragraph {::nomarkdown this='is' .ignore /} {::nomarkdown type='html'} bold {:/} {::nomarkdown type="latex"} \begin{itemize} \item[Yes] YESSSS! \end{itemize} {:/} {::nomarkdown} Another paragraph kramdown-1.17.0/test/testcases/block/12_extension/ignored.html0000644000004100000410000000014313321140127024344 0ustar www-datawww-data

paragraph

{::something} anotherthing {:/something}

{::something/} paragraph

kramdown-1.17.0/test/testcases/block/12_extension/options.text0000644000004100000410000000042313321140127024431 0ustar www-datawww-data# No header id {::options unusedvar="val" /} # without header id
some *para*
{::options parse_block_html="true" parse_span_html="true" /}
some *para*
{::options footnote_nr="10" /} Some text[^ab]. [^ab]: Some text. kramdown-1.17.0/test/testcases/block/12_extension/nomarkdown.html0000644000004100000410000000022313321140127025073 0ustar www-datawww-data

This is a simple paragraph.

This *is* not processed

And another paragraph

bold

{::nomarkdown} Another paragraph

kramdown-1.17.0/test/testcases/block/12_extension/options2.text0000644000004100000410000000010513321140127024510 0ustar www-datawww-data{::options footnote_nr="da10" /} Some text[^ab]. [^ab]: Some text. kramdown-1.17.0/test/testcases/block/12_extension/comment.html0000644000004100000410000000024513321140127024362 0ustar www-datawww-data

This is a simple paragraph.

And another paragraph

{::comment} Another paragraph

kramdown-1.17.0/test/testcases/block/12_extension/nomarkdown.kramdown0000644000004100000410000000040713321140127025755 0ustar www-datawww-dataThis is a simple paragraph. {::nomarkdown} This *is* not processed {:/} And another paragraph {::nomarkdown type="html"} bold {:/} {::nomarkdown type="latex"} \begin{itemize} \item[Yes] YESSSS! \end{itemize} {:/} \{::nomarkdown} Another paragraph kramdown-1.17.0/test/testcases/block/12_extension/options.html0000644000004100000410000000061513321140127024414 0ustar www-datawww-data

No header id

without header id

some *para*

some para

Some text10.

  1. Some text. 

kramdown-1.17.0/test/testcases/block/12_extension/nomarkdown.latex0000644000004100000410000000024413321140127025247 0ustar www-datawww-dataThis is a simple paragraph. This *is* not processed And another paragraph \begin{itemize} \item[Yes] YESSSS! \end{itemize} \{::nomarkdown\} Another paragraph kramdown-1.17.0/test/testcases/block/12_extension/comment.text0000644000004100000410000000030013321140127024372 0ustar www-datawww-dataThis is a simple paragraph. {::comment} This is a comment {:/}which is {:/comment} ignored. {:/comment} And another paragraph {::comment this='is' .ignore /} {::comment} Another paragraph kramdown-1.17.0/test/testcases/block/12_extension/options3.html0000644000004100000410000000040113321140127024470 0ustar www-datawww-data
x = Class.new
x = Class.new
kramdown-1.17.0/test/testcases/block/03_paragraph/0000755000004100000410000000000013321140127021762 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/03_paragraph/indented.html0000644000004100000410000000035213321140127024442 0ustar www-datawww-data

This is a para.

This is a para.

This is a para.

This is a para.

This is a code block.

And this is another.

A para with mixed indents. and with much indent

kramdown-1.17.0/test/testcases/block/03_paragraph/with_html_to_native.html0000644000004100000410000000010313321140127026711 0ustar www-datawww-data

some text

kramdown-1.17.0/test/testcases/block/03_paragraph/line_break_last_line.text0000644000004100000410000000014113321140127027011 0ustar www-datawww-dataFirst line First line\\ Last Line Last Line\\ kramdown-1.17.0/test/testcases/block/03_paragraph/indented.html.gfm0000644000004100000410000000040213321140127025206 0ustar www-datawww-data

This is a para.

This is a para.

This is a para.

This is a para.

This is a code block.

And this is another.

A para
with
mixed
indents.
and with much indent

kramdown-1.17.0/test/testcases/block/03_paragraph/no_newline_at_end.html0000644000004100000410000000012113321140127026311 0ustar www-datawww-data

One paragraph over multiple lines.

Second one without newline.

kramdown-1.17.0/test/testcases/block/03_paragraph/with_html_to_native.options0000644000004100000410000000002613321140127027444 0ustar www-datawww-data:html_to_native: true kramdown-1.17.0/test/testcases/block/03_paragraph/no_newline_at_end.text0000644000004100000410000000010413321140127026332 0ustar www-datawww-data One paragraph over multiple lines. Second one without newline.kramdown-1.17.0/test/testcases/block/03_paragraph/one_para.html0000644000004100000410000000005013321140127024427 0ustar www-datawww-data

This is just a normal paragraph.

kramdown-1.17.0/test/testcases/block/03_paragraph/two_para.text0000644000004100000410000000012613321140127024503 0ustar www-datawww-dataThis is just a normal paragraph. That goes on to the second line. Another paragraph. kramdown-1.17.0/test/testcases/block/03_paragraph/line_break_last_line.html0000644000004100000410000000030213321140127026770 0ustar www-datawww-data

First line
https://example.com

First line
https://example.com

Last Line

Last Line\

kramdown-1.17.0/test/testcases/block/03_paragraph/two_para.html0000644000004100000410000000014413321140127024463 0ustar www-datawww-data

This is just a normal paragraph. That goes on to the second line.

Another paragraph.

kramdown-1.17.0/test/testcases/block/03_paragraph/with_html_to_native.text0000644000004100000410000000010313321140127026731 0ustar www-datawww-data

some text kramdown-1.17.0/test/testcases/block/03_paragraph/indented.text0000644000004100000410000000027213321140127024463 0ustar www-datawww-dataThis is a para. This is a para. This is a para. This is a para. This is a code block. And this is another. A para with mixed indents. and with much indent kramdown-1.17.0/test/testcases/block/03_paragraph/one_para.text0000644000004100000410000000004113321140127024447 0ustar www-datawww-dataThis is just a normal paragraph. kramdown-1.17.0/test/testcases/block/04_header/0000755000004100000410000000000013321140127021246 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/04_header/with_auto_id_stripping.options0000644000004100000410000000003113321140127027433 0ustar www-datawww-data:auto_id_stripping: true kramdown-1.17.0/test/testcases/block/04_header/setext_header_no_newline_at_end.html0000644000004100000410000000002013321140127030477 0ustar www-datawww-data

header

kramdown-1.17.0/test/testcases/block/04_header/atx_header.html0000644000004100000410000000114513321140127024241 0ustar www-datawww-data

This is a header

This is a header

This is a header

This is a header

This is a header
This is a header

Header

Header

Header

blockquote

header

paragraph

blockquote ### not a header

header #

header

#

#

Header

Header

Header

Header

Header {#9ab}

Header{#noid}

Header ##{#noid}

Last

kramdown-1.17.0/test/testcases/block/04_header/header_type_offset.kramdown0000644000004100000410000000015013321140127026645 0ustar www-datawww-data## Lorem ipsum ### Lorem ipsum #### Lorem ipsum ###### Lorem ipsum ## Lorem ipsum ### Lorem ipsum kramdown-1.17.0/test/testcases/block/04_header/setext_header_no_newline_at_end.text0000644000004100000410000000001513321140127030523 0ustar www-datawww-dataheader ======kramdown-1.17.0/test/testcases/block/04_header/with_auto_ids.text0000644000004100000410000000031013321140127025010 0ustar www-datawww-data# This is a header ## 12. Another one-1-here ### Do ^& it now Hallo ===== Not now ------- # Hallo # 23232 # 33333 ## hallO # Header without ID {: id=""} # Transliterated: Đây-là-ví-dụ kramdown-1.17.0/test/testcases/block/04_header/header_type_offset.options0000644000004100000410000000004213321140127026516 0ustar www-datawww-data:header_offset: 1 :auto_ids: falsekramdown-1.17.0/test/testcases/block/04_header/atx_header_no_newline_at_end.text0000644000004100000410000000001013321140127027776 0ustar www-datawww-data# headerkramdown-1.17.0/test/testcases/block/04_header/atx_header_no_newline_at_end.html0000644000004100000410000000002013321140127027757 0ustar www-datawww-data

header

kramdown-1.17.0/test/testcases/block/04_header/with_auto_ids.options0000644000004100000410000000006113321140127025522 0ustar www-datawww-data:auto_ids: true :transliterated_header_ids: true kramdown-1.17.0/test/testcases/block/04_header/with_auto_id_prefix.html0000644000004100000410000000010713321140127026166 0ustar www-datawww-data

Header 1

123

kramdown-1.17.0/test/testcases/block/04_header/with_auto_id_stripping.text0000644000004100000410000000005113321140127026726 0ustar www-datawww-data# This is a header kramdown-1.17.0/test/testcases/block/04_header/with_auto_ids.html0000644000004100000410000000065613321140127025005 0ustar www-datawww-data

This is a header

12. Another one-1-here

Do ^& it now

Hallo

Not now

Hallo

23232

33333

hallO

Header without ID

Transliterated: Đây-là-ví-dụ

kramdown-1.17.0/test/testcases/block/04_header/setext_header.text0000644000004100000410000000043013321140127024775 0ustar www-datawww-datatest - test2 ========= test - para header = = This is a para. With two lines. And not a header. ================= > Blockquote. Not a Header - header {#id} ------------ header {#Id} ====== header {#A-Za-z0-9_:} ------ header{#noid} ----- header ------ kramdown-1.17.0/test/testcases/block/04_header/with_auto_id_stripping.html0000644000004100000410000000010613321140127026707 0ustar www-datawww-data

This is a header

kramdown-1.17.0/test/testcases/block/04_header/header_type_offset.html0000644000004100000410000000020313321140127025766 0ustar www-datawww-data

Lorem ipsum

Lorem ipsum

Lorem ipsum

Lorem ipsum

Lorem ipsum

Lorem ipsum

kramdown-1.17.0/test/testcases/block/04_header/header_type_offset.latex0000644000004100000410000000025113321140127026142 0ustar www-datawww-data\subsection*{Lorem ipsum} \subsubsection*{Lorem ipsum} \paragraph*{Lorem ipsum} \subparagraph*{Lorem ipsum} \subsection*{Lorem ipsum} \subsubsection*{Lorem ipsum} kramdown-1.17.0/test/testcases/block/04_header/with_auto_id_prefix.options0000644000004100000410000000005013321140127026712 0ustar www-datawww-data:auto_ids: true :auto_id_prefix: hallo_ kramdown-1.17.0/test/testcases/block/04_header/header_type_offset.text0000644000004100000410000000016513321140127026015 0ustar www-datawww-data# Lorem ipsum ## Lorem ipsum ### Lorem ipsum ###### Lorem ipsum Lorem ipsum =========== Lorem ipsum ----------- kramdown-1.17.0/test/testcases/block/04_header/setext_header.html0000644000004100000410000000056213321140127024763 0ustar www-datawww-data

test

test2

test

para

   header =

=

This is a para. With two lines. And not a header. =================

Blockquote. Not a Header -

header

header

header

header{#noid}

header

kramdown-1.17.0/test/testcases/block/04_header/atx_header.text0000644000004100000410000000066713321140127024271 0ustar www-datawww-data# This is a header ## This is a header ### This is a header #### This is a header ##### This is a header ###### This is a header # Header ^ # Header ##Header ##### > blockquote ###### header paragraph > blockquote ### not a header # header \# # header # # ### Header {#id} ### Header ## {#Id} ### Header ## {#id} ### Header {#A-Za-z0-9_:t} ### Header {#9ab} ### Header{#noid} ### Header ##{#noid} ### Last kramdown-1.17.0/test/testcases/block/04_header/with_auto_id_prefix.text0000644000004100000410000000002213321140127026202 0ustar www-datawww-data# Header 1 # 123 kramdown-1.17.0/test/testcases/block/08_list/0000755000004100000410000000000013321140127020775 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/08_list/simple_ul.text0000644000004100000410000000055013321140127023674 0ustar www-datawww-data* This is a simple list item * Followed by another * Followed by a para list item * and a normal one * and a para para * multi line list item para * list item line1 one line two lines * list item line2 one line two lines para * list item line3 one line two lines * list item line4 one line two lines para kramdown-1.17.0/test/testcases/block/08_list/item_ial.html0000644000004100000410000000024413321140127023446 0ustar www-datawww-data
  • IAL at first continued
  • another {:.cls}
  • IAL at last code
  • X test
  • X OK
kramdown-1.17.0/test/testcases/block/08_list/brackets_in_item.latex0000644000004100000410000000007013321140127025333 0ustar www-datawww-data\begin{itemize} \item{} {[}and{]} another \end{itemize} kramdown-1.17.0/test/testcases/block/08_list/lazy.text0000644000004100000410000000043513321140127022664 0ustar www-datawww-data* This is a simple list item * Followed by another list item * Followed by a para list item continued here * and a normal one * and a para continued here para * multi line list item para * list item line1 one line two lines * list item line2 one line two lines kramdown-1.17.0/test/testcases/block/08_list/mixed.html0000644000004100000410000000244313321140127022774 0ustar www-datawww-data

With tabs/spaces, no paras:

  • item1
  • item2
  • item3

With tabs/spaces, paras:

  • item1

  • item2

  • item3

With tabs/spaces, no paras:

  1. item1
  2. item2
  3. item3

With tabs/spaces, paras:

  1. item1

  2. item2

  3. item3

Nested, without paras:

  • item1
    • item2
      • item3

Nested, with paras:

  • item1

    • item2
      • item3 (level 3)

Ordered, without paras:

  1. item1
  2. item2
    • do
    • it
    • now
  3. item3

Ordered, with paras:

  1. item1

  2. item2

    • do
    • it
    • now
  3. item3

Mixed tabs and spaces:

  • some text
    • nested
kramdown-1.17.0/test/testcases/block/08_list/brackets_in_item.text0000644000004100000410000000002213321140127025177 0ustar www-datawww-data* \[and\] another kramdown-1.17.0/test/testcases/block/08_list/list_and_others.text0000644000004100000410000000022413321140127025062 0ustar www-datawww-data* list item > blockquote para * * * para - no list + item > block ## header * test codeblock test * test codeblock test kramdown-1.17.0/test/testcases/block/08_list/single_item.html0000644000004100000410000000003513321140127024160 0ustar www-datawww-data
  • single
kramdown-1.17.0/test/testcases/block/08_list/list_and_others.html0000644000004100000410000000063313321140127025046 0ustar www-datawww-data
  • list item

blockquote

para * * * para - no list

  • item

    block

    header

  • test

    codeblock
    

    test

  • test

    codeblock
    

    test

kramdown-1.17.0/test/testcases/block/08_list/simple_ol.text0000644000004100000410000000021213321140127023661 0ustar www-datawww-data1. This is a simple list item 3. Followed by another 10. Followed by a para list item 1. and a normal one 2. and a para para kramdown-1.17.0/test/testcases/block/08_list/other_first_element.text0000644000004100000410000000041113321140127025740 0ustar www-datawww-data* This is a code block. * > This is a blockquote. * ## A header ^ * This is a code block. * > This is a blockquote. continued by some para. * A header ========= a para ^ * * nested list * other nested item * item 2 kramdown-1.17.0/test/testcases/block/08_list/simple_ol.html0000644000004100000410000000037413321140127023652 0ustar www-datawww-data
  1. This is a simple list item
  2. Followed by another

  3. Followed by

    a para list item

  4. and a normal one
  5. and

    a para

para

kramdown-1.17.0/test/testcases/block/08_list/escaping.html0000644000004100000410000000044213321140127023454 0ustar www-datawww-data

I have read the book 1984. It was great - other say that, too!

I have read the book 1984. It was great - other say that, too!

I have read the book 1984. It was great.

I have read the book 1984. - it was great!

1984. Was great!

- This too!

kramdown-1.17.0/test/testcases/block/08_list/escaping.text0000644000004100000410000000037413321140127023500 0ustar www-datawww-dataI have read the book 1984. It was great - other say that, too! I have read the book 1984\. It was great \- other say that, too! I have read the book 1984. It was great. I have read the book 1984. - it was great! 1984\. Was great! \- This too! kramdown-1.17.0/test/testcases/block/08_list/mixed.text0000644000004100000410000000106713321140127023015 0ustar www-datawww-dataWith tabs/spaces, no paras: * item1 + item2 - item3 With tabs/spaces, paras: - item1 * item2 + item3 With tabs/spaces, no paras: 1. item1 20. item2 3. item3 With tabs/spaces, paras: 1. item1 2. item2 3. item3 Nested, without paras: * item1 * item2 * item3 Nested, with paras: + item1 * item2 * item3 (level 3) Ordered, without paras: 1. item1 2. item2 * do * it * now 3. item3 Ordered, with paras: 1. item1 2. item2 * do * it * now 3. item3 Mixed tabs and spaces: * some text * nested kramdown-1.17.0/test/testcases/block/08_list/special_cases.text0000644000004100000410000000046313321140127024504 0ustar www-datawww-data* not a para here > blockquote * and not here >blockquote * this is a para * > blockquote * this too ^ A paragraph 1. followed not by ol - followed not by ul A compact list: * compact * list * items A normal list: * not * compact * but here List item without content: * * a kramdown-1.17.0/test/testcases/block/08_list/single_item.text0000644000004100000410000000001113321140127024172 0ustar www-datawww-data* single kramdown-1.17.0/test/testcases/block/08_list/lazy_and_nested.text0000644000004100000410000000011213321140127025040 0ustar www-datawww-data1. Root level * Second level * Third level * Back to second level kramdown-1.17.0/test/testcases/block/08_list/other_first_element.html0000644000004100000410000000106313321140127025724 0ustar www-datawww-data
  • This is a code block.
    
  • This is a blockquote.

  • A header

  • This is a code block.
    
  • This is a blockquote. continued by some para.

  • A header

    a para

    • nested list
    • other nested item
  • item 2
kramdown-1.17.0/test/testcases/block/08_list/special_cases.html0000644000004100000410000000132313321140127024460 0ustar www-datawww-data
  • not a para here

    blockquote

  • and not here

    blockquote

  • this is a para

  • blockquote

  • this too

A paragraph 1. followed not by ol - followed not by ul

A compact list:

  • compact
  • list
  • items

A normal list:

  • not

  • compact

  • but here

List item without content:

  • a
kramdown-1.17.0/test/testcases/block/08_list/nested.text0000644000004100000410000000007613321140127023170 0ustar www-datawww-data* some item * nested * last item ^ * some text * nested kramdown-1.17.0/test/testcases/block/08_list/list_and_hr.text0000644000004100000410000000006013321140127024165 0ustar www-datawww-data* Starting a list * * * * Starting a new list kramdown-1.17.0/test/testcases/block/08_list/lazy.html0000644000004100000410000000071013321140127022640 0ustar www-datawww-data
  • This is a simple list item
  • Followed by another list item

  • Followed by

    a para list item continued here

  • and a normal one
  • and

    a para continued here

para

  • multi line list item

para

  • list item line1 one line two lines
  • list item line2 one line two lines
kramdown-1.17.0/test/testcases/block/08_list/nested.html0000644000004100000410000000027213321140127023146 0ustar www-datawww-data
  • some item
    • nested
  • last item
  • some text

    • nested
kramdown-1.17.0/test/testcases/block/08_list/simple_ul.html0000644000004100000410000000104213321140127023651 0ustar www-datawww-data
  • This is a simple list item
  • Followed by another

  • Followed by

    a para list item

  • and a normal one
  • and

    a para

para

  • multi line list item

para

  • list item line1 one line two lines
  • list item line2 one line two lines

para

  • list item line3 one line two lines
  • list item line4 one line two lines

para

kramdown-1.17.0/test/testcases/block/08_list/lazy_and_nested.html0000644000004100000410000000020013321140127025016 0ustar www-datawww-data
  1. Root level * Second level
    • Third level * Back to second level
kramdown-1.17.0/test/testcases/block/08_list/item_ial.text0000644000004100000410000000027613321140127023473 0ustar www-datawww-data* {:.cls} IAL at first continued * another {:.cls} * {:.cls} IAL at last code * {::nomarkdown type="html"}X{:/nomarkdown} test * {::nomarkdown type="html"}X{:/nomarkdown} OK kramdown-1.17.0/test/testcases/block/08_list/list_and_hr.html0000644000004100000410000000013113321140127024144 0ustar www-datawww-data
  • Starting a list

  • Starting a new list
kramdown-1.17.0/test/testcases/block/14_table/0000755000004100000410000000000013321140127021106 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/14_table/empty_tag_in_cell.options0000644000004100000410000000002613321140127026177 0ustar www-datawww-data:html_to_native: true kramdown-1.17.0/test/testcases/block/14_table/table_with_footnote.html0000644000004100000410000000072213321140127026034 0ustar www-datawww-data
this is 1 a table
with a footnote
  1. Something

    special here

kramdown-1.17.0/test/testcases/block/14_table/no_table.text0000644000004100000410000000004313321140127023574 0ustar www-datawww-dataNo table \| Some \| thing \| here kramdown-1.17.0/test/testcases/block/14_table/header.html0000644000004100000410000000362113321140127023226 0ustar www-datawww-data

Simple header

cell1 cell2
cell3 cell4

Full header

cell1 cell2
cell3 cell4

With alignment and superfluous alignment defs

default left center right default
cell1 cell2 cell3 cell4 cell5

With leading sep line

cell1 cell2
cell3 cell4

Multiple bodies

cell1 cell2
cell3 cell4
cell5 cell6

Sep line with tab

right center
cell1 cell2
cell3 cell4
kramdown-1.17.0/test/testcases/block/14_table/table_with_footnote.latex0000644000004100000410000000023513321140127026204 0ustar www-datawww-data\begin{longtable}{|l|l|} \hline this is \footnote{Something \begin{quote} special here \end{quote}} & a table\\ with a & footnote\\ \hline \end{longtable} kramdown-1.17.0/test/testcases/block/14_table/header.text0000644000004100000410000000101613321140127023242 0ustar www-datawww-dataSimple header | cell1 | cell2 |----- | cell3 | cell4 Full header | cell1 | cell2 |-------|-------| | cell3 | cell4 With alignment and superfluous alignment defs | default | left | center | right | default |-| :- |:-: | -: | - | :-: | :- | cell1 | cell2 | cell3 | cell4 | cell5 With leading sep line |:-:|-:| | cell1 | cell2 |-------|-------| | cell3 | cell4 Multiple bodies | cell1 | cell2 + :-: | | cell3 | cell4 |----||| | cell5 | cell6 Sep line with tab right | center ---: | :---: cell1 | cell2 cell3 | cell4 kramdown-1.17.0/test/testcases/block/14_table/empty_tag_in_cell.html0000644000004100000410000000022013321140127025444 0ustar www-datawww-data
first line of cell
second line of cell
another cell
kramdown-1.17.0/test/testcases/block/14_table/errors.html0000644000004100000410000000016313321140127023310 0ustar www-datawww-data

No table body

|-|-|-

|no|table|here|

|no|table|here| paragraph

|-|-| |-|-|

kramdown-1.17.0/test/testcases/block/14_table/escaping.html0000644000004100000410000000140513321140127023565 0ustar www-datawww-data

cell 1 | cell 2

cell 1 | cell 2

cell 1 cell 2 | continued
cell 1 cell 2
cell 1 code | span

cell 1 code | span

cell 1 | code | span

cell 1 cell `2 cell 3
cell 1` cell 2 cell 3

cell 1 | cell 2 | cell 3 cell 1 | cell 2 | cell 3

kramdown-1.17.0/test/testcases/block/14_table/escaping.text0000644000004100000410000000040713321140127023606 0ustar www-datawww-data`cell 1 | cell 2` cell 1 \| cell 2 cell 1 | cell 2 \| continued cell 1 | cell `2` cell 1 | `code | span` cell 1 `code | span` cell 1 \| `code | span` cell 1 | cell `2 | cell 3 cell 1` | cell 2 | cell 3 cell 1 \| cell `2 | cell 3 cell 1` | cell 2 | cell 3 kramdown-1.17.0/test/testcases/block/14_table/empty_tag_in_cell.text0000644000004100000410000000007513321140127025474 0ustar www-datawww-data| first line of cell
second line of cell | another cell | kramdown-1.17.0/test/testcases/block/14_table/footer.text0000644000004100000410000000037613321140127023320 0ustar www-datawww-dataSimple footer | cell1 | cell2 |= | cell3 | cell4 Full footer | cell1 | cell2 |=======|=======| | cell3 | cell4 Footer with separator lines | cell1 | cell2 |=======|=======| | cell3 | cell4 |--- | cell5 | cell6 |--- Empty footer | cell1 | cell2 |= kramdown-1.17.0/test/testcases/block/14_table/simple.text0000644000004100000410000000140513321140127023305 0ustar www-datawww-data| cell1 | cell2 | |cell3 | cell4| |cell5|cell6 \| | cell7|cell8 Missing cells at end | cell1 | cell2 | cell3 | | cell1 || || cell2 | cell3 Escaped pipe characters | cell1 \| cell1 | cell2 | | cell1 | cell2 \| | cell1 `|` con | cell2 Table with code elements | This is a span | with a pipe. | Some span | here | a span | with a | pipe. Special cases regarding codespan syntax |a|`b` |`a` {:.cls} | table | with | ial | table | with | ial {:.cls} not starting with a bar simple | table head1 | head2 ------|------ cell1 | cell2 head1 | head2 -------|------ | cell2 | a | b | c | d | e | f | | Key | Value type | |--------|------------------------| | `Type` | `"GROUP"`\|`"UNKNOWN"` | kramdown-1.17.0/test/testcases/block/14_table/table_with_footnote.text0000644000004100000410000000012213321140127026046 0ustar www-datawww-data| this is [^1] | a table | with a | footnote [^1]: Something > special here kramdown-1.17.0/test/testcases/block/14_table/footer.html0000644000004100000410000000144513321140127023276 0ustar www-datawww-data

Simple footer

cell1 cell2
cell3 cell4

Full footer

cell1 cell2
cell3 cell4

Footer with separator lines

cell1 cell2
cell3 cell4
cell5 cell6

Empty footer

cell1 cell2
kramdown-1.17.0/test/testcases/block/14_table/no_table.html0000644000004100000410000000005613321140127023560 0ustar www-datawww-data

No table

| Some | thing | here

kramdown-1.17.0/test/testcases/block/14_table/simple.html0000644000004100000410000000513513321140127023271 0ustar www-datawww-data
cell1 cell2
cell3 cell4
cell5 cell6 |
cell7 cell8

Missing cells at end

cell1 cell2 cell3
cell1    
  cell2 cell3

Escaped pipe characters

cell1 | cell1 cell2
cell1 cell2 |
cell1 | con cell2

Table with code elements

This is a span | with a pipe.      
Some span </em> here a span | with a pipe.

Special cases regarding codespan syntax

a b
a
table with ial
table with ial

not starting with a bar

simple table
head1 head2
cell1 cell2
head1 head2
  cell2
a b
c d
e f
Key Value type
Type "GROUP"|"UNKNOWN"
kramdown-1.17.0/test/testcases/block/14_table/errors.text0000644000004100000410000000013213321140127023324 0ustar www-datawww-dataNo table body |-|-|- [5]: test |no|table|here| |no|table|here| paragraph |-|-| |-|-| kramdown-1.17.0/test/testcases/block/11_ial/0000755000004100000410000000000013321140127020561 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/11_ial/auto_id_and_ial.html0000644000004100000410000000005013321140127024535 0ustar www-datawww-data

A header

kramdown-1.17.0/test/testcases/block/11_ial/simple.text0000644000004100000410000000074713321140127022770 0ustar www-datawww-dataSome paragraph. {:.class .-class id key="val"} Some paragraph. {:.cls1#id.cls2} > quote {: #id} {: .class} * list {: key="val"} code block {: #other} other code block ## A header {:#myid} {:.cls} Some paragraph here {:.cls1} {:.cls2} Some paragraph here Paragraph {:.cls} Paragraph Another header ============== {: .class #other} {:id: #id key="valo"} {:id: #other .myclass other} {:other: key1="val\"" - ig.nored as_is#this key2='val\'' .other-class} {:.invalid} kramdown-1.17.0/test/testcases/block/11_ial/nested.text0000644000004100000410000000014713321140127022753 0ustar www-datawww-data{:.cls}
test
{:#id} {:.cls}
test
{:#id} {:.cls} > para {:#id} kramdown-1.17.0/test/testcases/block/11_ial/auto_id_and_ial.options0000644000004100000410000000002013321140127025261 0ustar www-datawww-data:auto_ids: true kramdown-1.17.0/test/testcases/block/11_ial/auto_id_and_ial.text0000644000004100000410000000003213321140127024555 0ustar www-datawww-data## A header {:#myid .cls} kramdown-1.17.0/test/testcases/block/11_ial/nested.html0000644000004100000410000000022413321140127022727 0ustar www-datawww-data
test

test

para

kramdown-1.17.0/test/testcases/block/11_ial/simple.html0000644000004100000410000000107313321140127022741 0ustar www-datawww-data

Some paragraph.

Some paragraph.

quote

  • list
code block
other code block

A header

Some paragraph here

Some paragraph here

Paragraph

Paragraph

Another header

kramdown-1.17.0/test/testcases/block/15_math/0000755000004100000410000000000013321140127020751 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/15_math/ritex.html0000644000004100000410000000051113321140127022767 0ustar www-datawww-dataf(x)=ax3+bx2+cx+d kramdown-1.17.0/test/testcases/block/15_math/sskatex.text0000644000004100000410000000013113321140127023334 0ustar www-datawww-data$$\Delta = \frac{1}{2} \begin{vmatrix}a & b & c \\ d & e & f \\ g & h & i\end{vmatrix}$$ kramdown-1.17.0/test/testcases/block/15_math/gh_128.html0000644000004100000410000000012713321140127022627 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview.html0000644000004100000410000000031313321140127025031 0ustar www-datawww-data

This is a 5 + 5 statement

5 + 5
kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode_notexhints.html.190000644000004100000410000000073213321140127026656 0ustar www-datawww-data f ( x ) = a x 3 + b x 2 + c x + d kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview_simple.text0000644000004100000410000000005313321140127026423 0ustar www-datawww-dataThis is a $$5 + 5$$ statement $$ 5 + 5 $$ kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode_semantics.text0000644000004100000410000000004413321140127026225 0ustar www-datawww-data$$f(x) = a{x^3} + b{x^2} + cx + d$$ kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode.html.190000644000004100000410000000110013321140127024361 0ustar www-datawww-data f ( x ) = a x 3 + b x 2 + c x + d kramdown-1.17.0/test/testcases/block/15_math/no_engine.html0000644000004100000410000000006113321140127023575 0ustar www-datawww-data
$$ 5+5 $$
kramdown-1.17.0/test/testcases/block/15_math/katex.options0000644000004100000410000000002513321140127023477 0ustar www-datawww-data:math_engine: :katex kramdown-1.17.0/test/testcases/block/15_math/sskatex.html.190000644000004100000410000001734413321140127023562 0ustar www-datawww-dataΔ=12abcdefghi\Delta = \frac{1}{2} \begin{vmatrix}a & b & c \\ d & e & f \\ g & h & i\end{vmatrix} kramdown-1.17.0/test/testcases/block/15_math/normal.html0000644000004100000410000000133613321140127023132 0ustar www-datawww-data

This is a para.

This is a para.

$$5+5$$
kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode_semantics.html.190000644000004100000410000000146213321140127026442 0ustar www-datawww-data f ( x ) = a x 3 + b x 2 + c x + d f(x) = a{x^3} + b{x^2} + cx + d kramdown-1.17.0/test/testcases/block/15_math/katex.html.190000644000004100000410000001716613321140127023216 0ustar www-datawww-dataΔ=12abcdefghi\Delta = \frac{1}{2} \begin{vmatrix}a & b & c \\ d & e & f \\ g & h & i\end{vmatrix} kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview_as_code.html0000644000004100000410000000033013321140127026505 0ustar www-datawww-data

This is a 5 + 5 statement

5 + 5
kramdown-1.17.0/test/testcases/block/15_math/ritex.text0000644000004100000410000000004413321140127023010 0ustar www-datawww-data$$f(x) = a{x^3} + b{x^2} + cx + d$$ kramdown-1.17.0/test/testcases/block/15_math/itex2mml.options0000644000004100000410000000002713321140127024126 0ustar www-datawww-data:math_engine: itex2mml kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview.options0000644000004100000410000000004413321140127025561 0ustar www-datawww-data:math_engine_opts: :preview: true kramdown-1.17.0/test/testcases/block/15_math/sskatex.options0000644000004100000410000000002613321140127024046 0ustar www-datawww-data:math_engine: sskatex kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode.text0000644000004100000410000000004413321140127024157 0ustar www-datawww-data$$f(x) = a{x^3} + b{x^2} + cx + d$$ kramdown-1.17.0/test/testcases/block/15_math/gh_128.text0000644000004100000410000000007713321140127022653 0ustar www-datawww-data$$ $$ kramdown-1.17.0/test/testcases/block/15_math/no_engine.text0000644000004100000410000000002513321140127023615 0ustar www-datawww-data{: #math-id} $$5+5$$ kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode_semantics.options0000644000004100000410000000010013321140127026725 0ustar www-datawww-data:math_engine: mathjaxnode :math_engine_opts: :semantics: true kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview_as_code.text0000644000004100000410000000005313321140127026527 0ustar www-datawww-dataThis is a $$5 + 5$$ statement $$ 5 + 5 $$ kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview.text0000644000004100000410000000005313321140127025052 0ustar www-datawww-dataThis is a $$5 + 5$$ statement $$ 5 + 5 $$ kramdown-1.17.0/test/testcases/block/15_math/katex.text0000644000004100000410000000013113321140127022766 0ustar www-datawww-data$$\Delta = \frac{1}{2} \begin{vmatrix}a & b & c \\ d & e & f \\ g & h & i\end{vmatrix}$$ kramdown-1.17.0/test/testcases/block/15_math/ritex.options0000644000004100000410000000002413321140127023515 0ustar www-datawww-data:math_engine: ritex kramdown-1.17.0/test/testcases/block/15_math/normal.text0000644000004100000410000000041113321140127023143 0ustar www-datawww-dataThis is a para. $$ \text{LaTeX} \lambda_5 $$ $$\lambda_5 = \alpha + 4$$ $$\lambda_\alpha > 5$$ This is a para. $$\begin{align*} &=5 \\ &=6 \\ \end{align*}$$ $$5+5$$ $$5+5$$ $$5+5$$ $$5+5$$ $$5+5$$ {:.cls} $$5+5$$ ^ $$5+5$$ {:.cls} $$|x| = 5$$ kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview_simple.html0000644000004100000410000000031113321140127026400 0ustar www-datawww-data

This is a math statement

math
kramdown-1.17.0/test/testcases/block/15_math/itex2mml.html0000644000004100000410000000067313321140127023406 0ustar www-datawww-dataf(x)=ax 3+bx 2+cx+df(x) = a{x^3} + b{x^2} + cx + d kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode_notexhints.text0000644000004100000410000000004413321140127026442 0ustar www-datawww-data$$f(x) = a{x^3} + b{x^2} + cx + d$$ kramdown-1.17.0/test/testcases/block/15_math/itex2mml.text0000644000004100000410000000004413321140127023416 0ustar www-datawww-data$$f(x) = a{x^3} + b{x^2} + cx + d$$ kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview_as_code.options0000644000004100000410000000007513321140127027242 0ustar www-datawww-data:math_engine_opts: :preview: true :preview_as_code: true kramdown-1.17.0/test/testcases/block/15_math/mathjax_preview_simple.options0000644000004100000410000000004613321140127027134 0ustar www-datawww-data:math_engine_opts: :preview: 'math' kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode.options0000644000004100000410000000003213321140127024663 0ustar www-datawww-data:math_engine: mathjaxnode kramdown-1.17.0/test/testcases/block/15_math/mathjaxnode_notexhints.options0000644000004100000410000000010013321140127027142 0ustar www-datawww-data:math_engine: mathjaxnode :math_engine_opts: :texhints: false kramdown-1.17.0/test/testcases/block/15_math/no_engine.options0000644000004100000410000000002013321140127024317 0ustar www-datawww-data:math_engine: ~ kramdown-1.17.0/test/testcases/block/06_codeblock/0000755000004100000410000000000013321140127021745 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/06_codeblock/with_ial.text0000644000004100000410000000007613321140127024456 0ustar www-datawww-data code block continued here {:.cls} new block here kramdown-1.17.0/test/testcases/block/06_codeblock/whitespace.text0000644000004100000410000000007513321140127025011 0ustar www-datawww-data This is some whitespace {:.show-whitespaces} kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/0000755000004100000410000000000013321140127023066 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/06_codeblock/rouge/disabled.options0000644000004100000410000000012013321140127026243 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: block: disable: true kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/multiple.html0000644000004100000410000000132413321140127025607 0ustar www-datawww-data
puts "Hello"
puts "World"
$foo = new Bar;
kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/disabled.text0000644000004100000410000000002213321140127025535 0ustar www-datawww-data x = Class.new kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/multiple.text0000644000004100000410000000014013321140127025622 0ustar www-datawww-data~~~ ruby puts "Hello" ~~~ ~~~ ruby puts "World" ~~~ ~~~ php?start_inline=1 $foo = new Bar; ~~~kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/simple.options0000644000004100000410000000011213321140127025766 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: default_lang: ruby kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/disabled.html0000644000004100000410000000004713321140127025524 0ustar www-datawww-data
x = Class.new
kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/simple.text0000644000004100000410000000014413321140127025264 0ustar www-datawww-data x = Class.new ^ href {: .language-html} ~~~ php?start_inline=1 $foo = new Bar; ~~~ kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/multiple.options0000644000004100000410000000015313321140127026335 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: default_lang: ruby formatter: RougeHTMLFormatters kramdown-1.17.0/test/testcases/block/06_codeblock/rouge/simple.html0000644000004100000410000000130413321140127025243 0ustar www-datawww-data
x = Class.new
<a>href</a>
$foo = new Bar;
kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html0000644000004100000410000000025313321140127031617 0ustar www-datawww-data
text
text
text
kramdown-1.17.0/test/testcases/block/06_codeblock/no_newline_at_end_1.html0000644000004100000410000000004513321140127026521 0ustar www-datawww-data
test   test
kramdown-1.17.0/test/testcases/block/06_codeblock/with_eob_marker.html0000644000004100000410000000013413321140127025772 0ustar www-datawww-data
code block

continued here
new block here
kramdown-1.17.0/test/testcases/block/06_codeblock/with_blank_line.html0000644000004100000410000000023513321140127025764 0ustar www-datawww-data

paragraph

code block

continued here

ended

next blank line has 4 spaces

paragraph

kramdown-1.17.0/test/testcases/block/06_codeblock/issue_gh45.test0000644000004100000410000000726313321140127024635 0ustar www-datawww-data B BBBBBBBB. BBBB BB BBBBBBBB BBBBB. BBBBBBB BB BBBBB BB BBB BBBB BBBBB BBB BBB BBBB BBB BBBBBBB BBB BBBBBBB. B BBB'B BBBBB BBBB BBB BBBB BBBBBBB BBBB BBBB BBBB BBBBBBBB. BBB BBBBB BBBBB BBB BBBB BBBB BBBB, BBB BBBBB BB BBBBB BBB BB BBBBBB BBBB BBB BBBBB BBBB BB. BBBBB BBB BBBBB BBBBB BBB BBBB BB BBBB BBBB BBBBB. BBBB BBBBB, BBBBB, BBBBBBBB? BB BBB BB BBBB BBB BBBB BBB BBBBBB /BBB BB BBBBBBBBB BBBB BBBBBBB BBBBBB BB BBB. BBBB BBBBBBBB BBB BBBB BB BBBBB BBB BBBBBB BBBB BBBBB BBBBBB BBBBBBBBB BBBB BB BBBBB...................................................................... BBBBB B'B BBB BBBBB. BBBB BBBBB BBBBB. ( B BBBBB BBBBBBBBBB BBBBB BBBB'B BBBBB BBBBB. BBB BBBB BBBBB BBBB BBBB. BBBBBBB BBB BB BBBBBBB BBB BBB B BBBB BBBBBBBBBBBB. BBBBB BBBBB.) BBBB'B BB . B BBB BBB BBB ? B. B BBB BBBBBB BBBB BBB BBBB. BBBBBBB BB BBBBBBB B BBBB BBBB BBB BBBBBB. BBBB BB 'BBBB' BBBB BBBBB. BBBBBBBB B BBBB BBBBBB BB BBBBBBBB BBB BBBBBBB BBBBBBB BBBBBBB. B BBBB BB BBBB. BBBBB BBBBBBBB. BBB BB BB. BB BB BBBB BB BBBBBBBBBB. BB BBBBBBBB BB BBBBBBBBB. BBBBBBBB BB BBBB. BBBBBBB BBB BBBBB BBBBB BBBBB. B'BB BBBBBBB BB BBBBB BBBBB BBBBBBB BBB BBBBB. BBBB. B BBBBBB BBBB BB BBBB BBB. (BB BBB BBBBB BBBBB...............B) BBBB! BBBB BB BBB BBBBBBB BBBBBB. B B BBBBB BB/BBB BBBBB! BBBB BBBB BBBBBBBBBBB 'BBB'B BBBBBB.' BBBB BBBBBBB BBBB BB BBB BBBBBBBB BB BBBB BBBBBB BBB BBBBBBBBB BBBB. BBBBBBBB BBBBBBB BBBB BBBB BBBB BB BBBB BB BBBB BB BBBB B BBB BB BBBBB BBBBBB. B BBBB BBBBBBB BB BBBB BBBBB B BBB BBBBBBB BB BBBBB BBBB. BBB BBBBBBB BBBB. B BBB BBBB BBBB B BBBB BBBBBB BBB B BBBBBB BBBBBB. BBB BB BBBBBB BBBBBB BBBBBBBBBB BB...BBBBB BBBB BBBB BB BBBBB. (BBBBBBB BBB BBBBBB BBB'B BBBB BBB BBBBB BBB BB BBBBB BBBBBBBBBBB BBBBB B BBBB BBBB BBBBB. BBBBB BB BB BBBB B'B BBBB BBBBB BBBBB BBB BB BBBBBB/BBB (BBBBB) BBBBBB BB. BBBBBBBB. B BBB BBBB BB BB BBB/BBBBBB BBBBBB BBB BBBB BBBBBBBB BB BB B BBBBBB BBBBBB BBBBB. (BBB/B BBB BBBB BBBB...BBB BBB BBB BBBB BB BB B BBBB BB BBB BB? BBBBBBB B BBB B BBBB BBBBBBBB BBB B BBB BBB BBBBB BBBB BBB BBBB BB B BBBBBBBB BB BBBBB BB BB BBB BBBBB BBB BB BBBBB BBBBBBB B BBB BBBBBBB. BBBBBB (BBBBB) BBBB BBBBB BBBBBBB BBBBB BBBB BBBB BBB. 100 BBBBBB BB BBBBB. BBBB BBB BBB BBBBBB BBB BB. BBB BBBB BB BBB BBBBB! BBB BB BBBBBB BBBBB B BBB'B BBBBBBBBB BBBB BBB BBB. (BBBBBB BBBBBBB BB BBBB BBBBB (BBBBBB BBBBB BBBBB BBBBB.)) BBB B BBBBBBBBBBB BBBB BBB BB BBB. BBBBB BBB BBBBB B BBBB BBBBBB BBBBB BBB. BB BBBBBB BBB BBBB B BBB BB BBBBBBBB BBBBBB BBBB BBB B BBBBBB BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBBBBBB. BBBBB!!!!!!! B BBB BBBB BBBBBB BBBB BBBB BBBB B BBB BBBBB BBB BBBBB B BBBB BBBBBBB BB BB BBBB BBBBBBBBB. B BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBB. BB BB, BB BBBBBB BBBB, (BBBBBB BB BBB BBBB . BBBBB BB BBBB BBBB BB BB BBBB BBBB B BBBB BB BB (BB BBBB BB BBB BBBBBBB BB BBBBBBB. )) BB'BB BBB BBB'B BB BB BBBB BB B BBBB B BBBBB (BB BBBBBB BB BBB B'BB BBBBBBBB BB BBBB BBBB.) B BBBBB B'BB BBB BB BBBB BBB BBB. kramdown-1.17.0/test/testcases/block/06_codeblock/lazy.text0000644000004100000410000000006413321140127023632 0ustar www-datawww-data This is some code This is some other code kramdown-1.17.0/test/testcases/block/06_codeblock/disable-highlighting.text0000644000004100000410000000006413321140127026721 0ustar www-datawww-data x = Class.new ^ href {: lang="html"} kramdown-1.17.0/test/testcases/block/06_codeblock/error.text0000644000004100000410000000004013321140127023776 0ustar www-datawww-dataSome para ~~~~~~ not codeblock kramdown-1.17.0/test/testcases/block/06_codeblock/tilde_syntax.html0000644000004100000410000000015313321140127025341 0ustar www-datawww-data
Here comes some code.
~~~~~~~
code with tildes
~~~~~~~~
kramdown-1.17.0/test/testcases/block/06_codeblock/whitespace.html0000644000004100000410000000070213321140127024766 0ustar www-datawww-data
This	issome
whitespace
kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text0000644000004100000410000000007513321140127033027 0ustar www-datawww-data~~~ act-iii s1'dim'a'500'm'500'q'500'' index'j'j+1'j-1'' ~~~ kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-minted.options0000644000004100000410000000011313321140127027300 0ustar www-datawww-data:syntax_highlighter: minted :syntax_highlighter_opts: default_lang: ruby kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex0000644000004100000410000000037313321140127030666 0ustar www-datawww-data\begin{minted}[breaklines,linenos]{ruby} x = Class.new \end{minted} \begin{minted}[breaklines,linenos]{html} this is a reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, long link \end{minted} kramdown-1.17.0/test/testcases/block/06_codeblock/disable-highlighting.options0000644000004100000410000000002713321140127027427 0ustar www-datawww-data:enable_coderay: false kramdown-1.17.0/test/testcases/block/06_codeblock/issue_gh45.html0000644000004100000410000000671113321140127024617 0ustar www-datawww-data

B

                       BBBBBBBB. 



           BBBB BB BBBBBBBB BBBBB. BBBBBBB BB BBBBB BB BBB BBBB BBBBB BBB BBB BBBB BBB BBBBBBB BBB BBBBBBB. B BBB'B BBBBB BBBB BBB BBBB BBBBBBB BBBB BBBB BBBB BBBBBBBB.


                BBB BBBBB BBBBB BBB BBBB BBBB BBBB, BBB BBBBB BB BBBBB BBB BB BBBBBB BBBB BBB BBBBB BBBB BB. BBBBB BBB BBBBB BBBBB BBB BBBB BB BBBB BBBB BBBBB.


                         BBBB BBBBB, BBBBB, BBBBBBBB?

                   BB BBB BB BBBB BBB BBBB BBB BBBBBB /BBB BB BBBBBBBBB BBBB BBBBBBB BBBBBB BB BBB. 


                   BBBB BBBBBBBB BBB BBBB BB BBBBB BBB BBBBBB BBBB BBBBB BBBBBB BBBBBBBBB BBBB BB BBBBB......................................................................





















              BBBBB B'B BBB BBBBB. BBBB BBBBB BBBBB. ( B BBBBB BBBBBBBBBB BBBBB BBBB'B BBBBB BBBBB. BBB BBBB BBBBB BBBB BBBB. BBBBBBB BBB BB BBBBBBB BBB BBB B BBBB BBBBBBBBBBBB. BBBBB BBBBB.)




























             BBBB'B BB

.

        B BBB BBB BBB ? B. B BBB BBBBBB BBBB BBB BBBB. BBBBBBB BB BBBBBBB B BBBB BBBB BBB BBBBBB. 













         BBBB BB 'BBBB' BBBB BBBBB.


                           BBBBBBBB B BBBB BBBBBB BB BBBBBBBB BBB BBBBBBB BBBBBBB BBBBBBB. 


     B BBBB BB BBBB. BBBBB BBBBBBBB. BBB BB BB. BB BB BBBB BB BBBBBBBBBB. BB BBBBBBBB BB BBBBBBBBB. 


                     BBBBBBBB BB BBBB. BBBBBBB BBB BBBBB BBBBB BBBBB. B'BB BBBBBBB BB BBBBB BBBBB BBBBBBB BBB BBBBB. BBBB. 

  B BBBBBB BBBB BB BBBB BBB. (BB BBB BBBBB BBBBB...............B)



           BBBB!



         BBBB BB BBB BBBBBBB BBBBBB.            B

B

     BBBBB BB/BBB BBBBB!  BBBB BBBB BBBBBBBBBBB 'BBB'B BBBBBB.' 














          BBBB BBBBBBB BBBB BB BBB BBBBBBBB BB BBBB BBBBBB BBB BBBBBBBBB BBBB. BBBBBBBB BBBBBBB BBBB BBBB BBBB BB BBBB BB BBBB BB BBBB B BBB BB BBBBB BBBBBB.  B BBBB BBBBBBB BB BBBB BBBBB B BBB BBBBBBB BB BBBBB BBBB. BBB BBBBBBB BBBB. B BBB BBBB BBBB B BBBB BBBBBB BBB B BBBBBB BBBBBB. BBB BB BBBBBB BBBBBB BBBBBBBBBB BB...BBBBB BBBB BBBB BB BBBBB. (BBBBBBB BBB BBBBBB BBB'B BBBB BBB BBBBB BBB BB BBBBB BBBBBBBBBBB  BBBBB B BBBB BBBB BBBBB. 









BBBBB BB BB BBBB B'B BBBB BBBBB BBBBB BBB BB BBBBBB/BBB (BBBBB) BBBBBB BB. 
                          BBBBBBBB. B BBB BBBB BB BB BBB/BBBBBB BBBBBB BBB BBBB BBBBBBBB BB BB B BBBBBB BBBBBB BBBBB. (BBB/B BBB BBBB BBBB...BBB BBB BBB BBBB BB BB B BBBB BB BBB BB? BBBBBBB B BBB B BBBB BBBBBBBB BBB B BBB BBB BBBBB BBBB BBB BBBB BB B BBBBBBBB BB BBBBB BB BB BBB BBBBB BBB BB BBBBB BBBBBBB B BBB BBBBBBB. BBBBBB (BBBBB) BBBB BBBBB BBBBBBB BBBBB BBBB BBBB BBB. 100 BBBBBB BB BBBBB. BBBB BBB BBB BBBBBB BBB BB. BBB BBBB BB BBB BBBBB! BBB BB BBBBBB BBBBB B BBB'B BBBBBBBBB BBBB BBB BBB. (BBBBBB BBBBBBB BB BBBB BBBBB (BBBBBB BBBBB BBBBB BBBBB.))


    BBB B BBBBBBBBBBB BBBB BBB BB BBB. BBBBB BBB BBBBB B BBBB BBBBBB BBBBB BBB. BB BBBBBB BBB BBBB B BBB BB BBBBBBBB BBBBBB BBBB BBB B BBBBBB BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBBBBBB.











           BBBBB!!!!!!!


         B BBB BBBB BBBBBB BBBB BBBB BBBB B BBB BBBBB BBB BBBBB B BBBB BBBBBBB BB BB BBBB BBBBBBBBB. B BBBB BBBBBB BBBBBBB BBBB BBBB BBB BBBB.

                                               BB BB, BB BBBBBB BBBB, (BBBBBB BB BBB BBBB . BBBBB BB BBBB BBBB BB BB BBBB BBBB B BBBB BB BB (BB BBBB BB BBB BBBBBBB BB BBBBBBB. )) BB'BB BBB BBB'B BB BB BBBB BB B BBBB B BBBBB (BB BBBBBB BB BBB B'BB BBBBBBBB BB BBBB BBBB.)


  B BBBBB B'BB BBB BB BBBB BBB BBB.
kramdown-1.17.0/test/testcases/block/06_codeblock/no_newline_at_end.html0000644000004100000410000000004013321140127026274 0ustar www-datawww-data
test  
kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting.text0000644000004100000410000000006713321140127025323 0ustar www-datawww-data x = Class.new ^ href {: .language-html} kramdown-1.17.0/test/testcases/block/06_codeblock/tilde_syntax.text0000644000004100000410000000015313321140127025361 0ustar www-datawww-data~~~~~~~~ Here comes some code. ~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~ code with tildes ~~~~~~~~ ~~~~~~~~~~~~~~~~~~ kramdown-1.17.0/test/testcases/block/06_codeblock/with_ial.html0000644000004100000410000000015013321140127024427 0ustar www-datawww-data
code block

continued here
new block here
kramdown-1.17.0/test/testcases/block/06_codeblock/normal.html0000644000004100000410000000025013321140127024120 0ustar www-datawww-data
starting code

paragraph

other code  
with samples 

paragraph

  ending code
kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options0000644000004100000410000000003013321140127033525 0ustar www-datawww-data:enable_coderay: false kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-minted.text0000644000004100000410000000006713321140127026601 0ustar www-datawww-data x = Class.new ^ href {: .language-html} kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-minted.latex0000644000004100000410000000014413321140127026726 0ustar www-datawww-data\begin{minted}[]{ruby} x = Class.new \end{minted} \begin{minted}[]{html} href \end{minted} kramdown-1.17.0/test/testcases/block/06_codeblock/no_newline_at_end.text0000644000004100000410000000001213321140127026313 0ustar www-datawww-data test kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text0000644000004100000410000000035613321140127027777 0ustar www-datawww-data~~~ ruby def what? 42 end ~~~ ~~~ ruby def what? 42 end ~~~ {:.class1} ~~~ def what? 42 end ~~~ {: .language-ruby} ~~~ ruby def what? 42 end ~~~ {: .language-python} ~~~ ruby def what? 42 end ~~~ {: class="language-python"} kramdown-1.17.0/test/testcases/block/06_codeblock/no_newline_at_end_1.text0000644000004100000410000000002013321140127026532 0ustar www-datawww-data test test kramdown-1.17.0/test/testcases/block/06_codeblock/error.html0000644000004100000410000000005613321140127023765 0ustar www-datawww-data

Some para

~~~~~~ not codeblock

kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html0000644000004100000410000000061513321140127027755 0ustar www-datawww-data
def what?
  42
end
def what?
  42
end
def what?
  42
end
def what?
  42
end
def what?
  42
end
kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options0000644000004100000410000000013013321140127031233 0ustar www-datawww-data:syntax_highlighter: minted :syntax_highlighter_opts: wrap: true line_numbers: true kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options0000644000004100000410000000003013321140127030473 0ustar www-datawww-data:enable_coderay: false kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text0000644000004100000410000000027313321140127030534 0ustar www-datawww-data x = Class.new {: .language-ruby} this is a reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, reaally, long link {: .language-html} kramdown-1.17.0/test/testcases/block/06_codeblock/normal.text0000644000004100000410000000013713321140127024144 0ustar www-datawww-data starting code paragraph other code with samples paragraph ending code kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-opts.options0000644000004100000410000000015213321140127027010 0ustar www-datawww-data:syntax_highlighter_opts: block: css: class default_lang: ruby wrap: span line_numbers: null kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text0000644000004100000410000000010513321140127031633 0ustar www-datawww-data~~~ asn.1 text ~~~ ~~~ asn#w1 text ~~~ ~~~ русский text ~~~ kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-opts.html0000644000004100000410000000043613321140127026266 0ustar www-datawww-data
x = Class.new
<a>href</a>
kramdown-1.17.0/test/testcases/block/06_codeblock/with_eob_marker.text0000644000004100000410000000007013321140127026011 0ustar www-datawww-data code block continued here ^ new block here kramdown-1.17.0/test/testcases/block/06_codeblock/lazy.html0000644000004100000410000000010513321140127023606 0ustar www-datawww-data
This is some code

This is some  other code
kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting.options0000644000004100000410000000013613321140127026027 0ustar www-datawww-data:coderay_default_lang: ruby :coderay_wrap: span :coderay_line_numbers: ~ :coderay_css: class kramdown-1.17.0/test/testcases/block/06_codeblock/disable-highlighting.html0000644000004100000410000000014413321140127026700 0ustar www-datawww-data
x = Class.new
<a>href</a>
kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html0000644000004100000410000000013713321140127033006 0ustar www-datawww-data
s1'dim'a'500'm'500'q'500''
index'j'j+1'j-1''
kramdown-1.17.0/test/testcases/block/06_codeblock/with_blank_line.text0000644000004100000410000000015313321140127026003 0ustar www-datawww-dataparagraph code block continued here ended next blank line has 4 spaces paragraph kramdown-1.17.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options0000644000004100000410000000003013321140127032337 0ustar www-datawww-data:enable_coderay: false kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting-opts.text0000644000004100000410000000006713321140127026306 0ustar www-datawww-data x = Class.new ^ href {: .language-html} kramdown-1.17.0/test/testcases/block/06_codeblock/highlighting.html0000644000004100000410000000043613321140127025303 0ustar www-datawww-data
x = Class.new
<a>href</a>
kramdown-1.17.0/test/testcases/block/09_html/0000755000004100000410000000000013321140127020767 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/09_html/textarea.text0000644000004100000410000000012013321140127023503 0ustar www-datawww-dataThis is a kramdown-1.17.0/test/testcases/block/09_html/xml.text0000644000004100000410000000021113321140127022467 0ustar www-datawww-data doit doit doit kramdown-1.17.0/test/testcases/block/09_html/parse_as_span.htmlinput0000644000004100000410000000024513321140127025554 0ustar www-datawww-data

This text should be parsed as span

This produces `

` an unwanted result.</p>

This text too

some text

kramdown-1.17.0/test/testcases/block/09_html/html_and_codeblocks.html0000644000004100000410000000023713321140127025635 0ustar www-datawww-data

para

codeblock

test

<p>codeblock</p>

test

kramdown-1.17.0/test/testcases/block/09_html/html_and_codeblocks.text0000644000004100000410000000012413321140127025650 0ustar www-datawww-datapara codeblock
test

codeblock

test
kramdown-1.17.0/test/testcases/block/09_html/html_and_headers.html0000644000004100000410000000004513321140127025135 0ustar www-datawww-data

header

======
kramdown-1.17.0/test/testcases/block/09_html/html_and_codeblocks.options0000644000004100000410000000003013321140127026353 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/09_html/parse_as_span.text0000644000004100000410000000020313321140127024506 0ustar www-datawww-data

This *text should* be parsed as span

This produces `

` an unwanted result.

This *text* too

some text kramdown-1.17.0/test/testcases/block/09_html/parse_block_html.text0000644000004100000410000000021113321140127025177 0ustar www-datawww-data

test
test
test
code block with
No matching end tag kramdown-1.17.0/test/testcases/block/09_html/invalid_html_1.html0000644000004100000410000000005613321140127024550 0ustar www-datawww-data

para

</div>

para

kramdown-1.17.0/test/testcases/block/09_html/parse_block_html.options0000644000004100000410000000003013321140127025705 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/09_html/parse_as_raw.text0000644000004100000410000000076013321140127024346 0ustar www-datawww-data

baz { |qux| quux }

This is some para.

*parsed* This too

kramdown-1.17.0/test/testcases/block/09_html/html_and_headers.text0000644000004100000410000000004313321140127025153 0ustar www-datawww-dataheader ======
======
kramdown-1.17.0/test/testcases/block/09_html/invalid_html_2.text0000644000004100000410000000002113321140127024561 0ustar www-datawww-datapara
para kramdown-1.17.0/test/testcases/block/09_html/content_model/0000755000004100000410000000000013321140127023621 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/09_html/content_model/deflists.options0000644000004100000410000000003013321140127027044 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/09_html/content_model/tables.html0000644000004100000410000000027713321140127025767 0ustar www-datawww-data
Usage Output
Some data

Some more

kramdown-1.17.0/test/testcases/block/09_html/content_model/deflists.html0000644000004100000410000000010313321140127026316 0ustar www-datawww-data
text

para

kramdown-1.17.0/test/testcases/block/09_html/content_model/tables.options0000644000004100000410000000003013321140127026501 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/09_html/content_model/deflists.text0000644000004100000410000000005313321140127026342 0ustar www-datawww-data
*text*
para
kramdown-1.17.0/test/testcases/block/09_html/content_model/tables.text0000644000004100000410000000030013321140127025772 0ustar www-datawww-data
*Usage* Output
Some *data* # Some more
kramdown-1.17.0/test/testcases/block/09_html/markdown_attr.html0000644000004100000410000000044513321140127024534 0ustar www-datawww-data

para

para

para

*para*

para

para

para

*para*

emphasize

para

kramdown-1.17.0/test/testcases/block/09_html/html5_attributes.text0000644000004100000410000000045313321140127025176 0ustar www-datawww-data

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

kramdown-1.17.0/test/testcases/block/09_html/xml.html0000644000004100000410000000022713321140127022456 0ustar www-datawww-data doit doit doit</some> kramdown-1.17.0/test/testcases/block/09_html/html_to_native/0000755000004100000410000000000013321140127024003 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/09_html/html_to_native/emphasis.text0000644000004100000410000000022113321140127026515 0ustar www-datawww-dataThis is sizedhallo. This is strongitalic, yes!. This is not converted, as is this. kramdown-1.17.0/test/testcases/block/09_html/html_to_native/list_dl.text0000644000004100000410000000015313321140127026342 0ustar www-datawww-data
kram
down
kram
down
kram
down
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/list_ul.text0000644000004100000410000000043313321140127026364 0ustar www-datawww-data
  • This is a simple list item
  • Followed by another

  • Followed by

    a para list item

  • and a normal one
  • and

    a para

  • multi line list item
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/options0000644000004100000410000000002613321140127025417 0ustar www-datawww-data:html_to_native: true kramdown-1.17.0/test/testcases/block/09_html/html_to_native/header.html0000644000004100000410000000031313321140127026116 0ustar www-datawww-data

Some headerhere!

hallo

hallo

hallo

hallo
hallo
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/entity.html0000644000004100000410000000007113321140127026203 0ustar www-datawww-data

This is *raw* HTML text containing < entities!

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/table_normal.html0000644000004100000410000000022513321140127027327 0ustar www-datawww-data
Usage Other
Some *data*

Some more

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/header.text0000644000004100000410000000020413321140127026135 0ustar www-datawww-data

Some headerhere!

hallo

hallo

hallo

hallo
hallo
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/header.options0000644000004100000410000000004613321140127026650 0ustar www-datawww-data:auto_ids: true :html_to_native: true kramdown-1.17.0/test/testcases/block/09_html/html_to_native/list_ol.html0000644000004100000410000000035513321140127026341 0ustar www-datawww-data
  1. This is a simple list item
  2. Followed by another

  3. Followed by

    a para list item

  4. and a normal one
  5. and

    a para

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/typography.text0000644000004100000410000000007513321140127027121 0ustar www-datawww-data

This is … something “to remember”!

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/entity.text0000644000004100000410000000007113321140127026223 0ustar www-datawww-data

This is *raw* HTML text containing < entities!

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/code.text0000644000004100000410000000041313321140127025621 0ustar www-datawww-dataThis is a code span with <entities> that should be preserved. This is a simple code span.

Some <

Some very important < thing
Some code<<
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/table_simple.text0000644000004100000410000000135113321140127027351 0ustar www-datawww-data
Usage Output
Some *data* Some more
Usage Output
Some *data* Some more
foot locker
Usage Output
Some *data* Some more
Usage Output
Some *data* Some more
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/typography.html.190000644000004100000410000000006013321140127027323 0ustar www-datawww-data

This is … something “to remember”!

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/paragraph.text0000644000004100000410000000011113321140127026647 0ustar www-datawww-data

Some text here and end

Some other text here

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/list_ol.text0000644000004100000410000000035713321140127026363 0ustar www-datawww-data
  1. This is a simple list item
  2. Followed by another

  3. Followed by

    a para list item

  4. and a normal one
  5. and

    a para

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/comment.html0000644000004100000410000000006313321140127026332 0ustar www-datawww-data
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/paragraph.html0000644000004100000410000000011013321140127026626 0ustar www-datawww-data

Some text here and end

Some other text here

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/list_ul.html0000644000004100000410000000043113321140127026342 0ustar www-datawww-data
  • This is a simple list item
  • Followed by another

  • Followed by

    a para list item

  • and a normal one
  • and

    a para

  • multi line list item
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/typography.html0000644000004100000410000000007413321140127027100 0ustar www-datawww-data

This is … something “to remember”!

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/emphasis.html0000644000004100000410000000026213321140127026502 0ustar www-datawww-data

This is sizedhallo.

This is strongitalic, yes!.

This is not converted, as is this.

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/code.html0000644000004100000410000000040513321140127025602 0ustar www-datawww-data

This is a code span with <entities> that should be preserved. This is a simple code span.

Some <

Some very important < thing
Some code<<
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/comment.text0000644000004100000410000000006413321140127026353 0ustar www-datawww-data
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/table_simple.html0000644000004100000410000000156313321140127027336 0ustar www-datawww-data
Usage Output
Some *data* Some more
Usage Output
Some *data* Some more
foot locker
Usage Output
Some *data* Some more
Usage Output
Some *data* Some more
kramdown-1.17.0/test/testcases/block/09_html/html_to_native/table_normal.text0000644000004100000410000000022513321140127027347 0ustar www-datawww-data
Usage Other
Some *data*

Some more

kramdown-1.17.0/test/testcases/block/09_html/html_to_native/list_dl.html0000644000004100000410000000015313321140127026322 0ustar www-datawww-data
kram
down
kram
down
kram
down
kramdown-1.17.0/test/testcases/block/09_html/not_parsed.html0000644000004100000410000000041313321140127024011 0ustar www-datawww-data
This is some text
This is some text
</p>

Foo

This is some text

http://example.com

<http://example.com>
kramdown-1.17.0/test/testcases/block/09_html/invalid_html_1.text0000644000004100000410000000002313321140127024562 0ustar www-datawww-datapara
para kramdown-1.17.0/test/testcases/block/09_html/html_after_block.text0000644000004100000410000000012013321140127025165 0ustar www-datawww-dataPara
division
> Quote
division
kramdown-1.17.0/test/testcases/block/09_html/parse_as_raw.html0000644000004100000410000000104613321140127024324 0ustar www-datawww-data

baz { |qux| quux }

This is some para.

parsed This too

http://example.com

kramdown-1.17.0/test/testcases/block/09_html/parse_as_span.html0000644000004100000410000000024513321140127024474 0ustar www-datawww-data

This text should be parsed as span

This produces `

` an unwanted result.</p>

This text too

some text

kramdown-1.17.0/test/testcases/block/09_html/textarea.html0000644000004100000410000000012713321140127023472 0ustar www-datawww-data

This is a

kramdown-1.17.0/test/testcases/block/09_html/simple.options0000644000004100000410000000003013321140127023666 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/09_html/simple.text0000644000004100000410000000063113321140127023166 0ustar www-datawww-data
test

para2

tes

test weiter

para4
foo
bar 
para5
id
test
hallo
hallo
para6
Another para.
Test

Test

Test

kramdown-1.17.0/test/testcases/block/09_html/parse_block_html.html0000644000004100000410000000035513321140127025170 0ustar www-datawww-data

test

test
test
code block with </div>

No matching end tag

kramdown-1.17.0/test/testcases/block/09_html/comment.html0000644000004100000410000000023513321140127023317 0ustar www-datawww-data

para1

para2

para

This is

kramdown-1.17.0/test/testcases/block/09_html/parse_as_raw.htmlinput0000644000004100000410000000104513321140127025403 0ustar www-datawww-data

baz { |qux| quux }

This is some para.

parsed This too

http://example.com

kramdown-1.17.0/test/testcases/block/09_html/not_parsed.text0000644000004100000410000000033113321140127024030 0ustar www-datawww-data
This is some text
This is some text

Foo

This is some text

kramdown-1.17.0/test/testcases/block/09_html/simple.html.190000644000004100000410000000101613321140127023374 0ustar www-datawww-data

test

para2

tes

test weiter

para4

foo

bar 

para5

id

test

hallo

hallo

para6

Another para.

Test

Test

Test

kramdown-1.17.0/test/testcases/block/09_html/html5_attributes.html0000644000004100000410000000047613321140127025163 0ustar www-datawww-data

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

kramdown-1.17.0/test/testcases/block/09_html/processing_instruction.text0000644000004100000410000000013113321140127026505 0ustar www-datawww-data para para other kramdown-1.17.0/test/testcases/block/09_html/invalid_html_2.html0000644000004100000410000000004113321140127024543 0ustar www-datawww-data

para


para

kramdown-1.17.0/test/testcases/block/09_html/parse_as_raw.options0000644000004100000410000000003013321140127025043 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/09_html/comment.text0000644000004100000410000000015013321140127023333 0ustar www-datawww-data para1 para2 para > This is > kramdown-1.17.0/test/testcases/block/09_html/processing_instruction.html0000644000004100000410000000015613321140127026474 0ustar www-datawww-data

para

para

other

kramdown-1.17.0/test/testcases/block/09_html/html_after_block.html0000644000004100000410000000017113321140127025153 0ustar www-datawww-data

Para

division

Quote

division
kramdown-1.17.0/test/testcases/block/09_html/markdown_attr.text0000644000004100000410000000053413321140127024553 0ustar www-datawww-data
*para*
*para*
*para*
*para*

*para*

*para*

*para*

*para*

*emphasize*
para
kramdown-1.17.0/test/testcases/block/09_html/simple.html0000644000004100000410000000102213321140127023141 0ustar www-datawww-data

test

para2

tes

test weiter

para4

foo

bar 

para5

id

test

hallo

hallo

para6

Another para.

Test

Test

Test

kramdown-1.17.0/test/testcases/block/09_html/parse_as_span.options0000644000004100000410000000003013321140127025213 0ustar www-datawww-data:parse_block_html: true kramdown-1.17.0/test/testcases/block/07_horizontal_rule/0000755000004100000410000000000013321140127023241 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/07_horizontal_rule/septabs.html0000644000004100000410000000002513321140127025565 0ustar www-datawww-data


kramdown-1.17.0/test/testcases/block/07_horizontal_rule/error.text0000644000004100000410000000011513321140127025275 0ustar www-datawww-data_ * _ --- * * * _ - * ---------------------------------------------- test kramdown-1.17.0/test/testcases/block/07_horizontal_rule/normal.html0000644000004100000410000000022013321140127025411 0ustar www-datawww-data


d- -




para

text


- - -

kramdown-1.17.0/test/testcases/block/07_horizontal_rule/error.html.190000644000004100000410000000015113321140127025505 0ustar www-datawww-data

_ * _

— * * *

_ - *

———————————————- test

kramdown-1.17.0/test/testcases/block/07_horizontal_rule/error.html0000644000004100000410000000025113321140127025256 0ustar www-datawww-data

_ * _

— * * *

_ - *

———————————————- test

kramdown-1.17.0/test/testcases/block/07_horizontal_rule/normal.text0000644000004100000410000000014013321140127025432 0ustar www-datawww-data*** * * * - - - d- - --- ___ *** para ----------- text * * * - - - * * * {:.test} kramdown-1.17.0/test/testcases/block/07_horizontal_rule/sepspaces.html0000644000004100000410000000002513321140127026112 0ustar www-datawww-data


kramdown-1.17.0/test/testcases/block/07_horizontal_rule/septabs.text0000644000004100000410000000003313321140127025604 0ustar www-datawww-data- - - * * * _ _ _ _ _ kramdown-1.17.0/test/testcases/block/07_horizontal_rule/sepspaces.text0000644000004100000410000000004513321140127026134 0ustar www-datawww-data- - - * * * _ _ _ _ _ kramdown-1.17.0/test/testcases/block/10_ald/0000755000004100000410000000000013321140127020553 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/10_ald/simple.text0000644000004100000410000000025613321140127022755 0ustar www-datawww-dataSome paragraph {:id: ref1} {:id: .class1} {:id: #id} {:id: key="value"} {:id: .class2 .class3 ref2 #id-with key="value" key='value' key='dfsd\}' } {:test: k ey=value} kramdown-1.17.0/test/testcases/block/10_ald/simple.html0000644000004100000410000000002713321140127022731 0ustar www-datawww-data

Some paragraph

kramdown-1.17.0/test/testcases/block/02_eob/0000755000004100000410000000000013321140127020561 5ustar www-datawww-datakramdown-1.17.0/test/testcases/block/02_eob/beginning.text0000644000004100000410000000000413321140127023421 0ustar www-datawww-data^ kramdown-1.17.0/test/testcases/block/02_eob/middle.text0000644000004100000410000000000613321140127022721 0ustar www-datawww-data ^ kramdown-1.17.0/test/testcases/block/02_eob/beginning.html0000644000004100000410000000000113321140127023376 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/02_eob/middle.html0000644000004100000410000000000113321140127022674 0ustar www-datawww-data kramdown-1.17.0/test/testcases/block/02_eob/end.text0000644000004100000410000000000413321140127022227 0ustar www-datawww-data ^ kramdown-1.17.0/test/testcases/block/02_eob/end.html0000644000004100000410000000000113321140127022204 0ustar www-datawww-data kramdown-1.17.0/test/testcases/span/0000755000004100000410000000000013321140127017362 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/03_codespan/0000755000004100000410000000000013321140127021460 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/03_codespan/rouge/0000755000004100000410000000000013321140127022601 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/03_codespan/rouge/disabled.options0000644000004100000410000000011713321140127025764 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: span: disable: true kramdown-1.17.0/test/testcases/span/03_codespan/rouge/disabled.text0000644000004100000410000000004613321140127025256 0ustar www-datawww-dataYou can say `Class`{:.language-ruby}. kramdown-1.17.0/test/testcases/span/03_codespan/rouge/simple.options0000644000004100000410000000003313321140127025503 0ustar www-datawww-data:syntax_highlighter: rouge kramdown-1.17.0/test/testcases/span/03_codespan/rouge/disabled.html0000644000004100000410000000007513321140127025240 0ustar www-datawww-data

You can say Class.

kramdown-1.17.0/test/testcases/span/03_codespan/rouge/simple.text0000644000004100000410000000007313321140127025000 0ustar www-datawww-dataYou can say `x = Class.new`{:.language-ruby}, for example. kramdown-1.17.0/test/testcases/span/03_codespan/rouge/simple.html0000644000004100000410000000033113321140127024755 0ustar www-datawww-data

You can say x = Class.new, for example.

kramdown-1.17.0/test/testcases/span/03_codespan/empty.text0000644000004100000410000000007013321140127023521 0ustar www-datawww-dataThis is `` empty. This is ``empty. This is ````empty. kramdown-1.17.0/test/testcases/span/03_codespan/highlighting-minted.options0000644000004100000410000000003413321140127027015 0ustar www-datawww-data:syntax_highlighter: minted kramdown-1.17.0/test/testcases/span/03_codespan/empty.html0000644000004100000410000000011513321140127023501 0ustar www-datawww-data

This is `` empty.

This is ``empty.

This is ````empty.

kramdown-1.17.0/test/testcases/span/03_codespan/highlighting.text0000644000004100000410000000007313321140127025033 0ustar www-datawww-dataYou can say `x = Class.new`{:.language-ruby}, for example. kramdown-1.17.0/test/testcases/span/03_codespan/normal.html0000644000004100000410000000053313321140127023637 0ustar www-datawww-data

This is a simple span.

With some<ht>&ml in it.

And ` backticks.

And ``some`` more.

With backslash in\ it.

This is a ` literal backtick. As `are` these!

No literal backtick.

something

kramdown-1.17.0/test/testcases/span/03_codespan/highlighting-minted.text0000644000004100000410000000007313321140127026311 0ustar www-datawww-dataYou can say `x = Class.new`{:.language-ruby}, for example. kramdown-1.17.0/test/testcases/span/03_codespan/highlighting-minted.latex0000644000004100000410000000007413321140127026443 0ustar www-datawww-dataYou can say \mintinline{ruby}{x = Class.new}, for example. kramdown-1.17.0/test/testcases/span/03_codespan/errors.html0000644000004100000410000000003013321140127023653 0ustar www-datawww-data

Not ended `span.

kramdown-1.17.0/test/testcases/span/03_codespan/normal.text0000644000004100000410000000033313321140127023655 0ustar www-datawww-dataThis is `a` simple span. With `some&ml` in it. And `` ` `` backticks. And ``` ``some`` ``` more. With backslash `in\` it. This is a ` literal backtick. As \`are\` these! No `` literal backtick``. `something` kramdown-1.17.0/test/testcases/span/03_codespan/errors.text0000644000004100000410000000002113321140127023673 0ustar www-datawww-dataNot ended `span. kramdown-1.17.0/test/testcases/span/03_codespan/highlighting.html0000644000004100000410000000026413321140127025015 0ustar www-datawww-data

You can say x = Class.new, for example.

kramdown-1.17.0/test/testcases/span/text_substitutions/0000755000004100000410000000000013321140127023365 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/text_substitutions/typography_subst.html0000644000004100000410000000015713321140127027704 0ustar www-datawww-data

This ... something---this too--!

This <<is>> some text, << this >> too!

kramdown-1.17.0/test/testcases/span/text_substitutions/entities_symbolic.html0000644000004100000410000000010213321140127027771 0ustar www-datawww-data

This is the A&O. © 2008 by me ŗ and λ

kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_input.text0000644000004100000410000000006613321140127030023 0ustar www-datawww-dataThis is the A&O. © 2008 by me ŗ and λ kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_char.text0000644000004100000410000000007213321140127027576 0ustar www-datawww-dataThis "is" 'the' A&O. © 2008 by me ŗ and λ kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_input.options0000644000004100000410000000003213321140127030523 0ustar www-datawww-data:entity_output: :as_input kramdown-1.17.0/test/testcases/span/text_substitutions/typography_subst.latex0000644000004100000410000000024613321140127030054 0ustar www-datawww-dataThis ... something---this too--! This \textless{}\textless{}is\textgreater{}\textgreater{} some text, \textless{}\textless{} this \textgreater{}\textgreater{} too! kramdown-1.17.0/test/testcases/span/text_substitutions/entities_numeric.html0000644000004100000410000000010013321140127027610 0ustar www-datawww-data

This is the A&O. © 2008 by me ŗ and λ

kramdown-1.17.0/test/testcases/span/text_substitutions/entities.text0000644000004100000410000000022713321140127026120 0ustar www-datawww-dataThis is the A&O. © 2008 by me As well \& as this. Some ŗ other values may ¯ may also show but not st. like &#xYZ;. This is BS&T; done! kramdown-1.17.0/test/testcases/span/text_substitutions/entities_symbolic.text0000644000004100000410000000006613321140127030022 0ustar www-datawww-dataThis is the A&O. © 2008 by me ŗ and λ kramdown-1.17.0/test/testcases/span/text_substitutions/entities_numeric.text0000644000004100000410000000006613321140127027643 0ustar www-datawww-dataThis is the A&O. © 2008 by me ŗ and λ kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_char.html.190000644000004100000410000000007013321140127030004 0ustar www-datawww-data

This "is" 'the' A&O. © 2008 by me ŗ and λ

kramdown-1.17.0/test/testcases/span/text_substitutions/typography_subst.options0000644000004100000410000000021013321140127030421 0ustar www-datawww-datatypographic_symbols: hellip: '...' mdash: '---' ndash: '--' laquo: '<<' raquo: '>>' laquo_space: '<< ' raquo_space: ' >>' kramdown-1.17.0/test/testcases/span/text_substitutions/greaterthan.html0000644000004100000410000000002713321140127026556 0ustar www-datawww-data

2 > 1 > 0

kramdown-1.17.0/test/testcases/span/text_substitutions/entities.options0000644000004100000410000000003213321140127026621 0ustar www-datawww-data:entity_output: :as_input kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_char.options0000644000004100000410000000007413321140127030307 0ustar www-datawww-data:entity_output: :as_char :smart_quotes: apos,apos,quot,quot kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_char.html0000644000004100000410000000012713321140127027557 0ustar www-datawww-data

This "is" 'the' A&O. © 2008 by me ŗ and λ

kramdown-1.17.0/test/testcases/span/text_substitutions/typography.text0000644000004100000410000000122113321140127026475 0ustar www-datawww-dataThis is... something---this too--! This <> some text, << this >> too! "Fancy quotes" are 'cool', even in the '80s! Je t' aime. You're a funny one! Thomas' name Mark's name. "...you" "'Nested' quotes are 'possible'", too! '"Otherway" is "round"'! 'Opening now!' '80s are really cool. Cluster's Last Stand. Nam liber tempor "...At vero eos et accusam" "_Single underscores_ should work." "*Single asterisks* should work." '__Double underscores__ should work.' '**Double asterisks** should work.' "_Hurrah!_" '__Absolutely__.' "...some Text" "... some Text" This: "...some Text" This: "... some Text" "\[foo]" "\[foo]" d "\[foo]" kramdown-1.17.0/test/testcases/span/text_substitutions/lowerthan.html0000644000004100000410000000002713321140127026255 0ustar www-datawww-data

0 < 1 < 2

kramdown-1.17.0/test/testcases/span/text_substitutions/typography.options0000644000004100000410000000003113321140127027202 0ustar www-datawww-data:entity_output: symbolic kramdown-1.17.0/test/testcases/span/text_substitutions/entities_as_input.html0000644000004100000410000000010113321140127027771 0ustar www-datawww-data

This is the A&O. © 2008 by me ŗ and λ

kramdown-1.17.0/test/testcases/span/text_substitutions/entities_numeric.options0000644000004100000410000000003113321140127030342 0ustar www-datawww-data:entity_output: :numeric kramdown-1.17.0/test/testcases/span/text_substitutions/entities.html0000644000004100000410000000026513321140127026102 0ustar www-datawww-data

This is the A&O. © 2008 by me As well \& as this. Some ŗ other values may ¯ may also show but not st. like &#xYZ;.

This is BS&T; done!

kramdown-1.17.0/test/testcases/span/text_substitutions/greaterthan.text0000644000004100000410000000001213321140127026570 0ustar www-datawww-data2 > 1 > 0 kramdown-1.17.0/test/testcases/span/text_substitutions/typography.html0000644000004100000410000000233413321140127026463 0ustar www-datawww-data

This is… something—this too–!

This «is» some text, « this » too!

“Fancy quotes” are ‘cool’, even in the ’80s! Je t’ aime. You’re a funny one! Thomas’ name Mark’s name. “…you” “‘Nested’ quotes are ‘possible’”, too! ‘“Otherway” is “round”’!

‘Opening now!’

’80s are really cool.

Cluster’s Last Stand.

Nam liber tempor “…At vero eos et accusam”

Single underscores should work.”

Single asterisks should work.”

Double underscores should work.’

Double asterisks should work.’

Hurrah!

Absolutely.’

“…some Text”

“… some Text”

This: “…some Text”

This: “… some Text”

”[foo]” “[foo]” d “[foo]”

kramdown-1.17.0/test/testcases/span/text_substitutions/lowerthan.text0000644000004100000410000000001213321140127026267 0ustar www-datawww-data0 < 1 < 2 kramdown-1.17.0/test/testcases/span/text_substitutions/typography_subst.text0000644000004100000410000000011113321140127027712 0ustar www-datawww-dataThis ... something---this too--! This <> some text, << this >> too! kramdown-1.17.0/test/testcases/span/text_substitutions/entities_symbolic.options0000644000004100000410000000003213321140127030522 0ustar www-datawww-data:entity_output: :symbolic kramdown-1.17.0/test/testcases/span/math/0000755000004100000410000000000013321140127020313 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/math/ritex.html0000644000004100000410000000054413321140127022337 0ustar www-datawww-data

This is f(x)=ax3+bx2+cx+d something!

kramdown-1.17.0/test/testcases/span/math/sskatex.text0000644000004100000410000000010413321140127022676 0ustar www-datawww-dataErst einmal eine Formel wie $$a^2+b^2=c^2$$ innerhalb eines Satzes. kramdown-1.17.0/test/testcases/span/math/mathjaxnode.html.190000644000004100000410000000111213321140127023726 0ustar www-datawww-data

This is f ( x ) = a x 3 + b x 2 + c x + d something!

kramdown-1.17.0/test/testcases/span/math/no_engine.html0000644000004100000410000000006513321140127023143 0ustar www-datawww-data

$5+5$ inline math

kramdown-1.17.0/test/testcases/span/math/katex.options0000644000004100000410000000002513321140127023041 0ustar www-datawww-data:math_engine: :katex kramdown-1.17.0/test/testcases/span/math/sskatex.html.190000644000004100000410000000413513321140127023116 0ustar www-datawww-data

Erst einmal eine Formel wie a2+b2=c2a^2+b^2=c^2 innerhalb eines Satzes.

kramdown-1.17.0/test/testcases/span/math/normal.html0000644000004100000410000000047713321140127022501 0ustar www-datawww-data

This is some math. With new line characters in between.

inline math, $5.00 $$no math$$

$$5+5$$ inline math

$$5+5$$

kramdown-1.17.0/test/testcases/span/math/katex.html.190000644000004100000410000000413513321140127022550 0ustar www-datawww-data

Erst einmal eine Formel wie a2+b2=c2a^2+b^2=c^2 innerhalb eines Satzes.

kramdown-1.17.0/test/testcases/span/math/ritex.text0000644000004100000410000000006713321140127022357 0ustar www-datawww-dataThis is $$f(x) = a{x^3} + b{x^2} + cx + d$$ something! kramdown-1.17.0/test/testcases/span/math/itex2mml.options0000644000004100000410000000002713321140127023470 0ustar www-datawww-data:math_engine: itex2mml kramdown-1.17.0/test/testcases/span/math/sskatex.options0000644000004100000410000000002613321140127023410 0ustar www-datawww-data:math_engine: sskatex kramdown-1.17.0/test/testcases/span/math/mathjaxnode.text0000644000004100000410000000006713321140127023526 0ustar www-datawww-dataThis is $$f(x) = a{x^3} + b{x^2} + cx + d$$ something! kramdown-1.17.0/test/testcases/span/math/no_engine.text0000644000004100000410000000002413321140127023156 0ustar www-datawww-data$$5+5$$ inline math kramdown-1.17.0/test/testcases/span/math/katex.text0000644000004100000410000000010413321140127022330 0ustar www-datawww-dataErst einmal eine Formel wie $$a^2+b^2=c^2$$ innerhalb eines Satzes. kramdown-1.17.0/test/testcases/span/math/ritex.options0000644000004100000410000000002413321140127023057 0ustar www-datawww-data:math_engine: ritex kramdown-1.17.0/test/testcases/span/math/normal.text0000644000004100000410000000025613321140127022514 0ustar www-datawww-dataThis is $$\lambda_\alpha > 5$$ some math. With $$1 + 1$$ new line characters in between. $$5+5$$ inline math, $5.00 \$$no math$$ \$\$5+5$$ inline math \$$5+5$$ \$\$5+5$$ kramdown-1.17.0/test/testcases/span/math/itex2mml.html0000644000004100000410000000072613321140127022747 0ustar www-datawww-data

This is f(x)=ax 3+bx 2+cx+df(x) = a{x^3} + b{x^2} + cx + d something!

kramdown-1.17.0/test/testcases/span/math/itex2mml.text0000644000004100000410000000006713321140127022765 0ustar www-datawww-dataThis is $$f(x) = a{x^3} + b{x^2} + cx + d$$ something! kramdown-1.17.0/test/testcases/span/math/mathjaxnode.options0000644000004100000410000000003213321140127024225 0ustar www-datawww-data:math_engine: mathjaxnode kramdown-1.17.0/test/testcases/span/math/no_engine.options0000644000004100000410000000002013321140127023661 0ustar www-datawww-data:math_engine: ~ kramdown-1.17.0/test/testcases/span/autolinks/0000755000004100000410000000000013321140127021373 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/autolinks/url_links.html0000644000004100000410000000213513321140127024264 0ustar www-datawww-data

This should be a http://www.example.com/ link. This should be a john.doe@example.com link. As should john.doe@example.com this. As should john_doe@example.com this. As should CSS@example.com this. Another ampersand http://www.example.com/?doit&x=y link. More entities http://www.example.com/?doit&x="y&z=y.

Email international übung@macht.den.meister.de, ü.äß@hülse.de Email invalid: <me@example.com>

Autolink with underscore: http://www.example.com/with_under_score

http://www.example.com/

kramdown-1.17.0/test/testcases/span/autolinks/url_links.text0000644000004100000410000000110713321140127024302 0ustar www-datawww-dataThis should be a link. This should be a link. As should this. As should this. As should this. Another ampersand link. More entities . Email international <übung@macht.den.meister.de>, <ü.äß@hülse.de> Email invalid: <[me@example.com](mailtos:me@example.com)> Autolink with underscore: *[CSS]: Cascading kramdown-1.17.0/test/testcases/span/02_emphasis/0000755000004100000410000000000013321140127021474 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/02_emphasis/empty.text0000644000004100000410000000004713321140127023541 0ustar www-datawww-dataThis __is **empty. This ****is empty. kramdown-1.17.0/test/testcases/span/02_emphasis/empty.html0000644000004100000410000000007413321140127023521 0ustar www-datawww-data

This __is **empty.

This **is empty.

kramdown-1.17.0/test/testcases/span/02_emphasis/normal.html0000644000004100000410000000242013321140127023650 0ustar www-datawww-data

This is so hard.

This is so hard too.

At start At start

At end At end

At start At start

At end At end

And nested.

And nest**ed.

And *nested* like this.

And not_nest_ed.

And nested.

And nested.

And neste.

And lonely * here*.

And lonely ** here**.

And lonely ** here.

** and here**.

And compli*cated * here

Some**what more * **here

Do it *this* way Or this *this* way Or that *that* way Or that *that* way

http://blah.com/blah_%28

A-_B

  • test
  • test
  • test
  • (“test”)
  • (test)
  • test
  • `test
  • test
kramdown-1.17.0/test/testcases/span/02_emphasis/errors.html0000644000004100000410000000021313321140127023672 0ustar www-datawww-data

This is a *star.

This is a **star.

This is *a *star.

This is *a star*.

This** is** a star.

kramdown-1.17.0/test/testcases/span/02_emphasis/nesting.text0000644000004100000410000000073613321140127024057 0ustar www-datawww-data- ***test test*** - ___test test___ - *test **test*** - **test *test*** - ***test* test** - ***test** test* - ***test* test** - **test *test*** - *test **test*** - _test __test___ - __test _test___ - ___test_ test__ - ___test__ test_ - ___test_ test__ - __test _test___ - _test __test___ ^ - *a*b - a*b* - a*b*c - **a**b - a**b** - a**b**c ^ - _a_b - a_b_ - a_b_c - __a__b - a__b__ - a__b__c - a__2__c - a__2__3 - 1__2__3 ^ - *a _b_ c* - **a __b__ c** kramdown-1.17.0/test/testcases/span/02_emphasis/normal.text0000644000004100000410000000124613321140127023675 0ustar www-datawww-dataThis *is* so **hard**. This _is_ so __hard__ too. *At* start *At* start At *end* At *end* _At_ start _At_ start At _end_ At _end_ And *nest**ed***. And *nest**ed*. And *nest**ed* like** this. And *not_nest_ed*. And ***nested***. And ___nested___. And **nest*e***. And lonely * here*. And lonely ** here**. And **lonely ** here**. ** and here**. And **compli*cated \*** here Some***what* more * ***he*re Do it *\*this\** way Or this \**this*\* way Or that *\*that*\* way Or that \**that\** way [http://blah.com/blah_%28](http://blah.com/blah_%28) [A-_B](A_-B) - _test_ - '_test_' - "_test_" - ("_test_") - (_test_) - “_test_” - \`_test_' - „_test_“ kramdown-1.17.0/test/testcases/span/02_emphasis/nesting.html0000644000004100000410000000224313321140127024032 0ustar www-datawww-data
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • test test
  • ab
  • ab
  • abc
  • ab
  • ab
  • abc
  • _a_b
  • a_b_
  • a_b_c
  • __a__b
  • a__b__
  • a__b__c
  • a__2__c
  • a__2__3
  • 1__2__3
  • a _b_ c
  • a __b__ c
kramdown-1.17.0/test/testcases/span/02_emphasis/errors.text0000644000004100000410000000014213321140127023713 0ustar www-datawww-dataThis is a *star. This is a **star. This is **a *star*. This is *a star\*. This** is** a star. kramdown-1.17.0/test/testcases/span/02_emphasis/normal.options0000644000004100000410000000003113321140127024373 0ustar www-datawww-data:entity_output: :numeric kramdown-1.17.0/test/testcases/span/04_footnote/0000755000004100000410000000000013321140127021522 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/04_footnote/backlink_text.options0000644000004100000410000000005213321140127025756 0ustar www-datawww-data:footnote_backlink: 'text &8617; ' kramdown-1.17.0/test/testcases/span/04_footnote/without_backlink.options0000644000004100000410000000002713321140127026477 0ustar www-datawww-data:footnote_backlink: '' kramdown-1.17.0/test/testcases/span/04_footnote/inside_footnote.text0000644000004100000410000000026113321140127025617 0ustar www-datawww-dataLorem ipsum[^first] dolor sit amet. Lorem ipsum[^second] dolor sit amet. [^first]: Consecutur adisping.[^third] [^second]: Sed ut perspiciatis unde omnis. [^third]: Sed ut. kramdown-1.17.0/test/testcases/span/04_footnote/footnote_nr.text0000644000004100000410000000012613321140127024763 0ustar www-datawww-dataThis is a footnote[^ab]. And another[^bc]. [^ab]: Some text. [^bc]: Some other text. kramdown-1.17.0/test/testcases/span/04_footnote/without_backlink.text0000644000004100000410000000005713321140127025773 0ustar www-datawww-dataSome footnote here[^fn] [^fn]: Some text here kramdown-1.17.0/test/testcases/span/04_footnote/placement.html0000644000004100000410000000044013321140127024356 0ustar www-datawww-data
  1. Footnote \` text 

Some para with a1 footnote.

And another para.

kramdown-1.17.0/test/testcases/span/04_footnote/regexp_problem.options0000644000004100000410000000005313321140127026147 0ustar www-datawww-data:auto_ids: false :entity_output: :symbolic kramdown-1.17.0/test/testcases/span/04_footnote/regexp_problem.text0000644000004100000410000000016513321140127025444 0ustar www-datawww-data# Something something[^note1]. # Footnotes [^note1]: A note # Test kramdown-1.17.0/test/testcases/span/04_footnote/backlink_inline.text0000644000004100000410000000072513321140127025550 0ustar www-datawww-dataThis is [^paragraph][^header][^blockquote][^codeblock][^list][^table][^hrule][^mathblock][^html] [^paragraph]: A paragraph [^header]: # A header [^blockquote]: > blockquote > > paragraph [^codeblock]: codeblock [^list]: * item 1 * item 2 * sub item > blockquote > > # header [^table]: | a | b | | c | d | [^hrule]: *** [^mathblock]: $$x + 2$$ [^html]:
test
kramdown-1.17.0/test/testcases/span/04_footnote/markers.html0000644000004100000410000000307613321140127024062 0ustar www-datawww-data

This is some *ref.1

a blockquote 2

  • and a list item 3

And a header4

A marker without a definition [^without].

A marker 5 used twice1 and thrice1.

  1. Some foot note text  2 3

  2. other text with more lines

    and a quote

  3. some text 

  4. code block
    continued here
    

kramdown-1.17.0/test/testcases/span/04_footnote/footnote_nr.html0000644000004100000410000000071013321140127024742 0ustar www-datawww-data

This is a footnote35. And another36.

  1. Some text. 

  2. Some other text. 

kramdown-1.17.0/test/testcases/span/04_footnote/backlink_text.text0000644000004100000410000000005713321140127025254 0ustar www-datawww-dataSome footnote here[^fn] [^fn]: Some text here kramdown-1.17.0/test/testcases/span/04_footnote/backlink_inline.options0000644000004100000410000000003713321140127026253 0ustar www-datawww-datafootnote_backlink_inline: true kramdown-1.17.0/test/testcases/span/04_footnote/regexp_problem.html0000644000004100000410000000046213321140127025424 0ustar www-datawww-data

Something

something1.

Footnotes

Test

  1. A note 

kramdown-1.17.0/test/testcases/span/04_footnote/markers.latex0000644000004100000410000000076113321140127024231 0ustar www-datawww-dataThis is some *ref.\footnote{Some foot note text} \begin{quote} a blockquote \footnote{other text with more lines \begin{quote} and a quote \end{quote}} \end{quote} \begin{itemize} \item{} and a list item \footnote{some \emph{text}} \end{itemize} \section*{And a header\footnote{\begin{verbatim}code block continued here \end{verbatim}}} A marker without a definition {[}\^{}without{]}. A marker \footnote{} used twice\footnote{Some foot note text} and thrice\footnote{Some foot note text}. kramdown-1.17.0/test/testcases/span/04_footnote/markers.options0000644000004100000410000000005313321140127024601 0ustar www-datawww-data:auto_ids: false :entity_output: :symbolic kramdown-1.17.0/test/testcases/span/04_footnote/definitions.text0000644000004100000410000000036713321140127024751 0ustar www-datawww-dataSome para. [^footnote]: ignored definition [^footnote]: Some footnote text > blockquote [^other]: some foot note text * a list with some text [^tnote]: foot note * other list ^ code [^1]: > a blockquote and some para kramdown-1.17.0/test/testcases/span/04_footnote/without_backlink.html0000644000004100000410000000030313321140127025745 0ustar www-datawww-data

Some footnote here1

  1. Some text here

kramdown-1.17.0/test/testcases/span/04_footnote/placement.options0000644000004100000410000000003113321140127025101 0ustar www-datawww-data:entity_output: :numeric kramdown-1.17.0/test/testcases/span/04_footnote/markers.text0000644000004100000410000000054713321140127024102 0ustar www-datawww-dataThis is some *ref.[^fn] [^fn]: Some foot note text {: .class} > a blockquote [^3] * and a list item [^1] # And a header[^now] [^1]:some *text* [^3]: other text with more lines > and a quote A marker without a definition [^without]. A marker [^empty] used twice[^fn] and thrice[^fn]. [^now]: code block continued here [^empty]: kramdown-1.17.0/test/testcases/span/04_footnote/definitions.latex0000644000004100000410000000030513321140127025072 0ustar www-datawww-dataSome para. \begin{quote} blockquote \end{quote} \begin{itemize} \item{} a list with some text \end{itemize} \begin{itemize} \item{} other list \end{itemize} \begin{verbatim}code \end{verbatim} kramdown-1.17.0/test/testcases/span/04_footnote/inside_footnote.html0000644000004100000410000000130713321140127025601 0ustar www-datawww-data

Lorem ipsum1 dolor sit amet.

Lorem ipsum2 dolor sit amet.

  1. Consecutur adisping.3 

  2. Sed ut perspiciatis unde omnis. 

  3. Sed ut. 

kramdown-1.17.0/test/testcases/span/04_footnote/definitions.html0000644000004100000410000000026013321140127024721 0ustar www-datawww-data

Some para.

blockquote

  • a list with some text
  • other list
code
kramdown-1.17.0/test/testcases/span/04_footnote/backlink_text.html0000644000004100000410000000041613321140127025233 0ustar www-datawww-data

Some footnote here1

  1. Some text here text &8617; <img />

kramdown-1.17.0/test/testcases/span/04_footnote/backlink_inline.html0000644000004100000410000000466013321140127025532 0ustar www-datawww-data

This is 123456789

  1. A paragraph 

  2. A header 

  3. blockquote

    paragraph 

  4. codeblock
    

    • item 1
    • item 2
      • sub item

        blockquote

        header 

  5. a b
    c d


  6. test

kramdown-1.17.0/test/testcases/span/04_footnote/footnote_nr.options0000644000004100000410000000002113321140127025464 0ustar www-datawww-data:footnote_nr: 35 kramdown-1.17.0/test/testcases/span/04_footnote/footnote_nr.latex0000644000004100000410000000012213321140127025110 0ustar www-datawww-dataThis is a footnote\footnote{Some text.}. And another\footnote{Some other text.}. kramdown-1.17.0/test/testcases/span/04_footnote/placement.text0000644000004100000410000000017213321140127024400 0ustar www-datawww-data* footnotes will be placed here {:footnotes} Some para with a[^1] footnote. [^1]: Footnote \\\` text And another para. kramdown-1.17.0/test/testcases/span/05_html/0000755000004100000410000000000013321140127020632 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/05_html/xml.text0000644000004100000410000000021113321140127022332 0ustar www-datawww-dataThis doit test This doit test This doit test kramdown-1.17.0/test/testcases/span/05_html/button.html0000644000004100000410000000037513321140127023040 0ustar www-datawww-data

First some text and then a

and then text.

A it.

kramdown-1.17.0/test/testcases/span/05_html/button.text0000644000004100000410000000027113321140127023053 0ustar www-datawww-data First some text and then a and then text. A it. kramdown-1.17.0/test/testcases/span/05_html/markdown_attr.html0000644000004100000410000000040513321140127024373 0ustar www-datawww-data

This is text This is *text* This is text This is text This is *nothing* to fear about. This is <http://example.com>.

kramdown-1.17.0/test/testcases/span/05_html/raw_span_elements.html0000644000004100000410000000017113321140127025225 0ustar www-datawww-data

This is raw --version and --version and --version and ---version.

kramdown-1.17.0/test/testcases/span/05_html/xml.html0000644000004100000410000000025313321140127022320 0ustar www-datawww-data

This doit test

This doit test

This doit</some> test

kramdown-1.17.0/test/testcases/span/05_html/mark_element.html0000644000004100000410000000005613321140127024164 0ustar www-datawww-data

Lorem ipsum.

Test

kramdown-1.17.0/test/testcases/span/05_html/raw_span_elements.text0000644000004100000410000000016213321140127025245 0ustar www-datawww-dataThis is raw --version and --version and --version and ---version. kramdown-1.17.0/test/testcases/span/05_html/normal.html0000644000004100000410000000155213321140127023013 0ustar www-datawww-data

Empty !

title is a title.

This is .

This is comment.

This is multiline comment.

This is tag now .

This is tag now.

This is an empty tag.

This is something strange.

Auto-closing:

Expanding:

An invalid tag: <hR>

A <p>block tag</p>.

An invalid </closing> tag.

A tag.

An unclosed tag.

Some element with | pipe symbol

Some element with | pipe symbol

Some element with | pipe symbol|

underlined

kramdown-1.17.0/test/testcases/span/05_html/mark_element.text0000644000004100000410000000004013321140127024175 0ustar www-datawww-dataLorem ipsum. Test kramdown-1.17.0/test/testcases/span/05_html/across_lines.text0000644000004100000410000000004213321140127024220 0ustar www-datawww-dataLink: test kramdown-1.17.0/test/testcases/span/05_html/normal.text0000644000004100000410000000124713321140127023034 0ustar www-datawww-dataEmpty ! title is a title. This is . This is comment. This is multiline comment. This is tag now . This is tag now. This is an empty tag. This is _something strange_. Auto-closing:
Expanding: An invalid tag:
A

block tag

. An invalid tag. A tag. An unclosed *tag.* Some element with | pipe symbol Some element with | pipe symbol Some element with | pipe symbol| underlined kramdown-1.17.0/test/testcases/span/05_html/across_lines.html0000644000004100000410000000005113321140127024200 0ustar www-datawww-data

Link: test

kramdown-1.17.0/test/testcases/span/05_html/invalid.text0000644000004100000410000000003013321140127023157 0ustar www-datawww-dataThis is some text kramdown-1.17.0/test/testcases/span/05_html/markdown_attr.text0000644000004100000410000000047613321140127024423 0ustar www-datawww-dataThis is *text* This is *text* This is *text* This is *text* This is *nothing* to *fear* about. This is . kramdown-1.17.0/test/testcases/span/05_html/link_with_mailto.html0000644000004100000410000000007013321140127025052 0ustar www-datawww-data

Link: text

kramdown-1.17.0/test/testcases/span/05_html/invalid.html0000644000004100000410000000004613321140127023146 0ustar www-datawww-data

This is some text

kramdown-1.17.0/test/testcases/span/05_html/link_with_mailto.text0000644000004100000410000000006113321140127025072 0ustar www-datawww-dataLink: text kramdown-1.17.0/test/testcases/span/abbreviations/0000755000004100000410000000000013321140127022212 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/abbreviations/abbrev.text0000644000004100000410000000103613321140127024361 0ustar www-datawww-dataThis is some text. *[is some]: Yes it is *[OtHeR!]: This & that *[is some]: It is, yes *[empty]: There *is some real* concern about OtHeR! is some Think empty about Oesterreich. CSS und CSS3 no abbrev here because there is someone and kulis some *[Oesterreich]: Very nice country *[CSS]: Cascading *[CSS3]: Cascading 3 * (X)HTML test * line two [(X)HTML](http://en.wikipedia.org/wiki/Xhtml) * test (X)HTML *[(X)HTML]: (eXtensible) HyperText Markup Language This is awesome. {:.testit} *[awesome]: Some text here {:.test} kramdown-1.17.0/test/testcases/span/abbreviations/abbrev.html0000644000004100000410000000155213321140127024344 0ustar www-datawww-data

This is some text.

There is some real concern about OtHeR!

is some Think empty about Oesterreich. CSS und CSS3

no abbrev here because there is someone and kulis some

  • (X)HTML test
  • line two

(X)HTML

  • test (X)HTML

This is awesome.

kramdown-1.17.0/test/testcases/span/abbreviations/in_footnote.html0000644000004100000410000000047313321140127025427 0ustar www-datawww-data

There is a TXT file here. 1

  1. A TXT file. 

kramdown-1.17.0/test/testcases/span/abbreviations/in_footnote.text0000644000004100000410000000010513321140127025437 0ustar www-datawww-dataThere is a TXT file here. [^1] *[TXT]: Text File [^1]: A TXT file. kramdown-1.17.0/test/testcases/span/abbreviations/abbrev_defs.text0000644000004100000410000000017313321140127025363 0ustar www-datawww-data*[ABBR]: Some abbreviations *[one abbr]: one abbrev *[2 and other]: another *[3]: yet another *[4]: noabbrev kramdown-1.17.0/test/testcases/span/abbreviations/abbrev_defs.html0000644000004100000410000000005013321140127025335 0ustar www-datawww-data
*[4]: noabbrev
kramdown-1.17.0/test/testcases/span/escaped_chars/0000755000004100000410000000000013321140127022146 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/escaped_chars/normal.html0000644000004100000410000000040313321140127024321 0ustar www-datawww-data

\

.

*

_

+

-

`

(

)

[

]

{

}

#

!

<<

>>

:

|

"

'

=

>

<

kramdown-1.17.0/test/testcases/span/escaped_chars/normal.text0000644000004100000410000000014113321140127024340 0ustar www-datawww-data\\ \. \* \_ \+ \- \` \( \) \[ \] \{ \} \# \! \<< \>> \: \| \" \' \= \> \< kramdown-1.17.0/test/testcases/span/ial/0000755000004100000410000000000013321140127020127 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/ial/simple.text0000644000004100000410000000023013321140127022321 0ustar www-datawww-dataThis is a `span`{: .hund #dog}. This is a `span`{: .hund #dog}{: .katz key='val'}. This is an{: .ignored} span ial. This is an\{: .escaped} span ial. kramdown-1.17.0/test/testcases/span/ial/simple.html0000644000004100000410000000031613321140127022306 0ustar www-datawww-data

This is a span.

This is a span.

This is an{: .ignored} span ial. This is an{: .escaped} span ial.

kramdown-1.17.0/test/testcases/span/extension/0000755000004100000410000000000013321140127021376 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/extension/ignored.text0000644000004100000410000000004313321140127023730 0ustar www-datawww-dataThis is {::something}paragraph{:/} kramdown-1.17.0/test/testcases/span/extension/nomarkdown.text0000644000004100000410000000004713321140127024464 0ustar www-datawww-dataThis is {::nomarkdown}*some*{:/} text. kramdown-1.17.0/test/testcases/span/extension/ignored.html0000644000004100000410000000005213321140127023710 0ustar www-datawww-data

This is {::something}paragraph{:/}

kramdown-1.17.0/test/testcases/span/extension/options.text0000644000004100000410000000011513321140127023774 0ustar www-datawww-dataThis is an {::options parse_span_html="false" /} option *true*! kramdown-1.17.0/test/testcases/span/extension/nomarkdown.html0000644000004100000410000000003413321140127024440 0ustar www-datawww-data

This is *some* text.

kramdown-1.17.0/test/testcases/span/extension/comment.html0000644000004100000410000000034413321140127023727 0ustar www-datawww-data

This is a paragraph. This is a paragraph. This is a . This is a paragraph. This is a {:/comment} simple {:/} paragraph. This is a {::comment} paragraph.

kramdown-1.17.0/test/testcases/span/extension/options.html0000644000004100000410000000005713321140127023761 0ustar www-datawww-data

This is an option *true*!

kramdown-1.17.0/test/testcases/span/extension/comment.text0000644000004100000410000000041113321140127023742 0ustar www-datawww-dataThis is a {::comment}simple{:/} paragraph. This is a {::comment}simple{:/comment} paragraph. This is a {::comment}simple {:/other} paragraph{:/comment}. This is a {::comment/} paragraph. This is a {:/comment} simple {:/} paragraph. This is a {::comment} paragraph. kramdown-1.17.0/test/testcases/span/01_link/0000755000004100000410000000000013321140127020617 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/01_link/link_defs_with_ial.text0000644000004100000410000000045313321140127025345 0ustar www-datawww-dataLink def with [attr] and [attr 2] and [attr 3] and [attr before] [attr]: http://example.com 'title' {: hreflang="en" .test} [attr 2]: http://example.com 'title' {: hreflang="en"} {: .test} [attr 3]: http://example.com {: .test} test {: hreflang="en"} {: .test} [attr before]: http://example.com kramdown-1.17.0/test/testcases/span/01_link/imagelinks.html0000644000004100000410000000103413321140127023626 0ustar www-datawww-data

Simple: alt text

Simple with title: alt text

Empty img link: alt text

Reference style: alt text

Reference style with title: alt text

No alt text:

No id: imgo

With escaped pipe: an | pipe

kramdown-1.17.0/test/testcases/span/01_link/link_defs.html0000644000004100000410000000050013321140127023436 0ustar www-datawww-data

This is a para. [id]: http://www.example.com/

[4]: nourl

Points to 1 and 2 and 3 but not [4]

Points to _.:,;!?- and otherid8

kramdown-1.17.0/test/testcases/span/01_link/link_defs.text0000644000004100000410000000116513321140127023466 0ustar www-datawww-dataThis is a para. [id]: http://www.example.com/ [otherid1]: http://wwww.example.com/ "title 1" [otherid2]: http://wwww.example.com/ 'title 2' [otherid3]: [otherid4]: 'title' [otherid5]: some spaces.html [otherid6]: some spaces.html 'title' [otherid7]: some spaces "title" [otherid8]:test.html#'test' 'title' [break]: http://www.example.com/test/asdf.html 'Another title' [1]: ignored.url [1]: one.url [2]: two.url [3]: three.url [4]: nourl Points to [1] and [2] and [3] but not [4] [_.:,;!?-]: http://example.com Points to [_.:,;!?-] and [otherid8] kramdown-1.17.0/test/testcases/span/01_link/reference.html.190000644000004100000410000000211013321140127023665 0ustar www-datawww-data

simple URL and URL

simple URL and URL

simple 1 and isurl

simple 1 and isurl

this is [a holy isurl]

no [resolution][] here and [here]

with a break in the text

this not [isurl] and not [isurl]

a Link with_BIG letters

bad [no URL] d isurl

[no url] invalid.html [no url]:

“title”

test url but no title test [urldef]

[urldef]: some.url ‘title”

some with spaces

this is a ‘special’ occasion for /all/ of us

this is predefined for URI

kramdown-1.17.0/test/testcases/span/01_link/empty_title.htmlinput0000644000004100000410000000025213321140127025123 0ustar www-datawww-data

Image with empty title: alt text

Link reference with empty title.

kramdown-1.17.0/test/testcases/span/01_link/empty.text0000644000004100000410000000010513321140127022657 0ustar www-datawww-dataThis is [] empty. This is [][] empty. This is [](test.html) empty. kramdown-1.17.0/test/testcases/span/01_link/latex_escaping.latex0000644000004100000410000000035213321140127024644 0ustar www-datawww-data\href{https://example.com/~tilde/}{https://example.com/\ensuremath{\sim}tilde/} \href{http://example.com/percent\%20percent}{http://example.com/percent\%20percent} \href{http://example.com/hash#hash}{http://example.com/hash\#hash} kramdown-1.17.0/test/testcases/span/01_link/inline.text0000644000004100000410000000176213321140127023011 0ustar www-datawww-datasimple [URL]() simple [URL](something.html) simple [URL *with* formatting](something.html) simple [URL with single quoted title](something.html 'a t"itle') simple [URL with double quoted title](something.html "a t'itle") simple [URL \[with \] escaped](something.html) simple [URL with \] escaped](something.html) simple [URL [with] nested](something.html) simple [URL with [no](link.html) inside](something.html) simple [URL with parens](/something/to(do)) simple [URL with parens](/something/to(do "doit") simple [URL broken on line](something.html "title") simple [URL with spaces](with spaces.html) simple [URL with spaces](with spaces.html 'title') simple [URL with spaces](with (spaces).html) simple [leading/trailing spaces]( spaces.html) simple [leading/trailing spaces](spaces.html ) simple [leading/trailing spaces]( spaces.html ) bad [URL [not](something.html) bad [URL with parens](something(new.html) bad [URL with empty title](something.html '') bad [URL]( bad [URL](no kramdown-1.17.0/test/testcases/span/01_link/empty.html0000644000004100000410000000014513321140127022643 0ustar www-datawww-data

This is [] empty.

This is [][] empty.

This is empty.

kramdown-1.17.0/test/testcases/span/01_link/reference.options0000644000004100000410000000010613321140127024167 0ustar www-datawww-data:link_defs: predefined: [predefined.html] URI: [uri.html, My URI] kramdown-1.17.0/test/testcases/span/01_link/reference.text0000644000004100000410000000144013321140127023462 0ustar www-datawww-data[isurl]: someurl.html [1]: otherurl.html simple [URL][1] and [URL][isurl] simple [URL] [1] and [URL] [isurl] simple [1][] and [isurl][] simple [1] and [isurl] this is [a holy [isurl]] no [resolution][] here and [here] with a [break in the text] [break in the text]: url.html this not \[isurl] and not [isurl\] a [Link with_BIG] letters [link WITH_big]: letters.html 'This is the title' bad [no URL] d [isurl] [no url] invalid.html [no url]: [URL but no title]: invalid.html "title" test [url but no title] test [urldef] [urldef]: some.url 'title" some [with spaces] [with spaces]: with spaces.html "title" this [is a 'special' occasion for /all/ of us] [is a 'special' occasion for /all/ of us]: occasion.html this is [predefined] for [URI] kramdown-1.17.0/test/testcases/span/01_link/links_with_angle_brackets.text0000644000004100000410000000012713321140127026724 0ustar www-datawww-dataThis is a [link](). This is a [link]( 'and title'). kramdown-1.17.0/test/testcases/span/01_link/imagelinks.text0000644000004100000410000000053113321140127023647 0ustar www-datawww-dataSimple: ![alt text](/images/other.png) Simple with title: ![alt text](/images/other.png "title") Empty img link: ![alt text]() Reference style: ![alt text][img] Reference style with title: ![alt text][imgo] No alt text: ![](other.png) No id: ![imgo] [img]: other.png [imgo]: other.png "Title" With escaped pipe: ![an \| pipe](other.png) kramdown-1.17.0/test/testcases/span/01_link/link_defs_with_ial.html0000644000004100000410000000051413321140127025323 0ustar www-datawww-data

Link def with attr and attr 2 and attr 3 and attr before

test

kramdown-1.17.0/test/testcases/span/01_link/inline.html0000644000004100000410000000261613321140127022770 0ustar www-datawww-data

simple URL

simple URL

simple URL with formatting

simple URL with single quoted title

simple URL with double quoted title

simple URL [with ] escaped

simple URL with ] escaped

simple URL [with] nested

simple URL with [no](link.html) inside

simple URL with parens

simple URL with parens

simple URL broken on line

simple URL with spaces

simple URL with spaces

simple URL with spaces

simple leading/trailing spaces

simple leading/trailing spaces

simple leading/trailing spaces

bad [URL not

bad [URL with parens](something(new.html)

bad [URL with empty title](something.html ‘’)

bad [URL](

bad [URL](no

kramdown-1.17.0/test/testcases/span/01_link/image_in_a.html0000644000004100000410000000047213321140127023560 0ustar www-datawww-data

Simple: Some alt text

Nested: Some alt ![img](text.png) text

Simple: Some text alt text text

kramdown-1.17.0/test/testcases/span/01_link/links_with_angle_brackets.html0000644000004100000410000000017513321140127026707 0ustar www-datawww-data

This is a link.

This is a link.

kramdown-1.17.0/test/testcases/span/01_link/image_in_a.text0000644000004100000410000000031513321140127023574 0ustar www-datawww-dataSimple: [Some ![alt text](/images/other.png)](local.html) Nested: [Some ![alt ![img](text.png) text](/images/other.png)](local.html) Simple: [Some *text ![alt text](/images/other.png) text*](local.html) kramdown-1.17.0/test/testcases/span/01_link/inline.html.190000644000004100000410000000260613321140127023217 0ustar www-datawww-data

simple URL

simple URL

simple URL with formatting

simple URL with single quoted title

simple URL with double quoted title

simple URL [with ] escaped

simple URL with ] escaped

simple URL [with] nested

simple URL with [no](link.html) inside

simple URL with parens

simple URL with parens

simple URL broken on line

simple URL with spaces

simple URL with spaces

simple URL with spaces

simple leading/trailing spaces

simple leading/trailing spaces

simple leading/trailing spaces

bad [URL not

bad [URL with parens](something(new.html)

bad [URL with empty title](something.html ‘’)

bad [URL](

bad [URL](no

kramdown-1.17.0/test/testcases/span/01_link/empty_title.text0000644000004100000410000000017113321140127024063 0ustar www-datawww-dataImage with empty title: ![alt text](/images/other.png) Link [reference][1] with empty title. [1]: http://example.tld kramdown-1.17.0/test/testcases/span/01_link/latex_escaping.text0000644000004100000410000000014613321140127024514 0ustar www-datawww-data kramdown-1.17.0/test/testcases/span/01_link/reference.html0000644000004100000410000000214013321140127023440 0ustar www-datawww-data

simple URL and URL

simple URL and URL

simple 1 and isurl

simple 1 and isurl

this is [a holy isurl]

no [resolution][] here and [here]

with a break in the text

this not [isurl] and not [isurl]

a Link with_BIG letters

bad [no URL] d isurl

[no url] invalid.html [no url]:

“title”

test url but no title test [urldef]

[urldef]: some.url ‘title”

some with spaces

this is a ‘special’ occasion for /all/ of us

this is predefined for URI

kramdown-1.17.0/test/testcases/span/line_breaks/0000755000004100000410000000000013321140127021640 5ustar www-datawww-datakramdown-1.17.0/test/testcases/span/line_breaks/normal.html0000644000004100000410000000026713321140127024023 0ustar www-datawww-data

This is a line
with a line break.

This is a line without a line break.

This is a line
with a line\
break.

Line break on last line.

kramdown-1.17.0/test/testcases/span/line_breaks/normal.text0000644000004100000410000000022413321140127024034 0ustar www-datawww-dataThis is a line with a line break. This is a line without a line break. This is a line \\ with a line\\ break. Line break on last line. kramdown-1.17.0/test/testcases/span/line_breaks/normal.latex0000644000004100000410000000026113321140127024166 0ustar www-datawww-dataThis is a line\newline with a line break. This is a line without a line break. This is a line \newline with a line\textbackslash{} \newline break. Line break on last line. kramdown-1.17.0/test/testcases/encoding.html0000644000004100000410000000174513321140127021104 0ustar www-datawww-data

Das ist gewöhnlich ein Über-Problem mit manchen
Sälen http://example.org und anderen Dinge. Siehe Über mich!

Vielleicht höre ich nicht richtig?

  • Sollten wir uns das überlegen? Verhöhne mich nicht!
  • Ho ho höher! Sind *wir* da?

Titel sind urschön

Manche mögens ärmer

öha
was nun?
Töne
Laute Geräusche
vielleicht noch was ähnliches
hoch höher am höchsten
über drüber müde

Das ist schön gemacht

kramdown-1.17.0/test/test_location.rb0000644000004100000410000001605013321140127017621 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'minitest/autorun' require 'kramdown' Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9' describe 'location' do # checks that +element+'s :location option corresponds to the location stored # in the element.attr['class'] def check_element_for_location(element) if (match = /^line-(\d+)/.match(element.attr['class'] || '')) expected_line = match[1].to_i element.options[:location].must_equal(expected_line) end element.children.each do |child| check_element_for_location(child) end end # Test cases consist of a kramdown string that uses IALs to specify the expected # line numbers for a given element. test_cases = { 'autolink' => %(testing autolinks\n\n{:.line-3}), 'blockquote' => %( > block quote1 > > * {:.line-3} list item in block quote > * {:.line-4} list item in block quote > {:.line-3} {:.line-1} > block quote2 {:.line-8} ), 'codeblock' => %(\na para\n\n~~~~\ntest code 1\n~~~~\n{:.line-3}\n\n test code 2\n{:.line-8}\n), 'codespan' => %(a para\n\nanother para ``{:.line-3} with code\n), 'emphasis' => %( para *span*{:.line-1} {:.line-1} ## header *span*{:.line-4} {:.line-4} Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum *short span on single line*{:.line-11} dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non *long span over multiple lines - proident, sunt in culpa qui officia deserunt mollit anim id est laborum.*{:.line-13} Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo `code span`{:.line-18} Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo {:.line-7} ), 'header' => %( # header1 {:.line-1} ## header2 {:.line-4} ## header3 {:.line-7} header4 ======= {:.line-10} ^ header5 ------- {:.line-16} ), 'horizontal_rule' => %(\na para\n\n----\n{:.line-3}\n), 'html_entity' => "a para\n\nanother para with &{:.line-3} html entity.\n", 'link' => %( a para This is [a link](http://rubyforge.org){:.line-3} to a page. Here comes a ![smiley](../images/smiley.png){:.line-5} ), 'list' => %( * {:.line-1} list item * {:.line-2} list item * {:.line-3} list item {:.line-1} {:.line-7} 1. {:.line-7} list item 2. {:.line-8} list item 3. {:.line-9} list item {:.line-12} definition term 1 : {:.line-13} definition definition 1 definition term 2 : {:.line-15} definition definition 2 ), 'math_block' => %(\na para\n\n$$5+5$$\n{:.line-3}\n), 'math_inline' => %(\na para\n\nanother para with inline math $$5+5$${:.line-3}\n), 'paragraph' => %( para1 {:.line-1} para2 {:.line-4} Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse {:.line-7} {:.line-14} para with leading IAL ), 'table' => %( a para |first|second|third| |-----|------|-----| |a |b |c | {:.line-3} ), 'typographic_symbol' => %( a para another para ---{:.line-3} another para ...{:.line-5} ), 'gh issue 129' => %( `|` {:.line-1} ), 'gh issue 131' => %( * {:.line-1} test line 2 * {:.line-3} second * {:.line-4} third * {:.line-5} * {:.line-5} one * {:.line-6} two ), 'gh issue 158' => %( 😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁 {:.line-1} - {:.line-4} T {:.line-4} # T {:.line-7} ), 'gh issue 243 - HTML raw elements' => %(
  • Test
), } test_cases.each do |name, test_string| it "Handles #{ name }" do doc = Kramdown::Document.new(test_string.gsub(/^ /, '').strip) check_element_for_location(doc.root) end end it 'adds location info to duplicate abbreviation definition warnings' do test_string = %(This snippet contains a duplicate abbreviation definition *[duplicate]: The first definition *[duplicate]: The second definition ) doc = Kramdown::Document.new(test_string.strip) doc.warnings.must_equal ["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"] end it 'handles abbreviations' do str = "This *is* ABC and\n**and** ABC second\nanother ABC\nas ABC as\nABC at the end.\n\n*[ABC]: ABC" doc = Kramdown::Document.new(str) doc.root.children.first.children.select {|e| e.type == :abbreviation}.each_with_index do |e, i| assert_equal(i + 1, e.options[:location]) end end it 'handles line breaks' do str = "First \nsecond\\\\\nthird \n" doc = Kramdown::Document.new(str) doc.root.children.first.children.select {|e| e.type == :br}.each_with_index do |e, i| assert_equal(i + 1, e.options[:location]) end end it 'handles smart quotes' do str = "This is 'first'\nand 'second' and\n'third'" doc = Kramdown::Document.new(str) doc.root.children.first.children.select {|e| e.type == :smart_quote}.each_with_index do |e, i| assert_equal(((i + 1) /2.0).ceil, e.options[:location]) end end it 'handles hard wrapped paragraphs with the GFM parser' do str = "A*b*C\nA*b*C\nA*b*C" doc = Kramdown::Document.new(str, :input => 'GFM', :hard_wrap => true) para = doc.root.children.first 1.upto(3) do |line| 0.upto(line == 3 ? 2 : 3) do |element| assert_equal(line, para.children[4*(line - 1) + element].options[:location]) end end end it 'marks fenced code block as fenced with the GFM parser' do str = %(```\nfenced code\n```\n\n indented code\n) doc = Kramdown::Document.new(str, :input => 'GFM') fenced_cb = doc.root.children.first indented_cb = doc.root.children.last assert fenced_cb.options[:fenced] refute indented_cb.options[:fenced] end end kramdown-1.17.0/README.md0000644000004100000410000000541713321140127014732 0ustar www-datawww-data# kramdown ## Readme first! kramdown was originally licensed under the GPL until the 1.0.0 release. However, due to the many requests it is now released under the MIT license and therefore can easily be used in commercial projects, too. However, if you use kramdown in a commercial setting, please consider **contributing back any changes** for the benefit of the community and/or [**becoming a patron**](https://www.patreon.com/gettalong) - thanks! ## Introduction kramdown is a fast, pure Ruby Markdown superset converter, using a strict syntax definition and supporting several common extensions. The syntax definition for the kramdown syntax can be found in **doc/syntax.page** (or online at ) and a quick reference is available in **doc/quickref.page** or online at . The kramdown library is mainly written to support the kramdown-to-HTML conversion chain. However, due to its flexibility (by creating an internal AST) it supports other input and output formats as well. Here is a list of the supported formats: * input formats: kramdown (a Markdown superset), Markdown, GFM, HTML * output formats: HTML, kramdown, LaTeX (and therefore PDF), PDF via Prawn All the documentation on the available input and output formats is available in the **doc/** directory and online at . Starting from version 1.0.0 kramdown is using a versioning scheme with major, minor and patch parts in the version number where the major number changes on backwards-incompatible changes, the minor number on the introduction of new features and the patch number on everything else. For information about changes between versions, have a look at or the commit history! ## Usage kramdown has a very simple API, so using kramdown is as easy as ```ruby require 'kramdown' Kramdown::Document.new(text).to_html ``` For detailed information have a look at the API documentation of the `Kramdown::Document` class. The full API documentation is available at , other sites with an API documentation for kramdown probably don't provide the complete documentation! There are also some third-party libraries that extend the functionality of kramdown -- see the kramdown Wiki at . ## Development Just clone the git repository as described in **doc/installation.page** and you are good to go. You probably want to install `rake` so that you can use the provided rake tasks. If you want to run the tests, the development dependencies are needed as well as some additional programs like `tidy` and `latex`. See the `.travis.yml` file for more information. ## License MIT - see the **COPYING** file. kramdown-1.17.0/bin/0000755000004100000410000000000013321140127014214 5ustar www-datawww-datakramdown-1.17.0/bin/kramdown0000755000004100000410000000653313321140127015773 0ustar www-datawww-data#!/usr/bin/env ruby # -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2015 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'optparse' require 'rbconfig' require 'yaml' require 'kramdown' config_file = nil begin config_dir = case RbConfig::CONFIG['host_os'] when /bccwin|cygwin|djgpp|mingw|mswin|wince/i File.expand_path((ENV['HOME'] || ENV['USERPROFILE'] || "~") + "/AppData/Local") when /darwin|mac os/ File.expand_path("~/Library/Preferences/") else File.expand_path(ENV['XDG_CONFIG_HOME'] || '~/.config') end config_file = File.join(config_dir, "kramdownrc") rescue end options = {} format = ['html'] OptionParser.new do |opts| opts.banner = "Usage: kramdown [options] [FILE FILE ...]" opts.summary_indent = ' '*4 opts.separator "" opts.separator "Command line options:" opts.separator "" opts.on("-i", "--input ARG", "Specify the input format: kramdown (default), " \ "html, GFM or markdown") {|v| options[:input] = v} opts.on("-o", "--output ARG", Array, "Specify one or more output formats separated by commas: " \ "html (default),", "kramdown, latex, pdf, man or remove_html_tags") {|v| format = v} opts.separator "" opts.on("--no-config-file", "Do not read any configuration file. Default behavior is to check " \ "for a", "configuration file and read it if it exists.") {config_file = nil} opts.on("--config-file FILE", "Specify the name of a configuration file with kramdown options " \ "in YAML", "format, e.g. \"auto_id_prefix: ARG\" instead of \"--auto-id-prefix ARG\"", "and \"auto_ids: false\" instead of \"--no-auto-ids\".", "Default: #{config_file}") {|v| config_file = v} opts.separator "" opts.on("-v", "--version", "Show the version of kramdown") do puts Kramdown::VERSION exit end opts.on("-h", "--help", "Show the help") do puts opts.summarize('', 5, 72) exit end opts.separator "" opts.separator "kramdown options:" opts.separator "" Kramdown::Options.definitions.sort.each do |n, definition| no = n.to_s.tr('_', '-') if definition.type == Kramdown::Options::Boolean opts.on("--[no-]#{no}") {|v| options[n] = Kramdown::Options.parse(n, v)} else type = definition.type type = String if type == Symbol || type == Object opts.on("--#{no} ARG", type) {|v| options[n] = Kramdown::Options.parse(n, v)} end definition.desc.split(/\n/).each do |line| opts.separator opts.summary_indent + ' '*6 + line end opts.separator '' end end.parse! begin if config_file && File.exist?(config_file) config_file_options = YAML.safe_load(File.read(config_file), [Symbol]) case config_file_options when nil # empty configuration file except perhaps YAML header and comments # Nothing to do when Hash options = config_file_options.merge(options) else raise Kramdown::Error, "No YAML map in configuration file \"#{config_file}\"" end end doc = Kramdown::Document.new(ARGF.read, options) result = '' format.each {|f| result = doc.send("to_#{f}")} puts result doc.warnings.each {|warn| $stderr.puts "Warning: #{warn}"} rescue Kramdown::Error => e $stderr.puts "Error: #{e.message}" exit(1) end kramdown-1.17.0/CONTRIBUTERS0000644000004100000410000000545513321140127015323 0ustar www-datawww-data Count Name ======= ==== 887 Thomas Leitner 7 Christian Cornelssen 6 Gioele Barabucci 4 Ted Pak 4 Shuanglei Tao 4 Gleb Mazovetskiy 4 Arne Brasseur 3 Henning Perl 3 gettalong 3 Brandur 3 Ben Armston 3 Alex Marandon 2 Tom Thorogood 2 Parker Moore 2 Nathanael Jones 2 Max Meyer 2 Jo Hund 2 Dan Allen 2 Bran 1 winniehell 1 William 1 Uwe Kubosch 1 utenmiki 1 Trevor Wennblom 1 tomykaira 1 Tim Blair 1 Tim Besard 1 Tim Bates 1 Sun Yaozhu 1 Simon Lydell 1 Shusaku NAKAZATO 1 Sebastian Boehm 1 scherr 1 Postmodern 1 Pete Michaud 1 myqlarson 1 milo.simpson 1 Michal Till 1 Matt Hickford 1 Martyn Chamberlin 1 Marek Tuchowski 1 Marcus Stollsteimer 1 Luca Barbato 1 l3kn 1 Kir Kolyshkin 1 Jonathan Hooper 1 John Croisant 1 Joe Fiorini 1 Jens Kraemer 1 Hirofumi Wakasugi 1 Hector Correa 1 Florian Klampfer 1 Floreal Morandat florealm@gmail.com 1 Diego Galeota 1 Damien Pollet 1 Christopher Jefferson 1 Cédric Boutillier 1 Ashwin Maroli 1 Ashe Connor 1 Andrew 1 Alpha Chen 1 Alex Tomlins 1 Alexey Vasiliev kramdown-1.17.0/benchmark/0000755000004100000410000000000013321140127015376 5ustar www-datawww-datakramdown-1.17.0/benchmark/benchmark.sh0000755000004100000410000000320713321140127017671 0ustar www-datawww-data#!/bin/bash source ~/.profile RUBY_VERSIONS=`rvm list strings | sort` KD_VERSIONS="`git tag | sort -V` master" OTHERS=false AVERAGE=1 MASTER_AS=master while getopts "r:k:om:a:" optname; do case "$optname" in "r") RUBY_VERSIONS="$OPTARG" ;; "k") KD_VERSIONS="$OPTARG" ;; "o") OTHERS=true ;; "m") MASTER_AS="$OPTARG" ;; "a") AVERAGE="$OPTARG" ;; "?") echo "Unknown option $OPTARG" exit 1 ;; ":") echo "No argument value for option $OPTARG" exit 1 ;; *) echo "Unknown error while processing options" exit 1 ;; esac done TMPDIR=/tmp/kramdown-benchmark rm -rf $TMPDIR mkdir -p $TMPDIR cp benchmark/md* $TMPDIR cp benchmark/generate_data.rb $TMPDIR git clone .git ${TMPDIR}/kramdown cd ${TMPDIR}/kramdown for RUBY_VERSION in $RUBY_VERSIONS; do rvm use $RUBY_VERSION echo "Creating benchmark data for $(ruby -v)" for KD_VERSION in $KD_VERSIONS; do echo "Using kramdown version $KD_VERSION" git co $KD_VERSION 2>/dev/null if [ -z $MASTER_AS -o $KD_VERSION != master ]; then VNUM=${KD_VERSION} else VNUM=$MASTER_AS fi ruby -I${TMPDIR}/kramdown/lib ../generate_data.rb -k ${VNUM} -a ${AVERAGE} >/dev/null done if [ $OTHERS = "true" ]; then ruby -rubygems -I${TMPDIR}/kramdown/lib ../generate_data.rb -o >/dev/null fi done cd ${TMPDIR} rvm default ruby generate_data.rb -g kramdown-1.17.0/benchmark/timing.sh0000755000004100000410000000041113321140127017220 0ustar www-datawww-data#!/bin/bash source ~/.bashrc for VERSION in `rvm list strings | sort`; do rvm $VERSION echo $(ruby -v) ruby -Ilib bin/kramdown < benchmark/mdsyntax.text 2>/dev/null >/dev/null time ruby -Ilib bin/kramdown < benchmark/mdsyntax.text 2>/dev/null >/dev/null done kramdown-1.17.0/benchmark/benchmark.rb0000644000004100000410000000260213321140127017655 0ustar www-datawww-datarequire 'benchmark' require 'stringio' require 'kramdown' require 'bluecloth' require 'maruku' require 'maruku/version' require 'rdiscount' require 'bluefeather' require 'redcarpet' module MaRuKu::Errors def tell_user(s) end end RUNS=20 FILES=['mdsyntax.text', 'mdbasics.text'] puts "Running tests on #{Time.now.strftime("%Y-%m-%d")} under #{RUBY_DESCRIPTION}" FILES.each do |file| data = File.read(File.join(File.dirname(__FILE__), file)) puts puts "Test using file #{file} and #{RUNS} runs" results = Benchmark.bmbm do |b| b.report("kramdown #{Kramdown::VERSION}") { RUNS.times { Kramdown::Document.new(data).to_html } } b.report("Maruku #{MaRuKu::Version}") { RUNS.times { Maruku.new(data, :on_error => :ignore).to_html } } b.report("BlueFeather #{BlueFeather::VERSION}") { RUNS.times { BlueFeather.parse(data) } } b.report("BlueCloth #{BlueCloth::VERSION}") { RUNS.times { BlueCloth.new(data).to_html } } b.report("RDiscount #{RDiscount::VERSION}") { RUNS.times { RDiscount.new(data).to_html } } b.report("redcarpet #{Redcarpet::VERSION}") { RUNS.times { Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(data) } } end puts puts "Real time of X divided by real time of kramdown" kd = results.shift.real %w[Maruku BlueFeather BlueCloth RDiscount redcarpet].each do |name| puts name.ljust(19) << (results.shift.real/kd).round(4).to_s end end kramdown-1.17.0/benchmark/testing.sh0000755000004100000410000000032013321140127017405 0ustar www-datawww-data#!/bin/bash source ~/.profile COMMAND="$@" if [[ -z "$COMMAND" ]]; then COMMAND="rake test"; fi for VERSION in `rvm list strings | sort`; do rvm $VERSION echo $(ruby -v) RUBYOPT=-rubygems $COMMAND done kramdown-1.17.0/benchmark/mdsyntax.text0000644000004100000410000006544413321140127020170 0ustar www-datawww-dataMarkdown: Syntax ================ * [Overview](#overview) * [Philosophy](#philosophy) * [Inline HTML](#html) * [Automatic Escaping for Special Characters](#autoescape) * [Block Elements](#block) * [Paragraphs and Line Breaks](#p) * [Headers](#header) * [Blockquotes](#blockquote) * [Lists](#list) * [Code Blocks](#precode) * [Horizontal Rules](#hr) * [Span Elements](#span) * [Links](#link) * [Emphasis](#em) * [Code](#code) * [Images](#img) * [Miscellaneous](#misc) * [Backslash Escapes](#backslash) * [Automatic Links](#autolink) **Note:** This document is itself written using Markdown; you can [see the source for it by adding '.text' to the URL][src]. [src]: /projects/markdown/syntax.text * * *

Overview

Philosophy

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

Inline HTML

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

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

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

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

Automatic Escaping for Special Characters

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

Block Elements

Paragraphs and Line Breaks

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

Blockquotes

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

Lists

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

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

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

  • Magic

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

Code Blocks

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

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

    This is a normal paragraph:

        This is a code block.

Markdown will generate:

    

This is a normal paragraph:

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

Here is an example of AppleScript:

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

Horizontal Rules

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

Span Elements

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

This is an example inline link.

This link has no title attribute.

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

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

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

Emphasis

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

Code

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

Use the printf() function.

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

There is a literal backtick (`) here.

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

A single backtick in a code span: `

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

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

Please don't use any <blink> tags.

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

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

Images

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

Miscellaneous

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

Backslash Escapes

Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown's formatting syntax. For example, if you wanted to surround a word with literal asterisks (instead of an HTML `` tag), you can backslashes before the asterisks, like this: \*literal asterisks\* Markdown provides backslash escapes for the following characters: \ backslash ` backtick * asterisk _ underscore {} curly braces [] square brackets () parentheses # hash mark + plus sign - minus sign (hyphen) . dot ! exclamation mark kramdown-1.17.0/benchmark/generate_data.rb0000644000004100000410000000772213321140127020516 0ustar www-datawww-datarequire 'benchmark' require 'optparse' require 'fileutils' require 'kramdown' options = {:others => false, :average => 1} OptionParser.new do |opts| opts.on("-a AVG", "--average AVG", Integer, "Average times over the specified number of runs") {|v| options[:average] = v } opts.on("-o", "--[no-]others", "Generate data for other parsers") {|v| options[:others] = v} opts.on("-g", "--[no-]graph", "Generate graph") {|v| options[:graph] = v} opts.on("-k VERSION", "--kramdown VERSION", String, "Add benchmark data for kramdown version VERSION") {|v| options[:kramdown] = v} end.parse! THISRUBY = (self.class.const_defined?(:RUBY_DESCRIPTION) ? RUBY_DESCRIPTION.scan(/^.*?(?=\s*\()/).first.sub(/\s/, '-') : "ruby-#{RUBY_VERSION}") + '-' + RUBY_PATCHLEVEL.to_s Dir.chdir(File.dirname(__FILE__)) BMDATA = File.read('mdbasics.text') MULTIPLIER = (0..5).map {|i| 2**i} if options[:others] require 'maruku' require 'maruku/version' begin require 'rdiscount' rescue LoadError end #require 'bluefeather' module MaRuKu::Errors def tell_user(s) end end bmdata = {} labels = [] MULTIPLIER.each do |i| $stderr.puts "Generating benchmark data for other parsers, multiplier #{i}" mddata = BMDATA*i labels = [] bmdata[i] = Benchmark::bmbm do |x| labels << "Maruku #{MaRuKu::Version}" x.report { Maruku.new(mddata, :on_error => :ignore).to_html } if self.class.const_defined?(:BlueFeather) labels << "BlueFeather #{BlueFeather::VERSION}" x.report { BlueFeather.parse(mddata) } end if self.class.const_defined?(:RDiscount) labels << "RDiscount #{RDiscount::VERSION}" x.report { RDiscount.new(mddata).to_html } end end end File.open("static-#{THISRUBY}.dat", 'w+') do |f| f.puts "# " + labels.join(" || ") format_str = "%5d" + " %10.5f"*bmdata[MULTIPLIER.first].size bmdata.sort.each do |m,v| f.puts format_str % [m, *v.map {|tms| tms.real}] end end end if options[:kramdown] kramdown = "kramdown-#{THISRUBY}.dat" data = if File.exist?(kramdown) lines = File.readlines(kramdown).map {|l| l.chomp} lines.first << " || " lines else ["# ", *MULTIPLIER.map {|m| "%3d" % m}] end data.first << "#{options[:kramdown]}".rjust(10) times = [] options[:average].times do MULTIPLIER.each_with_index do |m, i| $stderr.puts "Generating benchmark data for kramdown version #{options[:kramdown]}, multiplier #{m}" mddata = BMDATA*m begin (times[i] ||= []) << Benchmark::bmbm {|x| x.report { Kramdown::Document.new(mddata).to_html } }.first.real rescue $stderr.puts $!.message (times[i] ||= []) << 0 end end end times.each_with_index {|t,i| data[i+1] << "%14.5f" % (t.inject(0) {|sum,v| sum+v}/3.0)} File.open(kramdown, 'w+') do |f| data.each {|l| f.puts l} end end if options[:graph] Dir['kramdown-*.dat'].each do |kramdown_name| theruby = kramdown_name.sub(/^kramdown-/, '').sub(/\.dat$/, '') graph_name = "graph-#{theruby}.png" static_name = "static-#{theruby}.dat" kramdown_names = File.readlines(kramdown_name).first.chomp[1..-1].split(/\s*\|\|\s*/) static_names = (File.exist?(static_name) ? File.readlines(static_name).first.chomp[1..-1].split(/\s*\|\|\s*/) : []) File.open("gnuplot.dat", "w+") do |f| f.puts <
  • Main
  • Basics
  • Syntax
  • License
  • Dingus
  • Getting the Gist of Markdown's Formatting Syntax ------------------------------------------------ This page offers a brief overview of what it's like to use Markdown. The [syntax page] [s] provides complete, detailed documentation for every feature, but Markdown should be very easy to pick up simply by looking at a few examples of it in action. The examples on this page are written in a before/after style, showing example syntax and the HTML output produced by Markdown. It's also helpful to simply try Markdown out; the [Dingus] [d] is a web application that allows you type your own Markdown-formatted text and translate it to XHTML. **Note:** This document is itself written using Markdown; you can [see the source for it by adding '.text' to the URL] [src]. [s]: /projects/markdown/syntax "Markdown Syntax" [d]: /projects/markdown/dingus "Markdown Dingus" [src]: /projects/markdown/basics.text ## Paragraphs, Headers, Blockquotes ## A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs. Markdown offers two styles of headers: *Setext* and *atx*. Setext-style headers for `

    ` and `

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

    A First Level Header

    A Second Level Header

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

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

    Header 3

    This is a blockquote.

    This is the second paragraph in the blockquote.

    This is an H2 in a blockquote

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

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

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

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

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

    • A list item.

      With multiple paragraphs.

    • Another item in the list.

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

    This is an example link.

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

    This is an example link.

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

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

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

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

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

    I strongly recommend against using any <blink> tags.

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

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

    For example.

    Output:

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

    <blockquote>
            <p>For example.</p>
        </blockquote>
        
    kramdown-1.17.0/AUTHORS0000644000004100000410000000007513321140127014516 0ustar www-datawww-dataThe author of kramdown is Thomas Leitner . kramdown-1.17.0/data/0000755000004100000410000000000013321140127014355 5ustar www-datawww-datakramdown-1.17.0/data/kramdown/0000755000004100000410000000000013321140127016177 5ustar www-datawww-datakramdown-1.17.0/data/kramdown/document.html0000644000004100000410000000117313321140127020705 0ustar www-datawww-data <% if @converter.root.options[:encoding] %> <% end %> <% extend ::Kramdown::Utils::Html title = '' h = @converter.root.children.find {|c| c.type == :header} if h collector = lambda {|c| c.children.collect {|cc| cc.type == :text ? escape_html(cc.value, :text) : collector.call(cc)}.join('')} title = collector.call(h) end %> <%= title %> <%= @body %> kramdown-1.17.0/data/kramdown/document.latex0000644000004100000410000000236413321140127021061 0ustar www-datawww-data<% encmap = { 'UTF-8' => 'utf8x', 'US-ASCII' => 'ascii', 'ISO-8859-1' => 'latin1', 'ISO-8859-2' => 'latin2', 'ISO-8859-3' => 'latin3', 'ISO-8859-4' => 'latin4', 'ISO-8859-5' => 'latin5', 'ISO-8859-9' => 'latin9', 'ISO-8859-10' => 'latin10', 'CP850' => 'cp850', 'CP852' => 'cp852', 'CP858' => 'cp858', 'CP437' => 'cp437', 'CP865' => 'cp865', 'CP1250' => 'cp120', 'CP1252' => 'cp1252', 'CP1257' => 'cp1257' } %> \documentclass{scrartcl} <% if RUBY_VERSION >= '1.9' %> \usepackage[<%= encmap[@body.encoding.name] %>]{inputenc} <% else %> \usepackage[mathletters]{ucs} \usepackage[utf8x]{inputenc} <% end %> \usepackage[T1]{fontenc} \usepackage{listings} <% @converter.data[:packages].each {|pkg| %>\usepackage{<%= pkg %>} <% } %> \usepackage{hyperref} <% if @converter.data[:packages].include?('fancyvrb') %> \VerbatimFootnotes <% end %> <% if @converter.data[:packages].include?('acronym') %> <% @converter.root.options[:abbrev_defs].each_pair do |k,v| %>\acrodef{<%= @converter.normalize_abbreviation_key(k) %>}[<%= k %>]{<%= @converter.escape(v) %>} <% end %> <% end %> \setcounter{footnote}{<%= @converter.options[:footnote_nr] - 1 %>} \hypersetup{colorlinks=true,urlcolor=blue} \begin{document} <%= @body %> \end{document} kramdown-1.17.0/man/0000755000004100000410000000000013321140127014217 5ustar www-datawww-datakramdown-1.17.0/man/man1/0000755000004100000410000000000013321140127015053 5ustar www-datawww-datakramdown-1.17.0/man/man1/kramdown.10000644000004100000410000003706713321140127016774 0ustar www-datawww-data.\" generated by kramdown .TH "KRAMDOWN" "1" "November 2016" .SH NAME kramdown \- a fast, pure\-Ruby Markdown\-superset converter .SH "SYNOPSIS" \fBkramdown\fP [\fIoptions\fP] [\fIFILE\fP\.\.\.] .SH "DESCRIPTION" kramdown is primarily used for parsing a superset of Markdown and converting it to different output formats\. It supports standard Markdown (with some minor modifications) and various extensions like tables and definition lists\. Due to its modular architecture it also allows other input formats than Markdown, for example, HTML or Github Flavored Markdown\. .P If \fIFILE\fP is not specified, kramdown reads from the standard input\. The result is written to the standard output\. .P There are two sets of options that kramdown accepts: The first one includes the options that are used directly by the kramdown binary\. The second set of options controls how kramdown parses and converts its input\. .P Default values for this second set can be set using YAML via the configuration file \fBkramdownrc\fP\&\. Note that configuration option names use underscores, not dashes (dashes are just used in the CLI options names), and boolean options do not have a \fBno\fP variant but a value of \fBtrue\fP or \fBfalse\fP\&\. This file has to be in XDG_CONFIG_HOME on Linux/Unix, ~/Library/Preferences on macOS and ~/AppData/Local on Windows\. .SH "CLI\-ONLY OPTIONS" .TP \fB\-i\fP \fIFORMAT\fP, \fB\-\-input\fP \fIFORMAT\fP Specify the input format\. Available input formats: \fIkramdown\fP (this is the default), \fImarkdown\fP, \fIGFM\fP or \fIhtml\fP\&\. .TP \fB\-o\fP \fIFORMAT\fP, \fB\-\-output\fP \fIFORMAT\fP Specify one or more output formats separated by commas: \fIhtml\fP (default), \fIkramdown\fP, \fIlatex\fP, \fIpdf\fP, \fIman\fP or \fIremove_html_tags\fP\&\. .TP \fB\-\-no\-config\-file\fP Do not read any configuration file\. Default behavior is to check for a configuration file and read it if it exists\. .TP \fB\-\-config\-file\fP \fIFILE\fP Override the default path and name of the configuration file\. .TP \fB\-v\fP, \fB\-\-version\fP Show the version of kramdown\. .TP \fB\-h\fP, \fB\-\-help\fP Show the help\. .SH "KRAMDOWN OPTIONS" .TP \fB\-\-auto\-id\-prefix\fP \fIARG\fP Prefix used for automatically generated header IDs .RS .P This option can be used to set a prefix for the automatically generated header IDs so that there is no conflict when rendering multiple kramdown documents into one output file separately\. The prefix should only contain characters that are valid in an ID! .P Default: \[u2018]\[u2019] Used by: HTML/Latex converter .RE .TP \fB\-\-[no\-]auto\-id\-stripping\fP Strip all formatting from header text for automatic ID generation .RS .P If this option is \fBtrue\fP, only the text elements of a header are used for generating the ID later (in contrast to just using the raw header text line)\. .P This option will be removed in version 2\.0 because this will be the default then\. .P Default: false Used by: kramdown parser .RE .TP \fB\-\-[no\-]auto\-ids\fP Use automatic header ID generation .RS .P If this option is \fBtrue\fP, ID values for all headers are automatically generated if no ID is explicitly specified\. .P Default: true Used by: HTML/Latex converter .RE .TP \fB\-\-coderay\-bold\-every\fP \fIARG\fP Defines how often a line number should be made bold .RS .P Can either be an integer or false (to turn off bold line numbers completely)\. .P Default: 10 Used by: HTML converter .RE .TP \fB\-\-coderay\-css\fP \fIARG\fP Defines how the highlighted code gets styled .RS .P Possible values are :class (CSS classes are applied to the code elements, one must supply the needed CSS file) or :style (default CSS styles are directly applied to the code elements)\. .P Default: style Used by: HTML converter .RE .TP \fB\-\-coderay\-default\-lang\fP \fIARG\fP Sets the default language for highlighting code blocks .RS .P If no language is set for a code block, the default language is used instead\. The value has to be one of the languages supported by coderay or nil if no default language should be used\. .P Default: nil Used by: HTML converter .RE .TP \fB\-\-coderay\-line\-number\-start\fP \fIARG\fP The start value for the line numbers .RS .P Default: 1 Used by: HTML converter .RE .TP \fB\-\-coderay\-line\-numbers\fP \fIARG\fP Defines how and if line numbers should be shown .RS .P The possible values are :table, :inline or nil\. If this option is nil, no line numbers are shown\. .P Default: :inline Used by: HTML converter .RE .TP \fB\-\-coderay\-tab\-width\fP \fIARG\fP The tab width used in highlighted code .RS .P Used by: HTML converter .RE .TP \fB\-\-coderay\-wrap\fP \fIARG\fP Defines how the highlighted code should be wrapped .RS .P The possible values are :span, :div or nil\. .P Default: :div Used by: HTML converter .RE .TP \fB\-\-[no\-]enable\-coderay\fP Use coderay for syntax highlighting .RS .P If this option is \fBtrue\fP, coderay is used by the HTML converter for syntax highlighting the content of code spans and code blocks\. .P Default: true Used by: HTML converter .RE .TP \fB\-\-entity\-output\fP \fIARG\fP Defines how entities are output .RS .P The possible values are :as_input (entities are output in the same form as found in the input), :numeric (entities are output in numeric form), :symbolic (entities are output in symbolic form if possible) or :as_char (entities are output as characters if possible, only available on Ruby 1\.9)\. .P Default: :as_char Used by: HTML converter, kramdown converter .RE .TP \fB\-\-footnote\-backlink\fP \fIARG\fP Defines the text that should be used for the footnote backlinks .RS .P The footnote backlink is just text, so any special HTML characters will be escaped\. .P If the footnote backlint text is an empty string, no footnote backlinks will be generated\. .P Default: \[u2018]\[u0026]8617;\[u2019] Used by: HTML converter .RE .TP \fB\-\-[no\-]footnote\-backlink\-inline\fP Specifies whether the footnote backlink should always be inline .RS .P With the default of false the footnote backlink is placed at the end of the last paragraph if there is one, or an extra paragraph with only the footnote backlink is created\. .P Setting this option to true tries to place the footnote backlink in the last, possibly nested paragraph or header\. If this fails (e\.g\. in the case of a table), an extra paragraph with only the footnote backlink is created\. .P Default: false Used by: HTML converter .RE .TP \fB\-\-footnote\-nr\fP \fIARG\fP The number of the first footnote .RS .P This option can be used to specify the number that is used for the first footnote\. .P Default: 1 Used by: HTML converter .RE .TP \fB\-\-gfm\-quirks\fP \fIARG\fP Enables a set of GFM specific quirks .RS .P The way how GFM is transformed on Github often differs from the way kramdown does things\. Many of these differences are negligible but others are not\. .P This option allows one to enable/disable certain GFM quirks, i\.e\. ways in which GFM parsing differs from kramdown parsing\. .P The value has to be a list of quirk names that should be enabled, separated by commas\. Possible names are: .IP \(bu 4 paragraph_end .RS .P Disables the kramdown restriction that at least one blank line has to be used after a paragraph before a new block element can be started\. .P Note that if this quirk is used, lazy line wrapping does not fully work anymore! .RE .IP \(bu 4 no_auto_typographic .RS .P Disables automatic conversion of some characters into their corresponding typographic symbols (like \fB\-\-\fP to em\-dash etc)\. This helps to achieve results closer to what GitHub Flavored Markdown produces\. .RE .P Default: paragraph_end Used by: GFM parser .RE .TP \fB\-\-[no\-]hard\-wrap\fP Interprets line breaks literally .RS .P Insert HTML \fB
    \fP tags inside paragraphs where the original Markdown document had newlines (by default, Markdown ignores these newlines)\. .P Default: true Used by: GFM parser .RE .TP \fB\-\-header\-offset\fP \fIARG\fP Sets the output offset for headers .RS .P If this option is c (may also be negative) then a header with level n will be output as a header with level c+n\. If c+n is lower than 1, level 1 will be used\. If c+n is greater than 6, level 6 will be used\. .P Default: 0 Used by: HTML converter, Kramdown converter, Latex converter .RE .TP \fB\-\-[no\-]html\-to\-native\fP Convert HTML elements to native elements .RS .P If this option is \fBtrue\fP, the parser converts HTML elements to native elements\. For example, when parsing \fBhallo\fP the emphasis tag would normally be converted to an \fB:html\fP element with tag type \fB:em\fP\&\. If \fBhtml_to_native\fP is \fBtrue\fP, then the emphasis would be converted to a native \fB:em\fP element\. .P This is useful for converters that cannot deal with HTML elements\. .P Default: false Used by: kramdown parser .RE .TP \fB\-\-latex\-headers\fP \fIARG\fP Defines the LaTeX commands for different header levels .RS .P The commands for the header levels one to six can be specified by separating them with commas\. .P Default: section,subsection,subsubsection,paragraph,subparagraph,subparagraph Used by: Latex converter .RE .TP \fB\-\-line\-width\fP \fIARG\fP Defines the line width to be used when outputting a document .RS .P Default: 72 Used by: kramdown converter .RE .TP \fB\-\-link\-defs\fP \fIARG\fP Pre\-defines link definitions .RS .P This option can be used to pre\-define link definitions\. The value needs to be a Hash where the keys are the link identifiers and the values are two element Arrays with the link URL and the link title\. .P If the value is a String, it has to contain a valid YAML hash and the hash has to follow the above guidelines\. .P Default: {} Used by: kramdown parser .RE .TP \fB\-\-math\-engine\fP \fIARG\fP Set the math engine .RS .P Specifies the math engine that should be used for converting math blocks/spans\. If this option is set to +nil+, no math engine is used and the math blocks/spans are output as is\. .P Options for the selected math engine can be set with the math_engine_opts configuration option\. .P Default: mathjax Used by: HTML converter .RE .TP \fB\-\-math\-engine\-opts\fP \fIARG\fP Set the math engine options .RS .P Specifies options for the math engine set via the math_engine configuration option\. .P The value needs to be a hash with key\-value pairs that are understood by the used math engine\. .P Default: {} Used by: HTML converter .RE .TP \fB\-\-[no\-]parse\-block\-html\fP Process kramdown syntax in block HTML tags .RS .P If this option is \fBtrue\fP, the kramdown parser processes the content of block HTML tags as text containing block\-level elements\. Since this is not wanted normally, the default is \fBfalse\fP\&\. It is normally better to selectively enable kramdown processing via the markdown attribute\. .P Default: false Used by: kramdown parser .RE .TP \fB\-\-[no\-]parse\-span\-html\fP Process kramdown syntax in span HTML tags .RS .P If this option is \fBtrue\fP, the kramdown parser processes the content of span HTML tags as text containing span\-level elements\. .P Default: true Used by: kramdown parser .RE .TP \fB\-\-[no\-]remove\-block\-html\-tags\fP Remove block HTML tags .RS .P If this option is \fBtrue\fP, the RemoveHtmlTags converter removes block HTML tags\. .P Default: true Used by: RemoveHtmlTags converter .RE .TP \fB\-\-[no\-]remove\-span\-html\-tags\fP Remove span HTML tags .RS .P If this option is \fBtrue\fP, the RemoveHtmlTags converter removes span HTML tags\. .P Default: false Used by: RemoveHtmlTags converter .RE .TP \fB\-\-smart\-quotes\fP \fIARG\fP Defines the HTML entity names or code points for smart quote output .RS .P The entities identified by entity name or code point that should be used for, in order, a left single quote, a right single quote, a left double and a right double quote are specified by separating them with commas\. .P Default: lsquo,rsquo,ldquo,rdquo Used by: HTML/Latex converter .RE .TP \fB\-\-syntax\-highlighter\fP \fIARG\fP Set the syntax highlighter .RS .P Specifies the syntax highlighter that should be used for highlighting code blocks and spans\. If this option is set to +nil+, no syntax highlighting is done\. .P Options for the syntax highlighter can be set with the syntax_highlighter_opts configuration option\. .P Default: coderay Used by: HTML/Latex converter .RE .TP \fB\-\-syntax\-highlighter\-opts\fP \fIARG\fP Set the syntax highlighter options .RS .P Specifies options for the syntax highlighter set via the syntax_highlighter configuration option\. .P The value needs to be a hash with key\-value pairs that are understood by the used syntax highlighter\. .P Default: {} Used by: HTML/Latex converter .RE .TP \fB\-\-template\fP \fIARG\fP The name of an ERB template file that should be used to wrap the output or the ERB template itself\. .RS .P This is used to wrap the output in an environment so that the output can be used as a stand\-alone document\. For example, an HTML template would provide the needed header and body tags so that the whole output is a valid HTML file\. If no template is specified, the output will be just the converted text\. .P When resolving the template file, the given template name is used first\. If such a file is not found, the converter extension (the same as the converter name) is appended\. If the file still cannot be found, the templates name is interpreted as a template name that is provided by kramdown (without the converter extension)\. If the file is still not found, the template name is checked if it starts with \[u2018]string://\[u2019] and if it does, this prefix is removed and the rest is used as template content\. .P kramdown provides a default template named \[u2018]document\[u2019] for each converter\. .P Default: \[u2018]\[u2019] Used by: all converters .RE .TP \fB\-\-toc\-levels\fP \fIARG\fP Defines the levels that are used for the table of contents .RS .P The individual levels can be specified by separating them with commas (e\.g\. 1,2,3) or by using the range syntax (e\.g\. 1\.\.3)\. Only the specified levels are used for the table of contents\. .P Default: 1\.\.6 Used by: HTML/Latex converter .RE .TP \fB\-\-[no\-]transliterated\-header\-ids\fP Transliterate the header text before generating the ID .RS .P Only ASCII characters are used in headers IDs\. This is not good for languages with many non\-ASCII characters\. By enabling this option the header text is transliterated to ASCII as good as possible so that the resulting header ID is more useful\. .P The stringex library needs to be installed for this feature to work! .P Default: false Used by: HTML/Latex converter .RE .TP \fB\-\-typographic\-symbols\fP \fIARG\fP Defines a mapping from typographical symbol to output characters .RS .P Typographical symbols are normally output using their equivalent Unicode codepoint\. However, sometimes one wants to change the output, mostly to fallback to a sequence of ASCII characters\. .P This option allows this by specifying a mapping from typographical symbol to its output string\. For example, the mapping {hellip: \.\.\.} would output the standard ASCII representation of an ellipsis\. .P The available typographical symbol names are: .IP \(bu 4 hellip: ellipsis .IP \(bu 4 mdash: em\-dash .IP \(bu 4 ndash: en\-dash .IP \(bu 4 laquo: left guillemet .IP \(bu 4 raquo: right guillemet .IP \(bu 4 laquo_space: left guillemet followed by a space .IP \(bu 4 raquo_space: right guillemet preceeded by a space .P Default: {} Used by: HTML/Latex converter .RE .SH "EXIT STATUS" The exit status is 0 if no error happened\. Otherwise it is 1\. .SH "SEE ALSO" The kramdown website .UR http://kramdown\.gettalong\.org .UE for more information, especially on the supported input syntax\. .SH "AUTHOR" kramdown was written by Thomas Leitner .MT t_leitner@gmx\.at .UE \&\. .P This manual page was written by Thomas Leitner .MT t_leitner@gmx\.at .UE \&\. kramdown-1.17.0/Rakefile0000644000004100000410000002417113321140127015116 0ustar www-datawww-data# -*- ruby -*- # load all optional developer libraries begin require 'rubygems' require 'rubygems/package_task' rescue LoadError end begin require 'webgen/page' rescue LoadError end begin gem 'rdoc' if RUBY_VERSION >= '1.9' require 'rdoc/task' require 'rdoc/rdoc' class RDoc::RDoc alias :old_parse_files :parse_files def parse_files(options) file_info = old_parse_files(options) require 'kramdown/options' # Add options documentation to Kramdown::Options module opt_module = @store.all_classes_and_modules.find {|m| m.full_name == 'Kramdown::Options'} opt_defs = Kramdown::Options.definitions.sort.collect do |n, definition| desc = definition.desc.split(/\n/).map {|l| " #{l}"} desc[-2] = [] desc = desc.join("\n") "[#{n} (type: #{definition.type}, default: #{definition.default.inspect})]\n#{desc}\n\n" end opt_module.comment.text += "\n== Available Options\n\n" << opt_defs.join("\n\n") file_info end end rescue LoadError end begin require 'rcov/rcovtask' rescue LoadError end require 'fileutils' require 'rake/clean' require 'rake/testtask' require 'rake/packagetask' require 'erb' $:.unshift('lib') require 'kramdown' # End user tasks ################################################################ task :default => :test desc "Install using setup.rb" task :install do ruby "setup.rb config" ruby "setup.rb setup" ruby "setup.rb install" end task :clobber do ruby "setup.rb clean" end if defined?(Webgen) desc "Generate the HTML documentation" task :htmldoc do ruby "-Ilib -S webgen" end CLOBBER << "htmldoc/" CLOBBER << "webgen-tmp" end if defined? RDoc::Task rd = RDoc::Task.new do |rdoc| rdoc.rdoc_dir = 'htmldoc/rdoc' rdoc.title = 'kramdown' rdoc.main = 'lib/kramdown/document.rb' rdoc.rdoc_files.include('lib') end end if defined?(Webgen) && defined?(RDoc::Task) desc "Build the whole user documentation" task :doc => [:rdoc, 'htmldoc'] end tt = Rake::TestTask.new do |test| test.warning = false test.libs << 'test' test.test_files = FileList['test/test_*.rb'] end # Release tasks and development tasks ############################################ namespace :dev do SUMMARY = 'kramdown is a fast, pure-Ruby Markdown-superset converter.' DESCRIPTION = < CONTRIBUTERS` `echo "======= ====" >> CONTRIBUTERS` `git log | grep ^Author: | sed 's/^Author: //' | sort | uniq -c | sort -nr >> CONTRIBUTERS` end CLOBBER << "man/man1/kramdown.1" file 'man/man1/kramdown.1' => ['man/man1/kramdown.1.erb'] do puts "Generating kramdown man page" File.open('man/man1/kramdown.1', 'w+') do |file| data = ERB.new(File.read('man/man1/kramdown.1.erb')).result(binding) file.write(Kramdown::Document.new(data).to_man) end end Rake::PackageTask.new('kramdown', Kramdown::VERSION) do |pkg| pkg.need_tar = true pkg.need_zip = true pkg.package_files = PKG_FILES end if defined? Gem spec = Gem::Specification.new do |s| #### Basic information s.name = 'kramdown' s.version = Kramdown::VERSION s.summary = SUMMARY s.description = DESCRIPTION s.license = 'MIT' #### Dependencies, requirements and files s.files = PKG_FILES.to_a s.require_path = 'lib' s.executables = ['kramdown'] s.default_executable = 'kramdown' s.required_ruby_version = '>= 2.0' s.add_development_dependency 'minitest', '~> 5.0' s.add_development_dependency 'coderay', '~> 1.0.0' s.add_development_dependency 'rouge' s.add_development_dependency 'stringex', '~> 1.5.1' s.add_development_dependency 'prawn', '~> 2.0' s.add_development_dependency 'prawn-table', '~> 0.2.2' s.add_development_dependency 'ritex', '~> 1.0' s.add_development_dependency 'itextomml', '~> 1.5' s.add_development_dependency 'execjs', '~> 2.7' s.add_development_dependency 'sskatex', '>= 0.9.37' s.add_development_dependency 'katex', '~> 0.4.3' #### Documentation s.has_rdoc = true s.rdoc_options = ['--main', 'lib/kramdown/document.rb'] #### Author and project details s.author = 'Thomas Leitner' s.email = 't_leitner@gmx.at' s.homepage = "http://kramdown.gettalong.org" end task :gemspec => [ 'CONTRIBUTERS', 'VERSION', 'man/man1/kramdown.1'] do print "Generating Gemspec\n" contents = spec.to_ruby File.open("kramdown.gemspec", 'w+') {|f| f.puts(contents)} end Gem::PackageTask.new(spec) do |pkg| pkg.need_zip = true pkg.need_tar = true end end if defined?(Webgen) && defined?(Gem) && defined?(Rake::RDocTask) desc 'Release Kramdown version ' + Kramdown::VERSION task :release => [:clobber, :package, :publish_files, :publish_website] end if defined?(Gem) desc "Upload the release to Rubygems" task :publish_files => [:package] do sh "gem push pkg/kramdown-#{Kramdown::VERSION}.gem" puts 'done' end end desc "Upload the website" task :publish_website => ['doc'] do puts "Transfer manually!!!" # sh "rsync -avc --delete --exclude 'MathJax' --exclude 'robots.txt' htmldoc/ gettalong@rubyforge.org:/var/www/gforge-projects/kramdown/" end if defined? Rcov Rcov::RcovTask.new do |rcov| rcov.libs << 'test' end end CODING_LINE = "# -*- coding: utf-8 -*-\n" COPYRIGHT=< # # This file is part of kramdown which is licensed under the MIT. #++ # EOF desc "Insert/Update copyright notice" task :update_copyright do inserted = false Dir["lib/**/*.rb", "test/**/*.rb"].each do |file| if !File.read(file).start_with?(CODING_LINE + COPYRIGHT) inserted = true puts "Updating file #{file}" old = File.read(file) if !old.gsub!(/\A#{Regexp.escape(CODING_LINE)}#\n#--.*?\n#\+\+\n#\n/m, CODING_LINE + COPYRIGHT) old.gsub!(/\A(#{Regexp.escape(CODING_LINE)})?/, CODING_LINE + COPYRIGHT + "\n") end File.open(file, 'w+') {|f| f.puts(old)} end end puts "Look through the above mentioned files and correct all problems" if inserted end desc "Check for MathjaxNode availability" task :test_mathjaxnode_deps do html = %x{echo '$$a$$' | \ #{RbConfig.ruby} -Ilib bin/kramdown --no-config-file --math-engine mathjaxnode} raise (<\Z}m === html The MathjaxNode engine is not available. Try "npm install mathjax-node-cli". MJN puts "MathjaxNode is available, and its default configuration works." end desc "Update kramdown MathjaxNode test reference outputs" task update_mathjaxnode_tests: [:test_mathjaxnode_deps] do # Not framed in terms of rake file tasks to prevent accidental overwrites. Dir['test/testcases/**/mathjaxnode*.text'].each do |f| stem = f[0..-6] # Remove .text ruby "-Ilib bin/kramdown --config-file #{stem}.options #{f} >#{stem}.html.19" end end desc "Check for SsKaTeX availability" task :test_sskatex_deps do katexjs = 'katex/katex.min.js' raise (<#{stem}.html.19" end end desc "Update kramdown KaTeX test reference outputs" task :update_katex_tests do # Not framed in terms of rake file tasks to prevent accidental overwrites. Dir['test/testcases/**/katex*.text'].each do |f| stem = f[0..-6] # Remove .text ruby "-Ilib bin/kramdown --config-file #{stem}.options #{f} >#{stem}.html.19" end end end task :gemspec => ['dev:gemspec'] task :clobber => ['dev:clobber'] kramdown-1.17.0/lib/0000755000004100000410000000000013321140127014212 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown.rb0000644000004100000410000000030013321140127016352 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/document' kramdown-1.17.0/lib/kramdown/0000755000004100000410000000000013321140127016034 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/parser/0000755000004100000410000000000013321140127017330 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/parser/base.rb0000644000004100000410000001105113321140127020565 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/utils' require 'kramdown/parser' module Kramdown module Parser # == \Base class for parsers # # This class serves as base class for parsers. It provides common methods that can/should be # used by all parsers, especially by those using StringScanner(Kramdown) for parsing. # # A parser object is used as a throw-away object, i.e. it is only used for storing the needed # state information during parsing. Therefore one can't instantiate a parser object directly but # only use the Base::parse method. # # == Implementing a parser # # Implementing a new parser is rather easy: just derive a new class from this class and put it # in the Kramdown::Parser module -- the latter is needed so that the auto-detection of the new # parser works correctly. Then you need to implement the +#parse+ method which has to contain # the parsing code. # # Have a look at the Base::parse, Base::new and Base#parse methods for additional information! class Base # The hash with the parsing options. attr_reader :options # The array with the parser warnings. attr_reader :warnings # The original source string. attr_reader :source # The root element of element tree that is created from the source string. attr_reader :root # Initialize the parser object with the +source+ string and the parsing +options+. # # The @root element, the @warnings array and @text_type (specifies the default type for newly # created text nodes) are automatically initialized. def initialize(source, options) @source = source @options = Kramdown::Options.merge(options) @root = Element.new(:root, nil, nil, :encoding => (source.encoding rescue nil), :location => 1, :options => {}, :abbrev_defs => {}, :abbrev_attr => {}) @warnings = [] @text_type = :text end private_class_method(:new, :allocate) # Parse the +source+ string into an element tree, possibly using the parsing +options+, and # return the root element of the element tree and an array with warning messages. # # Initializes a new instance of the calling class and then calls the +#parse+ method that must # be implemented by each subclass. def self.parse(source, options = {}) parser = new(source, options) parser.parse [parser.root, parser.warnings] end # Parse the source string into an element tree. # # The parsing code should parse the source provided in @source and build an element tree the # root of which should be @root. # # This is the only method that has to be implemented by sub-classes! def parse raise NotImplementedError end # Add the given warning +text+ to the warning array. def warning(text) @warnings << text #TODO: add position information end # Modify the string +source+ to be usable by the parser (unifies line ending characters to # +\n+ and makes sure +source+ ends with a new line character). def adapt_source(source) unless source.valid_encoding? raise "The source text contains invalid characters for the used encoding #{source.encoding}" end source = source.encode('UTF-8') source.gsub(/\r\n?/, "\n").chomp + "\n" end # This helper method adds the given +text+ either to the last element in the +tree+ if it is a # +type+ element or creates a new text element with the given +type+. def add_text(text, tree = @tree, type = @text_type) last = tree.children.last if last && last.type == type last.value << text elsif !text.empty? tree.children << Element.new(type, text, nil, :location => (last && last.options[:location] || tree.options[:location])) end end # Extract the part of the StringScanner +strscan+ backed string specified by the +range+. This # method works correctly under Ruby 1.8 and Ruby 1.9. def extract_string(range, strscan) result = nil begin enc = strscan.string.encoding strscan.string.force_encoding('ASCII-8BIT') result = strscan.string[range].force_encoding(enc) ensure strscan.string.force_encoding(enc) end result end end end end kramdown-1.17.0/lib/kramdown/parser/markdown.rb0000644000004100000410000000364013321140127021502 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser' module Kramdown module Parser # Used for parsing a document in Markdown format. # # This parser is based on the kramdown parser and removes the parser methods for the additional # non-Markdown features. However, since some things are handled differently by the kramdown # parser methods (like deciding when a list item contains just text), this parser differs from # real Markdown parsers in some respects. # # Note, though, that the parser basically fails just one of the Markdown test cases (some others # also fail but those failures are negligible). class Markdown < Kramdown # Array with all the parsing methods that should be removed from the standard kramdown parser. EXTENDED = [:codeblock_fenced, :table, :definition_list, :footnote_definition, :abbrev_definition, :block_math, :block_extensions, :footnote_marker, :smart_quotes, :inline_math, :span_extensions, :typographic_syms] def initialize(source, options) # :nodoc: super @block_parsers.delete_if {|i| EXTENDED.include?(i)} @span_parsers.delete_if {|i| EXTENDED.include?(i)} end # :stopdoc: BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|\Z/ LAZY_END = /#{BLANK_LINE}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/ CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+)*/ PARAGRAPH_END = LAZY_END IAL_RAND_CHARS = (('a'..'z').to_a + ('0'..'9').to_a) IAL_RAND_STRING = (1..20).collect {|a| IAL_RAND_CHARS[rand(IAL_RAND_CHARS.size)]}.join LIST_ITEM_IAL = /^\s*(#{IAL_RAND_STRING})?\s*\n/ IAL_SPAN_START = LIST_ITEM_IAL # :startdoc: end end end kramdown-1.17.0/lib/kramdown/parser/kramdown.rb0000644000004100000410000003160413321140127021503 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'strscan' require 'stringio' require 'kramdown/parser' #TODO: use [[:alpha:]] in all regexp to allow parsing of international values in 1.9.1 #NOTE: use @src.pre_match only before other check/match?/... operations, otherwise the content is changed module Kramdown module Parser # Used for parsing a document in kramdown format. # # If you want to extend the functionality of the parser, you need to do the following: # # * Create a new subclass # * add the needed parser methods # * modify the @block_parsers and @span_parsers variables and add the names of your parser # methods # # Here is a small example for an extended parser class that parses ERB style tags as raw text if # they are used as span-level elements (an equivalent block-level parser should probably also be # made to handle the block case): # # require 'kramdown/parser/kramdown' # # class Kramdown::Parser::ERBKramdown < Kramdown::Parser::Kramdown # # def initialize(source, options) # super # @span_parsers.unshift(:erb_tags) # end # # ERB_TAGS_START = /<%.*?%>/ # # def parse_erb_tags # @src.pos += @src.matched_size # @tree.children << Element.new(:raw, @src.matched) # end # define_parser(:erb_tags, ERB_TAGS_START, '<%') # # end # # The new parser can be used like this: # # require 'kramdown/document' # # require the file with the above parser class # # Kramdown::Document.new(input_text, :input => 'ERBKramdown').to_html # class Kramdown < Base include ::Kramdown # Create a new Kramdown parser object with the given +options+. def initialize(source, options) super reset_env @alds = {} @footnotes = {} @link_defs = {} update_link_definitions(@options[:link_defs]) @block_parsers = [:blank_line, :codeblock, :codeblock_fenced, :blockquote, :atx_header, :horizontal_rule, :list, :definition_list, :block_html, :setext_header, :block_math, :table, :footnote_definition, :link_definition, :abbrev_definition, :block_extensions, :eob_marker, :paragraph] @span_parsers = [:emphasis, :codespan, :autolink, :span_html, :footnote_marker, :link, :smart_quotes, :inline_math, :span_extensions, :html_entity, :typographic_syms, :line_break, :escaped_chars] end private_class_method(:new, :allocate) # The source string provided on initialization is parsed into the @root element. def parse configure_parser parse_blocks(@root, adapt_source(source)) update_tree(@root) correct_abbreviations_attributes replace_abbreviations(@root) @footnotes.each do |name,data| update_tree(data[:content]) replace_abbreviations(data[:content]) end @footnotes.each do |name, data| next if data.key?(:marker) line = data[:content].options[:location] warning("Footnote definition for '#{name}' on line #{line} is unreferenced - ignoring") end end ####### protected ####### # :doc: # # Update the parser specific link definitions with the data from +link_defs+ (the value of the # :link_defs option). # # The parameter +link_defs+ is a hash where the keys are possibly unnormalized link IDs and # the values are two element arrays consisting of the link target and a title (can be +nil+). def update_link_definitions(link_defs) link_defs.each {|k,v| @link_defs[normalize_link_id(k)] = v} end # Adapt the object to allow parsing like specified in the options. def configure_parser @parsers = {} (@block_parsers + @span_parsers).each do |name| if self.class.has_parser?(name) @parsers[name] = self.class.parser(name) else raise Kramdown::Error, "Unknown parser: #{name}" end end @span_start, @span_start_re = span_parser_regexps end # Create the needed span parser regexps. def span_parser_regexps(parsers = @span_parsers) span_start = /#{parsers.map {|name| @parsers[name].span_start}.join('|')}/ [span_start, /(?=#{span_start})/] end # Parse all block-level elements in +text+ into the element +el+. def parse_blocks(el, text = nil) @stack.push([@tree, @src, @block_ial]) @tree, @block_ial = el, nil @src = (text.nil? ? @src : ::Kramdown::Utils::StringScanner.new(text, el.options[:location])) status = catch(:stop_block_parsing) do while !@src.eos? @block_parsers.any? do |name| if @src.check(@parsers[name].start_re) send(@parsers[name].method) else false end end || begin warning('Warning: this should not occur - no block parser handled the line') add_text(@src.scan(/.*\n/)) end end end @tree, @src, @block_ial = *@stack.pop status end # Update the tree by parsing all :+raw_text+ elements with the span-level parser (resets the # environment) and by updating the attributes from the IALs. def update_tree(element) last_blank = nil element.children.map! do |child| if child.type == :raw_text last_blank = nil reset_env(:src => ::Kramdown::Utils::StringScanner.new(child.value, element.options[:location]), :text_type => :text) parse_spans(child) child.children elsif child.type == :eob update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial] [] elsif child.type == :blank if last_blank last_blank.value << child.value [] else last_blank = child child end else last_blank = nil update_tree(child) update_attr_with_ial(child.attr, child.options[:ial]) if child.options[:ial] # DEPRECATED: option auto_id_stripping will be removed in 2.0 because then this will be # the default behaviour if child.type == :dt || (child.type == :header && @options[:auto_id_stripping]) update_raw_text(child) end child end end.flatten! end # Parse all span-level elements in the source string of @src into +el+. # # If the parameter +stop_re+ (a regexp) is used, parsing is immediately stopped if the regexp # matches and if no block is given or if a block is given and it returns +true+. # # The parameter +parsers+ can be used to specify the (span-level) parsing methods that should # be used for parsing. # # The parameter +text_type+ specifies the type which should be used for created text nodes. def parse_spans(el, stop_re = nil, parsers = nil, text_type = @text_type) @stack.push([@tree, @text_type]) unless @tree.nil? @tree, @text_type = el, text_type span_start = @span_start span_start_re = @span_start_re span_start, span_start_re = span_parser_regexps(parsers) if parsers parsers = parsers || @span_parsers used_re = (stop_re.nil? ? span_start_re : /(?=#{Regexp.union(stop_re, span_start)})/) stop_re_found = false while !@src.eos? && !stop_re_found if result = @src.scan_until(used_re) add_text(result) if stop_re && @src.check(stop_re) stop_re_found = (block_given? ? yield : true) end processed = parsers.any? do |name| if @src.check(@parsers[name].start_re) send(@parsers[name].method) true else false end end unless stop_re_found add_text(@src.getch) if !processed && !stop_re_found else (add_text(@src.rest); @src.terminate) unless stop_re break end end @tree, @text_type = @stack.pop stop_re_found end # Reset the current parsing environment. The parameter +env+ can be used to set initial # values for one or more environment variables. def reset_env(opts = {}) opts = {:text_type => :raw_text, :stack => []}.merge(opts) @src = opts[:src] @tree = opts[:tree] @block_ial = opts[:block_ial] @stack = opts[:stack] @text_type = opts[:text_type] end # Return the current parsing environment. def save_env [@src, @tree, @block_ial, @stack, @text_type] end # Restore the current parsing environment. def restore_env(env) @src, @tree, @block_ial, @stack, @text_type = *env end # Update the given attributes hash +attr+ with the information from the inline attribute list # +ial+ and all referenced ALDs. def update_attr_with_ial(attr, ial) ial[:refs].each do |ref| update_attr_with_ial(attr, ref) if ref = @alds[ref] end if ial[:refs] ial.each do |k,v| if k == IAL_CLASS_ATTR attr[k] = (attr[k] || '') << " #{v}" attr[k].lstrip! elsif k.kind_of?(String) attr[k] = v end end end # Update the raw text for automatic ID generation. def update_raw_text(item) raw_text = '' append_text = lambda do |child| if child.type == :text raw_text << child.value else child.children.each {|c| append_text.call(c)} end end append_text.call(item) item.options[:raw_text] = raw_text end # Create a new block-level element, taking care of applying a preceding block IAL if it # exists. This method should always be used for creating a block-level element! def new_block_el(*args) el = Element.new(*args) if @block_ial el.options[:ial] = @block_ial @block_ial = nil end el end @@parsers = {} # Struct class holding all the needed data for one block/span-level parser method. Data = Struct.new(:name, :start_re, :span_start, :method) # Add a parser method # # * with the given +name+, # * using +start_re+ as start regexp # * and, for span parsers, +span_start+ as a String that can be used in a regexp and # which identifies the starting character(s) # # to the registry. The method name is automatically derived from the +name+ or can explicitly # be set by using the +meth_name+ parameter. def self.define_parser(name, start_re, span_start = nil, meth_name = "parse_#{name}") raise "A parser with the name #{name} already exists!" if @@parsers.has_key?(name) @@parsers[name] = Data.new(name, start_re, span_start, meth_name) end # Return the Data structure for the parser +name+. def self.parser(name = nil) @@parsers[name] end # Return +true+ if there is a parser called +name+. def self.has_parser?(name) @@parsers.has_key?(name) end # Regexp for matching indentation (one tab or four spaces) INDENT = /^(?:\t| {4})/ # Regexp for matching the optional space (zero or up to three spaces) OPT_SPACE = / {0,3}/ require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/eob' require 'kramdown/parser/kramdown/paragraph' require 'kramdown/parser/kramdown/header' require 'kramdown/parser/kramdown/blockquote' require 'kramdown/parser/kramdown/table' require 'kramdown/parser/kramdown/codeblock' require 'kramdown/parser/kramdown/horizontal_rule' require 'kramdown/parser/kramdown/list' require 'kramdown/parser/kramdown/link' require 'kramdown/parser/kramdown/extensions' require 'kramdown/parser/kramdown/footnote' require 'kramdown/parser/kramdown/html' require 'kramdown/parser/kramdown/escaped_chars' require 'kramdown/parser/kramdown/html_entity' require 'kramdown/parser/kramdown/line_break' require 'kramdown/parser/kramdown/typographic_symbol' require 'kramdown/parser/kramdown/autolink' require 'kramdown/parser/kramdown/codespan' require 'kramdown/parser/kramdown/emphasis' require 'kramdown/parser/kramdown/smart_quotes' require 'kramdown/parser/kramdown/math' require 'kramdown/parser/kramdown/abbreviation' end end end kramdown-1.17.0/lib/kramdown/parser/gfm.rb0000644000004100000410000001532613321140127020435 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser' module Kramdown module Parser class GFM < Kramdown::Parser::Kramdown def initialize(source, options) super @options[:auto_id_stripping] = true @id_counter = Hash.new(-1) @span_parsers.delete(:line_break) if @options[:hard_wrap] @span_parsers.delete(:typographic_syms) if @options[:gfm_quirks].include?(:no_auto_typographic) if @options[:gfm_quirks].include?(:paragraph_end) atx_header_parser = :atx_header_gfm_quirk @paragraph_end = self.class::PARAGRAPH_END_GFM else atx_header_parser = :atx_header_gfm @paragraph_end = self.class::PARAGRAPH_END end {:codeblock_fenced => :codeblock_fenced_gfm, :atx_header => atx_header_parser}.each do |current, replacement| i = @block_parsers.index(current) @block_parsers.delete(current) @block_parsers.insert(i, replacement) end i = @span_parsers.index(:escaped_chars) @span_parsers[i] = :escaped_chars_gfm if i @span_parsers << :strikethrough_gfm end def parse super update_elements(@root) end def update_elements(element) element.children.map! do |child| if child.type == :text && @options[:hard_wrap] && child.value =~ /\n/ children = [] lines = child.value.split(/\n/, -1) omit_trailing_br = (Kramdown::Element.category(element) == :block && element.children[-1] == child && lines[-1].empty?) lines.each_with_index do |line, index| new_element_options = { :location => child.options[:location] + index } children << Element.new(:text, (index > 0 ? "\n#{line}" : line), nil, new_element_options) children << Element.new(:br, nil, nil, new_element_options) if index < lines.size - 2 || (index == lines.size - 2 && !omit_trailing_br) end children elsif child.type == :html_element child elsif child.type == :header && @options[:auto_ids] && !child.attr.has_key?('id') child.attr['id'] = generate_gfm_header_id(child.options[:raw_text]) child else update_elements(child) child end end.flatten! end # Update the raw text for automatic ID generation. def update_raw_text(item) raw_text = '' append_text = lambda do |child| if child.type == :text || child.type == :codespan || child.type ==:math raw_text << child.value elsif child.type == :entity raw_text << child.value.char elsif child.type == :smart_quote raw_text << ::Kramdown::Utils::Entities.entity(child.value.to_s).char elsif child.type == :typographic_sym if child.value == :laquo_space raw_text << "« " elsif child.value == :raquo_space raw_text << " »" else raw_text << ::Kramdown::Utils::Entities.entity(child.value.to_s).char end else child.children.each {|c| append_text.call(c)} end end append_text.call(item) item.options[:raw_text] = raw_text end NON_WORD_RE = /[^\p{Word}\- \t]/ def generate_gfm_header_id(text) result = text.downcase result.gsub!(NON_WORD_RE, '') result.tr!(" \t", '-') @id_counter[result] += 1 result << (@id_counter[result] > 0 ? "-#{@id_counter[result]}" : '') @options[:auto_id_prefix] + result end ATX_HEADER_START = /^(?\#{1,6})[\t ]+(?.*)\n/ define_parser(:atx_header_gfm, ATX_HEADER_START, nil, 'parse_atx_header') define_parser(:atx_header_gfm_quirk, ATX_HEADER_START) # Copied from kramdown/parser/kramdown/header.rb, removed the first line def parse_atx_header_gfm_quirk text, id = parse_header_contents text.sub!(/[\t ]#+\z/, '') && text.rstrip! return false if text.empty? add_header(@src["level"].length, text, id) true end FENCED_CODEBLOCK_START = /^[ ]{0,3}[~`]{3,}/ FENCED_CODEBLOCK_MATCH = /^[ ]{0,3}(([~`]){3,})\s*?((\S+?)(?:\?\S*)?)?\s*?\n(.*?)^[ ]{0,3}\1\2*\s*?\n/m define_parser(:codeblock_fenced_gfm, FENCED_CODEBLOCK_START, nil, 'parse_codeblock_fenced') STRIKETHROUGH_DELIM = /~~/ STRIKETHROUGH_MATCH = /#{STRIKETHROUGH_DELIM}[^\s~](.*?)[^\s~]#{STRIKETHROUGH_DELIM}/m define_parser(:strikethrough_gfm, STRIKETHROUGH_MATCH, '~~') def parse_strikethrough_gfm line_number = @src.current_line_number @src.pos += @src.matched_size el = Element.new(:html_element, 'del', {}, :category => :span, :line => line_number) @tree.children << el env = save_env reset_env(:src => Kramdown::Utils::StringScanner.new(@src.matched[2..-3], line_number), :text_type => :text) parse_spans(el) restore_env(env) el end # To handle task-lists we override the parse method for lists, converting matching text into checkbox input # elements where necessary (as well as applying classes to the ul/ol and li elements). def parse_list super current_list = @tree.children.select{ |element| [:ul, :ol].include?(element.type) }.last is_tasklist = false box_unchecked = '' box_checked = '' current_list.children.each do |li| next unless li.children.size > 0 && li.children[0].type == :p # li -> p -> raw_text checked = li.children[0].children[0].value.gsub!(/\A\s*\[ \]\s+/, box_unchecked) unchecked = li.children[0].children[0].value.gsub!(/\A\s*\[x\]\s+/i, box_checked) is_tasklist ||= (!checked.nil? || !unchecked.nil?) li.attr['class'] = 'task-list-item' if is_tasklist end current_list.attr['class'] = 'task-list' if is_tasklist true end ESCAPED_CHARS_GFM = /\\([\\.*_+`<>()\[\]{}#!:\|"'\$=\-~])/ define_parser(:escaped_chars_gfm, ESCAPED_CHARS_GFM, '\\\\', :parse_escaped_chars) PARAGRAPH_END_GFM = /#{LAZY_END}|#{LIST_START}|#{ATX_HEADER_START}|#{DEFINITION_LIST_START}|#{BLOCKQUOTE_START}|#{FENCED_CODEBLOCK_START}/ def paragraph_end @paragraph_end end end end end kramdown-1.17.0/lib/kramdown/parser/html.rb0000644000004100000410000005520213321140127020625 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'rexml/parsers/baseparser' require 'strscan' require 'kramdown/utils' require 'kramdown/parser' module Kramdown module Parser # Used for parsing a HTML document. # # The parsing code is in the Parser module that can also be used by other parsers. class Html < Base # Contains all constants that are used when parsing. module Constants #:stopdoc: # The following regexps are based on the ones used by REXML, with some slight modifications. HTML_DOCTYPE_RE = //im HTML_COMMENT_RE = //m HTML_INSTRUCTION_RE = /<\?(.*?)\?>/m HTML_ATTRIBUTE_RE = /\s*(#{REXML::Parsers::BaseParser::UNAME_STR})(?:\s*=\s*(["'])(.*?)\2)?/m HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}(?:\s*=\s*(["']).*?\3)?)*)\s*(\/)?>/m HTML_TAG_CLOSE_RE = /<\/(#{REXML::Parsers::BaseParser::UNAME_STR})\s*>/m HTML_ENTITY_RE = /&([\w:][\-\w\.:]*);|&#(\d+);|&\#x([0-9a-fA-F]+);/ HTML_CONTENT_MODEL_BLOCK = %w{address applet article aside blockquote body dd details div dl fieldset figure figcaption footer form header hgroup iframe li main map menu nav noscript object section summary td} HTML_CONTENT_MODEL_SPAN = %w{a abbr acronym b bdo big button cite caption del dfn dt em h1 h2 h3 h4 h5 h6 i ins label legend optgroup p q rb rbc rp rt rtc ruby select small span strong sub sup th tt} HTML_CONTENT_MODEL_RAW = %w{script style math option textarea pre code kbd samp var} # The following elements are also parsed as raw since they need child elements that cannot # be expressed using kramdown syntax: colgroup table tbody thead tfoot tr ul ol HTML_CONTENT_MODEL = Hash.new {|h,k| h[k] = :raw} HTML_CONTENT_MODEL_BLOCK.each {|i| HTML_CONTENT_MODEL[i] = :block} HTML_CONTENT_MODEL_SPAN.each {|i| HTML_CONTENT_MODEL[i] = :span} HTML_CONTENT_MODEL_RAW.each {|i| HTML_CONTENT_MODEL[i] = :raw} # Some HTML elements like script belong to both categories (i.e. are valid in block and # span HTML) and don't appear therefore! # script, textarea HTML_SPAN_ELEMENTS = %w{a abbr acronym b big bdo br button cite code del dfn em i img input ins kbd label mark option q rb rbc rp rt rtc ruby samp select small span strong sub sup tt u var} HTML_BLOCK_ELEMENTS = %w{address article aside applet body blockquote caption col colgroup dd div dl dt fieldset figcaption footer form h1 h2 h3 h4 h5 h6 header hgroup hr html head iframe legend menu li main map nav ol optgroup p pre section summary table tbody td th thead tfoot tr ul} HTML_ELEMENTS_WITHOUT_BODY = %w{area base br col command embed hr img input keygen link meta param source track wbr} HTML_ELEMENT = Hash.new(false) (HTML_SPAN_ELEMENTS + HTML_BLOCK_ELEMENTS + HTML_ELEMENTS_WITHOUT_BODY + HTML_CONTENT_MODEL.keys).each do |a| HTML_ELEMENT[a] = true end end # Contains the parsing methods. This module can be mixed into any parser to get HTML parsing # functionality. The only thing that must be provided by the class are instance variable # @stack for storing the needed state and @src (instance of StringScanner) for the actual # parsing. module Parser include Constants # Process the HTML start tag that has already be scanned/checked via @src. # # Does the common processing steps and then yields to the caller for further processing # (first parameter is the created element; the second parameter is +true+ if the HTML # element is already closed, ie. contains no body; the third parameter specifies whether the # body - and the end tag - need to be handled in case closed=false). def handle_html_start_tag(line = nil) # :yields: el, closed, handle_body name = @src[1] name.downcase! if HTML_ELEMENT[name.downcase] closed = !@src[4].nil? attrs = parse_html_attributes(@src[2], line, HTML_ELEMENT[name]) el = Element.new(:html_element, name, attrs, :category => :block) el.options[:location] = line if line @tree.children << el if !closed && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) closed = true end if name == 'script' || name == 'style' handle_raw_html_tag(name) yield(el, false, false) else yield(el, closed, true) end end # Parses the given string for HTML attributes and returns the resulting hash. # # If the optional +line+ parameter is supplied, it is used in warning messages. # # If the optional +in_html_tag+ parameter is set to +false+, attributes are not modified to # contain only lowercase letters. def parse_html_attributes(str, line = nil, in_html_tag = true) attrs = Utils::OrderedHash.new str.scan(HTML_ATTRIBUTE_RE).each do |attr, sep, val| attr.downcase! if in_html_tag if attrs.has_key?(attr) warning("Duplicate HTML attribute '#{attr}' on line #{line || '?'} - overwriting previous one") end attrs[attr] = val || "" end attrs end # Handle the raw HTML tag at the current position. def handle_raw_html_tag(name) curpos = @src.pos if @src.scan_until(/(?=<\/#{name}\s*>)/mi) add_text(extract_string(curpos...@src.pos, @src), @tree.children.last, :raw) @src.scan(HTML_TAG_CLOSE_RE) else add_text(@src.rest, @tree.children.last, :raw) @src.terminate warning("Found no end tag for '#{name}' - auto-closing it") end end HTML_RAW_START = /(?=<(#{REXML::Parsers::BaseParser::UNAME_STR}|\/|!--|\?))/ # :nodoc: # Parse raw HTML from the current source position, storing the found elements in +el+. # Parsing continues until one of the following criteria are fulfilled: # # - The end of the document is reached. # - The matching end tag for the element +el+ is found (only used if +el+ is an HTML # element). # # When an HTML start tag is found, processing is deferred to #handle_html_start_tag, # providing the block given to this method. def parse_raw_html(el, &block) @stack.push(@tree) @tree = el done = false while !@src.eos? && !done if result = @src.scan_until(HTML_RAW_START) add_text(result, @tree, :text) line = @src.current_line_number if result = @src.scan(HTML_COMMENT_RE) @tree.children << Element.new(:xml_comment, result, nil, :category => :block, :location => line) elsif result = @src.scan(HTML_INSTRUCTION_RE) @tree.children << Element.new(:xml_pi, result, nil, :category => :block, :location => line) elsif @src.scan(HTML_TAG_RE) if method(:handle_html_start_tag).arity.abs >= 1 handle_html_start_tag(line, &block) else handle_html_start_tag(&block) # DEPRECATED: method needs to accept line number in 2.0 end elsif @src.scan(HTML_TAG_CLOSE_RE) if @tree.value == (HTML_ELEMENT[@tree.value] ? @src[1].downcase : @src[1]) done = true else add_text(@src.matched, @tree, :text) warning("Found invalidly used HTML closing tag for '#{@src[1]}' on line #{line} - ignoring it") end else add_text(@src.getch, @tree, :text) end else add_text(@src.rest, @tree, :text) @src.terminate warning("Found no end tag for '#{@tree.value}' on line #{@tree.options[:location]} - auto-closing it") if @tree.type == :html_element done = true end end @tree = @stack.pop end end # Converts HTML elements to native elements if possible. class ElementConverter # :stopdoc: include Constants include ::Kramdown::Utils::Entities REMOVE_TEXT_CHILDREN = %w{html head hgroup ol ul dl table colgroup tbody thead tfoot tr select optgroup} WRAP_TEXT_CHILDREN = %w{body section nav article aside header footer address div li dd blockquote figure figcaption fieldset form} REMOVE_WHITESPACE_CHILDREN = %w{body section nav article aside header footer address div li dd blockquote figure figcaption td th fieldset form} STRIP_WHITESPACE = %w{address article aside blockquote body caption dd div dl dt fieldset figcaption form footer header h1 h2 h3 h4 h5 h6 legend li nav p section td th} SIMPLE_ELEMENTS = %w{em strong blockquote hr br img p thead tbody tfoot tr td th ul ol dl li dl dt dd} def initialize(root) @root = root end def self.convert(root, el = root) new(root).process(el) end # Convert the element +el+ and its children. def process(el, do_conversion = true, preserve_text = false, parent = nil) case el.type when :xml_comment, :xml_pi ptype = if parent.nil? 'div' else case parent.type when :html_element then parent.value when :code_span then 'code' when :code_block then 'pre' when :header then 'h1' else parent.type.to_s end end el.options.replace({:category => (HTML_CONTENT_MODEL[ptype] == :span ? :span : :block)}) return when :html_element when :root el.children.each {|c| process(c)} remove_whitespace_children(el) return else return end mname = "convert_#{el.value}" if do_conversion && self.class.method_defined?(mname) send(mname, el) else type = el.value remove_text_children(el) if do_conversion && REMOVE_TEXT_CHILDREN.include?(type) if do_conversion && SIMPLE_ELEMENTS.include?(type) set_basics(el, type.intern) process_children(el, do_conversion, preserve_text) else process_html_element(el, do_conversion, preserve_text) end if do_conversion strip_whitespace(el) if STRIP_WHITESPACE.include?(type) remove_whitespace_children(el) if REMOVE_WHITESPACE_CHILDREN.include?(type) wrap_text_children(el) if WRAP_TEXT_CHILDREN.include?(type) end end end def process_children(el, do_conversion = true, preserve_text = false) el.children.map! do |c| if c.type == :text process_text(c.value, preserve_text || !do_conversion) else process(c, do_conversion, preserve_text, el) c end end.flatten! end # Process the HTML text +raw+: compress whitespace (if +preserve+ is +false+) and convert # entities in entity elements. def process_text(raw, preserve = false) raw.gsub!(/\s+/, ' ') unless preserve src = Kramdown::Utils::StringScanner.new(raw) result = [] while !src.eos? if tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/) result << Element.new(:text, tmp) src.scan(HTML_ENTITY_RE) val = src[1] || (src[2] && src[2].to_i) || src[3].hex result << if %w{lsquo rsquo ldquo rdquo}.include?(val) Element.new(:smart_quote, val.intern) elsif %w{mdash ndash hellip laquo raquo}.include?(val) Element.new(:typographic_sym, val.intern) else begin Element.new(:entity, entity(val), nil, :original => src.matched) rescue ::Kramdown::Error src.pos -= src.matched_size - 1 Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp')) end end else result << Element.new(:text, src.rest) src.terminate end end result end def process_html_element(el, do_conversion = true, preserve_text = false) el.options.replace(:category => HTML_SPAN_ELEMENTS.include?(el.value) ? :span : :block, :content_model => (do_conversion ? HTML_CONTENT_MODEL[el.value] : :raw)) process_children(el, do_conversion, preserve_text) end def remove_text_children(el) el.children.delete_if {|c| c.type == :text} end def wrap_text_children(el) tmp = [] last_is_p = false el.children.each do |c| if Element.category(c) != :block || c.type == :text if !last_is_p tmp << Element.new(:p, nil, nil, :transparent => true) last_is_p = true end tmp.last.children << c tmp else tmp << c last_is_p = false end end el.children = tmp end def strip_whitespace(el) return if el.children.empty? if el.children.first.type == :text el.children.first.value.lstrip! end if el.children.last.type == :text el.children.last.value.rstrip! end end def remove_whitespace_children(el) i = -1 el.children = el.children.reject do |c| i += 1 c.type == :text && c.value.strip.empty? && (i == 0 || i == el.children.length - 1 || (Element.category(el.children[i-1]) == :block && Element.category(el.children[i+1]) == :block)) end end def set_basics(el, type, opts = {}) el.type = type el.options.replace(opts) el.value = nil end def extract_text(el, raw) raw << el.value.to_s if el.type == :text el.children.each {|c| extract_text(c, raw)} end def convert_textarea(el) process_html_element(el, true, true) end def convert_a(el) if el.attr['href'] set_basics(el, :a) process_children(el) else process_html_element(el, false) end end EMPHASIS_TYPE_MAP = {'em' => :em, 'i' => :em, 'strong' => :strong, 'b' => :strong} def convert_em(el) text = '' extract_text(el, text) if text =~ /\A\s/ || text =~ /\s\z/ process_html_element(el, false) else set_basics(el, EMPHASIS_TYPE_MAP[el.value]) process_children(el) end end %w{b strong i}.each do |i| alias_method("convert_#{i}".to_sym, :convert_em) end def convert_h1(el) set_basics(el, :header, :level => el.value[1..1].to_i) extract_text(el, el.options[:raw_text] = '') process_children(el) end %w{h2 h3 h4 h5 h6}.each do |i| alias_method("convert_#{i}".to_sym, :convert_h1) end def convert_code(el) raw = '' extract_text(el, raw) result = process_text(raw, true) begin str = result.inject('') do |mem, c| if c.type == :text mem << c.value elsif c.type == :entity if [60, 62, 34, 38].include?(c.value.code_point) mem << c.value.code_point.chr else mem << c.value.char end elsif c.type == :smart_quote || c.type == :typographic_sym mem << entity(c.value.to_s).char else raise "Bug - please report" end end result.clear result << Element.new(:text, str) rescue end if result.length > 1 || result.first.type != :text process_html_element(el, false, true) else if el.value == 'code' set_basics(el, :codespan) el.attr['class'].gsub!(/\s+\bhighlighter-\w+\b|\bhighlighter-\w+\b\s*/, '') if el.attr['class'] else set_basics(el, :codeblock) if el.children.size == 1 && el.children.first.value == 'code' value = (el.children.first.attr['class'] || '').scan(/\blanguage-\S+/).first el.attr['class'] = "#{value} #{el.attr['class']}".rstrip if value end end el.value = result.first.value el.children.clear end end alias :convert_pre :convert_code def convert_table(el) if !is_simple_table?(el) process_html_element(el, false) return end remove_text_children(el) process_children(el) set_basics(el, :table) calc_alignment = lambda do |c| if c.type == :tr el.options[:alignment] = c.children.map do |td| if td.attr['style'] td.attr['style'].slice!(/(?:;\s*)?text-align:\s+(center|left|right)/) td.attr.delete('style') if td.attr['style'].strip.empty? $1 ? $1.to_sym : :default else :default end end else c.children.each {|cc| calc_alignment.call(cc)} end end calc_alignment.call(el) el.children.delete_if {|c| c.type == :html_element} change_th_type = lambda do |c| if c.type == :th c.type = :td else c.children.each {|cc| change_th_type.call(cc)} end end change_th_type.call(el) if el.children.first.type == :tr tbody = Element.new(:tbody) tbody.children = el.children el.children = [tbody] end end def is_simple_table?(el) only_phrasing_content = lambda do |c| c.children.all? do |cc| (cc.type == :text || !HTML_BLOCK_ELEMENTS.include?(cc.value)) && only_phrasing_content.call(cc) end end check_cells = Proc.new do |c| if c.value == 'th' || c.value == 'td' return false if !only_phrasing_content.call(c) else c.children.each {|cc| check_cells.call(cc)} end end check_cells.call(el) nr_cells = 0 check_nr_cells = lambda do |t| if t.value == 'tr' count = t.children.select {|cc| cc.value == 'th' || cc.value == 'td'}.length if count != nr_cells if nr_cells == 0 nr_cells = count else nr_cells = -1 break end end else t.children.each {|cc| check_nr_cells.call(cc)} end end check_nr_cells.call(el) return false if nr_cells == -1 alignment = nil check_alignment = Proc.new do |t| if t.value == 'tr' cur_alignment = t.children.select {|cc| cc.value == 'th' || cc.value == 'td'}.map do |cell| md = /text-align:\s+(center|left|right|justify|inherit)/.match(cell.attr['style'].to_s) return false if md && (md[1] == 'justify' || md[1] == 'inherit') md.nil? ? :default : md[1] end alignment = cur_alignment if alignment.nil? return false if alignment != cur_alignment else t.children.each {|cc| check_alignment.call(cc)} end end check_alignment.call(el) check_rows = lambda do |t, type| t.children.all? {|r| (r.value == 'tr' || r.type == :text) && r.children.all? {|c| c.value == type || c.type == :text}} end check_rows.call(el, 'td') || (el.children.all? do |t| t.type == :text || (t.value == 'thead' && check_rows.call(t, 'th')) || ((t.value == 'tfoot' || t.value == 'tbody') && check_rows.call(t, 'td')) end && el.children.any? {|t| t.value == 'tbody'}) end def convert_script(el) if !is_math_tag?(el) process_html_element(el) else handle_math_tag(el) end end def is_math_tag?(el) el.attr['type'].to_s =~ /\bmath\/tex\b/ end def handle_math_tag(el) set_basics(el, :math, :category => (el.attr['type'] =~ /mode=display/ ? :block : :span)) el.value = el.children.shift.value.sub(/\A(?:%\s*)?\z/m, '\1') el.attr.delete('type') end end include Parser # Parse the source string provided on initialization as HTML document. def parse @stack, @tree = [], @root @src = Kramdown::Utils::StringScanner.new(adapt_source(source)) while true if result = @src.scan(/\s*#{HTML_INSTRUCTION_RE}/) @tree.children << Element.new(:xml_pi, result.strip, nil, :category => :block) elsif result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/) # ignore the doctype elsif result = @src.scan(/\s*#{HTML_COMMENT_RE}/) @tree.children << Element.new(:xml_comment, result.strip, nil, :category => :block) else break end end tag_handler = lambda do |c, closed, handle_body| parse_raw_html(c, &tag_handler) if !closed && handle_body end parse_raw_html(@tree, &tag_handler) ElementConverter.convert(@tree) end end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/0000755000004100000410000000000013321140127021152 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/parser/kramdown/list.rb0000644000004100000410000002272113321140127022456 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/eob' require 'kramdown/parser/kramdown/horizontal_rule' require 'kramdown/parser/kramdown/extensions' module Kramdown module Parser class Kramdown LIST_ITEM_IAL = /^\s*(?:\{:(?!(?:#{ALD_ID_NAME})?:|\/)(#{ALD_ANY_CHARS}+)\})\s*/ LIST_ITEM_IAL_CHECK = /^#{LIST_ITEM_IAL}?\s*\n/ PARSE_FIRST_LIST_LINE_REGEXP_CACHE = Hash.new do |h, indentation| indent_re = /^ {#{indentation}}/ content_re = /^(?:(?:\t| {4}){#{indentation / 4}} {#{indentation % 4}}|(?:\t| {4}){#{indentation / 4 + 1}}).*\S.*\n/ lazy_re = /(?!^ {0,#{[indentation, 3].min}}(?:#{IAL_BLOCK}|#{LAZY_END_HTML_STOP}|#{LAZY_END_HTML_START})).*\S.*\n/ h[indentation] = [content_re, lazy_re, indent_re] end # Used for parsing the first line of a list item or a definition, i.e. the line with list item # marker or the definition marker. def parse_first_list_line(indentation, content) if content =~ self.class::LIST_ITEM_IAL_CHECK indentation = 4 else while content =~ /^ *\t/ temp = content.scan(/^ */).first.length + indentation content.sub!(/^( *)(\t+)/) {$1 << " "*(4 - (temp % 4) + ($2.length - 1)*4)} end indentation += content[/^ */].length end content.sub!(/^\s*/, '') [content, indentation, *PARSE_FIRST_LIST_LINE_REGEXP_CACHE[indentation]] end LIST_START_UL = /^(#{OPT_SPACE}[+*-])([\t| ].*?\n)/ LIST_START_OL = /^(#{OPT_SPACE}\d+\.)([\t| ].*?\n)/ LIST_START = /#{LIST_START_UL}|#{LIST_START_OL}/ # Parse the ordered or unordered list at the current location. def parse_list start_line_number = @src.current_line_number type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL]) list = new_block_el(type, nil, nil, :location => start_line_number) item = nil content_re, lazy_re, indent_re = nil eob_found = false nested_list_found = false last_is_blank = false while !@src.eos? start_line_number = @src.current_line_number if last_is_blank && @src.check(HR_START) break elsif @src.scan(EOB_MARKER) eob_found = true break elsif @src.scan(list_start_re) item = Element.new(:li, nil, nil, :location => start_line_number) item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2]) list.children << item item.value.sub!(self.class::LIST_ITEM_IAL) do |match| parse_attribute_list($1, item.options[:ial] ||= {}) '' end list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ : /^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/) nested_list_found = (item.value =~ LIST_START) last_is_blank = false item.value = [item.value] elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re))) result.sub!(/^(\t+)/) { " " * 4 * $1.length } indentation_found = result.sub!(indent_re, '') if !nested_list_found && indentation_found && result =~ LIST_START item.value << '' nested_list_found = true elsif nested_list_found && !indentation_found && result =~ LIST_START result = " " * (indentation + 4) << result end item.value.last << result last_is_blank = false elsif result = @src.scan(BLANK_LINE) nested_list_found = true last_is_blank = true item.value.last << result else break end end @tree.children << list last = nil list.children.each do |it| temp = Element.new(:temp, nil, nil, :location => it.options[:location]) env = save_env location = it.options[:location] it.value.each do |val| @src = ::Kramdown::Utils::StringScanner.new(val, location) parse_blocks(temp) location = @src.current_line_number end restore_env(env) it.children = temp.children it.value = nil next if it.children.size == 0 # Handle the case where an EOB marker is inserted by a block IAL for the first paragraph it.children.delete_at(1) if it.children.first.type == :p && it.children.length >= 2 && it.children[1].type == :eob && it.children.first.options[:ial] if it.children.first.type == :p && (it.children.length < 2 || it.children[1].type != :blank || (it == list.children.last && it.children.length == 2 && !eob_found)) && (list.children.last != it || list.children.size == 1 || list.children[0..-2].any? {|cit| !cit.children.first || cit.children.first.type != :p || cit.children.first.options[:transparent]}) it.children.first.children.first.value << "\n" if it.children.size > 1 && it.children[1].type != :blank it.children.first.options[:transparent] = true end if it.children.last.type == :blank last = it.children.pop else last = nil end end @tree.children << last if !last.nil? && !eob_found true end define_parser(:list, LIST_START) DEFINITION_LIST_START = /^(#{OPT_SPACE}:)([\t| ].*?\n)/ # Parse the ordered or unordered list at the current location. def parse_definition_list children = @tree.children if !children.last || (children.length == 1 && children.last.type != :p ) || (children.length >= 2 && children[-1].type != :p && (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p)) return false end first_as_para = false deflist = new_block_el(:dl) para = @tree.children.pop if para.type == :blank para = @tree.children.pop first_as_para = true end deflist.options[:location] = para.options[:location] # take location from preceding para which is the first definition term para.children.first.value.split(/\n/).each do |term| el = Element.new(:dt, nil, nil, :location => @src.current_line_number) term.sub!(self.class::LIST_ITEM_IAL) do parse_attribute_list($1, el.options[:ial] ||= {}) '' end el.options[:raw_text] = term el.children << Element.new(:raw_text, term) deflist.children << el end deflist.options[:ial] = para.options[:ial] item = nil content_re, lazy_re, indent_re = nil def_start_re = DEFINITION_LIST_START last_is_blank = false while !@src.eos? start_line_number = @src.current_line_number if @src.scan(def_start_re) item = Element.new(:dd, nil, nil, :location => start_line_number) item.options[:first_as_para] = first_as_para item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2]) deflist.children << item item.value.sub!(self.class::LIST_ITEM_IAL) do |match| parse_attribute_list($1, item.options[:ial] ||= {}) '' end def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/ first_as_para = false last_is_blank = false elsif @src.check(EOB_MARKER) break elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re))) result.sub!(/^(\t+)/) { " "*($1 ? 4*$1.length : 0) } result.sub!(indent_re, '') item.value << result first_as_para = false last_is_blank = false elsif result = @src.scan(BLANK_LINE) first_as_para = true item.value << result last_is_blank = true else break end end last = nil deflist.children.each do |it| next if it.type == :dt parse_blocks(it, it.value) it.value = nil next if it.children.size == 0 if it.children.last.type == :blank last = it.children.pop else last = nil end if it.children.first && it.children.first.type == :p && !it.options.delete(:first_as_para) it.children.first.children.first.value << "\n" if it.children.size > 1 it.children.first.options[:transparent] = true end end if @tree.children.length >= 1 && @tree.children.last.type == :dl @tree.children[-1].children.concat(deflist.children) elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank && @tree.children[-2].type == :dl @tree.children.pop @tree.children[-1].children.concat(deflist.children) else @tree.children << deflist end @tree.children << last if !last.nil? true end define_parser(:definition_list, DEFINITION_LIST_START) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/escaped_chars.rb0000644000004100000410000000102013321140127024254 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown ESCAPED_CHARS = /\\([\\.*_+`<>()\[\]{}#!:|"'\$=-])/ # Parse the backslash-escaped character at the current location. def parse_escaped_chars @src.pos += @src.matched_size add_text(@src[1]) end define_parser(:escaped_chars, ESCAPED_CHARS, '\\\\') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/block_boundary.rb0000644000004100000410000000152413321140127024476 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/extensions' require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/eob' module Kramdown module Parser class Kramdown BLOCK_BOUNDARY = /#{BLANK_LINE}|#{EOB_MARKER}|#{IAL_BLOCK_START}|\Z/ # Return +true+ if we are after a block boundary. def after_block_boundary? !@tree.children.last || @tree.children.last.type == :blank || (@tree.children.last.type == :eob && @tree.children.last.value.nil?) || @block_ial end # Return +true+ if we are before a block boundary. def before_block_boundary? @src.check(self.class::BLOCK_BOUNDARY) end end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/line_break.rb0000644000004100000410000000105613321140127023574 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown LINE_BREAK = /( |\\\\)(?=\n)/ # Parse the line break at the current location. def parse_line_break @tree.children << Element.new(:br, nil, nil, :location => @src.current_line_number) @src.pos += @src.matched_size end define_parser(:line_break, LINE_BREAK, '( |\\\\)(?=\n)') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/codespan.rb0000644000004100000410000000214613321140127023276 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown CODESPAN_DELIMITER = /`+/ # Parse the codespan at the current scanner location. def parse_codespan start_line_number = @src.current_line_number result = @src.scan(CODESPAN_DELIMITER) simple = (result.length == 1) saved_pos = @src.save_pos if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/) add_text(result) return end if text = @src.scan_until(/#{result}/) text.sub!(/#{result}\Z/, '') if !simple text = text[1..-1] if text[0..0] == ' ' text = text[0..-2] if text[-1..-1] == ' ' end @tree.children << Element.new(:codespan, text, nil, :location => start_line_number) else @src.revert_pos(saved_pos) add_text(result) end end define_parser(:codespan, CODESPAN_DELIMITER, '`') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/paragraph.rb0000644000004100000410000000412013321140127023441 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/extensions' require 'kramdown/parser/kramdown/eob' require 'kramdown/parser/kramdown/list' require 'kramdown/parser/kramdown/html' module Kramdown module Parser class Kramdown LAZY_END_HTML_SPAN_ELEMENTS = HTML_SPAN_ELEMENTS + %w{script} LAZY_END_HTML_START = /<(?>(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR})/ LAZY_END_HTML_STOP = /<\/(?!(?:#{LAZY_END_HTML_SPAN_ELEMENTS.join('|')})\b)#{REXML::Parsers::BaseParser::UNAME_STR}\s*>/m LAZY_END = /#{BLANK_LINE}|#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START}|\Z/ PARAGRAPH_START = /^#{OPT_SPACE}[^ \t].*?\n/ PARAGRAPH_MATCH = /^.*?\n/ PARAGRAPH_END = /#{LAZY_END}|#{DEFINITION_LIST_START}/ # Parse the paragraph at the current location. def parse_paragraph pos = @src.pos start_line_number = @src.current_line_number result = @src.scan(PARAGRAPH_MATCH) while !@src.match?(paragraph_end) result << @src.scan(PARAGRAPH_MATCH) end result.rstrip! if @tree.children.last && @tree.children.last.type == :p last_item_in_para = @tree.children.last.children.last if last_item_in_para && last_item_in_para.type == @text_type joiner = (extract_string((pos - 3)...pos, @src) == " \n" ? " \n" : "\n") last_item_in_para.value << joiner << result else add_text(result, @tree.children.last) end else @tree.children << new_block_el(:p, nil, nil, :location => start_line_number) result.lstrip! add_text(result, @tree.children.last) end true end define_parser(:paragraph, PARAGRAPH_START) def paragraph_end self.class::PARAGRAPH_END end end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/header.rb0000644000004100000410000000362513321140127022735 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/block_boundary' module Kramdown module Parser class Kramdown SETEXT_HEADER_START = /^#{OPT_SPACE}(?[^ \t].*)\n(?[-=])[-=]*[ \t\r\f\v]*\n/ # Parse the Setext header at the current location. def parse_setext_header return false if !after_block_boundary? text, id = parse_header_contents return false if text.empty? add_header(@src["level"] == '-' ? 2 : 1, text, id) true end define_parser(:setext_header, SETEXT_HEADER_START) ATX_HEADER_START = /^(?\#{1,6})[\t ]*(?[^ \t].*)\n/ # Parse the Atx header at the current location. def parse_atx_header return false if !after_block_boundary? text, id = parse_header_contents text.sub!(/[\t ]#+\z/, '') && text.rstrip! return false if text.empty? add_header(@src["level"].length, text, id) true end define_parser(:atx_header, ATX_HEADER_START) protected HEADER_ID = /[\t ]{#(?[A-Za-z][\w:-]*)}\z/ # Returns header text and optional ID. def parse_header_contents text = @src["contents"] text.rstrip! id_match = HEADER_ID.match(text) if id_match id = id_match["id"] text = text[0...-id_match[0].length] text.rstrip! end [text, id] end def add_header(level, text, id) start_line_number = @src.current_line_number @src.pos += @src.matched_size el = new_block_el(:header, nil, nil, :level => level, :raw_text => text, :location => start_line_number) add_text(text, el) el.attr['id'] = id if id @tree.children << el end end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/autolink.rb0000644000004100000410000000156513321140127023334 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown ACHARS = '[[:alnum:]]_' AUTOLINK_START_STR = "<((mailto|https?|ftps?):.+?|[-.#{ACHARS}]+@[-#{ACHARS}]+(?:\.[-#{ACHARS}]+)*\.[a-z]+)>" AUTOLINK_START = /#{AUTOLINK_START_STR}/u # Parse the autolink at the current location. def parse_autolink start_line_number = @src.current_line_number @src.pos += @src.matched_size href = (@src[2].nil? ? "mailto:#{@src[1]}" : @src[1]) el = Element.new(:a, nil, {'href' => href}, :location => start_line_number) add_text(@src[1].sub(/^mailto:/, ''), el) @tree.children << el end define_parser(:autolink, AUTOLINK_START, '<') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/codeblock.rb0000644000004100000410000000354013321140127023426 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/extensions' require 'kramdown/parser/kramdown/eob' require 'kramdown/parser/kramdown/paragraph' module Kramdown module Parser class Kramdown CODEBLOCK_START = INDENT CODEBLOCK_MATCH = /(?:#{BLANK_LINE}?(?:#{INDENT}[ \t]*\S.*\n)+(?:(?!#{IAL_BLOCK_START}|#{EOB_MARKER}|^#{OPT_SPACE}#{LAZY_END_HTML_STOP}|^#{OPT_SPACE}#{LAZY_END_HTML_START})^[ \t]*\S.*\n)*)*/ # Parse the indented codeblock at the current location. def parse_codeblock start_line_number = @src.current_line_number data = @src.scan(self.class::CODEBLOCK_MATCH) data.gsub!(/\n( {0,3}\S)/, ' \\1') data.gsub!(INDENT, '') @tree.children << new_block_el(:codeblock, data, nil, :location => start_line_number) true end define_parser(:codeblock, CODEBLOCK_START) FENCED_CODEBLOCK_START = /^~{3,}/ FENCED_CODEBLOCK_MATCH = /^((~){3,})\s*?((\S+?)(?:\?\S*)?)?\s*?\n(.*?)^\1\2*\s*?\n/m # Parse the fenced codeblock at the current location. def parse_codeblock_fenced if @src.check(self.class::FENCED_CODEBLOCK_MATCH) start_line_number = @src.current_line_number @src.pos += @src.matched_size el = new_block_el(:codeblock, @src[5], nil, :location => start_line_number, :fenced => true) lang = @src[3].to_s.strip unless lang.empty? el.options[:lang] = lang el.attr['class'] = "language-#{@src[4]}" end @tree.children << el true else false end end define_parser(:codeblock_fenced, FENCED_CODEBLOCK_START) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/footnote.rb0000644000004100000410000000431313321140127023335 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/extensions' require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/codeblock' module Kramdown module Parser class Kramdown FOOTNOTE_DEFINITION_START = /^#{OPT_SPACE}\[\^(#{ALD_ID_NAME})\]:\s*?(.*?\n#{CODEBLOCK_MATCH})/ # Parse the foot note definition at the current location. def parse_footnote_definition start_line_number = @src.current_line_number @src.pos += @src.matched_size el = Element.new(:footnote_def, nil, nil, :location => start_line_number) parse_blocks(el, @src[2].gsub(INDENT, '')) warning("Duplicate footnote name '#{@src[1]}' on line #{start_line_number} - overwriting") if @footnotes[@src[1]] @tree.children << new_block_el(:eob, :footnote_def) (@footnotes[@src[1]] = {})[:content] = el @footnotes[@src[1]][:eob] = @tree.children.last true end define_parser(:footnote_definition, FOOTNOTE_DEFINITION_START) FOOTNOTE_MARKER_START = /\[\^(#{ALD_ID_NAME})\]/ # Parse the footnote marker at the current location. def parse_footnote_marker start_line_number = @src.current_line_number @src.pos += @src.matched_size fn_def = @footnotes[@src[1]] if fn_def if fn_def[:eob] update_attr_with_ial(fn_def[:eob].attr, fn_def[:eob].options[:ial] || {}) fn_def[:attr] = fn_def[:eob].attr fn_def[:options] = fn_def[:eob].options fn_def.delete(:eob) end fn_def[:marker] ||= [] fn_def[:marker].push(Element.new(:footnote, fn_def[:content], fn_def[:attr], fn_def[:options].merge(:name => @src[1], :location => start_line_number))) @tree.children << fn_def[:marker].last else warning("Footnote definition for '#{@src[1]}' not found on line #{start_line_number}") add_text(@src.matched) end end define_parser(:footnote_marker, FOOTNOTE_MARKER_START, '\[') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/html_entity.rb0000644000004100000410000000203313321140127024035 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/html' module Kramdown module Parser class Kramdown # Parse the HTML entity at the current location. def parse_html_entity start_line_number = @src.current_line_number @src.pos += @src.matched_size begin @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2] && @src[2].to_i) || @src[3].hex), nil, :original => @src.matched, :location => start_line_number) rescue ::Kramdown::Error @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'), nil, :location => start_line_number) add_text(@src.matched[1..-1]) end end define_parser(:html_entity, Kramdown::Parser::Html::Constants::HTML_ENTITY_RE, '&') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/blank_line.rb0000644000004100000410000000123213321140127023573 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown BLANK_LINE = /(?>^\s*\n)+/ # Parse the blank line at the current postition. def parse_blank_line @src.pos += @src.matched_size if @tree.children.last && @tree.children.last.type == :blank @tree.children.last.value << @src.matched else @tree.children << new_block_el(:blank, @src.matched) end true end define_parser(:blank_line, BLANK_LINE) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/abbreviation.rb0000644000004100000410000000550013321140127024144 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown ABBREV_DEFINITION_START = /^#{OPT_SPACE}\*\[(.+?)\]:(.*?)\n/ # Parse the link definition at the current location. def parse_abbrev_definition start_line_number = @src.current_line_number @src.pos += @src.matched_size abbrev_id, abbrev_text = @src[1], @src[2] abbrev_text.strip! warning("Duplicate abbreviation ID '#{abbrev_id}' on line #{start_line_number} - overwriting") if @root.options[:abbrev_defs][abbrev_id] @tree.children << new_block_el(:eob, :abbrev_def) @root.options[:abbrev_defs][abbrev_id] = abbrev_text @root.options[:abbrev_attr][abbrev_id] = @tree.children.last true end define_parser(:abbrev_definition, ABBREV_DEFINITION_START) # Correct abbreviation attributes. def correct_abbreviations_attributes @root.options[:abbrev_attr].keys.each do |k| @root.options[:abbrev_attr][k] = @root.options[:abbrev_attr][k].attr end end # Replace the abbreviation text with elements. def replace_abbreviations(el, regexps = nil) return if @root.options[:abbrev_defs].empty? if !regexps sorted_abbrevs = @root.options[:abbrev_defs].keys.sort {|a,b| b.length <=> a.length} regexps = [Regexp.union(*sorted_abbrevs.map {|k| /#{Regexp.escape(k)}/})] regexps << /(?=(?:\W|^)#{regexps.first}(?!\w))/ # regexp should only match on word boundaries end el.children.map! do |child| if child.type == :text if child.value =~ regexps.first result = [] strscan = Kramdown::Utils::StringScanner.new(child.value, child.options[:location]) text_lineno = strscan.current_line_number while temp = strscan.scan_until(regexps.last) abbr_lineno = strscan.current_line_number abbr = strscan.scan(regexps.first) # begin of line case of abbr with \W char as first one if abbr.nil? temp << strscan.scan(/\W|^/) abbr = strscan.scan(regexps.first) end result << Element.new(:text, temp, nil, :location => text_lineno) result << Element.new(:abbreviation, abbr, nil, :location => abbr_lineno) text_lineno = strscan.current_line_number end result << Element.new(:text, strscan.rest, nil, :location => text_lineno) else child end else replace_abbreviations(child, regexps) child end end.flatten! end end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/extensions.rb0000644000004100000410000001650013321140127023700 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown IAL_CLASS_ATTR = 'class' # Parse the string +str+ and extract all attributes and add all found attributes to the hash # +opts+. def parse_attribute_list(str, opts) return if str.strip.empty? || str.strip == ':' attrs = str.scan(ALD_TYPE_ANY) attrs.each do |key, sep, val, ref, id_and_or_class, _, _| if ref (opts[:refs] ||= []) << ref elsif id_and_or_class id_and_or_class.scan(ALD_TYPE_ID_OR_CLASS).each do |id_attr, class_attr| if class_attr opts[IAL_CLASS_ATTR] = (opts[IAL_CLASS_ATTR] || '') << " #{class_attr}" opts[IAL_CLASS_ATTR].lstrip! else opts['id'] = id_attr end end else val.gsub!(/\\(\}|#{sep})/, "\\1") opts[key] = val end end warning("No or invalid attributes found in IAL/ALD content: #{str}") if attrs.length == 0 end # Update the +ial+ with the information from the inline attribute list +opts+. def update_ial_with_ial(ial, opts) (ial[:refs] ||= []) << opts[:refs] opts.each do |k,v| if k == IAL_CLASS_ATTR ial[k] = (ial[k] || '') << " #{v}" ial[k].lstrip! elsif k.kind_of?(String) ial[k] = v end end end # Parse the generic extension at the current point. The parameter +type+ can either be :block # or :span depending whether we parse a block or span extension tag. def parse_extension_start_tag(type) saved_pos = @src.save_pos start_line_number = @src.current_line_number @src.pos += @src.matched_size error_block = lambda do |msg| warning(msg) @src.revert_pos(saved_pos) add_text(@src.getch) if type == :span false end if @src[4] || @src.matched == '{:/}' name = (@src[4] ? "for '#{@src[4]}' " : '') return error_block.call("Invalid extension stop tag #{name} found on line #{start_line_number} - ignoring it") end ext = @src[1] opts = {} body = nil parse_attribute_list(@src[2] || '', opts) if !@src[3] stop_re = (type == :block ? /#{EXT_BLOCK_STOP_STR % ext}/ : /#{EXT_STOP_STR % ext}/) if result = @src.scan_until(stop_re) body = result.sub!(stop_re, '') body.chomp! if type == :block else return error_block.call("No stop tag for extension '#{ext}' found on line #{start_line_number} - ignoring it") end end if !handle_extension(ext, opts, body, type, start_line_number) error_block.call("Invalid extension with name '#{ext}' specified on line #{start_line_number} - ignoring it") else true end end def handle_extension(name, opts, body, type, line_no = nil) case name when 'comment' @tree.children << Element.new(:comment, body, nil, :category => type, :location => line_no) if body.kind_of?(String) true when 'nomarkdown' @tree.children << Element.new(:raw, body, nil, :category => type, :location => line_no, :type => opts['type'].to_s.split(/\s+/)) if body.kind_of?(String) true when 'options' opts.select do |k,v| k = k.to_sym if Kramdown::Options.defined?(k) begin val = Kramdown::Options.parse(k, v) @options[k] = val (@root.options[:options] ||= {})[k] = val rescue end false else true end end.each do |k,v| warning("Unknown kramdown option '#{k}'") end @tree.children << new_block_el(:eob, :extension) if type == :block true else false end end ALD_ID_CHARS = /[\w-]/ ALD_ANY_CHARS = /\\\}|[^\}]/ ALD_ID_NAME = /\w#{ALD_ID_CHARS}*/ ALD_CLASS_NAME = /[^\s\.#]+/ ALD_TYPE_KEY_VALUE_PAIR = /(#{ALD_ID_NAME})=("|')((?:\\\}|\\\2|[^\}\2])*?)\2/ ALD_TYPE_CLASS_NAME = /\.(#{ALD_CLASS_NAME})/ ALD_TYPE_ID_NAME = /#([A-Za-z][\w:-]*)/ ALD_TYPE_ID_OR_CLASS = /#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME}/ ALD_TYPE_ID_OR_CLASS_MULTI = /((?:#{ALD_TYPE_ID_NAME}|#{ALD_TYPE_CLASS_NAME})+)/ ALD_TYPE_REF = /(#{ALD_ID_NAME})/ ALD_TYPE_ANY = /(?:\A|\s)(?:#{ALD_TYPE_KEY_VALUE_PAIR}|#{ALD_TYPE_REF}|#{ALD_TYPE_ID_OR_CLASS_MULTI})(?=\s|\Z)/ ALD_START = /^#{OPT_SPACE}\{:(#{ALD_ID_NAME}):(#{ALD_ANY_CHARS}+)\}\s*?\n/ EXT_STOP_STR = "\\{:/(%s)?\\}" EXT_START_STR = "\\{::(\\w+)(?:\\s(#{ALD_ANY_CHARS}*?)|)(\\/)?\\}" EXT_BLOCK_START = /^#{OPT_SPACE}(?:#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME})\s*?\n/ EXT_BLOCK_STOP_STR = "^#{OPT_SPACE}#{EXT_STOP_STR}\s*?\n" IAL_BLOCK = /\{:(?!:|\/)(#{ALD_ANY_CHARS}+)\}\s*?\n/ IAL_BLOCK_START = /^#{OPT_SPACE}#{IAL_BLOCK}/ BLOCK_EXTENSIONS_START = /^#{OPT_SPACE}\{:/ # Parse one of the block extensions (ALD, block IAL or generic extension) at the current # location. def parse_block_extensions if @src.scan(ALD_START) parse_attribute_list(@src[2], @alds[@src[1]] ||= Utils::OrderedHash.new) @tree.children << new_block_el(:eob, :ald) true elsif @src.check(EXT_BLOCK_START) parse_extension_start_tag(:block) elsif @src.scan(IAL_BLOCK_START) if @tree.children.last && @tree.children.last.type != :blank && (@tree.children.last.type != :eob || [:link_def, :abbrev_def, :footnote_def].include?(@tree.children.last.value)) parse_attribute_list(@src[1], @tree.children.last.options[:ial] ||= Utils::OrderedHash.new) @tree.children << new_block_el(:eob, :ial) unless @src.check(IAL_BLOCK_START) else parse_attribute_list(@src[1], @block_ial ||= Utils::OrderedHash.new) end true else false end end define_parser(:block_extensions, BLOCK_EXTENSIONS_START) EXT_SPAN_START = /#{EXT_START_STR}|#{EXT_STOP_STR % ALD_ID_NAME}/ IAL_SPAN_START = /\{:(#{ALD_ANY_CHARS}+)\}/ SPAN_EXTENSIONS_START = /\{:/ # Parse the extension span at the current location. def parse_span_extensions if @src.check(EXT_SPAN_START) parse_extension_start_tag(:span) elsif @src.check(IAL_SPAN_START) if @tree.children.last && @tree.children.last.type != :text @src.pos += @src.matched_size attr = Utils::OrderedHash.new parse_attribute_list(@src[1], attr) update_ial_with_ial(@tree.children.last.options[:ial] ||= Utils::OrderedHash.new, attr) update_attr_with_ial(@tree.children.last.attr, attr) else warning("Found span IAL after text - ignoring it") add_text(@src.getch) end else add_text(@src.getch) end end define_parser(:span_extensions, SPAN_EXTENSIONS_START, '\{:') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/table.rb0000644000004100000410000001421213321140127022566 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/block_boundary' module Kramdown module Parser class Kramdown TABLE_SEP_LINE = /^([+|: \t-]*?-[+|: \t-]*?)[ \t]*\n/ TABLE_HSEP_ALIGN = /[ \t]?(:?)-+(:?)[ \t]?/ TABLE_FSEP_LINE = /^[+|: \t=]*?=[+|: \t=]*?[ \t]*\n/ TABLE_ROW_LINE = /^(.*?)[ \t]*\n/ TABLE_PIPE_CHECK = /(?:\||.*?[^\\\n]\|)/ TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/ TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/ # Parse the table at the current location. def parse_table return false if !after_block_boundary? saved_pos = @src.save_pos orig_pos = @src.pos table = new_block_el(:table, nil, nil, :alignment => [], :location => @src.current_line_number) leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/) @src.scan(TABLE_SEP_LINE) rows = [] has_footer = false columns = 0 add_container = lambda do |type, force| if !has_footer || type != :tbody || force cont = Element.new(type) cont.children, rows = rows, [] table.children << cont end end while !@src.eos? break if !@src.check(TABLE_LINE) if @src.scan(TABLE_SEP_LINE) if rows.empty? # nothing to do, ignoring multiple consecutive separator lines elsif table.options[:alignment].empty? && !has_footer add_container.call(:thead, false) table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right| (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center end else # treat as normal separator line add_container.call(:tbody, false) end elsif @src.scan(TABLE_FSEP_LINE) add_container.call(:tbody, true) if !rows.empty? has_footer = true elsif @src.scan(TABLE_ROW_LINE) trow = Element.new(:tr) # parse possible code spans on the line and correctly split the line into cells env = save_env cells = [] @src[1].split(/(.*?<\/code>)/).each_with_index do |str, i| if i % 2 == 1 (cells.empty? ? cells : cells.last) << str else reset_env(:src => Kramdown::Utils::StringScanner.new(str, @src.current_line_number)) root = Element.new(:root) parse_spans(root, nil, [:codespan]) root.children.each do |c| if c.type == :raw_text f, *l = c.value.split(/(? 1}#{c.value}#{' ' if delim.size > 1}#{delim}" (cells.empty? ? cells : cells.last) << tmp end end end end restore_env(env) cells.shift if leading_pipe && cells.first.strip.empty? cells.pop if cells.last.strip.empty? cells.each do |cell_text| tcell = Element.new(:td) tcell.children << Element.new(:raw_text, cell_text.strip) trow.children << tcell end columns = [columns, cells.length].max rows << trow else break end end if !before_block_boundary? @src.revert_pos(saved_pos) return false end # Parse all lines of the table with the code span parser env = save_env l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src), @src.current_line_number) reset_env(:src => l_src) root = Element.new(:root) parse_spans(root, nil, [:codespan, :span_html]) restore_env(env) # Check if each line has at least one unescaped pipe that is not inside a code span/code # HTML element # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting # algorithm above only takes elements into account! pipe_on_line = false while (c = root.children.shift) next unless (lines = c.value) lines = lines.split("\n") if c.type == :codespan if lines.size > 2 || (lines.size == 2 && !pipe_on_line) break elsif lines.size == 2 && pipe_on_line pipe_on_line = false end else break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/ pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/) end end @src.revert_pos(saved_pos) and return false if !pipe_on_line add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty? if !table.children.any? {|el| el.type == :tbody} warning("Found table without body on line #{table.options[:location]} - ignoring it") @src.revert_pos(saved_pos) return false end # adjust all table rows to have equal number of columns, same for alignment defs table.children.each do |kind| kind.children.each do |row| (columns - row.children.length).times do row.children << Element.new(:td) end end end if table.options[:alignment].length > columns table.options[:alignment] = table.options[:alignment][0...columns] else table.options[:alignment] += [:default] * (columns - table.options[:alignment].length) end @tree.children << table true end define_parser(:table, TABLE_START) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/smart_quotes.rb0000644000004100000410000001427413321140127024235 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # #-- # Parts of this file are based on code from RubyPants: # # = RubyPants -- SmartyPants ported to Ruby # # Ported by Christian Neukirchen # Copyright (C) 2004 Christian Neukirchen # # Incooporates ideas, comments and documentation by Chad Miller # Copyright (C) 2004 Chad Miller # # Original SmartyPants by John Gruber # Copyright (C) 2003 John Gruber # # # = RubyPants -- SmartyPants ported to Ruby # # # [snip] # # == Authors # # John Gruber did all of the hard work of writing this software in # Perl for Movable Type and almost all of this useful documentation. # Chad Miller ported it to Python to use with Pyblosxom. # # Christian Neukirchen provided the Ruby port, as a general-purpose # library that follows the *Cloth API. # # # == Copyright and License # # === SmartyPants license: # # Copyright (c) 2003 John Gruber # (http://daringfireball.net) # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # * Neither the name "SmartyPants" nor the names of its contributors # may be used to endorse or promote products derived from this # software without specific prior written permission. # # This software is provided by the copyright holders and contributors # "as is" and any express or implied warranties, including, but not # limited to, the implied warranties of merchantability and fitness # for a particular purpose are disclaimed. In no event shall the # copyright owner or contributors be liable for any direct, indirect, # incidental, special, exemplary, or consequential damages (including, # but not limited to, procurement of substitute goods or services; # loss of use, data, or profits; or business interruption) however # caused and on any theory of liability, whether in contract, strict # liability, or tort (including negligence or otherwise) arising in # any way out of the use of this software, even if advised of the # possibility of such damage. # # === RubyPants license # # RubyPants is a derivative work of SmartyPants and smartypants.py. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # This software is provided by the copyright holders and contributors # "as is" and any express or implied warranties, including, but not # limited to, the implied warranties of merchantability and fitness # for a particular purpose are disclaimed. In no event shall the # copyright owner or contributors be liable for any direct, indirect, # incidental, special, exemplary, or consequential damages (including, # but not limited to, procurement of substitute goods or services; # loss of use, data, or profits; or business interruption) however # caused and on any theory of liability, whether in contract, strict # liability, or tort (including negligence or otherwise) arising in # any way out of the use of this software, even if advised of the # possibility of such damage. # # == Links # # John Gruber:: http://daringfireball.net # SmartyPants:: http://daringfireball.net/projects/smartypants # # Chad Miller:: http://web.chad.org # # Christian Neukirchen:: http://kronavita.de/chris # #++ # module Kramdown module Parser class Kramdown SQ_PUNCT = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]' SQ_CLOSE = %![^\ \\\\\t\r\n\\[{(-]! SQ_RULES = [ [/("|')(?=[_*]{1,2}\S)/, [:lquote1]], [/("|')(?=#{SQ_PUNCT}(?!\.\.)\B)/, [:rquote1]], # Special case for double sets of quotes, e.g.: #

    He said, "'Quoted' words in a larger quote."

    [/(\s?)"'(?=\w)/, [1, :ldquo, :lsquo]], [/(\s?)'"(?=\w)/, [1, :lsquo, :ldquo]], # Special case for decade abbreviations (the '80s): [/(\s?)'(?=\d\ds)/, [1, :rsquo]], # Get most opening single/double quotes: [/(\s)('|")(?=\w)/, [1, :lquote2]], # Single/double closing quotes: [/(#{SQ_CLOSE})('|")/, [1, :rquote2]], # Special case for e.g. "Custer's Last Stand." [/("|')(?=\s|s\b|$)/, [:rquote1]], # Any remaining single quotes should be opening ones: [/(.?)'/m, [1, :lsquo]], [/(.?)"/m, [1, :ldquo]], ] #'" SQ_SUBSTS = { [:rquote1, '"'] => :rdquo, [:rquote1, "'"] => :rsquo, [:rquote2, '"'] => :rdquo, [:rquote2, "'"] => :rsquo, [:lquote1, '"'] => :ldquo, [:lquote1, "'"] => :lsquo, [:lquote2, '"'] => :ldquo, [:lquote2, "'"] => :lsquo, } SMART_QUOTES_RE = /[^\\]?["']/ # Parse the smart quotes at current location. def parse_smart_quotes start_line_number = @src.current_line_number substs = SQ_RULES.find {|reg, subst| @src.scan(reg)}[1] substs.each do |subst| if subst.kind_of?(Integer) add_text(@src[subst]) else val = SQ_SUBSTS[[subst, @src[subst.to_s[-1,1].to_i]]] || subst @tree.children << Element.new(:smart_quote, val, nil, :location => start_line_number) end end end define_parser(:smart_quotes, SMART_QUOTES_RE, '[^\\\\]?["\']') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/math.rb0000644000004100000410000000266613321140127022442 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/block_boundary' module Kramdown module Parser class Kramdown BLOCK_MATH_START = /^#{OPT_SPACE}(\\)?\$\$(.*?)\$\$(\s*?\n)?/m # Parse the math block at the current location. def parse_block_math start_line_number = @src.current_line_number if !after_block_boundary? return false elsif @src[1] @src.scan(/^#{OPT_SPACE}\\/) if @src[3] return false end saved_pos = @src.save_pos @src.pos += @src.matched_size data = @src[2].strip if before_block_boundary? @tree.children << new_block_el(:math, data, nil, :category => :block, :location => start_line_number) true else @src.revert_pos(saved_pos) false end end define_parser(:block_math, BLOCK_MATH_START) INLINE_MATH_START = /\$\$(.*?)\$\$/m # Parse the inline math at the current location. def parse_inline_math start_line_number = @src.current_line_number @src.pos += @src.matched_size @tree.children << Element.new(:math, @src[1].strip, nil, :category => :span, :location => start_line_number) end define_parser(:inline_math, INLINE_MATH_START, '\$') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/eob.rb0000644000004100000410000000076313321140127022252 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown EOB_MARKER = /^\^\s*?\n/ # Parse the EOB marker at the current location. def parse_eob_marker @src.pos += @src.matched_size @tree.children << new_block_el(:eob) true end define_parser(:eob_marker, EOB_MARKER) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/horizontal_rule.rb0000644000004100000410000000120513321140127024715 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown HR_START = /^#{OPT_SPACE}(\*|-|_)[ \t]*\1[ \t]*\1(\1|[ \t])*\n/ # Parse the horizontal rule at the current location. def parse_horizontal_rule start_line_number = @src.current_line_number @src.pos += @src.matched_size @tree.children << new_block_el(:hr, nil, nil, :location => start_line_number) true end define_parser(:horizontal_rule, HR_START) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/html.rb0000644000004100000410000001502013321140127022441 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/html' module Kramdown module Parser class Kramdown include Kramdown::Parser::Html::Parser # Mapping of markdown attribute value to content model. I.e. :raw when "0", :default when "1" # (use default content model for the HTML element), :span when "span", :block when block and # for everything else +nil+ is returned. HTML_MARKDOWN_ATTR_MAP = {"0" => :raw, "1" => :default, "span" => :span, "block" => :block} TRAILING_WHITESPACE = /[ \t]*\n/ def handle_kramdown_html_tag(el, closed, handle_body) if @block_ial el.options[:ial] = @block_ial @block_ial = nil end content_model = if @tree.type != :html_element || @tree.options[:content_model] != :raw (@options[:parse_block_html] ? HTML_CONTENT_MODEL[el.value] : :raw) else :raw end if val = HTML_MARKDOWN_ATTR_MAP[el.attr.delete('markdown')] content_model = (val == :default ? HTML_CONTENT_MODEL[el.value] : val) end @src.scan(TRAILING_WHITESPACE) if content_model == :block el.options[:content_model] = content_model el.options[:is_closed] = closed if !closed && handle_body if content_model == :block if !parse_blocks(el) warning("Found no end tag for '#{el.value}' (line #{el.options[:location]}) - auto-closing it") end elsif content_model == :span curpos = @src.pos if @src.scan_until(/(?=<\/#{el.value}\s*>)/mi) add_text(extract_string(curpos...@src.pos, @src), el) @src.scan(HTML_TAG_CLOSE_RE) else add_text(@src.rest, el) @src.terminate warning("Found no end tag for '#{el.value}' (line #{el.options[:location]}) - auto-closing it") end else parse_raw_html(el, &method(:handle_kramdown_html_tag)) end @src.scan(TRAILING_WHITESPACE) unless (@tree.type == :html_element && @tree.options[:content_model] == :raw) end end HTML_BLOCK_START = /^#{OPT_SPACE}<(#{REXML::Parsers::BaseParser::UNAME_STR}|\?|!--|\/)/ # Parse the HTML at the current position as block-level HTML. def parse_block_html line = @src.current_line_number if result = @src.scan(HTML_COMMENT_RE) @tree.children << Element.new(:xml_comment, result, nil, :category => :block, :location => line) @src.scan(TRAILING_WHITESPACE) true elsif result = @src.scan(HTML_INSTRUCTION_RE) @tree.children << Element.new(:xml_pi, result, nil, :category => :block, :location => line) @src.scan(TRAILING_WHITESPACE) true else if result = @src.check(/^#{OPT_SPACE}#{HTML_TAG_RE}/) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase) @src.pos += @src.matched_size handle_html_start_tag(line, &method(:handle_kramdown_html_tag)) Kramdown::Parser::Html::ElementConverter.convert(@root, @tree.children.last) if @options[:html_to_native] true elsif result = @src.check(/^#{OPT_SPACE}#{HTML_TAG_CLOSE_RE}/) && !HTML_SPAN_ELEMENTS.include?(@src[1].downcase) name = @src[1].downcase if @tree.type == :html_element && @tree.value == name @src.pos += @src.matched_size throw :stop_block_parsing, :found else false end else false end end end define_parser(:block_html, HTML_BLOCK_START) HTML_SPAN_START = /<(#{REXML::Parsers::BaseParser::UNAME_STR}|\?|!--|\/)/ # Parse the HTML at the current position as span-level HTML. def parse_span_html line = @src.current_line_number if result = @src.scan(HTML_COMMENT_RE) @tree.children << Element.new(:xml_comment, result, nil, :category => :span, :location => line) elsif result = @src.scan(HTML_INSTRUCTION_RE) @tree.children << Element.new(:xml_pi, result, nil, :category => :span, :location => line) elsif result = @src.scan(HTML_TAG_CLOSE_RE) warning("Found invalidly used HTML closing tag for '#{@src[1]}' on line #{line}") add_text(result) elsif result = @src.scan(HTML_TAG_RE) tag_name = @src[1] tag_name.downcase! if HTML_ELEMENT[tag_name.downcase] if HTML_BLOCK_ELEMENTS.include?(tag_name) warning("Found block HTML tag '#{tag_name}' in span-level text on line #{line}") add_text(result) return end attrs = parse_html_attributes(@src[2], line, HTML_ELEMENT[tag_name]) attrs.each {|name, value| value.gsub!(/\n+/, ' ')} do_parsing = (HTML_CONTENT_MODEL[tag_name] == :raw || @tree.options[:content_model] == :raw ? false : @options[:parse_span_html]) if val = HTML_MARKDOWN_ATTR_MAP[attrs.delete('markdown')] if val == :block warning("Cannot use block-level parsing in span-level HTML tag (line #{line}) - using default mode") elsif val == :span do_parsing = true elsif val == :default do_parsing = HTML_CONTENT_MODEL[tag_name] != :raw elsif val == :raw do_parsing = false end end el = Element.new(:html_element, tag_name, attrs, :category => :span, :location => line, :content_model => (do_parsing ? :span : :raw), :is_closed => !!@src[4]) @tree.children << el stop_re = /<\/#{Regexp.escape(tag_name)}\s*>/ stop_re = Regexp.new(stop_re.source, Regexp::IGNORECASE) if HTML_ELEMENT[tag_name] if !@src[4] && !HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) if parse_spans(el, stop_re, (do_parsing ? nil : [:span_html])) @src.scan(stop_re) else warning("Found no end tag for '#{el.value}' (line #{line}) - auto-closing it") add_text(@src.rest, el) @src.terminate end end Kramdown::Parser::Html::ElementConverter.convert(@root, el) if @options[:html_to_native] else add_text(@src.getch) end end define_parser(:span_html, HTML_SPAN_START, '<') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/blockquote.rb0000644000004100000410000000170013321140127023645 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/blank_line' require 'kramdown/parser/kramdown/extensions' require 'kramdown/parser/kramdown/eob' module Kramdown module Parser class Kramdown BLOCKQUOTE_START = /^#{OPT_SPACE}> ?/ # Parse the blockquote at the current location. def parse_blockquote start_line_number = @src.current_line_number result = @src.scan(PARAGRAPH_MATCH) while !@src.match?(self.class::LAZY_END) result << @src.scan(PARAGRAPH_MATCH) end result.gsub!(BLOCKQUOTE_START, '') el = new_block_el(:blockquote, nil, nil, :location => start_line_number) @tree.children << el parse_blocks(el, result) true end define_parser(:blockquote, BLOCKQUOTE_START) end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/typographic_symbol.rb0000644000004100000410000000352413321140127025421 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown TYPOGRAPHIC_SYMS = [['---', :mdash], ['--', :ndash], ['...', :hellip], ['\\<<', '<<'], ['\\>>', '>>'], ['<< ', :laquo_space], [' >>', :raquo_space], ['<<', :laquo], ['>>', :raquo]] TYPOGRAPHIC_SYMS_SUBST = Hash[*TYPOGRAPHIC_SYMS.flatten] TYPOGRAPHIC_SYMS_RE = /#{TYPOGRAPHIC_SYMS.map {|k,v| Regexp.escape(k)}.join('|')}/ # Parse the typographic symbols at the current location. def parse_typographic_syms start_line_number = @src.current_line_number @src.pos += @src.matched_size val = TYPOGRAPHIC_SYMS_SUBST[@src.matched] if val.kind_of?(Symbol) @tree.children << Element.new(:typographic_sym, val, nil, :location => start_line_number) elsif @src.matched == '\\<<' @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'), nil, :location => start_line_number) @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'), nil, :location => start_line_number) else @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'), nil, :location => start_line_number) @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'), nil, :location => start_line_number) end end define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/emphasis.rb0000644000004100000410000000345013321140127023312 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Parser class Kramdown EMPHASIS_START = /(?:\*\*?|__?)/ # Parse the emphasis at the current location. def parse_emphasis start_line_number = @src.current_line_number saved_pos = @src.save_pos result = @src.scan(EMPHASIS_START) element = (result.length == 2 ? :strong : :em) type = result[0..0] if (type == '_' && @src.pre_match =~ /[[:alpha:]-]\z/) || @src.check(/\s/) || @tree.type == element || @stack.any? {|el, _| el.type == element} add_text(result) return end sub_parse = lambda do |delim, elem| el = Element.new(elem, nil, nil, :location => start_line_number) stop_re = /#{Regexp.escape(delim)}/ found = parse_spans(el, stop_re) do (@src.pre_match[-1, 1] !~ /\s/) && (elem != :em || !@src.match?(/#{Regexp.escape(delim*2)}(?!#{Regexp.escape(delim)})/)) && (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alnum:]]/)) && el.children.size > 0 end [found, el, stop_re] end found, el, stop_re = sub_parse.call(result, element) if !found && element == :strong && @tree.type != :em @src.revert_pos(saved_pos) @src.pos += 1 found, el, stop_re = sub_parse.call(type, :em) end if found @src.scan(stop_re) @tree.children << el else @src.revert_pos(saved_pos) @src.pos += result.length add_text(result) end end define_parser(:emphasis, EMPHASIS_START, '\*|_') end end end kramdown-1.17.0/lib/kramdown/parser/kramdown/link.rb0000644000004100000410000001123013321140127022431 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/escaped_chars' module Kramdown module Parser class Kramdown # Normalize the link identifier. def normalize_link_id(id) id.gsub(/[\s]+/, ' ').downcase end LINK_DEFINITION_START = /^#{OPT_SPACE}\[([^\n\]]+)\]:[ \t]*(?:<(.*?)>|([^\n]*?\S[^\n]*?))(?:(?:[ \t]*?\n|[ \t]+?)[ \t]*?(["'])(.+?)\4)?[ \t]*?\n/ # Parse the link definition at the current location. def parse_link_definition return false if @src[3].to_s =~ /[ \t]+["']/ @src.pos += @src.matched_size link_id, link_url, link_title = normalize_link_id(@src[1]), @src[2] || @src[3], @src[5] warning("Duplicate link ID '#{link_id}' on line #{@src.current_line_number} - overwriting") if @link_defs[link_id] @tree.children << new_block_el(:eob, :link_def) @link_defs[link_id] = [link_url, link_title, @tree.children.last] true end define_parser(:link_definition, LINK_DEFINITION_START) # This helper methods adds the approriate attributes to the element +el+ of type +a+ or +img+ # and the element itself to the @tree. def add_link(el, href, title, alt_text = nil, ial = nil) el.options[:ial] = ial update_attr_with_ial(el.attr, ial) if ial if el.type == :a el.attr['href'] = href else el.attr['src'] = href el.attr['alt'] = alt_text el.children.clear end el.attr['title'] = title if title @tree.children << el end LINK_BRACKET_STOP_RE = /(\])|!?\[/ LINK_PAREN_STOP_RE = /(\()|(\))|\s(?=['"])/ LINK_INLINE_ID_RE = /\s*?\[([^\]]+)?\]/ LINK_INLINE_TITLE_RE = /\s*?(["'])(.+?)\1\s*?\)/m LINK_START = /!?\[(?=[^^])/ # Parse the link at the current scanner position. This method is used to parse normal links as # well as image links. def parse_link start_line_number = @src.current_line_number result = @src.scan(LINK_START) cur_pos = @src.pos saved_pos = @src.save_pos link_type = (result =~ /^!/ ? :img : :a) # no nested links allowed if link_type == :a && (@tree.type == :img || @tree.type == :a || @stack.any? {|t,s| t && (t.type == :img || t.type == :a)}) add_text(result) return end el = Element.new(link_type, nil, nil, :location => start_line_number) count = 1 found = parse_spans(el, LINK_BRACKET_STOP_RE) do count = count + (@src[1] ? -1 : 1) count - el.children.select {|c| c.type == :img}.size == 0 end unless found @src.revert_pos(saved_pos) add_text(result) return end alt_text = extract_string(cur_pos...@src.pos, @src).gsub(ESCAPED_CHARS, '\1') @src.scan(LINK_BRACKET_STOP_RE) # reference style link or no link url if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/) emit_warning = !@src[1] link_id = normalize_link_id(@src[1] || alt_text) if @link_defs.has_key?(link_id) add_link(el, @link_defs[link_id][0], @link_defs[link_id][1], alt_text, @link_defs[link_id][2] && @link_defs[link_id][2].options[:ial]) else if emit_warning warning("No link definition for link ID '#{link_id}' found on line #{start_line_number}") end @src.revert_pos(saved_pos) add_text(result) end return end # link url in parentheses if @src.scan(/\(<(.*?)>/) link_url = @src[1] if @src.scan(/\)/) add_link(el, link_url, nil, alt_text) return end else link_url = '' nr_of_brackets = 0 while temp = @src.scan_until(LINK_PAREN_STOP_RE) link_url << temp if @src[2] nr_of_brackets -= 1 break if nr_of_brackets == 0 elsif @src[1] nr_of_brackets += 1 else break end end link_url = link_url[1..-2] link_url.strip! if nr_of_brackets == 0 add_link(el, link_url, nil, alt_text) return end end if @src.scan(LINK_INLINE_TITLE_RE) add_link(el, link_url, @src[2], alt_text) else @src.revert_pos(saved_pos) add_text(result) end end define_parser(:link, LINK_START, '!?\[') end end end kramdown-1.17.0/lib/kramdown/version.rb0000644000004100000410000000035113321140127020045 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown # The kramdown version. VERSION = '1.17.0' end kramdown-1.17.0/lib/kramdown/document.rb0000644000004100000410000001161313321140127020201 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # # = kramdown # # kramdown is fast, pure Ruby Markdown superset converter, using a strict syntax definition and # supporting several common extensions. # # The kramdown library is mainly written to support the kramdown-to-HTML conversion chain. However, # due to its flexibility it supports other input and output formats as well. Here is a list of the # supported formats: # # * input formats: kramdown (a Markdown superset), Markdown, GFM, HTML # * output formats: HTML, kramdown, LaTeX (and therefore PDF), PDF via Prawn # # All the documentation on the available input and output formats is available at # http://kramdown.gettalong.org. # # == Usage # # kramdown has a simple API, so using kramdown is as easy as # # require 'kramdown' # # Kramdown::Document.new(text).to_html # # For detailed information have a look at the *\Kramdown::Document* class. # # == License # # MIT - see the COPYING file. require 'kramdown/version' require 'kramdown/element' require 'kramdown/error' require 'kramdown/parser' require 'kramdown/converter' require 'kramdown/options' require 'kramdown/utils' module Kramdown # Return the data directory for kramdown. def self.data_dir unless defined?(@@data_dir) require 'rbconfig' @@data_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'kramdown')) @@data_dir = File.expand_path(File.join(RbConfig::CONFIG["datadir"], "kramdown")) if !File.exist?(@@data_dir) raise "kramdown data directory not found! This is a bug, please report it!" unless File.directory?(@@data_dir) end @@data_dir end # The main interface to kramdown. # # This class provides a one-stop-shop for using kramdown to convert text into various output # formats. Use it like this: # # require 'kramdown' # doc = Kramdown::Document.new('This *is* some kramdown text') # puts doc.to_html # # The #to_html method is a shortcut for using the Converter::Html class. See #method_missing for # more information. # # The second argument to the ::new method is an options hash for customizing the behaviour of the # used parser and the converter. See ::new for more information! class Document # The root Element of the element tree. It is immediately available after the ::new method has # been called. attr_accessor :root # The options hash which holds the options for parsing/converting the Kramdown document. attr_reader :options # An array of warning messages. It is filled with warnings during the parsing phase (i.e. in # ::new) and the conversion phase. attr_reader :warnings # Create a new Kramdown document from the string +source+ and use the provided +options+. The # options that can be used are defined in the Options module. # # The special options key :input can be used to select the parser that should parse the # +source+. It has to be the name of a class in the Kramdown::Parser module. For example, to # select the kramdown parser, one would set the :input key to +Kramdown+. If this key is not # set, it defaults to +Kramdown+. # # The +source+ is immediately parsed by the selected parser so that the root element is # immediately available and the output can be generated. def initialize(source, options = {}) @options = Options.merge(options).freeze parser = (@options[:input] || 'kramdown').to_s parser = parser[0..0].upcase + parser[1..-1] try_require('parser', parser) if Parser.const_defined?(parser) @root, @warnings = Parser.const_get(parser).parse(source, @options) else raise Kramdown::Error.new("kramdown has no parser to handle the specified input format: #{@options[:input]}") end end # Check if a method is invoked that begins with +to_+ and if so, try to instantiate a converter # class (i.e. a class in the Kramdown::Converter module) and use it for converting the document. # # For example, +to_html+ would instantiate the Kramdown::Converter::Html class. def method_missing(id, *attr, &block) if id.to_s =~ /^to_(\w+)$/ && (name = Utils.camelize($1)) && try_require('converter', name) && Converter.const_defined?(name) output, warnings = Converter.const_get(name).convert(@root, @options) @warnings.concat(warnings) output else super end end def inspect #:nodoc: "" end # Try requiring a parser or converter class and don't raise an error if the file is not found. def try_require(type, name) require("kramdown/#{type}/#{Utils.snake_case(name)}") true rescue LoadError true end protected :try_require end end kramdown-1.17.0/lib/kramdown/utils/0000755000004100000410000000000013321140127017174 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/utils/ordered_hash.rb0000644000004100000410000000035013321140127022146 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Utils OrderedHash = Hash end end kramdown-1.17.0/lib/kramdown/utils/configurable.rb0000644000004100000410000000262213321140127022163 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Utils # Methods for registering configurable extensions. module Configurable # Create a new configurable extension called +name+. # # Three methods will be defined on the calling object which allow to use this configurable # extension: # # configurables:: Returns a hash of hashes that is used to store all configurables of the # object. # # (ext_name):: Return the configured extension +ext_name+. # # add_(ext_name, data=nil, &block):: Define an extension +ext_name+ by specifying either # the data as argument or by using a block. def configurable(name) singleton_class = (class << self; self; end) singleton_class.send(:define_method, :configurables) do @_configurables ||= Hash.new {|h, k| h[k] = {}} end unless respond_to?(:configurables) singleton_class.send(:define_method, name) do |data| configurables[name][data] end singleton_class.send(:define_method, "add_#{name}".intern) do |data, *args, &block| configurables[name][data] = args.first || block end end end end end kramdown-1.17.0/lib/kramdown/utils/entities.rb0000644000004100000410000002765113321140127021360 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Utils # Provides convenience methods for handling named and numeric entities. module Entities # Represents an entity that has a +code_point+ and +name+. class Entity < Struct.new(:code_point, :name) # Return the UTF8 representation of the entity. def char [code_point].pack('U*') rescue nil end end # Array of arrays. Each sub-array specifies a code point and the associated name. # # This table is not used directly -- Entity objects are automatically created from it and put # into a Hash map when this file is loaded. ENTITY_TABLE = [ [913, 'Alpha'], [914, 'Beta'], [915, 'Gamma'], [916, 'Delta'], [917, 'Epsilon'], [918, 'Zeta'], [919, 'Eta'], [920, 'Theta'], [921, 'Iota'], [922, 'Kappa'], [923, 'Lambda'], [924, 'Mu'], [925, 'Nu'], [926, 'Xi'], [927, 'Omicron'], [928, 'Pi'], [929, 'Rho'], [931, 'Sigma'], [932, 'Tau'], [933, 'Upsilon'], [934, 'Phi'], [935, 'Chi'], [936, 'Psi'], [937, 'Omega'], [945, 'alpha'], [946, 'beta'], [947, 'gamma'], [948, 'delta'], [949, 'epsilon'], [950, 'zeta'], [951, 'eta'], [952, 'theta'], [953, 'iota'], [954, 'kappa'], [955, 'lambda'], [956, 'mu'], [957, 'nu'], [958, 'xi'], [959, 'omicron'], [960, 'pi'], [961, 'rho'], [963, 'sigma'], [964, 'tau'], [965, 'upsilon'], [966, 'phi'], [967, 'chi'], [968, 'psi'], [969, 'omega'], [962, 'sigmaf'], [977, 'thetasym'], [978, 'upsih'], [982, 'piv'], [8204, 'zwnj'], [8205, 'zwj'], [8206, 'lrm'], [8207, 'rlm'], [8230, 'hellip'], [8242, 'prime'], [8243, 'Prime'], [8254, 'oline'], [8260, 'frasl'], [8472, 'weierp'], [8465, 'image'], [8476, 'real'], [8501, 'alefsym'], [8226, 'bull'], [8482, 'trade'], [8592, 'larr'], [8594, 'rarr'], [8593, 'uarr'], [8595, 'darr'], [8596, 'harr'], [8629, 'crarr'], [8657, 'uArr'], [8659, 'dArr'], [8656, 'lArr'], [8658, 'rArr'], [8660, 'hArr'], [8704, 'forall'], [8706, 'part'], [8707, 'exist'], [8709, 'empty'], [8711, 'nabla'], [8712, 'isin'], [8715, 'ni'], [8713, 'notin'], [8721, 'sum'], [8719, 'prod'], [8722, 'minus'], [8727, 'lowast'], [8730, 'radic'], [8733, 'prop'], [8734, 'infin'], [8736, 'ang'], [8743, 'and'], [8744, 'or'], [8745, 'cap'], [8746, 'cup'], [8747, 'int'], [8756, 'there4'], [8764, 'sim'], [8776, 'asymp'], [8773, 'cong'], [8800, 'ne'], [8801, 'equiv'], [8804, 'le'], [8805, 'ge'], [8834, 'sub'], [8835, 'sup'], [8838, 'sube'], [8839, 'supe'], [8836, 'nsub'], [8853, 'oplus'], [8855, 'otimes'], [8869, 'perp'], [8901, 'sdot'], [8942, 'vellip'], [8968, 'rceil'], [8969, 'lceil'], [8970, 'lfloor'], [8971, 'rfloor'], [9001, 'rang'], [9002, 'lang'], [9674, 'loz'], [9824, 'spades'], [9827, 'clubs'], [9829, 'hearts'], [9830, 'diams'], [38, 'amp'], [34, 'quot'], [39, 'apos'], [169, 'copy'], [60, 'lt'], [62, 'gt'], [338, 'OElig'], [339, 'oelig'], [352, 'Scaron'], [353, 'scaron'], [376, 'Yuml'], [710, 'circ'], [732, 'tilde'], [8211, 'ndash'], [8212, 'mdash'], [8216, 'lsquo'], [8217, 'rsquo'], [8220, 'ldquo'], [8221, 'rdquo'], [8224, 'dagger'], [8225, 'Dagger'], [8240, 'permil'], [8364, 'euro'], [8249, 'lsaquo'], [8250, 'rsaquo'], [160, 'nbsp'], [161, 'iexcl'], [163, 'pound'], [164, 'curren'], [165, 'yen'], [166, 'brvbar'], [167, 'sect'], [168, 'uml'], [171, 'laquo'], [187, 'raquo'], [174, 'reg'], [170, 'ordf'], [172, 'not'], [173, 'shy'], [175, 'macr'], [176, 'deg'], [177, 'plusmn'], [180, 'acute'], [181, 'micro'], [182, 'para'], [183, 'middot'], [184, 'cedil'], [186, 'ordm'], [162, 'cent'], [185, 'sup1'], [178, 'sup2'], [179, 'sup3'], [189, 'frac12'], [188, 'frac14'], [190, 'frac34'], [191, 'iquest'], [192, 'Agrave'], [193, 'Aacute'], [194, 'Acirc'], [195, 'Atilde'], [196, 'Auml'], [197, 'Aring'], [198, 'AElig'], [199, 'Ccedil'], [200, 'Egrave'], [201, 'Eacute'], [202, 'Ecirc'], [203, 'Euml'], [204, 'Igrave'], [205, 'Iacute'], [206, 'Icirc'], [207, 'Iuml'], [208, 'ETH'], [209, 'Ntilde'], [210, 'Ograve'], [211, 'Oacute'], [212, 'Ocirc'], [213, 'Otilde'], [214, 'Ouml'], [215, 'times'], [216, 'Oslash'], [217, 'Ugrave'], [218, 'Uacute'], [219, 'Ucirc'], [220, 'Uuml'], [221, 'Yacute'], [222, 'THORN'], [223, 'szlig'], [224, 'agrave'], [225, 'aacute'], [226, 'acirc'], [227, 'atilde'], [228, 'auml'], [229, 'aring'], [230, 'aelig'], [231, 'ccedil'], [232, 'egrave'], [233, 'eacute'], [234, 'ecirc'], [235, 'euml'], [236, 'igrave'], [237, 'iacute'], [238, 'icirc'], [239, 'iuml'], [240, 'eth'], [241, 'ntilde'], [242, 'ograve'], [243, 'oacute'], [244, 'ocirc'], [245, 'otilde'], [246, 'ouml'], [247, 'divide'], [248, 'oslash'], [249, 'ugrave'], [250, 'uacute'], [251, 'ucirc'], [252, 'uuml'], [253, 'yacute'], [254, 'thorn'], [255, 'yuml'], [8218, 'sbquo'], [402, 'fnof'], [8222, 'bdquo'], [128, 8364], [130, 8218], [131, 402], [132, 8222], [133, 8230], [134, 8224], [135, 8225], [136, 710], [137, 8240], [138, 352], [139, 8249], [140, 338], [142, 381], [145, 8216], [146, 8217], [147, 8220], [148, 8221], [149, 8226], [150, 8211], [151, 8212], [152, 732], [153, 8482], [154, 353], [155, 8250], [156, 339], [158, 382], [159, 376], [8194, 'ensp'], [8195, 'emsp'], [8201, 'thinsp'], ] # Contains the mapping of code point (or name) to the actual Entity object. ENTITY_MAP = Hash.new do |h,k| if k.kind_of?(Integer) h[k] = Entity.new(k, nil) else raise Kramdown::Error, "Can't handle generic non-integer character reference '#{k}'" end end ENTITY_TABLE.each do |code_point, data| if data.kind_of?(String) ENTITY_MAP[code_point] = ENTITY_MAP[data] = Entity.new(code_point, data) else ENTITY_MAP[code_point] = ENTITY_MAP[data] end end # Return the entity for the given code point or name +point_or_name+. def entity(point_or_name) ENTITY_MAP[point_or_name] end module_function :entity end end end kramdown-1.17.0/lib/kramdown/utils/lru_cache.rb0000644000004100000410000000204313321140127021445 0ustar www-datawww-data# -*- encoding: utf-8 -*- # #-- # Copyright (C) 2014-2017 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ module Kramdown module Utils # A simple least recently used (LRU) cache. # # The cache relies on the fact that Ruby's Hash class maintains insertion order. So deleting # and re-inserting a key-value pair on access moves the key to the last position. When an # entry is added and the cache is full, the first entry is removed. class LRUCache # Creates a new LRUCache that can hold +size+ entries. def initialize(size) @size = size @cache = {} end # Returns the stored value for +key+ or +nil+ if no value was stored under the key. def [](key) (val = @cache.delete(key)).nil? ? nil : @cache[key] = val end # Stores the +value+ under the +key+. def []=(key, value) @cache.delete(key) @cache[key] = value @cache.shift if @cache.length > @size end end end end kramdown-1.17.0/lib/kramdown/utils/string_scanner.rb0000644000004100000410000000513613321140127022545 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'strscan' module Kramdown module Utils # This patched StringScanner adds line number information for current scan position and a # start_line_number override for nested StringScanners. class StringScanner < ::StringScanner # The start line number. Used for nested StringScanners that scan a sub-string of the source # document. The kramdown parser uses this, e.g., for span level parsers. attr_reader :start_line_number # Takes the start line number as optional second argument. # # Note: The original second argument is no longer used so this should be safe. def initialize(string, start_line_number = 1) super(string) @start_line_number = start_line_number || 1 @previous_pos = 0 @previous_line_number = @start_line_number end # Sets the byte position of the scan pointer. # # Note: This also resets some internal variables, so always use pos= when setting the position # and don't use any other method for that! def pos=(pos) if self.pos > pos @previous_line_number = @start_line_number @previous_pos = 0 end super end # Return information needed to revert the byte position of the string scanner in a performant # way. # # The returned data can be fed to #revert_pos to revert the position to the saved one. # # Note: Just saving #pos won't be enough. def save_pos [pos, @previous_pos, @previous_line_number] end # Revert the position to one saved by #save_pos. def revert_pos(data) self.pos = data[0] @previous_pos, @previous_line_number = data[1], data[2] end # Returns the line number for current charpos. # # NOTE: Requires that all line endings are normalized to '\n' # # NOTE: Normally we'd have to add one to the count of newlines to get the correct line number. # However we add the one indirectly by using a one-based start_line_number. def current_line_number # Not using string[@previous_pos..best_pos].count('\n') because it is slower strscan = ::StringScanner.new(string) strscan.pos = @previous_pos old_pos = pos + 1 @previous_line_number += 1 while strscan.skip_until(/\n/) && strscan.pos <= old_pos @previous_pos = (eos? ? pos : pos + 1) @previous_line_number end end end end kramdown-1.17.0/lib/kramdown/utils/unidecoder.rb0000644000004100000410000000225513321140127021646 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # # This file is based on code originally from the Stringex library and needs the data files from # Stringex to work correctly. module Kramdown module Utils # Provides the ability to tranliterate Unicode strings into plain ASCII ones. module Unidecoder gem 'stringex' if defined?(Gem) path = $:.find {|dir| File.directory?(File.join(File.expand_path(dir), "stringex", "unidecoder_data"))} if !path def self.decode(string) string end else CODEPOINTS = Hash.new do |h, k| h[k] = YAML.load_file(File.join(path, "stringex", "unidecoder_data", "#{k}.yml")) end # Transliterate string from Unicode into ASCII. def self.decode(string) string.gsub(/[^\x00-\x7f]/u) do |codepoint| begin unpacked = codepoint.unpack("U")[0] CODEPOINTS["x%02x" % (unpacked >> 8)][unpacked & 255] rescue "?" end end end end end end end kramdown-1.17.0/lib/kramdown/utils/html.rb0000644000004100000410000000514613321140127020473 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'rexml/parsers/baseparser' module Kramdown module Utils # Provides convenience methods for HTML related tasks. # # *Note* that this module has to be mixed into a class that has a @root (containing an element # of type :root) and an @options (containing an options hash) instance variable so that some of # the methods can work correctly. module Html # Convert the entity +e+ to a string. The optional parameter +original+ may contain the # original representation of the entity. # # This method uses the option +entity_output+ to determine the output form for the entity. def entity_to_str(e, original = nil) entity_output = @options[:entity_output] if entity_output == :as_char && (c = e.char.encode(@root.options[:encoding]) rescue nil) && ((c = e.char) == '"' || !ESCAPE_MAP.has_key?(c)) c elsif (entity_output == :as_input || entity_output == :as_char) && original original elsif (entity_output == :symbolic || ESCAPE_MAP.has_key?(e.char)) && !e.name.nil? "&#{e.name};" else # default to :numeric "&##{e.code_point};" end end # Return the HTML representation of the attributes +attr+. def html_attributes(attr) attr.map {|k,v| v.nil? || (k == 'id' && v.strip.empty?) ? '' : " #{k}=\"#{escape_html(v.to_s, :attribute)}\"" }.join('') end # :stopdoc: ESCAPE_MAP = { '<' => '<', '>' => '>', '&' => '&', '"' => '"' } ESCAPE_ALL_RE = /<|>|&/ ESCAPE_TEXT_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&/) ESCAPE_ATTRIBUTE_RE = Regexp.union(REXML::Parsers::BaseParser::REFERENCE_RE, /<|>|&|"/) ESCAPE_RE_FROM_TYPE = { :all => ESCAPE_ALL_RE, :text => ESCAPE_TEXT_RE, :attribute => ESCAPE_ATTRIBUTE_RE } # :startdoc: # Escape the special HTML characters in the string +str+. The parameter +type+ specifies what # is escaped: :all - all special HTML characters except the quotation mark as well as # entities, :text - all special HTML characters except the quotation mark but no entities and # :attribute - all special HTML characters including the quotation mark but no entities. def escape_html(str, type = :all) str.gsub(ESCAPE_RE_FROM_TYPE[type]) {|m| ESCAPE_MAP[m] || m} end end end end kramdown-1.17.0/lib/kramdown/converter/0000755000004100000410000000000013321140127020043 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/converter/man.rb0000644000004100000410000002161513321140127021150 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/converter' module Kramdown module Converter # Converts a Kramdown::Document to a manpage in groff format. See man(7), groff_man(7) and # man-pages(7) for information regarding the output. class Man < Base def convert(el, opts = {:indent => 0, :result => ''}) #:nodoc: send("convert_#{el.type}", el, opts) end private def inner(el, opts, use = :all) arr = el.children.reject {|e| e.type == :blank} arr.each_with_index do |inner_el, index| next if use == :rest && index == 0 break if use == :first && index > 0 options = opts.dup options[:parent] = el options[:index] = index options[:prev] = (index == 0 ? nil : arr[index - 1]) options[:next] = (index == arr.length - 1 ? nil : arr[index + 1]) convert(inner_el, options) end end def convert_root(el, opts) @title_done = false opts[:result] = ".\\\" generated by kramdown\n" inner(el, opts) opts[:result] end def convert_blank(*) end alias :convert_hr :convert_blank alias :convert_xml_pi :convert_blank def convert_p(el, opts) if (opts[:index] != 0 && opts[:prev].type != :header) || (opts[:parent].type == :blockquote && opts[:index] == 0) opts[:result] << macro("P") end inner(el, opts) newline(opts[:result]) end def convert_header(el, opts) return unless opts[:parent].type == :root case el.options[:level] when 1 unless @title_done @title_done = true data = el.options[:raw_text].scan(/([^(]+)\s*\((\d\w*)\)(?:\s*-+\s*(.*))?/).first || el.options[:raw_text].scan(/([^\s]+)\s*(?:-*\s+)?()(.*)/).first return unless data && data[0] name = data[0] section = (data[1].to_s.empty? ? el.attr['data-section'] || '7' : data[1]) description = (data[2].to_s.empty? ? nil : " - #{data[2]}") date = el.attr['data-date'] ? quote(el.attr['data-date']) : nil extra = (el.attr['data-extra'] ? quote(escape(el.attr['data-extra'].to_s)) : nil) opts[:result] << macro("TH", quote(escape(name.upcase)), quote(section), date, extra) if description opts[:result] << macro("SH", "NAME") << escape("#{name}#{description}") << "\n" end end when 2 opts[:result] << macro("SH", quote(escape(el.options[:raw_text]))) when 3 opts[:result] << macro("SS", quote(escape(el.options[:raw_text]))) else warning("Header levels greater than three are not supported") end end def convert_codeblock(el, opts) opts[:result] << macro("sp") << macro("RS", 4) << macro("EX") opts[:result] << newline(escape(el.value, true)) opts[:result] << macro("EE") << macro("RE") end def convert_blockquote(el, opts) opts[:result] << macro("RS") inner(el, opts) opts[:result] << macro("RE") end def convert_ul(el, opts) compact = (el.attr['class'] =~ /\bcompact\b/) opts[:result] << macro("sp") << macro("PD", 0) if compact inner(el, opts) opts[:result] << macro("PD") if compact end alias :convert_dl :convert_ul alias :convert_ol :convert_ul def convert_li(el, opts) sym = (opts[:parent].type == :ul ? '\(bu' : "#{opts[:index] + 1}.") opts[:result] << macro("IP", sym, 4) inner(el, opts, :first) if el.children.size > 1 opts[:result] << macro("RS") inner(el, opts, :rest) opts[:result] << macro("RE") end end def convert_dt(el, opts) opts[:result] << macro(opts[:prev] && opts[:prev].type == :dt ? "TQ" : "TP") inner(el, opts) opts[:result] << "\n" end def convert_dd(el, opts) inner(el, opts, :first) if el.children.size > 1 opts[:result] << macro("RS") inner(el, opts, :rest) opts[:result] << macro("RE") end opts[:result] << macro("sp") if opts[:next] && opts[:next].type == :dd end TABLE_CELL_ALIGNMENT = {:left => 'l', :center => 'c', :right => 'r', :default => 'l'} def convert_table(el, opts) opts[:alignment] = el.options[:alignment].map {|a| TABLE_CELL_ALIGNMENT[a]} table_options = ["box"] table_options << "center" if el.attr['class'] =~ /\bcenter\b/ opts[:result] << macro("TS") << "#{table_options.join(" ")} ;\n" inner(el, opts) opts[:result] << macro("TE") << macro("sp") end def convert_thead(el, opts) opts[:result] << opts[:alignment].map {|a| "#{a}b"}.join(' ') << " .\n" inner(el, opts) opts[:result] << "=\n" end def convert_tbody(el, opts) opts[:result] << ".T&\n" if opts[:index] != 0 opts[:result] << opts[:alignment].join(' ') << " .\n" inner(el, opts) opts[:result] << (opts[:next].type == :tfoot ? "=\n" : "_\n") if opts[:next] end def convert_tfoot(el, opts) inner(el, opts) end def convert_tr(el, opts) inner(el, opts) opts[:result] << "\n" end def convert_td(el, opts) result = opts[:result] opts[:result] = '' inner(el, opts) if opts[:result] =~ /\n/ warning("Table cells using links are not supported") result << "\t" else result << opts[:result] << "\t" end end def convert_html_element(*) warning("HTML elements are not supported") end def convert_xml_comment(el, opts) newline(opts[:result]) << ".\"#{escape(el.value, true).rstrip.gsub(/\n/, "\n.\"")}\n" end alias :convert_comment :convert_xml_comment def convert_a(el, opts) if el.children.size == 1 && el.children[0].type == :text && el.attr['href'] == el.children[0].value newline(opts[:result]) << macro("UR", escape(el.attr['href'])) << macro("UE") elsif el.attr['href'].start_with?('mailto:') newline(opts[:result]) << macro("MT", escape(el.attr['href'].sub(/^mailto:/, ''))) << macro("UE") else newline(opts[:result]) << macro("UR", escape(el.attr['href'])) inner(el, opts) newline(opts[:result]) << macro("UE") end end def convert_img(el, opts) warning("Images are not supported") end def convert_em(el, opts) opts[:result] << '\fI' inner(el, opts) opts[:result] << '\fP' end def convert_strong(el, opts) opts[:result] << '\fB' inner(el, opts) opts[:result] << '\fP' end def convert_codespan(el, opts) opts[:result] << "\\fB#{escape(el.value)}\\fP" end def convert_br(el, opts) newline(opts[:result]) << macro("br") end def convert_abbreviation(el, opts) opts[:result] << escape(el.value) end def convert_math(el, opts) if el.options[:category] == :block convert_codeblock(el, opts) else convert_codespan(el, opts) end end def convert_footnote(*) warning("Footnotes are not supported") end def convert_raw(*) warning("Raw content is not supported") end def convert_text(el, opts) text = escape(el.value) text.lstrip! if opts[:result][-1] == ?\n opts[:result] << text end def convert_entity(el, opts) opts[:result] << unicode_char(el.value.code_point) end def convert_smart_quote(el, opts) opts[:result] << unicode_char(::Kramdown::Utils::Entities.entity(el.value.to_s).code_point) end TYPOGRAPHIC_SYMS_MAP = { :mdash => '\(em', :ndash => '\(em', :hellip => '\.\.\.', :laquo_space => '\[Fo]', :raquo_space => '\[Fc]', :laquo => '\[Fo]', :raquo => '\[Fc]' } def convert_typographic_sym(el, opts) opts[:result] << TYPOGRAPHIC_SYMS_MAP[el.value] end def macro(name, *args) ".#{[name, *args].compact.join(' ')}\n" end def newline(text) text << "\n" unless text[-1] == ?\n text end def quote(text) "\"#{text.gsub(/"/, '\\"')}\"" end def escape(text, preserve_whitespace = false) text = (preserve_whitespace ? text.dup : text.gsub(/\s+/, ' ')) text.gsub!('\\', "\\e") text.gsub!(/^\./, '\\\\&.') text.gsub!(/[.'-]/) {|m| "\\#{m}"} text end def unicode_char(codepoint) "\\[u#{codepoint.to_s(16).rjust(4, '0')}]" end end end end kramdown-1.17.0/lib/kramdown/converter/syntax_highlighter/0000755000004100000410000000000013321140127023747 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/converter/syntax_highlighter/rouge.rb0000644000004100000410000000416313321140127025421 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::SyntaxHighlighter # Uses Rouge which is CSS-compatible to Pygments to highlight code blocks and code spans. module Rouge begin require 'rouge' # Highlighting via Rouge is available if this constant is +true+. AVAILABLE = true rescue LoadError, SyntaxError AVAILABLE = false # :nodoc: end def self.call(converter, text, lang, type, call_opts) opts = options(converter, type) call_opts[:default_lang] = opts[:default_lang] lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text) return nil if opts[:disable] || !lexer opts[:css_class] ||= 'highlight' # For backward compatibility when using Rouge 2.0 formatter = formatter_class(opts).new(opts) formatter.format(lexer.lex(text)) end def self.options(converter, type) prepare_options(converter) converter.data[:syntax_highlighter_rouge][type] end def self.prepare_options(converter) return if converter.data.key?(:syntax_highlighter_rouge) cache = converter.data[:syntax_highlighter_rouge] = {} opts = converter.options[:syntax_highlighter_opts].dup span_opts = (opts.delete(:span) || {}).dup block_opts = (opts.delete(:block) || {}).dup [span_opts, block_opts].each do |hash| hash.keys.each do |k| hash[k.kind_of?(String) ? Kramdown::Options.str_to_sym(k) : k] = hash.delete(k) end end cache[:span] = opts.merge(span_opts).update(:wrap => false) cache[:block] = opts.merge(block_opts) end def self.formatter_class(opts = {}) case formatter = opts[:formatter] when Class formatter when /\A[[:upper:]][[:alnum:]_]*\z/ ::Rouge::Formatters.const_get(formatter) else # Available in Rouge 2.0 or later ::Rouge::Formatters::HTMLLegacy end rescue NameError # Fallback to Rouge 1.x ::Rouge::Formatters::HTML end end end kramdown-1.17.0/lib/kramdown/converter/syntax_highlighter/coderay.rb0000644000004100000410000000513413321140127025725 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::SyntaxHighlighter # Uses Coderay to highlight code blocks and code spans. module Coderay begin require 'coderay' # Highlighting via coderay is available if this constant is +true+. AVAILABLE = true rescue LoadError AVAILABLE = false # :nodoc: end def self.call(converter, text, lang, type, call_opts) return nil unless converter.options[:enable_coderay] if type == :span && lang ::CodeRay.scan(text, lang.to_sym).html(options(converter, :span)).chomp elsif type == :block && (lang || options(converter, :default_lang)) lang ||= call_opts[:default_lang] = options(converter, :default_lang) ::CodeRay.scan(text, lang.to_s.gsub(/-/, '_').to_sym).html(options(converter, :block)).chomp << "\n" else nil end rescue converter.warning("There was an error using CodeRay: #{$!.message}") nil end def self.options(converter, type) prepare_options(converter) converter.data[:syntax_highlighter_coderay][type] end def self.prepare_options(converter) return if converter.data.key?(:syntax_highlighter_coderay) cache = converter.data[:syntax_highlighter_coderay] = {} opts = converter.options[:syntax_highlighter_opts].dup span_opts = (opts.delete(:span) || {}).dup block_opts = (opts.delete(:block) || {}).dup [span_opts, block_opts].each do |hash| hash.keys.each do |k| hash[k.kind_of?(String) ? Kramdown::Options.str_to_sym(k) : k] = hash.delete(k) end end cache[:default_lang] = converter.options[:coderay_default_lang] || opts.delete(:default_lang) cache[:span] = { :css => converter.options[:coderay_css] }.update(opts).update(span_opts).update(:wrap => :span) cache[:block] = { :wrap => converter.options[:coderay_wrap], :line_numbers => converter.options[:coderay_line_numbers], :line_number_start => converter.options[:coderay_line_number_start], :tab_width => converter.options[:coderay_tab_width], :bold_every => converter.options[:coderay_bold_every], :css => converter.options[:coderay_css] }.update(opts).update(block_opts) [:css, :wrap, :line_numbers].each do |key| [:block, :span].each do |type| cache[type][key] = cache[type][key].to_sym if cache[type][key].kind_of?(String) end end end end end kramdown-1.17.0/lib/kramdown/converter/syntax_highlighter/minted.rb0000644000004100000410000000156113321140127025557 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::SyntaxHighlighter # Uses Minted to highlight code blocks and code spans. module Minted def self.call(converter, text, lang, type, _opts) opts = converter.options[:syntax_highlighter_opts] # Fallback to default language lang ||= opts[:default_lang] options = [] options << "breaklines" if opts[:wrap] options << "linenos" if opts[:line_numbers] options << "frame=#{opts[:frame]}" if opts[:frame] if lang && type == :block "\\begin{minted}[#{options.join(',')}]{#{lang}}\n#{text}\n\\end{minted}" elsif lang && type == :span "\\mintinline{#{lang}}{#{text}}" else nil end end end end kramdown-1.17.0/lib/kramdown/converter/base.rb0000644000004100000410000002410013321140127021277 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'erb' require 'kramdown/utils' require 'kramdown/document' module Kramdown module Converter # == \Base class for converters # # This class serves as base class for all converters. It provides methods that can/should be # used by all converters (like #generate_id) as well as common functionality that is # automatically applied to the result (for example, embedding the output into a template). # # A converter object is used as a throw-away object, i.e. it is only used for storing the needed # state information during conversion. Therefore one can't instantiate a converter object # directly but only use the Base::convert method. # # == Implementing a converter # # Implementing a new converter is rather easy: just derive a new class from this class and put # it in the Kramdown::Converter module (the latter is only needed if auto-detection should work # properly). Then you need to implement the #convert method which has to contain the conversion # code for converting an element and has to return the conversion result. # # The actual transformation of the document tree can be done in any way. However, writing one # method per element type is a straight forward way to do it - this is how the Html and Latex # converters do the transformation. # # Have a look at the Base::convert method for additional information! class Base # Can be used by a converter for storing arbitrary information during the conversion process. attr_reader :data # The hash with the conversion options. attr_reader :options # The root element that is converted. attr_reader :root # The warnings array. attr_reader :warnings # Initialize the converter with the given +root+ element and +options+ hash. def initialize(root, options) @options = options @root = root @data = {} @warnings = [] end private_class_method(:new, :allocate) # Returns whether the template should be applied before the conversion of the tree. # # Defaults to false. def apply_template_before? false end # Returns whether the template should be applied after the conversion of the tree. # # Defaults to true. def apply_template_after? true end # Convert the element tree +tree+ and return the resulting conversion object (normally a # string) and an array with warning messages. The parameter +options+ specifies the conversion # options that should be used. # # Initializes a new instance of the calling class and then calls the #convert method with # +tree+ as parameter. # # If the +template+ option is specified and non-empty, the template is evaluate with ERB # before and/or after the tree conversion depending on the result of #apply_template_before? # and #apply_template_after?. If the template is evaluated before, an empty string is used for # the body; if evaluated after, the result is used as body. See ::apply_template. # # The template resolution is done in the following way (for the converter ConverterName): # # 1. Look in the current working directory for the template. # # 2. Append +.converter_name+ (e.g. +.html+) to the template name and look for the resulting # file in the current working directory (the form +.convertername+ is deprecated). # # 3. Append +.converter_name+ to the template name and look for it in the kramdown data # directory (the form +.convertername+ is deprecated). # # 4. Check if the template name starts with 'string://' and if so, strip this prefix away and # use the rest as template. def self.convert(tree, options = {}) converter = new(tree, ::Kramdown::Options.merge(options.merge(tree.options[:options] || {}))) apply_template(converter, '') if !converter.options[:template].empty? && converter.apply_template_before? result = converter.convert(tree) result.encode!(tree.options[:encoding]) if result.respond_to?(:encode!) && result.encoding != Encoding::BINARY result = apply_template(converter, result) if !converter.options[:template].empty? && converter.apply_template_after? [result, converter.warnings] end # Convert the element +el+ and return the resulting object. # # This is the only method that has to be implemented by sub-classes! def convert(el) raise NotImplementedError end # Apply the +template+ using +body+ as the body string. # # The template is evaluated using ERB and the body is available in the @body instance variable # and the converter object in the @converter instance variable. def self.apply_template(converter, body) # :nodoc: erb = ERB.new(get_template(converter.options[:template])) obj = Object.new obj.instance_variable_set(:@converter, converter) obj.instance_variable_set(:@body, body) erb.result(obj.instance_eval{binding}) end # Return the template specified by +template+. def self.get_template(template) #DEPRECATED: use content of #get_template_new in 2.0 format_ext = '.' + self.name.split(/::/).last.downcase shipped = File.join(::Kramdown.data_dir, template + format_ext) if File.exist?(template) File.read(template) elsif File.exist?(template + format_ext) File.read(template + format_ext) elsif File.exist?(shipped) File.read(shipped) elsif template.start_with?('string://') template.sub(/\Astring:\/\//, '') else get_template_new(template) end end def self.get_template_new(template) # :nodoc: format_ext = '.' + ::Kramdown::Utils.snake_case(self.name.split(/::/).last) shipped = File.join(::Kramdown.data_dir, template + format_ext) if File.exist?(template) File.read(template) elsif File.exist?(template + format_ext) File.read(template + format_ext) elsif File.exist?(shipped) File.read(shipped) elsif template.start_with?('string://') template.sub(/\Astring:\/\//, '') else raise "The specified template file #{template} does not exist" end end # Add the given warning +text+ to the warning array. def warning(text) @warnings << text end # Return +true+ if the header element +el+ should be used for the table of contents (as # specified by the +toc_levels+ option). def in_toc?(el) @options[:toc_levels].include?(el.options[:level]) && (el.attr['class'] || '') !~ /\bno_toc\b/ end # Return the output header level given a level. # # Uses the +header_offset+ option for adjusting the header level. def output_header_level(level) [[level + @options[:header_offset], 6].min, 1].max end # Extract the code block/span language from the attributes. def extract_code_language(attr) if attr['class'] && attr['class'] =~ /\blanguage-\S+/ attr['class'].scan(/\blanguage-(\S+)/).first.first end end # See #extract_code_language # # *Warning*: This version will modify the given attributes if a language is present. def extract_code_language!(attr) lang = extract_code_language(attr) attr['class'] = attr['class'].sub(/\blanguage-\S+/, '').strip if lang attr.delete('class') if lang && attr['class'].empty? lang end # Highlight the given +text+ in the language +lang+ with the syntax highlighter configured # through the option 'syntax_highlighter'. def highlight_code(text, lang, type, opts = {}) return nil unless @options[:syntax_highlighter] highlighter = ::Kramdown::Converter.syntax_highlighter(@options[:syntax_highlighter]) if highlighter highlighter.call(self, text, lang, type, opts) else warning("The configured syntax highlighter #{@options[:syntax_highlighter]} is not available.") nil end end # Format the given math element with the math engine configured through the option # 'math_engine'. def format_math(el, opts = {}) return nil unless @options[:math_engine] engine = ::Kramdown::Converter.math_engine(@options[:math_engine]) if engine engine.call(self, el, opts) else warning("The configured math engine #{@options[:math_engine]} is not available.") nil end end # Generate an unique alpha-numeric ID from the the string +str+ for use as a header ID. # # Uses the option +auto_id_prefix+: the value of this option is prepended to every generated # ID. def generate_id(str) str = ::Kramdown::Utils::Unidecoder.decode(str) if @options[:transliterated_header_ids] gen_id = basic_generate_id(str) gen_id = 'section' if gen_id.length == 0 @used_ids ||= {} if @used_ids.has_key?(gen_id) gen_id += '-' << (@used_ids[gen_id] += 1).to_s else @used_ids[gen_id] = 0 end @options[:auto_id_prefix] + gen_id end # The basic version of the ID generator, without any special provisions for empty or unique # IDs. def basic_generate_id(str) gen_id = str.gsub(/^[^a-zA-Z]+/, '') gen_id.tr!('^a-zA-Z0-9 -', '') gen_id.tr!(' ', '-') gen_id.downcase! gen_id end SMART_QUOTE_INDICES = {:lsquo => 0, :rsquo => 1, :ldquo => 2, :rdquo => 3} # :nodoc: # Return the entity that represents the given smart_quote element. def smart_quote_entity(el) res = @options[:smart_quotes][SMART_QUOTE_INDICES[el.value]] ::Kramdown::Utils::Entities.entity(res) end end end end kramdown-1.17.0/lib/kramdown/converter/latex.rb0000644000004100000410000004627613321140127021524 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'set' require 'kramdown/converter' module Kramdown module Converter # Converts an element tree to LaTeX. # # This converter uses ideas from other Markdown-to-LaTeX converters like Pandoc and Maruku. # # You can customize this converter by sub-classing it and overriding the +convert_NAME+ methods. # Each such method takes the following parameters: # # [+el+] The element of type +NAME+ to be converted. # # [+opts+] A hash containing processing options that are passed down from parent elements. The # key :parent is always set and contains the parent element as value. # # The return value of such a method has to be a string containing the element +el+ formatted # correctly as LaTeX markup. class Latex < Base # Initialize the LaTeX converter with the +root+ element and the conversion +options+. def initialize(root, options) super @data[:packages] = Set.new end # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of # the element. def convert(el, opts = {}) send("convert_#{el.type}", el, opts) end # Return the converted content of the children of +el+ as a string. def inner(el, opts) result = '' options = opts.dup.merge(:parent => el) el.children.each_with_index do |inner_el, index| options[:index] = index options[:result] = result result << send("convert_#{inner_el.type}", inner_el, options) end result end def convert_root(el, opts) inner(el, opts) end def convert_blank(el, opts) opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n" end def convert_text(el, opts) escape(el.value) end def convert_p(el, opts) if el.children.size == 1 && el.children.first.type == :img && !(img = convert_img(el.children.first, opts)).empty? convert_standalone_image(el, opts, img) else "#{latex_link_target(el)}#{inner(el, opts)}\n\n" end end # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img # element. def convert_standalone_image(el, opts, img) attrs = attribute_list(el) "\\begin{figure}#{attrs}\n\\begin{center}\n#{img}\n\\end{center}\n\\caption{#{escape(el.children.first.attr['alt'])}}\n#{latex_link_target(el, true)}\n\\end{figure}#{attrs}\n" end def convert_codeblock(el, opts) show_whitespace = el.attr['class'].to_s =~ /\bshow-whitespaces\b/ lang = extract_code_language(el.attr) if @options[:syntax_highlighter] == :minted && (highlighted_code = highlight_code(el.value, lang, :block)) @data[:packages] << 'minted' "#{latex_link_target(el)}#{highlighted_code}\n" elsif show_whitespace || lang options = [] options << "showspaces=%s,showtabs=%s" % (show_whitespace ? ['true', 'true'] : ['false', 'false']) options << "language=#{lang}" if lang options << "basicstyle=\\ttfamily\\footnotesize,columns=fixed,frame=tlbr" id = el.attr['id'] options << "label=#{id}" if id attrs = attribute_list(el) "#{latex_link_target(el)}\\begin{lstlisting}[#{options.join(',')}]\n#{el.value}\n\\end{lstlisting}#{attrs}\n" else "#{latex_link_target(el)}\\begin{verbatim}#{el.value}\\end{verbatim}\n" end end def convert_blockquote(el, opts) latex_environment(el.children.size > 1 ? 'quotation' : 'quote', el, inner(el, opts)) end def convert_header(el, opts) type = @options[:latex_headers][output_header_level(el.options[:level]) - 1] if ((id = el.attr['id']) || (@options[:auto_ids] && (id = generate_id(el.options[:raw_text])))) && in_toc?(el) "\\#{type}{#{inner(el, opts)}}\\hypertarget{#{id}}{}\\label{#{id}}\n\n" else "\\#{type}*{#{inner(el, opts)}}\n\n" end end def convert_hr(el, opts) attrs = attribute_list(el) "#{latex_link_target(el)}\\begin{center}#{attrs}\n\\rule{3in}{0.4pt}\n\\end{center}#{attrs}\n" end def convert_ul(el, opts) if !@data[:has_toc] && (el.options[:ial][:refs].include?('toc') rescue nil) @data[:has_toc] = true '\tableofcontents' else latex_environment(el.type == :ul ? 'itemize' : 'enumerate', el, inner(el, opts)) end end alias :convert_ol :convert_ul def convert_dl(el, opts) latex_environment('description', el, inner(el, opts)) end def convert_li(el, opts) "\\item{} #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n" end def convert_dt(el, opts) "\\item[#{inner(el, opts)}] " end def convert_dd(el, opts) "#{latex_link_target(el)}#{inner(el, opts)}\n\n" end def convert_html_element(el, opts) if el.value == 'i' || el.value == 'em' "\\emph{#{inner(el, opts)}}" elsif el.value == 'b' || el.value == 'strong' "\\textbf{#{inner(el, opts)}}" else warning("Can't convert HTML element") '' end end def convert_xml_comment(el, opts) el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n" end def convert_xml_pi(el, opts) warning("Can't convert XML PI") '' end TABLE_ALIGNMENT_CHAR = {:default => 'l', :left => 'l', :center => 'c', :right => 'r'} # :nodoc: def convert_table(el, opts) @data[:packages] << 'longtable' align = el.options[:alignment].map {|a| TABLE_ALIGNMENT_CHAR[a]}.join('|') attrs = attribute_list(el) "#{latex_link_target(el)}\\begin{longtable}{|#{align}|}#{attrs}\n\\hline\n#{inner(el, opts)}\\hline\n\\end{longtable}#{attrs}\n\n" end def convert_thead(el, opts) "#{inner(el, opts)}\\hline\n" end def convert_tbody(el, opts) inner(el, opts) end def convert_tfoot(el, opts) "\\hline \\hline \n#{inner(el, opts)}" end def convert_tr(el, opts) el.children.map {|c| send("convert_#{c.type}", c, opts)}.join(' & ') << "\\\\\n" end def convert_td(el, opts) inner(el, opts) end def convert_comment(el, opts) el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") << "\n" end def convert_br(el, opts) res = "\\newline" res << "\n" if (c = opts[:parent].children[opts[:index]+1]) && (c.type != :text || c.value !~ /^\s*\n/) res end def convert_a(el, opts) url = el.attr['href'] if url.start_with?('#') "\\hyperlink{#{url[1..-1].gsub('%', "\\%")}}{#{inner(el, opts)}}" else "\\href{#{url.gsub('%', "\\%")}}{#{inner(el, opts)}}" end end def convert_img(el, opts) line = el.options[:location] if el.attr['src'] =~ /^(https?|ftps?):\/\// warning("Cannot include non-local image#{line ? " (line #{line})" : ''}") '' elsif !el.attr['src'].empty? @data[:packages] << 'graphicx' "#{latex_link_target(el)}\\includegraphics{#{el.attr['src']}}" else warning("Cannot include image with empty path#{line ? " (line #{line})" : ''}") '' end end def convert_codespan(el, opts) lang = extract_code_language(el.attr) if @options[:syntax_highlighter] == :minted && (highlighted_code = highlight_code(el.value, lang, :span)) @data[:packages] << 'minted' "#{latex_link_target(el)}#{highlighted_code}" else "\\texttt{#{latex_link_target(el)}#{escape(el.value)}}" end end def convert_footnote(el, opts) @data[:packages] << 'fancyvrb' "\\footnote{#{inner(el.value, opts).rstrip}}" end def convert_raw(el, opts) if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('latex') el.value + (el.options[:category] == :block ? "\n" : '') else '' end end def convert_em(el, opts) "\\emph{#{latex_link_target(el)}#{inner(el, opts)}}" end def convert_strong(el, opts) "\\textbf{#{latex_link_target(el)}#{inner(el, opts)}}" end # Inspired by Maruku: entity conversion table based on the one from htmltolatex # (http://sourceforge.net/projects/htmltolatex/), with some small adjustments/additions ENTITY_CONV_TABLE = { 913 => ['$A$'], 914 => ['$B$'], 915 => ['$\Gamma$'], 916 => ['$\Delta$'], 917 => ['$E$'], 918 => ['$Z$'], 919 => ['$H$'], 920 => ['$\Theta$'], 921 => ['$I$'], 922 => ['$K$'], 923 => ['$\Lambda$'], 924 => ['$M$'], 925 => ['$N$'], 926 => ['$\Xi$'], 927 => ['$O$'], 928 => ['$\Pi$'], 929 => ['$P$'], 931 => ['$\Sigma$'], 932 => ['$T$'], 933 => ['$Y$'], 934 => ['$\Phi$'], 935 => ['$X$'], 936 => ['$\Psi$'], 937 => ['$\Omega$'], 945 => ['$\alpha$'], 946 => ['$\beta$'], 947 => ['$\gamma$'], 948 => ['$\delta$'], 949 => ['$\epsilon$'], 950 => ['$\zeta$'], 951 => ['$\eta$'], 952 => ['$\theta$'], 953 => ['$\iota$'], 954 => ['$\kappa$'], 955 => ['$\lambda$'], 956 => ['$\mu$'], 957 => ['$\nu$'], 958 => ['$\xi$'], 959 => ['$o$'], 960 => ['$\pi$'], 961 => ['$\rho$'], 963 => ['$\sigma$'], 964 => ['$\tau$'], 965 => ['$\upsilon$'], 966 => ['$\phi$'], 967 => ['$\chi$'], 968 => ['$\psi$'], 969 => ['$\omega$'], 962 => ['$\varsigma$'], 977 => ['$\vartheta$'], 982 => ['$\varpi$'], 8230 => ['\ldots'], 8242 => ['$\prime$'], 8254 => ['-'], 8260 => ['/'], 8472 => ['$\wp$'], 8465 => ['$\Im$'], 8476 => ['$\Re$'], 8501 => ['$\aleph$'], 8226 => ['$\bullet$'], 8482 => ['$^{\rm TM}$'], 8592 => ['$\leftarrow$'], 8594 => ['$\rightarrow$'], 8593 => ['$\uparrow$'], 8595 => ['$\downarrow$'], 8596 => ['$\leftrightarrow$'], 8629 => ['$\hookleftarrow$'], 8657 => ['$\Uparrow$'], 8659 => ['$\Downarrow$'], 8656 => ['$\Leftarrow$'], 8658 => ['$\Rightarrow$'], 8660 => ['$\Leftrightarrow$'], 8704 => ['$\forall$'], 8706 => ['$\partial$'], 8707 => ['$\exists$'], 8709 => ['$\emptyset$'], 8711 => ['$\nabla$'], 8712 => ['$\in$'], 8715 => ['$\ni$'], 8713 => ['$\notin$'], 8721 => ['$\sum$'], 8719 => ['$\prod$'], 8722 => ['$-$'], 8727 => ['$\ast$'], 8730 => ['$\surd$'], 8733 => ['$\propto$'], 8734 => ['$\infty$'], 8736 => ['$\angle$'], 8743 => ['$\wedge$'], 8744 => ['$\vee$'], 8745 => ['$\cap$'], 8746 => ['$\cup$'], 8747 => ['$\int$'], 8756 => ['$\therefore$', 'amssymb'], 8764 => ['$\sim$'], 8776 => ['$\approx$'], 8773 => ['$\cong$'], 8800 => ['$\neq$'], 8801 => ['$\equiv$'], 8804 => ['$\leq$'], 8805 => ['$\geq$'], 8834 => ['$\subset$'], 8835 => ['$\supset$'], 8838 => ['$\subseteq$'], 8839 => ['$\supseteq$'], 8836 => ['$\nsubset$', 'amssymb'], 8853 => ['$\oplus$'], 8855 => ['$\otimes$'], 8869 => ['$\perp$'], 8901 => ['$\cdot$'], 8968 => ['$\rceil$'], 8969 => ['$\lceil$'], 8970 => ['$\lfloor$'], 8971 => ['$\rfloor$'], 9001 => ['$\rangle$'], 9002 => ['$\langle$'], 9674 => ['$\lozenge$', 'amssymb'], 9824 => ['$\spadesuit$'], 9827 => ['$\clubsuit$'], 9829 => ['$\heartsuit$'], 9830 => ['$\diamondsuit$'], 38 => ['\&'], 34 => ['"'], 39 => ['\''], 169 => ['\copyright'], 60 => ['\textless'], 62 => ['\textgreater'], 338 => ['\OE'], 339 => ['\oe'], 352 => ['\v{S}'], 353 => ['\v{s}'], 376 => ['\"Y'], 710 => ['\textasciicircum'], 732 => ['\textasciitilde'], 8211 => ['--'], 8212 => ['---'], 8216 => ['`'], 8217 => ['\''], 8220 => ['``'], 8221 => ['\'\''], 8224 => ['\dag'], 8225 => ['\ddag'], 8240 => ['\permil', 'wasysym'], 8364 => ['\euro', 'eurosym'], 8249 => ['\guilsinglleft'], 8250 => ['\guilsinglright'], 8218 => ['\quotesinglbase', 'mathcomp'], 8222 => ['\quotedblbase', 'mathcomp'], 402 => ['\textflorin', 'mathcomp'], 381 => ['\v{Z}'], 382 => ['\v{z}'], 160 => ['~'], 161 => ['\textexclamdown'], 163 => ['\pounds'], 164 => ['\currency', 'wasysym'], 165 => ['\textyen', 'textcomp'], 166 => ['\brokenvert', 'wasysym'], 167 => ['\S'], 171 => ['\guillemotleft'], 187 => ['\guillemotright'], 174 => ['\textregistered'], 170 => ['\textordfeminine'], 172 => ['$\neg$'], 173 => ['\-'], 176 => ['$\degree$', 'mathabx'], 177 => ['$\pm$'], 180 => ['\''], 181 => ['$\mu$'], 182 => ['\P'], 183 => ['$\cdot$'], 186 => ['\textordmasculine'], 162 => ['\cent', 'wasysym'], 185 => ['$^1$'], 178 => ['$^2$'], 179 => ['$^3$'], 189 => ['$\frac{1}{2}$'], 188 => ['$\frac{1}{4}$'], 190 => ['$\frac{3}{4}'], 192 => ['\`A'], 193 => ['\\\'A'], 194 => ['\^A'], 195 => ['\~A'], 196 => ['\"A'], 197 => ['\AA'], 198 => ['\AE'], 199 => ['\cC'], 200 => ['\`E'], 201 => ['\\\'E'], 202 => ['\^E'], 203 => ['\"E'], 204 => ['\`I'], 205 => ['\\\'I'], 206 => ['\^I'], 207 => ['\"I'], 208 => ['$\eth$', 'amssymb'], 209 => ['\~N'], 210 => ['\`O'], 211 => ['\\\'O'], 212 => ['\^O'], 213 => ['\~O'], 214 => ['\"O'], 215 => ['$\times$'], 216 => ['\O'], 217 => ['\`U'], 218 => ['\\\'U'], 219 => ['\^U'], 220 => ['\"U'], 221 => ['\\\'Y'], 222 => ['\Thorn', 'wasysym'], 223 => ['\ss'], 224 => ['\`a'], 225 => ['\\\'a'], 226 => ['\^a'], 227 => ['\~a'], 228 => ['\"a'], 229 => ['\aa'], 230 => ['\ae'], 231 => ['\cc'], 232 => ['\`e'], 233 => ['\\\'e'], 234 => ['\^e'], 235 => ['\"e'], 236 => ['\`i'], 237 => ['\\\'i'], 238 => ['\^i'], 239 => ['\"i'], 240 => ['$\eth$'], 241 => ['\~n'], 242 => ['\`o'], 243 => ['\\\'o'], 244 => ['\^o'], 245 => ['\~o'], 246 => ['\"o'], 247 => ['$\divide$'], 248 => ['\o'], 249 => ['\`u'], 250 => ['\\\'u'], 251 => ['\^u'], 252 => ['\"u'], 253 => ['\\\'y'], 254 => ['\thorn', 'wasysym'], 255 => ['\"y'], 8201 => ['\thinspace'], 8194 => ['\hskip .5em\relax'], 8195 => ['\quad'], } # :nodoc: ENTITY_CONV_TABLE.each {|k,v| ENTITY_CONV_TABLE[k][0].insert(-1, '{}')} def entity_to_latex(entity) text, package = ENTITY_CONV_TABLE[entity.code_point] if text @data[:packages] << package if package text else warning("Couldn't find entity with code #{entity.code_point} in substitution table!") '' end end def convert_entity(el, opts) entity_to_latex(el.value) end TYPOGRAPHIC_SYMS = { :mdash => '---', :ndash => '--', :hellip => '\ldots{}', :laquo_space => '\guillemotleft{}~', :raquo_space => '~\guillemotright{}', :laquo => '\guillemotleft{}', :raquo => '\guillemotright{}' } # :nodoc: def convert_typographic_sym(el, opts) if (result = @options[:typographic_symbols][el.value]) escape(result) else TYPOGRAPHIC_SYMS[el.value] end end def convert_smart_quote(el, opts) res = entity_to_latex(smart_quote_entity(el)).chomp('{}') res << "{}" if ((nel = opts[:parent].children[opts[:index]+1]) && nel.type == :smart_quote) || res =~ /\w$/ res end def convert_math(el, opts) @data[:packages] += %w[amssymb amsmath amsthm amsfonts] if el.options[:category] == :block if el.value =~ /\A\s*\\begin\{/ el.value else latex_environment('displaymath', el, el.value) end else "$#{el.value}$" end end def convert_abbreviation(el, opts) @data[:packages] += %w[acronym] "\\ac{#{normalize_abbreviation_key(el.value)}}" end # Normalize the abbreviation key so that it only contains allowed ASCII character def normalize_abbreviation_key(key) key.gsub(/\W/) {|m| m.unpack('H*').first} end # Wrap the +text+ inside a LaTeX environment of type +type+. The element +el+ is passed on to # the method #attribute_list -- the resulting string is appended to both the \\begin and the # \\end lines of the LaTeX environment for easier post-processing of LaTeX environments. def latex_environment(type, el, text) attrs = attribute_list(el) "\\begin{#{type}}#{latex_link_target(el)}#{attrs}\n#{text.rstrip}\n\\end{#{type}}#{attrs}\n" end # Return a string containing a valid \hypertarget command if the element has an ID defined, or # +nil+ otherwise. If the parameter +add_label+ is +true+, a \label command will also be used # additionally to the \hypertarget command. def latex_link_target(el, add_label = false) if (id = el.attr['id']) "\\hypertarget{#{id}}{}" << (add_label ? "\\label{#{id}}" : '') else nil end end # Return a LaTeX comment containing all attributes as 'key="value"' pairs. def attribute_list(el) attrs = el.attr.map {|k,v| v.nil? ? '' : " #{k}=\"#{v.to_s}\""}.compact.sort.join('') attrs = " % #{attrs}" if !attrs.empty? attrs end ESCAPE_MAP = { "^" => "\\^{}", "\\" => "\\textbackslash{}", "~" => "\\ensuremath{\\sim}", "|" => "\\textbar{}", "<" => "\\textless{}", ">" => "\\textgreater{}", "[" => "{[}", "]" => "{]}", }.merge(Hash[*("{}$%&_#".scan(/./).map {|c| [c, "\\#{c}"]}.flatten)]) # :nodoc: ESCAPE_RE = Regexp.union(*ESCAPE_MAP.collect {|k,v| k}) # :nodoc: # Escape the special LaTeX characters in the string +str+. def escape(str) str.gsub(ESCAPE_RE) {|m| ESCAPE_MAP[m]} end end end end kramdown-1.17.0/lib/kramdown/converter/hash_ast.rb0000644000004100000410000000150513321140127022163 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser' require 'kramdown/converter' require 'kramdown/utils' module Kramdown module Converter # Converts a Kramdown::Document to a nested hash for further processing or debug output. class HashAST < Base def convert(el) hash = {:type => el.type} hash[:attr] = el.attr unless el.attr.empty? hash[:value] = el.value unless el.value.nil? hash[:options] = el.options unless el.options.empty? unless el.children.empty? hash[:children] = [] el.children.each {|child| hash[:children] << convert(child)} end hash end end HashAst = HashAST end end kramdown-1.17.0/lib/kramdown/converter/pdf.rb0000644000004100000410000004477013321140127021155 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'prawn' require 'prawn/table' require 'kramdown/converter' require 'kramdown/utils' require 'open-uri' module Kramdown module Converter # Converts an element tree to a PDF using the prawn PDF library. # # This basic version provides a nice starting point for customizations but can also be used # directly. # # There can be the following two methods for each element type: render_TYPE(el, opts) and # TYPE_options(el, opts) where +el+ is a kramdown element and +opts+ an hash with rendering # options. # # The render_TYPE(el, opts) is used for rendering the specific element. If the element is a span # element, it should return a hash or an array of hashes that can be used by the #formatted_text # method of Prawn::Document. This method can then be used in block elements to actually render # the span elements. # # The rendering options are passed from the parent to its child elements. This allows one to # define general options at the top of the tree (the root element) that can later be changed or # amended. # # # Currently supports the conversion of all elements except those of the following types: # # :html_element, :img, :footnote # # class Pdf < Base include Prawn::Measurements def initialize(root, options) super @stack = [] @dests = {} end # PDF templates are applied before conversion. They should contain code to augment the # converter object (i.e. to override the methods). def apply_template_before? true end # Returns +false+. def apply_template_after? false end DISPATCHER_RENDER = Hash.new {|h,k| h[k] = "render_#{k}"} #:nodoc: DISPATCHER_OPTIONS = Hash.new {|h,k| h[k] = "#{k}_options"} #:nodoc: # Invoke the special rendering method for the given element +el+. # # A PDF destination is also added at the current location if th element has an ID or if the # element is of type :header and the :auto_ids option is set. def convert(el, opts = {}) id = el.attr['id'] id = generate_id(el.options[:raw_text]) if !id && @options[:auto_ids] && el.type == :header if !id.to_s.empty? && !@dests.has_key?(id) @pdf.add_dest(id, @pdf.dest_xyz(0, @pdf.y)) @dests[id] = @pdf.dest_xyz(0, @pdf.y) end send(DISPATCHER_RENDER[el.type], el, opts) end protected # Render the children of this element with the given options and return the results as array. # # Each time a child is rendered, the +TYPE_options+ method is invoked (if it exists) to get # the specific options for the element with which the given options are updated. def inner(el, opts) @stack.push([el, opts]) result = el.children.map do |inner_el| options = opts.dup options.update(send(DISPATCHER_OPTIONS[inner_el.type], inner_el, options)) convert(inner_el, options) end.flatten.compact @stack.pop result end # ---------------------------- # :section: Element rendering methods # ---------------------------- def root_options(root, opts) {:font => 'Times-Roman', :size => 12, :leading => 2} end def render_root(root, opts) @pdf = setup_document(root) inner(root, root_options(root, opts)) create_outline(root) finish_document(root) @pdf.render end def header_options(el, opts) size = opts[:size] * 1.15**(6 - el.options[:level]) { :font => "Helvetica", :styles => (opts[:styles] || []) + [:bold], :size => size, :bottom_padding => opts[:size], :top_padding => opts[:size] } end def render_header(el, opts) render_padded_and_formatted_text(el, opts) end def p_options(el, opts) bpad = (el.options[:transparent] ? opts[:leading] : opts[:size]) {:align => :justify, :bottom_padding => bpad} end def render_p(el, opts) if el.children.size == 1 && el.children.first.type == :img render_standalone_image(el, opts) else render_padded_and_formatted_text(el, opts) end end def render_standalone_image(el, opts) img = el.children.first line = img.options[:location] if img.attr['src'].empty? warning("Rendering an image without a source is not possible#{line ? " (line #{line})" : ''}") return nil elsif img.attr['src'] !~ /\.jpe?g$|\.png$/ warning("Cannot render images other than JPEG or PNG, got #{img.attr['src']}#{line ? " on line #{line}" : ''}") return nil end img_dirs = (@options[:image_directories] || ['.']).dup begin img_path = File.join(img_dirs.shift, img.attr['src']) image_obj, image_info = @pdf.build_image_object(open(img_path)) rescue img_dirs.empty? ? raise : retry end options = {:position => :center} if img.attr['height'] && img.attr['height'] =~ /px$/ options[:height] = img.attr['height'].to_i / (@options[:image_dpi] || 150.0) * 72 elsif img.attr['width'] && img.attr['width'] =~ /px$/ options[:width] = img.attr['width'].to_i / (@options[:image_dpi] || 150.0) * 72 else options[:scale] =[(@pdf.bounds.width - mm2pt(20)) / image_info.width.to_f, 1].min end if img.attr['class'] =~ /\bright\b/ options[:position] = :right @pdf.float { @pdf.embed_image(image_obj, image_info, options) } else with_block_padding(el, opts) do @pdf.embed_image(image_obj, image_info, options) end end end def blockquote_options(el, opts) {:styles => [:italic]} end def render_blockquote(el, opts) @pdf.indent(mm2pt(10), mm2pt(10)) { inner(el, opts) } end def ul_options(el, opts) {:bottom_padding => opts[:size]} end def render_ul(el, opts) with_block_padding(el, opts) do el.children.each do |li| @pdf.float { @pdf.formatted_text([text_hash("•", opts)]) } @pdf.indent(mm2pt(6)) { convert(li, opts) } end end end def ol_options(el, opts) {:bottom_padding => opts[:size]} end def render_ol(el, opts) with_block_padding(el, opts) do el.children.each_with_index do |li, index| @pdf.float { @pdf.formatted_text([text_hash("#{index+1}.", opts)]) } @pdf.indent(mm2pt(6)) { convert(li, opts) } end end end def li_options(el, opts) {} end def render_li(el, opts) inner(el, opts) end def dl_options(el, opts) {} end def render_dl(el, opts) inner(el, opts) end def dt_options(el, opts) {:styles => (opts[:styles] || []) + [:bold], :bottom_padding => 0} end def render_dt(el, opts) render_padded_and_formatted_text(el, opts) end def dd_options(el, opts) {} end def render_dd(el, opts) @pdf.indent(mm2pt(10)) { inner(el, opts) } end def math_options(el, opts) {} end def render_math(el, opts) if el.options[:category] == :block @pdf.formatted_text([{:text => el.value}], block_hash(opts)) else {:text => el.value} end end def hr_options(el, opts) {:top_padding => opts[:size], :bottom_padding => opts[:size]} end def render_hr(el, opts) with_block_padding(el, opts) do @pdf.stroke_horizontal_line(@pdf.bounds.left + mm2pt(5), @pdf.bounds.right - mm2pt(5)) end end def codeblock_options(el, opts) { :font => 'Courier', :color => '880000', :bottom_padding => opts[:size] } end def render_codeblock(el, opts) with_block_padding(el, opts) do @pdf.formatted_text([text_hash(el.value, opts, false)], block_hash(opts)) end end def table_options(el, opts) {:bottom_padding => opts[:size]} end def render_table(el, opts) data = [] el.children.each do |container| container.children.each do |row| data << [] row.children.each do |cell| if cell.children.any? {|child| child.options[:category] == :block} line = el.options[:location] warning("Can't render tables with cells containing block elements#{line ? " (line #{line})" : ''}") return end cell_data = inner(cell, opts) data.last << cell_data.map {|c| c[:text]}.join('') end end end with_block_padding(el, opts) do @pdf.table(data, :width => @pdf.bounds.right) do el.options[:alignment].each_with_index do |alignment, index| columns(index).align = alignment unless alignment == :default end end end end def text_options(el, opts) {} end def render_text(el, opts) text_hash(el.value.to_s, opts) end def em_options(el, opts) if opts[:styles] && opts[:styles].include?(:italic) {:styles => opts[:styles].reject {|i| i == :italic}} else {:styles => (opts[:styles] || []) << :italic} end end def strong_options(el, opts) {:styles => (opts[:styles] || []) + [:bold]} end def a_options(el, opts) hash = {:color => '000088'} if el.attr['href'].start_with?('#') hash[:anchor] = el.attr['href'].sub(/\A#/, '') else hash[:link] = el.attr['href'] end hash end def render_em(el, opts) inner(el, opts) end alias_method :render_strong, :render_em alias_method :render_a, :render_em def codespan_options(el, opts) {:font => 'Courier', :color => '880000'} end def render_codespan(el, opts) text_hash(el.value, opts) end def br_options(el, opts) {} end def render_br(el, opts) text_hash("\n", opts, false) end def smart_quote_options(el, opts) {} end def render_smart_quote(el, opts) text_hash(smart_quote_entity(el).char, opts) end def typographic_sym_options(el, opts) {} end def render_typographic_sym(el, opts) str = if el.value == :laquo_space ::Kramdown::Utils::Entities.entity('laquo').char + ::Kramdown::Utils::Entities.entity('nbsp').char elsif el.value == :raquo_space ::Kramdown::Utils::Entities.entity('raquo').char + ::Kramdown::Utils::Entities.entity('nbsp').char else ::Kramdown::Utils::Entities.entity(el.value.to_s).char end text_hash(str, opts) end def entity_options(el, opts) {} end def render_entity(el, opts) text_hash(el.value.char, opts) end def abbreviation_options(el, opts) {} end def render_abbreviation(el, opts) text_hash(el.value, opts) end def img_options(el, opts) {} end def render_img(el, *args) #:nodoc: line = el.options[:location] warning("Rendering span images is not supported for PDF converter#{line ? " (line #{line})" : ''}") nil end def xml_comment_options(el, opts) #:nodoc: {} end alias_method :xml_pi_options, :xml_comment_options alias_method :comment_options, :xml_comment_options alias_method :blank_options, :xml_comment_options alias_method :footnote_options, :xml_comment_options alias_method :raw_options, :xml_comment_options alias_method :html_element_options, :xml_comment_options def render_xml_comment(el, opts) #:nodoc: # noop end alias_method :render_xml_pi, :render_xml_comment alias_method :render_comment, :render_xml_comment alias_method :render_blank, :render_xml_comment def render_footnote(el, *args) #:nodoc: line = el.options[:location] warning("Rendering #{el.type} not supported for PDF converter#{line ? " (line #{line})" : ''}") nil end alias_method :render_raw, :render_footnote alias_method :render_html_element, :render_footnote # ---------------------------- # :section: Organizational methods # # These methods are used, for example, to up the needed Prawn::Document instance or to create # a PDF outline. # ---------------------------- # This module gets mixed into the Prawn::Document instance. module PrawnDocumentExtension # Extension for the formatted box class to recognize images and move text around them. module CustomBox def available_width return super unless @document.respond_to?(:converter) && @document.converter @document.image_floats.each do |pn, x, y, w, h| next if @document.page_number != pn if @at[1] + @baseline_y <= y - @document.bounds.absolute_bottom && (@at[1] + @baseline_y + @arranger.max_line_height + @leading >= y - h - @document.bounds.absolute_bottom) return @width - w end end return super end end Prawn::Text::Formatted::Box.extensions << CustomBox # Access the converter instance from within Prawn attr_accessor :converter def image_floats @image_floats ||= [] end # Override image embedding method for adding image positions to #image_floats. def embed_image(pdf_obj, info, options) # find where the image will be placed and how big it will be w,h = info.calc_image_dimensions(options) if options[:at] x,y = map_to_absolute(options[:at]) else x,y = image_position(w,h,options) move_text_position h end #--> This part is new if options[:position] == :right image_floats << [page_number, x - 15, y, w + 15, h + 15] end # add a reference to the image object to the current page # resource list and give it a label label = "I#{next_image_id}" state.page.xobjects.merge!(label => pdf_obj) # add the image to the current page instruct = "\nq\n%.3f 0 0 %.3f %.3f %.3f cm\n/%s Do\nQ" add_content instruct % [ w, h, x, y - h, label ] end end # Return a hash with options that are suitable for Prawn::Document.new. # # Used in #setup_document. def document_options(root) { :page_size => 'A4', :page_layout => :portrait, :margin => mm2pt(20), :info => { :Creator => 'kramdown PDF converter', :CreationDate => Time.now }, :compress => true, :optimize_objects => true } end # Create a Prawn::Document object and return it. # # Can be used to define repeatable content or register fonts. # # Used in #render_root. def setup_document(root) doc = Prawn::Document.new(document_options(root)) doc.extend(PrawnDocumentExtension) doc.converter = self doc end # # # Used in #render_root. def finish_document(root) # no op end # Create the PDF outline from the header elements in the TOC. def create_outline(root) toc = ::Kramdown::Converter::Toc.convert(root).first text_of_header = lambda do |el| if el.type == :text el.value else el.children.map {|c| text_of_header.call(c)}.join('') end end add_section = lambda do |item, parent| text = text_of_header.call(item.value) destination = @dests[item.attr[:id]] if !parent @pdf.outline.page(:title => text, :destination => destination) else @pdf.outline.add_subsection_to(parent) do @pdf.outline.page(:title => text, :destination => destination) end end item.children.each {|c| add_section.call(c, text)} end toc.children.each do |item| add_section.call(item, nil) end end # ---------------------------- # :section: Helper methods # ---------------------------- # Move the prawn document cursor down before and/or after yielding the given block. # # The :top_padding and :bottom_padding options are used for determinig the padding amount. def with_block_padding(el, opts) @pdf.move_down(opts[:top_padding]) if opts.has_key?(:top_padding) yield @pdf.move_down(opts[:bottom_padding]) if opts.has_key?(:bottom_padding) end # Render the children of the given element as formatted text and respect the top/bottom # padding (see #with_block_padding). def render_padded_and_formatted_text(el, opts) with_block_padding(el, opts) { @pdf.formatted_text(inner(el, opts), block_hash(opts)) } end # Helper function that returns a hash with valid "formatted text" options. # # The +text+ parameter is used as value for the :text key and if +squeeze_whitespace+ is # +true+, all whitespace is converted into spaces. def text_hash(text, opts, squeeze_whitespace = true) text = text.gsub(/\s+/, ' ') if squeeze_whitespace hash = {:text => text} [:styles, :size, :character_spacing, :font, :color, :link, :anchor, :draw_text_callback, :callback].each do |key| hash[key] = opts[key] if opts.has_key?(key) end hash end # Helper function that returns a hash with valid options for the prawn #text_box extracted # from the given options. def block_hash(opts) hash = {} [:align, :valign, :mode, :final_gap, :leading, :fallback_fonts, :direction, :indent_paragraphs].each do |key| hash[key] = opts[key] if opts.has_key?(key) end hash end end end end kramdown-1.17.0/lib/kramdown/converter/toc.rb0000644000004100000410000000347213321140127021163 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/converter' module Kramdown module Converter # Converts a Kramdown::Document to an element tree that represents the table of contents. # # The returned tree consists of Element objects of type :toc where the root element is just used # as container object. Each :toc element contains as value the wrapped :header element and under # the attribute key :id the header ID that should be used (note that this ID may not exist in # the wrapped element). # # Since the TOC tree consists of special :toc elements, one cannot directly feed this tree to # other converters! class Toc < Base def initialize(root, options) super @toc = Element.new(:toc) @stack = [] @options[:template] = '' end def convert(el) if el.type == :header && in_toc?(el) attr = el.attr.dup attr['id'] = generate_id(el.options[:raw_text]) if @options[:auto_ids] && !attr['id'] add_to_toc(el, attr['id']) if attr['id'] else el.children.each {|child| convert(child)} end @toc end private def add_to_toc(el, id) toc_element = Element.new(:toc, el, :id => id) success = false while !success if @stack.empty? @toc.children << toc_element @stack << toc_element success = true elsif @stack.last.value.options[:level] < el.options[:level] @stack.last.children << toc_element @stack << toc_element success = true else @stack.pop end end end end end end kramdown-1.17.0/lib/kramdown/converter/kramdown.rb0000644000004100000410000003450613321140127022222 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/converter' require 'kramdown/utils' module Kramdown module Converter # Converts an element tree to the kramdown format. class Kramdown < Base # :stopdoc: include ::Kramdown::Utils::Html def initialize(root, options) super @linkrefs = [] @footnotes = [] @abbrevs = [] @stack = [] end def convert(el, opts = {:indent => 0}) res = send("convert_#{el.type}", el, opts) if ![:html_element, :li, :dt, :dd, :td].include?(el.type) && (ial = ial_for_element(el)) res << ial res << "\n\n" if Element.category(el) == :block elsif [:ul, :dl, :ol, :codeblock].include?(el.type) && opts[:next] && ([el.type, :codeblock].include?(opts[:next].type) || (opts[:next].type == :blank && opts[:nnext] && [el.type, :codeblock].include?(opts[:nnext].type))) res << "^\n\n" elsif Element.category(el) == :block && ![:li, :dd, :dt, :td, :th, :tr, :thead, :tbody, :tfoot, :blank].include?(el.type) && (el.type != :html_element || @stack.last.type != :html_element) && (el.type != :p || !el.options[:transparent]) res << "\n" end res end def inner(el, opts = {:indent => 0}) @stack.push(el) result = '' el.children.each_with_index do |inner_el, index| options = opts.dup options[:index] = index options[:prev] = (index == 0 ? nil : el.children[index-1]) options[:pprev] = (index <= 1 ? nil : el.children[index-2]) options[:next] = (index == el.children.length - 1 ? nil : el.children[index+1]) options[:nnext] = (index >= el.children.length - 2 ? nil : el.children[index+2]) result << convert(inner_el, options) end @stack.pop result end def convert_blank(el, opts) "" end ESCAPED_CHAR_RE = /(\$\$|[\\*_`\[\]\{"'|])|^[ ]{0,3}(:)/ def convert_text(el, opts) if opts[:raw_text] el.value else el.value.gsub(/\A\n/) do opts[:prev] && opts[:prev].type == :br ? '' : "\n" end.gsub(/\s+/, ' ').gsub(ESCAPED_CHAR_RE) { "\\#{$1 || $2}" } end end def convert_p(el, opts) w = @options[:line_width] - opts[:indent].to_s.to_i first, second, *rest = inner(el, opts).strip.gsub(/(.{1,#{w}})( +|$\n?)/, "\\1\n").split(/\n/) first.gsub!(/^(?:(#|>)|(\d+)\.|([+-]\s))/) { $1 || $3 ? "\\#{$1 || $3}" : "#{$2}\\."} if first second.gsub!(/^([=-]+\s*?)$/, "\\\1") if second res = [first, second, *rest].compact.join("\n") + "\n" if el.children.length == 1 && el.children.first.type == :math res = "\\#{res}" elsif res.start_with?('\$$') && res.end_with?("\\$$\n") res.sub!(/^\\\$\$/, '\$\$') end res end def convert_codeblock(el, opts) el.value.split(/\n/).map {|l| l.empty? ? " " : " #{l}"}.join("\n") + "\n" end def convert_blockquote(el, opts) opts[:indent] += 2 inner(el, opts).chomp.split(/\n/).map {|l| "> #{l}"}.join("\n") << "\n" end def convert_header(el, opts) res = '' res << "#{'#' * output_header_level(el.options[:level])} #{inner(el, opts)}" res[-1, 1] = "\\#" if res[-1] == ?# res << " {##{el.attr['id']}}" if el.attr['id'] && !el.attr['id'].strip.empty? res << "\n" end def convert_hr(el, opts) "* * *\n" end def convert_ul(el, opts) inner(el, opts).sub(/\n+\Z/, "\n") end alias :convert_ol :convert_ul alias :convert_dl :convert_ul def convert_li(el, opts) sym, width = if @stack.last.type == :ul ['* ', el.children.first && el.children.first.type == :codeblock ? 4 : 2] else ["#{opts[:index] + 1}.".ljust(4), 4] end if ial = ial_for_element(el) sym << ial << " " end opts[:indent] += width text = inner(el, opts) newlines = text.scan(/\n*\Z/).first first, *last = text.split(/\n/) last = last.map {|l| " "*width + l}.join("\n") text = (first.nil? ? "\n" : first + (last.empty? ? "" : "\n") + last + newlines) if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent] res = "#{sym}#{text}" res << "^\n" if el.children.size == 1 && @stack.last.children.last == el && (@stack.last.children.any? {|c| c.children.first.type != :p} || @stack.last.children.size == 1) res elsif el.children.first && el.children.first.type == :codeblock "#{sym}\n #{text}" else "#{sym}#{text}" end end def convert_dd(el, opts) sym, width = ": ", (el.children.first && el.children.first.type == :codeblock ? 4 : 2) if ial = ial_for_element(el) sym << ial << " " end opts[:indent] += width text = inner(el, opts) newlines = text.scan(/\n*\Z/).first first, *last = text.split(/\n/) last = last.map {|l| " "*width + l}.join("\n") text = first.to_s + (last.empty? ? "" : "\n") + last + newlines text.chomp! if text =~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dd text << "\n" if (text !~ /\n\n\Z/ && opts[:next] && opts[:next].type == :dt) text << "\n" if el.children.empty? if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent] "\n#{sym}#{text}" elsif el.children.first && el.children.first.type == :codeblock "#{sym}\n #{text}" else "#{sym}#{text}" end end def convert_dt(el, opts) result = '' if ial = ial_for_element(el) result << ial << " " end result << inner(el, opts) << "\n" end HTML_TAGS_WITH_BODY=['div', 'script', 'iframe', 'textarea'] def convert_html_element(el, opts) markdown_attr = el.options[:category] == :block && el.children.any? do |c| c.type != :html_element && (c.type != :p || !c.options[:transparent]) && Element.category(c) == :block end opts[:force_raw_text] = true if %w{script pre code}.include?(el.value) opts[:raw_text] = opts[:force_raw_text] || opts[:block_raw_text] || (el.options[:category] != :span && !markdown_attr) opts[:block_raw_text] = true if el.options[:category] == :block && opts[:raw_text] res = inner(el, opts) if el.options[:category] == :span "<#{el.value}#{html_attributes(el.attr)}" << (!res.empty? || HTML_TAGS_WITH_BODY.include?(el.value) ? ">#{res}" : " />") else output = '' attr = el.attr.dup attr['markdown'] = '1' if markdown_attr output << "<#{el.value}#{html_attributes(attr)}" if !res.empty? && el.options[:content_model] != :block output << ">#{res}" elsif !res.empty? output << ">\n#{res}" << "" elsif HTML_TAGS_WITH_BODY.include?(el.value) output << ">" else output << " />" end output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw output end end def convert_xml_comment(el, opts) if el.options[:category] == :block && (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw) el.value + "\n" else el.value.dup end end alias :convert_xml_pi :convert_xml_comment def convert_table(el, opts) opts[:alignment] = el.options[:alignment] inner(el, opts) end def convert_thead(el, opts) rows = inner(el, opts) if opts[:alignment].all? {|a| a == :default} "#{rows}|" << "-"*10 << "\n" else "#{rows}| " << opts[:alignment].map do |a| case a when :left then ":-" when :right then "-:" when :center then ":-:" when :default then "-" end end.join(' ') << "\n" end end def convert_tbody(el, opts) res = '' res << inner(el, opts) res << '|' << '-'*10 << "\n" if opts[:next] && opts[:next].type == :tbody res end def convert_tfoot(el, opts) "|" << "="*10 << "\n#{inner(el, opts)}" end def convert_tr(el, opts) "| " << el.children.map {|c| convert(c, opts)}.join(" | ") << " |\n" end def convert_td(el, opts) inner(el, opts) end def convert_comment(el, opts) if el.options[:category] == :block "{::comment}\n#{el.value}\n{:/}\n" else "{::comment}#{el.value}{:/}" end end def convert_br(el, opts) " \n" end def convert_a(el, opts) if el.attr['href'].empty? "[#{inner(el, opts)}]()" elsif el.attr['href'] =~ /^(?:http|ftp)/ || el.attr['href'].count("()") > 0 index = if link_el = @linkrefs.find {|c| c.attr['href'] == el.attr['href']} @linkrefs.index(link_el) + 1 else @linkrefs << el @linkrefs.size end "[#{inner(el, opts)}][#{index}]" else title = parse_title(el.attr['title']) "[#{inner(el, opts)}](#{el.attr['href']}#{title})" end end def convert_img(el, opts) alt_text = el.attr['alt'].to_s.gsub(ESCAPED_CHAR_RE) { $1 ? "\\#{$1}" : $2 } src = el.attr['src'].to_s if src.empty? "![#{alt_text}]()" else title = parse_title(el.attr['title']) link = if src.count("()") > 0 "<#{src}>" else src end "![#{alt_text}](#{link}#{title})" end end def convert_codespan(el, opts) delim = (el.value.scan(/`+/).max || '') + '`' "#{delim}#{' ' if delim.size > 1}#{el.value}#{' ' if delim.size > 1}#{delim}" end def convert_footnote(el, opts) @footnotes << [el.options[:name], el.value] "[^#{el.options[:name]}]" end def convert_raw(el, opts) attr = (el.options[:type] || []).join(' ') attr = " type=\"#{attr}\"" if attr.length > 0 if @stack.last.type == :html_element el.value elsif el.options[:category] == :block "{::nomarkdown#{attr}}\n#{el.value}\n{:/}\n" else "{::nomarkdown#{attr}}#{el.value}{:/}" end end def convert_em(el, opts) "*#{inner(el, opts)}*" + (opts[:next] && [:em, :strong].include?(opts[:next].type) && !ial_for_element(el) ? '{::}' : '') end def convert_strong(el, opts) "**#{inner(el, opts)}**" + (opts[:next] && [:em, :strong].include?(opts[:next].type) && !ial_for_element(el) ? '{::}' : '') end def convert_entity(el, opts) entity_to_str(el.value, el.options[:original]) end TYPOGRAPHIC_SYMS = { :mdash => '---', :ndash => '--', :hellip => '...', :laquo_space => '<< ', :raquo_space => ' >>', :laquo => '<<', :raquo => '>>' } def convert_typographic_sym(el, opts) TYPOGRAPHIC_SYMS[el.value] end def convert_smart_quote(el, opts) el.value.to_s =~ /[rl]dquo/ ? "\"" : "'" end def convert_math(el, opts) "$$#{el.value}$$" + (el.options[:category] == :block ? "\n" : '') end def convert_abbreviation(el, opts) el.value end def convert_root(el, opts) res = inner(el, opts) res << create_link_defs res << create_footnote_defs res << create_abbrev_defs res end def create_link_defs res = '' res << "\n\n" if @linkrefs.size > 0 @linkrefs.each_with_index do |el, i| title = parse_title(el.attr['title']) res << "[#{i+1}]: #{el.attr['href']}#{title}\n" end res end def create_footnote_defs res = '' @footnotes.each do |name, data| res << "[^#{name}]:\n" res << inner(data).chomp.split(/\n/).map {|l| " #{l}"}.join("\n") + "\n\n" end res end def create_abbrev_defs return '' unless @root.options[:abbrev_defs] res = '' @root.options[:abbrev_defs].each do |name, text| res << "*[#{name}]: #{text}\n" res << ial_for_element(Element.new(:unused, nil, @root.options[:abbrev_attr][name])).to_s << "\n\n" end res end # Return the IAL containing the attributes of the element +el+. def ial_for_element(el) res = el.attr.map do |k,v| next if [:img, :a].include?(el.type) && ['href', 'src', 'alt', 'title'].include?(k) next if el.type == :header && k == 'id' && !v.strip.empty? if v.nil? '' elsif k == 'class' && !v.empty? && !v.index(/[\.#]/) " " + v.split(/\s+/).map {|w| ".#{w}"}.join(" ") elsif k == 'id' && !v.strip.empty? " ##{v}" else " #{k}=\"#{v.to_s}\"" end end.compact.join('') res = "toc" << (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) && (el.options[:ial][:refs].include?('toc') rescue nil) res = "footnotes" << (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) && (el.options[:ial][:refs].include?('footnotes') rescue nil) if el.type == :dl && el.options[:ial] && el.options[:ial][:refs] auto_ids = el.options[:ial][:refs].select {|ref| ref =~ /\Aauto_ids/}.join(" ") res = auto_ids << (res.strip.empty? ? '' : " #{res}") unless auto_ids.empty? end res.strip.empty? ? nil : "{:#{res}}" end def parse_title(attr) attr.to_s.empty? ? '' : ' "' + attr.gsub(/"/, '"') + '"' end # :startdoc: end end end kramdown-1.17.0/lib/kramdown/converter/syntax_highlighter.rb0000644000004100000410000000407313321140127024300 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown module Converter # == Container for Syntax Highlighters # # This module serves as container for the syntax highlighters that can be used together with # kramdown. # # A syntax highlighter should not store any data itself but should use the provided converter # object to do so (See Kramdown::Converter::Base#data). # # == Implementing a Syntax Highlighter # # Implementing a new syntax highlighter is easy because it is just an object that needs to # respond to #call. # # The method #call needs to take the following arguments: # # converter:: This argument contains the converter object that calls the syntax highlighter. It # can be used, for example, to store data in Kramdown::Converter::Base#data for one # conversion run. # # text:: The raw text that should be highlighted. # # lang:: The language that the text should be highlighted for (e.g. ruby, python, ...). # # type:: The type of text, either :span for span-level code or :block for a codeblock. # # opts:: A Hash with options that may be passed from the converter. # # The return value of the method should be the highlighted text, suitable for the given # converter (e.g. HTML for the HTML converter). # # == Special Implementation Details # # HTML converter:: If the syntax highlighter is used with a HTML converter, it should return # :block type text correctly wrapped (i.e. normally inside a pre-tag, but may # also be a table-tag or just a div-tag) but :span type text *without* a # code-tag! # # Also, a syntax highlighter should store the default highlighting language for # the invocation in the +opts+ hash under the key :default_lang. module SyntaxHighlighter end end end kramdown-1.17.0/lib/kramdown/converter/remove_html_tags.rb0000644000004100000410000000322113321140127023725 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/converter' module Kramdown module Converter # Removes all block (and optionally span) level HTML tags from the element tree. # # This converter can be used on parsed HTML documents to get an element tree that will only # contain native kramdown elements. # # *Note* that the returned element tree may not be fully conformant (i.e. the content models of # *some elements may be violated)! # # This converter modifies the given tree in-place and returns it. class RemoveHtmlTags < Base def initialize(root, options) super @options[:template] = '' end def convert(el) real_el, el = el, el.value if el.type == :footnote children = el.children.dup index = 0 while index < children.length if [:xml_pi].include?(children[index].type) || (children[index].type == :html_element && %w[style script].include?(children[index].value)) children[index..index] = [] elsif children[index].type == :html_element && ((@options[:remove_block_html_tags] && children[index].options[:category] == :block) || (@options[:remove_span_html_tags] && children[index].options[:category] == :span)) children[index..index] = children[index].children else convert(children[index]) index += 1 end end el.children = children real_el || el end end end end kramdown-1.17.0/lib/kramdown/converter/html.rb0000644000004100000410000004264213321140127021344 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser' require 'kramdown/converter' require 'kramdown/utils' module Kramdown module Converter # Converts a Kramdown::Document to HTML. # # You can customize the HTML converter by sub-classing it and overriding the +convert_NAME+ # methods. Each such method takes the following parameters: # # [+el+] The element of type +NAME+ to be converted. # # [+indent+] A number representing the current amount of spaces for indent (only used for # block-level elements). # # The return value of such a method has to be a string containing the element +el+ formatted as # HTML element. class Html < Base include ::Kramdown::Utils::Html include ::Kramdown::Parser::Html::Constants # The amount of indentation used when nesting HTML tags. attr_accessor :indent # Initialize the HTML converter with the given Kramdown document +doc+. def initialize(root, options) super @footnote_counter = @footnote_start = @options[:footnote_nr] @footnotes = [] @footnotes_by_name = {} @footnote_location = nil @toc = [] @toc_code = nil @indent = 2 @stack = [] end # The mapping of element type to conversion method. DISPATCHER = Hash.new {|h,k| h[k] = "convert_#{k}"} # Dispatch the conversion of the element +el+ to a +convert_TYPE+ method using the +type+ of # the element. def convert(el, indent = -@indent) send(DISPATCHER[el.type], el, indent) end # Return the converted content of the children of +el+ as a string. The parameter +indent+ has # to be the amount of indentation used for the element +el+. # # Pushes +el+ onto the @stack before converting the child elements and pops it from the stack # afterwards. def inner(el, indent) result = '' indent += @indent @stack.push(el) el.children.each do |inner_el| result << send(DISPATCHER[inner_el.type], inner_el, indent) end @stack.pop result end def convert_blank(el, indent) "\n" end def convert_text(el, indent) escape_html(el.value, :text) end def convert_p(el, indent) if el.options[:transparent] inner(el, indent) else format_as_block_html(el.type, el.attr, inner(el, indent), indent) end end def convert_codeblock(el, indent) attr = el.attr.dup lang = extract_code_language!(attr) hl_opts = {} highlighted_code = highlight_code(el.value, el.options[:lang] || lang, :block, hl_opts) if highlighted_code add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang]) "#{' '*indent}#{highlighted_code}#{' '*indent}
    \n" else result = escape_html(el.value) result.chomp! if el.attr['class'].to_s =~ /\bshow-whitespaces\b/ result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m| suffix = ($1 ? '-l' : ($2 ? '-r' : '')) m.scan(/./).map do |c| case c when "\t" then "\t" when " " then "" end end.join('') end end code_attr = {} code_attr['class'] = "language-#{lang}" if lang "#{' '*indent}#{result}\n\n" end end def convert_blockquote(el, indent) format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent) end def convert_header(el, indent) attr = el.attr.dup if @options[:auto_ids] && !attr['id'] attr['id'] = generate_id(el.options[:raw_text]) end @toc << [el.options[:level], attr['id'], el.children] if attr['id'] && in_toc?(el) level = output_header_level(el.options[:level]) format_as_block_html("h#{level}", attr, inner(el, indent), indent) end def convert_hr(el, indent) "#{' '*indent}\n" end def convert_ul(el, indent) if !@toc_code && (el.options[:ial][:refs].include?('toc') rescue nil) @toc_code = [el.type, el.attr, (0..128).to_a.map{|a| rand(36).to_s(36)}.join] @toc_code.last elsif !@footnote_location && el.options[:ial] && (el.options[:ial][:refs] || []).include?('footnotes') @footnote_location = (0..128).to_a.map{|a| rand(36).to_s(36)}.join else format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent) end end alias :convert_ol :convert_ul def convert_dl(el, indent) format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent) end def convert_li(el, indent) output = ' '*indent << "<#{el.type}" << html_attributes(el.attr) << ">" res = inner(el, indent) if el.children.empty? || (el.children.first.type == :p && el.children.first.options[:transparent]) output << res << (res =~ /\n\Z/ ? ' '*indent : '') else output << "\n" << res << ' '*indent end output << "\n" end alias :convert_dd :convert_li def convert_dt(el, indent) attr = el.attr.dup @stack.last.options[:ial][:refs].each do |ref| if ref =~ /\Aauto_ids(?:-([\w-]+))?/ attr['id'] = ($1 ? $1 : '') << basic_generate_id(el.options[:raw_text]) break end end if !attr['id'] && @stack.last.options[:ial] && @stack.last.options[:ial][:refs] format_as_block_html(el.type, attr, inner(el, indent), indent) end def convert_html_element(el, indent) res = inner(el, indent) if el.options[:category] == :span "<#{el.value}#{html_attributes(el.attr)}" << (res.empty? && HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) ? " />" : ">#{res}") else output = '' output << ' '*indent if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw output << "<#{el.value}#{html_attributes(el.attr)}" if el.options[:is_closed] && el.options[:content_model] == :raw output << " />" elsif !res.empty? && el.options[:content_model] != :block output << ">#{res}" elsif !res.empty? output << ">\n#{res.chomp}\n" << ' '*indent << "" elsif HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) output << " />" else output << ">" end output << "\n" if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw output end end def convert_xml_comment(el, indent) if el.options[:category] == :block && (@stack.last.type != :html_element || @stack.last.options[:content_model] != :raw) ' '*indent << el.value << "\n" else el.value end end alias :convert_xml_pi :convert_xml_comment def convert_table(el, indent) format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent) end alias :convert_thead :convert_table alias :convert_tbody :convert_table alias :convert_tfoot :convert_table alias :convert_tr :convert_table ENTITY_NBSP = ::Kramdown::Utils::Entities.entity('nbsp') # :nodoc: def convert_td(el, indent) res = inner(el, indent) type = (@stack[-2].type == :thead ? :th : :td) attr = el.attr alignment = @stack[-3].options[:alignment][@stack.last.children.index(el)] if alignment != :default attr = el.attr.dup attr['style'] = (attr.has_key?('style') ? "#{attr['style']}; ": '') << "text-align: #{alignment}" end format_as_block_html(type, attr, res.empty? ? entity_to_str(ENTITY_NBSP) : res, indent) end def convert_comment(el, indent) if el.options[:category] == :block "#{' '*indent}\n" else "" end end def convert_br(el, indent) "
    " end def convert_a(el, indent) format_as_span_html(el.type, el.attr, inner(el, indent)) end def convert_img(el, indent) "" end def convert_codespan(el, indent) attr = el.attr.dup lang = extract_code_language(attr) hl_opts = {} result = highlight_code(el.value, lang, :span, hl_opts) if result add_syntax_highlighter_to_class_attr(attr, hl_opts[:default_lang]) else result = escape_html(el.value) end format_as_span_html('code', attr, result) end def convert_footnote(el, indent) repeat = '' if (footnote = @footnotes_by_name[el.options[:name]]) number = footnote[2] repeat = ":#{footnote[3] += 1}" else number = @footnote_counter @footnote_counter += 1 @footnotes << [el.options[:name], el.value, number, 0] @footnotes_by_name[el.options[:name]] = @footnotes.last end "#{number}" end def convert_raw(el, indent) if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('html') el.value + (el.options[:category] == :block ? "\n" : '') else '' end end def convert_em(el, indent) format_as_span_html(el.type, el.attr, inner(el, indent)) end alias :convert_strong :convert_em def convert_entity(el, indent) entity_to_str(el.value, el.options[:original]) end TYPOGRAPHIC_SYMS = { :mdash => [::Kramdown::Utils::Entities.entity('mdash')], :ndash => [::Kramdown::Utils::Entities.entity('ndash')], :hellip => [::Kramdown::Utils::Entities.entity('hellip')], :laquo_space => [::Kramdown::Utils::Entities.entity('laquo'), ::Kramdown::Utils::Entities.entity('nbsp')], :raquo_space => [::Kramdown::Utils::Entities.entity('nbsp'), ::Kramdown::Utils::Entities.entity('raquo')], :laquo => [::Kramdown::Utils::Entities.entity('laquo')], :raquo => [::Kramdown::Utils::Entities.entity('raquo')] } # :nodoc: def convert_typographic_sym(el, indent) if (result = @options[:typographic_symbols][el.value]) escape_html(result, :text) else TYPOGRAPHIC_SYMS[el.value].map {|e| entity_to_str(e)}.join('') end end def convert_smart_quote(el, indent) entity_to_str(smart_quote_entity(el)) end def convert_math(el, indent) if (result = format_math(el, :indent => indent)) result else attr = el.attr.dup (attr['class'] = (attr['class'] || '') << " kdmath").lstrip! if el.options[:category] == :block format_as_block_html('div', attr, "$$\n#{el.value}\n$$", indent) else format_as_span_html('span', attr, "$#{el.value}$") end end end def convert_abbreviation(el, indent) title = @root.options[:abbrev_defs][el.value] attr = @root.options[:abbrev_attr][el.value].dup attr['title'] = title unless title.empty? format_as_span_html("abbr", attr, el.value) end def convert_root(el, indent) result = inner(el, indent) if @footnote_location result.sub!(/#{@footnote_location}/, footnote_content.gsub(/\\/, "\\\\\\\\")) else result << footnote_content end if @toc_code toc_tree = generate_toc_tree(@toc, @toc_code[0], @toc_code[1] || {}) text = if toc_tree.children.size > 0 convert(toc_tree, 0) else '' end result.sub!(/#{@toc_code.last}/, text.gsub(/\\/, "\\\\\\\\")) end result end # Format the given element as span HTML. def format_as_span_html(name, attr, body) "<#{name}#{html_attributes(attr)}>#{body}" end # Format the given element as block HTML. def format_as_block_html(name, attr, body, indent) "#{' '*indent}<#{name}#{html_attributes(attr)}>#{body}\n" end # Format the given element as block HTML with a newline after the start tag and indentation # before the end tag. def format_as_indented_block_html(name, attr, body, indent) "#{' '*indent}<#{name}#{html_attributes(attr)}>\n#{body}#{' '*indent}\n" end # Add the syntax highlighter name to the 'class' attribute of the given attribute hash. And # overwrites or add a "language-LANG" part using the +lang+ parameter if +lang+ is not nil. def add_syntax_highlighter_to_class_attr(attr, lang = nil) (attr['class'] = (attr['class'] || '') + " highlighter-#{@options[:syntax_highlighter]}").lstrip! attr['class'].sub!(/\blanguage-\S+|(^)/) { "language-#{lang}#{$1 ? ' ' : ''}" } if lang end # Generate and return an element tree for the table of contents. def generate_toc_tree(toc, type, attr) sections = Element.new(type, nil, attr) sections.attr['id'] ||= 'markdown-toc' stack = [] toc.each do |level, id, children| li = Element.new(:li, nil, nil, {:level => level}) li.children << Element.new(:p, nil, nil, {:transparent => true}) a = Element.new(:a, nil) a.attr['href'] = "##{id}" a.attr['id'] = "#{sections.attr['id']}-#{id}" a.children.concat(fix_for_toc_entry(Marshal.load(Marshal.dump(children)))) li.children.last.children << a li.children << Element.new(type) success = false while !success if stack.empty? sections.children << li stack << li success = true elsif stack.last.options[:level] < li.options[:level] stack.last.children.last.children << li stack << li success = true else item = stack.pop item.children.pop unless item.children.last.children.size > 0 end end end while !stack.empty? item = stack.pop item.children.pop unless item.children.last.children.size > 0 end sections end # Fixes the elements for use in a TOC entry. def fix_for_toc_entry(elements) remove_footnotes(elements) unwrap_links(elements) elements end # Remove all link elements by unwrapping them. def unwrap_links(elements) elements.map! do |c| unwrap_links(c.children) c.type == :a ? c.children : c end.flatten! end # Remove all footnotes from the given elements. def remove_footnotes(elements) elements.delete_if do |c| remove_footnotes(c.children) c.type == :footnote end end # Obfuscate the +text+ by using HTML entities. def obfuscate(text) result = "" text.each_byte do |b| result << (b > 128 ? b.chr : "&#%03d;" % b) end result.force_encoding(text.encoding) result end FOOTNOTE_BACKLINK_FMT = "%s%s" # Return a HTML ordered list with the footnote content for the used footnotes. def footnote_content ol = Element.new(:ol) ol.attr['start'] = @footnote_start if @footnote_start != 1 i = 0 backlink_text = escape_html(@options[:footnote_backlink], :text) while i < @footnotes.length name, data, _, repeat = *@footnotes[i] li = Element.new(:li, nil, {'id' => "fn:#{name}"}) li.children = Marshal.load(Marshal.dump(data.children)) para = nil if li.children.last.type == :p || @options[:footnote_backlink_inline] parent = li while !parent.children.empty? && ![:p, :header].include?(parent.children.last.type) parent = parent.children.last end para = parent.children.last insert_space = true end unless para li.children << (para = Element.new(:p)) insert_space = false end unless @options[:footnote_backlink].empty? nbsp = entity_to_str(ENTITY_NBSP) para.children << Element.new(:raw, FOOTNOTE_BACKLINK_FMT % [insert_space ? nbsp : '', name, backlink_text]) (1..repeat).each do |index| para.children << Element.new(:raw, FOOTNOTE_BACKLINK_FMT % [nbsp, "#{name}:#{index}", "#{backlink_text}#{index+1}"]) end end ol.children << Element.new(:raw, convert(li, 4)) i += 1 end (ol.children.empty? ? '' : format_as_indented_block_html('div', {:class => "footnotes"}, convert(ol, 2), 0)) end end end end kramdown-1.17.0/lib/kramdown/converter/math_engine/0000755000004100000410000000000013321140127022321 5ustar www-datawww-datakramdown-1.17.0/lib/kramdown/converter/math_engine/mathjaxnode.rb0000644000004100000410000000304213321140127025147 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::MathEngine # Uses the mathjax-node-cli library for converting math formulas to MathML. module MathjaxNode # MathjaxNode is available if this constant is +true+. AVAILABLE = begin %x{node --version}[1..-2] >= '4.5' rescue begin %x{nodejs --version}[1..-2] >= '4.5' rescue false end end && begin npm = %x{npm --global --depth=1 list mathjax-node-cli 2>&1} unless /mathjax-node-cli@/ === npm.lines.drop(1).join("\n") npm = %x{npm --depth=1 list mathjax-node-cli 2>&1} end T2MPATH = File.join(npm.lines.first.strip, "node_modules/mathjax-node-cli/bin/tex2mml") /mathjax-node-cli@/ === npm.lines.drop(1).join("\n") && File.exist?(T2MPATH) rescue false end def self.call(converter, el, opts) type = el.options[:category] cmd = [T2MPATH] cmd << "--inline" unless type == :block cmd << "--semantics" if converter.options[:math_engine_opts][:semantics] == true cmd << "--notexhints" if converter.options[:math_engine_opts][:texhints] == false result = IO.popen(cmd << el.value).read.strip attr = el.attr.dup attr.delete('xmlns') attr.delete('display') result.insert(" # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::MathEngine # Uses the Itex2MML library for converting math formulas to MathML. module Itex2MML begin require 'itextomml' # Itex2MML is available if this constant is +true+. AVAILABLE = true rescue LoadError AVAILABLE = false # :nodoc: end def self.call(converter, el, opts) type = el.options[:category] parser = ::Itex2MML::Parser.new result = (type == :block ? parser.block_filter(el.value) : parser.inline_filter(el.value)) attr = el.attr.dup attr.delete('xmlns') attr.delete('display') result.insert(" # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::MathEngine # Uses the MathJax javascript library for displaying math. # # Note that the javascript library itself is not include or linked, this has to be done # separately. Only the math content is marked up correctly. module Mathjax def self.call(converter, el, opts) type = el.options[:category] text = (el.value =~ /<|&/ ? "% " : el.value) text.gsub!(/<\/?script>?/, '') preview = preview_string(converter, el, opts) attr = {:type => "math/tex#{type == :block ? '; mode=display' : ''}"} if type == :block preview << converter.format_as_block_html('script', attr, text, opts[:indent]) else preview << converter.format_as_span_html('script', attr, text) end end def self.preview_string(converter, el, opts) preview = converter.options[:math_engine_opts][:preview] return '' unless preview preview = (preview == true ? converter.escape_html(el.value) : preview.to_s) preview_as_code = converter.options[:math_engine_opts][:preview_as_code] if el.options[:category] == :block if preview_as_code converter.format_as_block_html('pre', {'class' => 'MathJax_Preview'}, converter.format_as_span_html('code', {}, preview), opts[:indent]) else converter.format_as_block_html('div', {'class' => 'MathJax_Preview'}, preview, opts[:indent]) end else converter.format_as_span_html(preview_as_code ? 'code' : 'span', {'class' => 'MathJax_Preview'}, preview) end end end end kramdown-1.17.0/lib/kramdown/converter/math_engine/ritex.rb0000644000004100000410000000153213321140127024002 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown::Converter::MathEngine # Uses the Ritex library for converting math formulas to MathML. module Ritex begin require 'ritex' # Ritex is available if this constant is +true+. AVAILABLE = true rescue LoadError AVAILABLE = false # :nodoc: end def self.call(converter, el, opts) type = el.options[:category] result = ::Ritex::Parser.new.parse(el.value, :display => (type == :block)) attr = el.attr.dup attr.delete('xmlns') attr.delete('display') result.insert(" # # This file is part of kramdown which is licensed under the MIT. #++ module Kramdown::Converter::MathEngine # Uses the KaTeX gem for converting math formulas to KaTeX HTML. module Katex AVAILABLE = begin require 'katex' true rescue LoadError false end def self.call(converter, el, opts) display_mode = el.options[:category] == :block result = ::Katex.render( el.value, display_mode: display_mode, throw_on_error: false, **converter.options[:math_engine_opts] ) attr = el.attr.dup attr.delete('xmlns') attr.delete('display') result.insert(result =~ /[[:space:]>]/, converter.html_attributes(attr)) result = "#{' ' * opts[:indent]}#{result}\n" if display_mode result end end end kramdown-1.17.0/lib/kramdown/converter/math_engine/sskatex.rb0000644000004100000410000001013413321140127024327 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2017 Christian Cornelssen # # This file is part of kramdown which is licensed under the MIT. #++ module Kramdown::Converter::MathEngine # Consider this a lightweight alternative to MathjaxNode. Uses KaTeX and ExecJS (via ::SsKaTeX) # instead of MathJax and Node.js. Javascript execution context initialization is done only once. # As a result, the performance is reasonable. module SsKaTeX # Indicate whether SsKaTeX may be available. # # This test is incomplete; it cannot test the existence of _katex_js_ nor the availability of a # specific _js_run_ because those depend on configuration not given here. This test mainly # indicates whether static dependencies such as the +sskatex+ and +execjs+ gems are available. AVAILABLE = begin require 'sskatex' # No test for any JS engine availability here; specifics are config-dependent anyway true rescue LoadError false end if AVAILABLE # Class-level cache for ::SsKaTeX converter state, queried by configuration. Note: KTXC # contents may become stale if the contents of used JS files change while the configuration # remains unchanged. KTXC = ::Kramdown::Utils::LRUCache.new(10) # A logger that routes messages to the debug channel only. No need to create this dynamically. DEBUG_LOGGER = lambda { |level, &expr| warn(expr.call) } class << self private # Given a Kramdown::Converter::Base object _converter_, retrieves the logging options and # builds an object usable for ::SsKaTeX#logger. The result is either +nil+ (no logging) or a # +Proc+ object which, when given a _level_ (either +:verbose+ or +:debug+) and a block, # decides whether logging is enabled, and if so, evaluates the given block for the message # and routes that message to the appropriate channels. With level == :verbose+, # messages are passed to _converter_.warning if the _converter_'s +:verbose+ option is set. # All messages are passed to +warn+ if the _converter_'s +:debug+ option is set. # # Note that the returned logger may contain references to the given _converter_ and is not # affected by subsequent changes in the _converter_'s logging options. def logger(converter) config = converter.options[:math_engine_opts] debug = config[:debug] if config[:verbose] # Need a closure lambda do |level, &expr| verbose = (level == :verbose) msg = expr.call if debug || verbose warn(msg) if debug converter.warning(msg) if verbose end elsif debug DEBUG_LOGGER end end # Given a Kramdown::Converter::Base object _converter_, return a ::SsKaTeX converter _sktx_ # that has been configured with _converter_'s +math_engine_opts+, but not for logging. Cache # _sktx_ for reuse, without references to _converter_. def katex_conv(converter) config = converter.options[:math_engine_opts] # Could .reject { |key, _| [:verbose, :debug].include?(key.to_sym) } # because the JS engine setup can be reused for different logging settings. # But then the +math_engine_opts+ dict would be essentially dup'ed every time, # and late activation of logging would miss the initialization if the engine is reused. KTXC[config] ||= ::SsKaTeX.new(config) end public # The function used by kramdown for rendering TeX math to HTML def call(converter, el, opts) display_mode = el.options[:category] ans = katex_conv(converter).call(el.value, display_mode == :block, &logger(converter)) attr = el.attr.dup attr.delete('xmlns') attr.delete('display') ans.insert(ans =~ /[[:space:]>]/, converter.html_attributes(attr)) ans = ' ' * opts[:indent] << ans << "\n" if display_mode == :block ans end end end end end kramdown-1.17.0/lib/kramdown/error.rb0000644000004100000410000000060413321140127017512 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown # This error is raised when an error condition is encountered. # # *Note* that this error is only raised by the support framework for the parsers and converters. class Error < RuntimeError; end end kramdown-1.17.0/lib/kramdown/element.rb0000644000004100000410000003670013321140127020020 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown # Represents all elements in the element tree. # # kramdown only uses this one class for representing all available elements in an element tree # (paragraphs, headers, emphasis, ...). The type of element can be set via the #type accessor. # # Following is a description of all supported element types. # # Note that the option :location may contain the start line number of an element in the source # document. # # == Structural Elements # # === :root # # [Category] None # [Usage context] As the root element of a document # [Content model] Block-level elements # # Represents the root of a kramdown document. # # The root element contains the following option keys: # # :encoding:: When running on Ruby 1.9 this key has to be set to the encoding used for the text # parts of the kramdown document. # # :abbrev_defs:: This key may be used to store the mapping of abbreviation to abbreviation # definition. # # :abbrev_attr:: This key may be used to store the mapping of abbreviation to abbreviation # attributes. # # :options:: This key may be used to store options that were set during parsing of the document. # # # === :blank # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] Empty # # Represents one or more blank lines. It is not allowed to have two or more consecutive blank # elements. # # The +value+ field may contain the original content of the blank lines. # # # === :p # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] Span-level elements # # Represents a paragraph. # # If the option :transparent is +true+, this element just represents a block of text. I.e. this # element just functions as a container for span-level elements. # # # === :header # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] Span-level elements # # Represents a header. # # The option :level specifies the header level and has to contain a number between 1 and \6. The # option :raw_text has to contain the raw header text. # # # === :blockquote # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] Block-level elements # # Represents a blockquote. # # # === :codeblock # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] Empty # # Represents a code block, i.e. a block of text that should be used as-is. # # The +value+ field has to contain the content of the code block. # # The option :lang specifies a highlighting language with possible HTML style options (e.g. # php?start_inline=1) and should be used instead of a possibly also available language embedded in # a class name of the form 'language-LANG'. # # # === :ul # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] One or more :li elements # # Represents an unordered list. # # # === :ol # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] One or more :li elements # # Represents an ordered list. # # # === :li # # [Category] Block-level element # [Usage context] Inside :ol and :ul elements # [Content model] Block-level elements # # Represents a list item of an ordered or unordered list. # # Note that the first child of a list item must not be a :blank element! # # # === :dl # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] One or more groups each consisting of one or more :dt elements followed by one # or more :dd elements. # # Represents a definition list which contains groups consisting of terms and definitions for them. # # # === :dt # # [Category] Block-level element # [Usage context] Before :dt or :dd elements inside a :dl elment # [Content model] Span-level elements # # Represents the term part of a term-definition group in a definition list. # # # === :dd # # [Category] Block-level element # [Usage context] After :dt or :dd elements inside a :dl elment # [Content model] Block-level elements # # Represents the definition part of a term-definition group in a definition list. # # # === :hr # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] None # # Represents a horizontal line. # # # === :table # # [Category] Block-level element # [Usage context] Where block-level elements are expected # [Content model] Zero or one :thead elements, one or more :tbody elements, zero or one :tfoot # elements # # Represents a table. Each table row (i.e. :tr element) of the table has to contain the same # number of :td elements. # # The option :alignment has to be an array containing the alignment values, exactly one for each # column of the table. The possible alignment values are :left, :center, :right and :default. # # # === :thead # # [Category] None # [Usage context] As first element inside a :table element # [Content model] One or more :tr elements # # Represents the table header. # # # === :tbody # # [Category] None # [Usage context] After a :thead element but before a :tfoot element inside a :table element # [Content model] One or more :tr elements # # Represents a table body. # # # === :tfoot # # [Category] None # [Usage context] As last element inside a :table element # [Content model] One or more :tr elements # # Represents the table footer. # # # === :tr # # [Category] None # [Usage context] Inside :thead, :tbody and :tfoot elements # [Content model] One or more :td elements # # Represents a table row. # # # === :td # # [Category] Block-level element # [Usage context] Inside :tr elements # [Content model] As child of :thead/:tr span-level elements, as child of :tbody/:tr and # :tfoot/:tr block-level elements # # Represents a table cell. # # # === :math # # [Category] Block/span-level element # [Usage context] Where block/span-level elements are expected # [Content model] None # # Represents mathematical text that is written in LaTeX. # # The +value+ field has to contain the actual mathematical text. # # The option :category has to be set to either :span or :block depending on the context where the # element is used. # # # == Text Markup Elements # # === :text # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents text. # # The +value+ field has to contain the text itself. # # # === :br # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents a hard line break. # # # === :a # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] Span-level elements # # Represents a link to an URL. # # The attribute +href+ has to be set to the URL to which the link points. The attribute +title+ # optionally contains the title of the link. # # # === :img # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents an image. # # The attribute +src+ has to be set to the URL of the image. The attribute +alt+ has to contain a # text description of the image. The attribute +title+ optionally contains the title of the image. # # # === :codespan # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents verbatim text. # # The +value+ field has to contain the content of the code span. # # # === :footnote # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents a footnote marker. # # The +value+ field has to contain an element whose children are the content of the footnote. The # option :name has to contain a valid and unique footnote name. A valid footnote name consists of # a word character or a digit and then optionally followed by other word characters, digits or # dashes. # # # === :em # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] Span-level elements # # Represents emphasis of its contents. # # # === :strong # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] Span-level elements # # Represents strong importance for its contents. # # # === :entity # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents an HTML entity. # # The +value+ field has to contain an instance of Kramdown::Utils::Entities::Entity. The option # :original can be used to store the original representation of the entity. # # # === :typographic_sym # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents a typographic symbol. # # The +value+ field needs to contain a Symbol representing the specific typographic symbol from # the following list: # # :mdash:: An mdash character (---) # :ndash:: An ndash character (--) # :hellip:: An ellipsis (...) # :laquo:: A left guillemet (<<) # :raquo:: A right guillemet (>>) # :laquo_space:: A left guillemet with a space (<< ) # :raquo_space:: A right guillemet with a space ( >>) # # # === :smart_quote # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents a quotation character. # # The +value+ field needs to contain a Symbol representing the specific quotation character: # # :lsquo:: Left single quote # :rsquo:: Right single quote # :ldquo:: Left double quote # :rdquo:: Right double quote # # # === :abbreviation # # [Category] Span-level element # [Usage context] Where span-level elements are expected # [Content model] None # # Represents a text part that is an abbreviation. # # The +value+ field has to contain the text part that is the abbreviation. The definition of the # abbreviation is stored in the :root element of the document. # # # == Other Elements # # === :html_element # # [Category] Block/span-level element # [Usage context] Where block/span-level elements or raw HTML elements are expected # [Content model] Depends on the element # # Represents an HTML element. # # The +value+ field has to contain the name of the HTML element the element is representing. # # The option :category has to be set to either :span or :block depending on the whether the # element is a block-level or a span-level element. The option :content_model has to be set to the # content model for the element (either :block if it contains block-level elements, :span if it # contains span-level elements or :raw if it contains raw content). # # # === :xml_comment # # [Category] Block/span-level element # [Usage context] Where block/span-level elements are expected or in raw HTML elements # [Content model] None # # Represents an XML/HTML comment. # # The +value+ field has to contain the whole XML/HTML comment including the delimiters. # # The option :category has to be set to either :span or :block depending on the context where the # element is used. # # # === :xml_pi # # [Category] Block/span-level element # [Usage context] Where block/span-level elements are expected or in raw HTML elements # [Content model] None # # Represents an XML/HTML processing instruction. # # The +value+ field has to contain the whole XML/HTML processing instruction including the # delimiters. # # The option :category has to be set to either :span or :block depending on the context where the # element is used. # # # === :comment # # [Category] Block/span-level element # [Usage context] Where block/span-level elements are expected # [Content model] None # # Represents a comment. # # The +value+ field has to contain the comment. # # The option :category has to be set to either :span or :block depending on the context where the # element is used. If it is set to :span, then no blank lines are allowed in the comment. # # # === :raw # # [Category] Block/span-level element # [Usage context] Where block/span-level elements are expected # [Content model] None # # Represents a raw string that should not be modified. For example, the element could contain some # HTML code that should be output as-is without modification and escaping. # # The +value+ field has to contain the actual raw text. # # The option :category has to be set to either :span or :block depending on the context where the # element is used. If it is set to :span, then no blank lines are allowed in the raw text. # # The option :type can be set to an array of strings to define for which converters the raw string # is valid. # class Element # A symbol representing the element type. For example, :p or :blockquote. attr_accessor :type # The value of the element. The interpretation of this field depends on the type of the element. # Many elements don't use this field. attr_accessor :value # The child elements of this element. attr_accessor :children # Create a new Element object of type +type+. The optional parameters +value+, +attr+ and # +options+ can also be set in this constructor for convenience. def initialize(type, value = nil, attr = nil, options = nil) @type, @value, @attr, @options = type, value, (Utils::OrderedHash.new.merge!(attr) if attr), options @children = [] end # The attributes of the element. Uses an Utils::OrderedHash to retain the insertion order. def attr @attr ||= Utils::OrderedHash.new end # The options hash for the element. It is used for storing arbitray options. def options @options ||= {} end def inspect #:nodoc: "" end CATEGORY = {} # :nodoc: [:blank, :p, :header, :blockquote, :codeblock, :ul, :ol, :li, :dl, :dt, :dd, :table, :td, :hr].each {|b| CATEGORY[b] = :block} [:text, :a, :br, :img, :codespan, :footnote, :em, :strong, :entity, :typographic_sym, :smart_quote, :abbreviation].each {|b| CATEGORY[b] = :span} # Return the category of +el+ which can be :block, :span or +nil+. # # Most elements have a fixed category, however, some elements can either appear in a block-level # or a span-level context. These elements need to have the option :category correctly set. def self.category(el) CATEGORY[el.type] || el.options[:category] end end end kramdown-1.17.0/lib/kramdown/utils.rb0000644000004100000410000000240513321140127017522 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown # == \Utils Module # # This module contains utility class/modules/methods that can be used by both parsers and # converters. module Utils autoload :Entities, 'kramdown/utils/entities' autoload :Html, 'kramdown/utils/html' autoload :OrderedHash, 'kramdown/utils/ordered_hash' autoload :Unidecoder, 'kramdown/utils/unidecoder' autoload :StringScanner, 'kramdown/utils/string_scanner' autoload :Configurable, 'kramdown/utils/configurable' autoload :LRUCache, 'kramdown/utils/lru_cache' # Treat +name+ as if it were snake cased (e.g. snake_case) and camelize it (e.g. SnakeCase). def self.camelize(name) name.split('_').inject('') {|s,x| s << x[0..0].upcase << x[1..-1] } end # Treat +name+ as if it were camelized (e.g. CamelizedName) and snake-case it (e.g. camelized_name). def self.snake_case(name) name = name.dup name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2') name.gsub!(/([a-z])([A-Z])/,'\1_\2') name.downcase! name end def self.deep_const_get(str) ::Object.const_get(str) end end end kramdown-1.17.0/lib/kramdown/options.rb0000644000004100000410000005171013321140127020060 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'yaml' module Kramdown # This module defines all options that are used by parsers and/or converters as well as providing # methods to deal with the options. module Options # Helper class introducing a boolean type for specifying boolean values (+true+ and +false+) as # option types. class Boolean # Return +true+ if +other+ is either +true+ or +false+ def self.===(other) FalseClass === other || TrueClass === other end end # ---------------------------- # :section: Option definitions # # This sections describes the methods that can be used on the Options module. # ---------------------------- # Struct class for storing the definition of an option. Definition = Struct.new(:name, :type, :default, :desc, :validator) # Allowed option types. ALLOWED_TYPES = [String, Integer, Float, Symbol, Boolean, Object] @options = {} # Define a new option called +name+ (a Symbol) with the given +type+ (String, Integer, Float, # Symbol, Boolean, Object), default value +default+ and the description +desc+. If a block is # specified, it should validate the value and either raise an error or return a valid value. # # The type 'Object' should only be used for complex types for which none of the other types # suffices. A block needs to be specified when using type 'Object' and it has to cope with # a value given as string and as the opaque type. def self.define(name, type, default, desc, &block) name = name.to_sym raise ArgumentError, "Option name #{name} is already used" if @options.has_key?(name) raise ArgumentError, "Invalid option type #{type} specified" if !ALLOWED_TYPES.include?(type) raise ArgumentError, "Invalid type for default value" if !(type === default) && !default.nil? raise ArgumentError, "Missing validator block" if type == Object && block.nil? @options[name] = Definition.new(name, type, default, desc, block) end # Return all option definitions. def self.definitions @options end # Return +true+ if an option called +name+ is defined. def self.defined?(name) @options.has_key?(name.to_sym) end # Return a Hash with the default values for all options. def self.defaults temp = {} @options.each {|n, o| temp[o.name] = o.default} temp end # Merge the #defaults Hash with the *parsed* options from the given Hash, i.e. only valid option # names are considered and their value is run through the #parse method. def self.merge(hash) temp = defaults hash.each do |k,v| k = k.to_sym @options.has_key?(k) ? temp[k] = parse(k, v) : temp[k] = v end temp end # Parse the given value +data+ as if it was a value for the option +name+ and return the parsed # value with the correct type. # # If +data+ already has the correct type, it is just returned. Otherwise it is converted to a # String and then to the correct type. def self.parse(name, data) name = name.to_sym raise ArgumentError, "No option named #{name} defined" if !@options.has_key?(name) if !(@options[name].type === data) data = data.to_s data = if @options[name].type == String data elsif @options[name].type == Integer Integer(data) rescue raise Kramdown::Error, "Invalid integer value for option '#{name}': '#{data}'" elsif @options[name].type == Float Float(data) rescue raise Kramdown::Error, "Invalid float value for option '#{name}': '#{data}'" elsif @options[name].type == Symbol str_to_sym(data) elsif @options[name].type == Boolean data.downcase.strip != 'false' && !data.empty? end end data = @options[name].validator[data] if @options[name].validator data end # Converts the given String +data+ into a Symbol or +nil+ with the # following provisions: # # - A leading colon is stripped from the string. # - An empty value or a value equal to "nil" results in +nil+. def self.str_to_sym(data) data = data.strip data = data[1..-1] if data[0] == ?: (data.empty? || data == 'nil' ? nil : data.to_sym) end # ---------------------------- # :section: Option Validators # # This sections contains all pre-defined option validators. # ---------------------------- # Ensures that the option value +val+ for the option called +name+ is a valid array. The # parameter +val+ can be # # - a comma separated string which is split into an array of values # - or an array. # # Optionally, the array is checked for the correct size. def self.simple_array_validator(val, name, size = nil) if String === val val = val.split(/,/) elsif !(Array === val) raise Kramdown::Error, "Invalid type #{val.class} for option #{name}" end if size && val.size != size raise Kramdown::Error, "Option #{name} needs exactly #{size} values" end val end # Ensures that the option value +val+ for the option called +name+ is a valid hash. The # parameter +val+ can be # # - a hash in YAML format # - or a Ruby Hash object. def self.simple_hash_validator(val, name) if String === val begin val = YAML.load(val) rescue RuntimeError, ArgumentError, SyntaxError raise Kramdown::Error, "Invalid YAML value for option #{name}" end end raise Kramdown::Error, "Invalid type #{val.class} for option #{name}" if !(Hash === val) val end # ---------------------------- # :section: Option Definitions # # This sections contains all option definitions that are used by the included # parsers/converters. # ---------------------------- define(:template, String, '', <hallo
    ` the emphasis tag would normally be converted to an `:html` element with tag type `:em`. If `html_to_native` is `true`, then the emphasis would be converted to a native `:em` element. This is useful for converters that cannot deal with HTML elements. Default: false Used by: kramdown parser EOF define(:link_defs, Object, {}, < 2 || v.size < 1 raise Kramdown::Error, "Invalid structure for hash value of option #{name}" end v << nil if v.size == 1 end val end define(:footnote_nr, Integer, 1, <` tags inside paragraphs where the original Markdown document had newlines (by default, Markdown ignores these newlines). Default: true Used by: GFM parser EOF define(:syntax_highlighter, Symbol, :coderay, < # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown # This module contains all available parsers. A parser takes an input string and converts the # string to an element tree. # # New parsers should be derived from the Base class which provides common functionality - see its # API documentation for how to create a custom converter class. module Parser autoload :Base, 'kramdown/parser/base' autoload :Kramdown, 'kramdown/parser/kramdown' autoload :Html, 'kramdown/parser/html' autoload :Markdown, 'kramdown/parser/markdown' autoload :GFM, 'kramdown/parser/gfm' end end kramdown-1.17.0/lib/kramdown/converter.rb0000644000004100000410000000475413321140127020402 0ustar www-datawww-data# -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2016 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/utils' module Kramdown # This module contains all available converters, i.e. classes that take a root Element and convert # it to a specific output format. The result is normally a string. For example, the # Converter::Html module converts an element tree into valid HTML. # # Converters use the Base class for common functionality (like applying a template to the output) # \- see its API documentation for how to create a custom converter class. module Converter autoload :Base, 'kramdown/converter/base' autoload :Html, 'kramdown/converter/html' autoload :Latex, 'kramdown/converter/latex' autoload :Kramdown, 'kramdown/converter/kramdown' autoload :Toc, 'kramdown/converter/toc' autoload :RemoveHtmlTags, 'kramdown/converter/remove_html_tags' autoload :Pdf, 'kramdown/converter/pdf' autoload :HashAST, 'kramdown/converter/hash_ast' autoload :HashAst, 'kramdown/converter/hash_ast' autoload :Man, 'kramdown/converter/man' extend ::Kramdown::Utils::Configurable configurable(:syntax_highlighter) ['Minted', "Coderay", "Rouge"].each do |klass_name| kn_down = klass_name.downcase.intern add_syntax_highlighter(kn_down) do |converter, text, lang, type, opts| require "kramdown/converter/syntax_highlighter/#{kn_down}" klass = ::Kramdown::Utils.deep_const_get("::Kramdown::Converter::SyntaxHighlighter::#{klass_name}") if !klass.const_defined?(:AVAILABLE) || klass::AVAILABLE add_syntax_highlighter(kn_down, klass) else add_syntax_highlighter(kn_down) {|*args| nil} end syntax_highlighter(kn_down).call(converter, text, lang, type, opts) end end configurable(:math_engine) ["Mathjax", "MathjaxNode", "Katex", "SsKaTeX", "Ritex", "Itex2MML"].each do |klass_name| kn_down = klass_name.downcase.intern add_math_engine(kn_down) do |converter, el, opts| require "kramdown/converter/math_engine/#{kn_down}" klass = ::Kramdown::Utils.deep_const_get("::Kramdown::Converter::MathEngine::#{klass_name}") if !klass.const_defined?(:AVAILABLE) || klass::AVAILABLE add_math_engine(kn_down, klass) else add_math_engine(kn_down) {|*args| nil} end math_engine(kn_down).call(converter, el, opts) end end end end kramdown-1.17.0/doc/0000755000004100000410000000000013321140127014211 5ustar www-datawww-datakramdown-1.17.0/doc/default.scss0000644000004100000410000000743313321140127016541 0ustar www-datawww-data@import 'design'; a:hover { background-color: rgba(0,0,0,0.1); } aside.banner { font-size: 18px; line-height: 27px; } aside a { text-decoration: none; &:hover, &:link { text-decoration: underline; } } #content { blockquote.information { border-left: 12px solid #080; background-color: #bfb; padding: 12px 12px 12px 0; margin-left: -48px; padding-left: 48px; } blockquote.markdown-difference { border-left: 12px solid #dc0; background-color: #ffa; padding: 12px 12px 12px 0; margin-left: -48px; padding-left: 48px; &:before { content: "Difference to Standard Markdown"; display: block; font-weight: bold; } } blockquote pre { border: none; } table { border-collapse: collapse; margin-left: auto; margin-right: auto; width: 100%; td, th { padding: 3px 5px; } th { background-color: #080; color: white; } } pre.show-whitespaces .ws-space { background-color: #f44; } pre.show-whitespaces .ws-space-l { background-color: #f22; } pre.show-whitespaces .ws-space-r { background-color: #f00; } pre.show-whitespaces .ws-tab { background-color: #ff4; } pre.show-whitespaces .ws-tab-l { background-color: #ff2; } pre.show-whitespaces .ws-tab-r { background-color: #ff0; } pre.show-whitespaces.ws-lr .ws-tab { background-color: inherit; } pre.show-whitespaces.ws-lr .ws-space { background-color: inherit; opacity: 0; } table.kdexample td { vertical-align: top; } table.kdexample pre { margin: 5px 0px; } .kdexample:hover .kdexample-after-source { display: block; } .kdexample-after-source { display: none; background-color: #ffffee; border: 2px solid #e6e8e9; margin: 0 10px; padding: 5px; } .kdexample-after-live { background-color: #eeffee; border: 2px solid #e6e8e9; margin: 5px 0px 12px; padding: 5px; } div.kdsyntaxlink { float: right; position: relative; top: -17px; padding: 5px; border: 1px solid #e6e8e9; margin-right: 10px; margin-left: 10px; a { text-decoration: none; } } } .news-item { border-top: 2px solid #ddd; margin-top: 46px; } .news-date { float: right; margin-top: 2px; font-size: small; color: #888; } footer { clear: both; font-size: 92%; text-align: left; a { color: #898989; &:hover { text-decoration: none; color: #666; } } } /* common rules */ acronym { cursor: help; border-bottom: 1px solid #777; } .float-left { float: left; } .float-right { float: right; } .a-left, tr.a-left td { text-align: left; } .a-center, tr.a-center td { text-align: center; } .a-right, tr.a-right td { text-align: right; } .clear { clear: both; } .inline-important { font-weight: bold; display: block; text-align: center; } .patreon, .patreon:hover { border-radius: 50px; padding: 5px 10px; margin: 0 5px; display: inline-block; text-decoration: none !important; background-color: #e6461a !important; box-shadow: 0px 0px 5px 5px #e6461a; color: white !important; font-weight: bold; &:hover { box-shadow: 0px 0px 0px 5px #e6461a; } } #call-to-arms { text-align: center; margin: 40px 0 10px; background-color: rgba(255, 255, 255, 0.18); padding: 30px; border-radius: 100px; } kramdown-1.17.0/doc/bg.png0000644000004100000410000015553413321140127015324 0ustar www-datawww-dataPNG  IHDR,-J tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp , IDAT b6 @%% 7*8m:ǽl#N6]쾍B|r0,ܢ ǶwQH睼\ Ġ$r1saΡxb]Pu-ksGq^#)*d=KLK{TH'#ܛ@uYuQ}G"i-HRϴKdo9r^trQ}|AGnyY\TBRg;(B?CB7ְ|GSoh{ٷڻD\NcѶ0r9ц{4кI,v I8ԟp}AZu/Jv&˾ۑ{KPzmx6:1ܧ`%drb vW(W ^ُeahbqOjO1cՕ+8;9 Gx?\P$c ѼҫJO8w+kV8nq;I=nw9#Jh!ss}˹Efg|Iޫ.w!S\r(g;Ľu@M$u{ LJ3qJX4 '[1BB!Wkq ndK\;<|J|w{_CbYL'6~DZO\ϴ >Hwº?;zBg TGIl3^0a(=_M,/K#i)IwLnN{>apY4גdUmS fF94 HjO4 'ry'Y9߅ꓹ%Rh]h&0J qK(L$]1J2ŝ t#P,HqElEܫlGn)q|eC݋y$&=hx8-S[DshJT;g=)~RT,zm»e}Hh})jƧ@jĆRT G 8 x(-y #~+cȭ1=O2) tE Ow4wq*J b_:YGDH|,D#cj}4oWTG<1%/C"CNViT' Fa<9DJ{ mg%\!8 CK럛C[z'';u'N.a<Ӈza!!w< cw4y/aɷU4Z$e@q)Aň3YIr)QAni϶O>JF_Ό:{:Ѡ1;BY=9\k t;[ ;Q&Z"=&^5Y93zp{'(?Itgݽ^&Q3$S ^!maQWSS)}9ķi>e ]| a~̕l:fVU)ܻrQ=OC\G\= X&z\J]%jJrw8\$+R_KBR 5aʸ-#0Dƪښ% sEu|j욄ļuITy4GL9?lOև!PE˞)q%:O[b!Y` ׻L6vE3IԐT2 ,,OF8 G%~ G"Nrr0\~sPn=)nr<#OdP9D [zgF&T+Rj,410bZ@I SXV%T kyO!ynD*,0ۘ.N2L iO<$qe-X)WAm MtGK6C=9Rwlm;1 "${Vb :BԭLw5t\1ɛ%Pr_ lsœ~%RWF:X[CEq $'jw }e]C8'ћq^(KLCF#B2:{4Ww1Mn1HG,P]#{9$rxVّf H{ Tߒ{VNM(4%Cߟt1 2_cZ'aק([wΗü\.44Il $抨'Sv| :c;s-ҷa..m?){ҙ$nW]WGg xBhCO³ jyu Pe_C!+MYdvWQ{6MDyW<8"Ց VQ&6B( چwڗY B3ArP[\c+ectD|7HZ`徒bˢ@ѕ{KxD)OV=%TkmP+$90'9^rtOѓ3^>2C☈h#%8"a>܉ :Y,ND+wtY1&9!K8KtEk!ݥFcJ_`ً wj,( A^Va3C\fF"ԂB2Pp"'z c]y\z*q7&|+g)/JQ#^e 5Gjʞ7cnGs $,lheEr Wyvs en4u%_0?7BxV.v5BZ=Smq>rbWL=x5I̗\|91JH#kD{9frCp.H 1EYmg Bt9a< br]r&xQ@4迷x;q5@sv9]`>\jOEWr>!7%%&Lgzϓ ^g3ɹV?B%mCr"^ޮǪP}MPV~2njNaE\Gi? +OŇ*6oWu~JV?q9Kב 0F\[F򝨜FWOaX8:Ku5 M+dȟg<\m.' Y5[Hϻa?LqN:Sh ]Z(C-; ?ѵz11oh[}ب'vpkAr}_zzvV~YƑ(Θ^u5ƻ3`FؾA>`DmՐYOҽuיcWŐw m#bשW!]OƋ|i+Wי]$J.Υ/H}'1`붐8\Ztᰧ;QeP ~YjWIa)D%\)^:yyMZ1@-TH,P9\tQ-$+|G}_,}4xT-q6{N8WL{6UHYVN&bbeW5Y9ߢn>UôX\jVU&!|\ p6MJb)wTjڍJ:2"*S݁RyGR+ 6㶄ӧMõ+.} WEK؞)lӰIKLKJFvg$m (%!E\ %N{!}Q::.\/uK|/ E@u^{s|+<ٚ` F.jȌ۴w@%A%)TWHuj\ 2bdHr;3- 2$H 0q^4^SnkWԳ&.4H ZX1nҙ%/~aa+A\8X_z׳H,nN>㩇:͇^5Xx -u>R(Ӱq['m!b?lL __ӛz?CxlSC?Gɾ-tjg>^,o( +ҋ~sX]czKZ6W'FXp욡ʳ3ӫCbpCJw\tNP@RHO[TM#u)uv%-(hKL1 uPxl $Ph= BK6rRg⚑ x~#f>4{HRh͓3I u2|]TSW4֞pgb iy%p~) [$)˜:D*wQ#X4D[b!mq1إ fW&A"f,i krK3&:egy2w8%yc*"59[ÇvG] gD=9+@өܗ=̢jkXpc*V&tuXsZUNX.!h'x"_I~L?Vȡ*Ի_O 5}7`H5fW՜?8һ{Y0W9 4u)k360.! loIPc5 h!K?Mm.#=Ow =C/^;%wY~0^/G7a}U~Ou?Flg)ew;upr{!ֳb|rd#g?]^,w4q]@eH.#הorɾf%tHu@ ^|l6 !.J$o||P[x$rx,uc1]rhJb!qSW4pRyjd>j Ⱥ׿((;hO;P|/&J`qN! >۝$םzF`|=<ǓYȀWo G{k/Ag q/0MNq^뙸+''<]qc̳>_Rվ# c9s^'ӵ5%^lL4]u@VYք}c█8i[sHo dSɸjT)?|Ij@ľyY@odtpTaq9`c%݈0WhTii6)Oi$,x&UA :=[q& T?b%E儻"DF*ʹ2L;r;O*56QP^Y1lW Ơ4ᄰЩ+A˗5QJBXSSWg=ئ q)WS//34 kE| ;9< Et7DigZF&:AF&[S'mN!>U9L#kU|0N|RC[IL_!ȫ '96;J յ5wJCE:wtZЌX9%yZ!gtQydih0wc Pak;򠡴جVgwoo8tI`)g!l rI!_@}U\˽ĒN|Dp.I!B*zt'9 & Wkb?[;o"ߜnL~^2w(\/4G:O5~RAבϪ~l]{^ Z?s3xrDd{*GqF>\+ c 6+F߯D_zL:wt,ķ3ℬ8B_O3WCAxG -5ώ5Jy+ (_ѽ觏i| <{{ Vyeϊ eg~0~+{3 Q: gﻄ] 68N~QO=l meřoCՕJ1a t[ To,}SN- ~GY==K, \q)%ߞ#$hHgu_~l跔JmwK*k)XWC&P2ՀH_L1dc ]%Kf-h;zPYqGb ]E)4Ќ̔z`'[a'$w8QdxLN.8#l+4 XǓ2~!0jQegbu;đ^Oo<,;!o5œb}0JF:F^2ay1"K|j»pt'ŧyG|GE]E4_Y[GT;N$ʍ[v] C\#2~T-[I1xe+%|oSWZ/ɮ:ouYgr.V'4,#H=nQO Jpn 53HrN2Nh+1cu]*?t(WwXB;,6H9جjgB启%- q$n5E>Kyfc#~= 瓥dO{`Ng (}*eߑg"+G!BKɡ=p,@5!T i/aL}mș(j+>O11#;wZ`f%gvltN-P3+Mu?ӳRi_2ד/ aTlܘ9Wu;[;Z`NB@?yKx⸊oۣ1,ד9wIx#١q5/U)?ɗ;P =k3χ8cv] ;kfo.NFZճqO:ԕ]CNtgq=\$%G9ng6^w>+;~W0]:b[PsI(>_wJg+lPaXVϾi2f|5Nvyvz,ܬ|1I`obEV|:^|NR Lg}pp/ uY>2C)|0qy\ -B N|aWNPq׀e5_ɂfѸ$Ph}3++R;Z_Deu/ߙvЅᥳRnA05L}+.V7s~Gh,}', r9*yRܢJ!fe >Zi‘Nt|tca|Ƅؗ,g~_ snd H0&q2ݙK~LW"f?Ryxq տe.9X{w".œN.P+I+",L95per0nԵ+;ngq:y5{32W>rP}9)C|b>X(:Ot$ Pxo9*rݹüJSэ!=B:artN:򳈺CKm= WlO*؄ԕwCB~ Dq,A2SeK$cHJvf304lLgpZ3?G@T\|2΀ )-XH{ {R!SZ iewa[0G#yOYwbHL.ݸGg^`T~:+P,OE|w =1:ԧm=ZF 2)R2=_Mb!A]Jw6Nre*`.Մ8S2҄? !5m06pk- J[UR4|-mF~f8&hAy"&zuIB>&i" c20;|RB\B`KNǭBz*؊2Xw &ѪTV'ĴDr/<+o *iE,[1 I>"2 2oVolnC!Hg> yZ~*j|F t);hP@WCBjp23}.u|*0P1uMydz/>&řZqV  Ӄ@oE4a:3ut<QCjPG(`ص-|~7;c_멧Z@|So ӃaZ-*7c8Z+!^;RqYpk)L48U ut>b>7C=@;bT8/gg +<.BG8W<#pq -\oݍ1jEƎe>Δϻ6ڮDWvm'L+C~b^OYuU#R[ #qtcQLp]\B\&n $Ҍ[P;}!-N1\ : J8}mZ?Ft]JC88J22,;(MqyERmtp̎Jշ<-@ɐjc1U̵evvDO91=#\*s[Vk _/)iʾ[_!xֻ>&}fs(! TOcH\9\G:l5'B3躋tHbM  h#5PHzKť3ʥ4z&/gg]c) A\# Sy;} 9I#I(~ͮDٻ{t zi)[ֶWrCK(k|Mf9-\r_쬫;6hC7g< *vY' ^~k>g=wq>..g g8QYw; Z3\(G:F~۽֣8~V:+ɫS^錅d^7ցgvS{dzJ]@~g'+w;Jrڽ: %,kCD?,QKvnA so}u]\V)G]paqS ~|Zqzh6sp.L|Sث/.ޏ7y`J~<'[z5Hg% ɳP0UY`7š![wZ 2{GLPAFSa\Yzj3KEgHΦyQW|v }']fr\m;A(L4LaN3D7RpQQL#BϷWvgї5$N`gUr`\n^7SX|`߇m$+sHD)n:=HT{1>9 <'%VXœ@UGmF"tg/AY٧fѴN! tG!3[KmqGSm{kpp2+2Lb߅Ϩkq,&0!lJBP Lh,|BDq@lm%`,}ipe[JRfAVgD摨, 'zRH&ڽ9iÈ|]ږ8jN9Ҋ̠zfﭧ}{Z@wCOEp zѰ4ҹ=N6g&א_$qy);bN5WV/GU,#zC>_ ixK pv;P0/,gP a=l0J!T\[C4;S*>_]9e-8Y;NW>~pBr?X8wh9exWaɧ*z/;Sݍgr!_F.*5frCA; t{85,CB(g!ns fk"kA:D+B;M(Ǎb@[gh3bg@8G2/JNPs$৽%#0|0vf\C9AU嗴eADAe][W04o2Rs|Pɼ /\Ӿ߯_ѸkօCǚsGqv}9r;]lG3]ٕ{*vWgc4Wδf k/N3[r@nG^+\B,(QȻ"ꉧwMY~Mӹ2 Lc9[MJAKHNLJG V@\\. "9cc9;W,v& @ '8Ě6@5rmzonTW֕Q~>z\ރF~Ұ+3yHe0Ȇ@%oMN$FQeX)iF yP,BYsAuF3P&բ+S+^[?|V!{l !8&`wGCVd˲*U{ Ԓe.n5A<ʥP)]*l)h2!^98 :#![&R'Pʝ`vcm2ѸئhKC\?1:aCjé"fvEb1; #7yAf3 @O>j"6n =h !#3yvBU|40?'ʠ#)z03^+_#ܑFCθݍY\_buq?.oRC}GrmTY j7a.7 xJ1JkU $ i +Zt9UZ@22+h:`og3V}#[i6NHIpEw!Mw C< 1Q'bU#YLXi}4Cr)mnS_ )Or\R=&ZdgVinKVl ަa7;u5b ]S_wvҼ+L8Q9O~9Ds3)Ƴ^ՇolQƝߋ1}V!$_OO9#AHʻ_ db sg7U]ByWtSvXѧU{sQCB,- '{Aj3Jw8GWrڟZҟ ah}_ Tc>v*e8̫=|]<7S%u ͏aY|MKШ_CDO~FgQiAq :ͻI?Uػ 5#~` 5r'WSNa=:cK!*݂95E0jH(ؤq6#uM ǹ/=8-H!ԝ (,!}DA,&ya= QctN@l8`K 4. Ӏ m_Hy+20`:R SɕxA=rKf OGe>=cv}%< \w'BoueDLϰ:C@yUtA8 S>Bާa2Hwet&mSWf_&"J(K[JٰzH$琋wOqd/<of4HvV C`'ˠJ6|9ެ>k>eUҼ+DPv \P'"Dq$_ƲcPByGq8b݃5fd'{+lO0]mHf 1F<\-304(e`^1"iX[*qFD\)LҌ&y&ۙćXL̶\+c\B{W<$I"w'qDRo!XP9IzԳ+ eGTKwLDè^ J/֘F]s͙%A.'W&e[ɁX6{rAR;Hg崔 }ΩG \`S)421X;gQuJZYrKBYi()H38 DET75aҥPO' x}ķ&(ַz9J *Cw B:ϥ\j!misIzCB*:g .d~0+LVCp bڗbd]u-_)-(2-N o:$93B/8t"NN<ٗtr6oMU6穮꨾> ~^g[lG}@>uC,緺zlN^k+c=i5ӷ38\A~+ֳYEU~q B~{!KrEÅ4f}UڊvT{WSI;=uLTߏ{LulޟEumӋ>.5\Yg)}zbHG#] ;..v%qmy归M(A;Rn.u?JH^`13[(˙0tbjhWGxa$6X;OS)Noys!ܳx1\;? J`ړ=ׯfvgPϊHPgO=} TlX5s*p] 3ɸ٘l cE?\H9Bjcw ɼrh.'ؑho/2k ,;41wPOP+嬾6n~cJBj=_n>FPIG^Z߿Sҽ#4d\%8t)'qܤ ןWh RjĊ3>@mkB$#(CN`u$AdAUVA gp!Nv!c!ֶHO(䌌\&Qi$aWQ\PKj\Čb4*X IdDX[(Ud-F].:4^(Uk`+:cID+rkze!JbkFrS)MIp$ցgT"/utmJRҼYV!f"{7&ێR½"eIK !U~{1pڒ<: |ѫO1lIi'I.+ҧMܒSSH bn`N!h!z: 8U^# iuW>ޞӣ:bfv ))-S.12U!/laF,[ȸg^]Cu󷜃 F#~{ p}躓k*X_:7W2̻4WY|gg/{EgLv9)T<̻DR|NO 5ql5@e.~v4WVC8(Wmobtvt{~'.]Tui!.6E涸 q@L!PJS13Ł!@PlOuiUбfwBBü(a"7P/PS\)L )qgπ'鄹Q-ܒt*} Tbn67~D:=Bžih +# G8OjRz_/cS]apz)5Ԧ=(-jR_Oc~QF37ΔB#=GP "ZksW&gyU<&z2BVL>1B7Zrr4|zm>9vxUik2];pD:!]IwE(ի}~Fth<%ǔfGi"pM>xhz`(.+0F]W.N~|u%O^k s\r?~oXV;"TJb9W-7Nsliݕ\OvS^k CHp0Fo9+Ҋ+CZ0NbO%욂Rͅjt  UPaO -Isj@>Wg%>;=BZʑ(1o ; bn|ĸ| Im+֊hQ%PG`9ūJSmj68`N*u 5flF-tĦ B61mzǰ.*ƒ%@V; Ox)8,7 sf$S^H杤21@,a(0?RGEOoc yd]?p(5xc(! mEA-ޘ2R; ̻R$&DkvC[:!N"` I ;xnSqr)J "Im*?Ec$w e2r@'Q{*]HL/ '!nlF@\Ⱥ)o3@v1lOCܷW-XW>@tϭxڅ;*8LmblB3w,:tԽAY󢎚AwW9Bc6䒧R(]䳸O->&c*N{j VY>8Wz)ٱ4?U|~7bC)5]8\i_J̞$G+ L /y+"O|q!WZ%C?8`C|LOѭc:#5crb*v?)]}}f>5䵊44ruG:k'?_Q|%-) QKгCwHPG*h!BQ8gW j\3ʳ4NNآw._a,>$B(B8{I$%#\L5dS)_K ꭓYòg^)qWaJr w(R^hjRFɏvgv㕯K Tͨ^e9Чw;;Kr$3"S#xw.JW1 vnWR{8gWv!r2R@JP2[ 񚨟JT[%r8*' £G4M܊f}B.$,4bT e6ΟH˧H-WE[ 2Bz7Hۄ>I !W$ienp]D:3/+'T&_>xΕPlRb^&{ސ>[@S{Fb^*szH pD:<l) >UZ$kU(QS9uA^{ ep%w=$(i QO*jL_ zN 6{c߭eL?JkG4{WturDg /Osaf b 2tuoJŗk[gV`lGz62׽G.7:-k3dt-v{Sh}$RZOeBS1.gu\"Me37H./4_\vķϿ+pqVyFa9ueC:Wv"gbNܽ/s-R)FGTڮGDx5|bIyUquq4Uslb. |ճ &?T*8{~"7-g1CcjEr/TW Xk^׺2/3\gb[D0ޛjyƹbȯt]5dYw`Mҏ <B B]1ht) nHU.ƈ>_i3v*IKOz_eLX5UѮFȲ?gxɚ)V2#( Kr*W&r/OAZ+^H2ښ($O@< O1ЖLPW:!'<`3]M24NZn"cw rC`3Hkj&63YOY;)yK訜 ,,ɫm6 CdO%.Cbك)o6c y$8杄ر^]xHC5CjT 7bLJȬX8};=/Ղ6Xzd(@2l;#J to "ڄȫaz2G0uOH@K%\I.`g7żz5I:RBvF]@ J\ OEI!xf4 >9$='J3`DA]  e/$7NהA'5mGx,|eeT̑[(ײqk.*NX@'O<a\DCEWmՅ&B=ﭜh%4zm` 3P:wx_CCnr]jQ~Y#,HO wXiX9ӹV?^z_ԥ+všh^pV|>*war-K.εnYSȣ9(ťQQs}ӣߔo.a|R^;ClO(I8k ߉#3w<#gH{z}j׳/ﭼqZҽ9|M[gdb k#N^zßN9z/+ÍbpN>6y(Pj6}Q-^[0 J.a/[O˫@yW߳g~O g]{w {3*q8zD}+=QƶDAw@_~ +Tu5x*G_OW)xE 釄 | p $q d\Ypɧr~'S=Re`TX6;ao~"4 u5A ̈́srdo)4*j HS.iϧV8J6<}]ZHG1},IF`ʎ0Q)"wkrU#d0E2يn`Ub3AcGL{P8(X;Z,W .!'a; {pF ]IUAJl SȬ,IQ(5,, qGIU>IF IPJgO@d=Lm[RJ.g8ʠxݒGD@ّ6x Mկs#;%=*A|QB bi쐯ne.75 '1dHD:`LmRQQj=y2)AITWsʍ=iPLl!4bC0 k23[O>Hj|L efҤ&o8_CśqwqEFs3'(/ ]Op+kY5S~hNv|'9&miPVrUE2^rj迍"uw= %˵ȡo u5Dy^;r04^SL)Hg}2ǵ;K ? i>R^__* U-fpa޻J/$wSE.xm)OnG2fȡ֑!W\o=&wMF8O/r%$ҙƟӂή˂K4kg%Bm6>\{܁{<*5˨W y>5H6j*g:V;)$u-P*ð~$sW4V1\ˡT*\OG!Ѡ8oyi E߮6:Z5z{1o۽}P1Ő\vz_5%kcGy."Ʊ5p5te|{3t!w=Pϝ`t#;H]/~綗 ?4&t{X#ȑ􂢲FyW3 sWHg[yqLOqnBh|Dl$4Oo:vN5o= #z-Aم͗C&jF b3j:ˬO٫ 5$ddˁ֝h8iR1E%GT3 W0\ež+0`G :q߉VV+!ijrG vDe1PѷBZQ6~ X A9'A.:~֑5O -:( GR,!_W`@jG[MCiܬtJџWĴM&98O iK+6;Pj^;AgFִb ChԨKN WARP*KE)l%*/66ytd(rZeeB,jivY{<}˘w1CF詄KpA)0?RAaFw=b  H-s9'BwԱ bPL 0wg b #C@}O:jquDA jqz`{g2dNPv Qs]̔KaYNwHs'0` d6c#|~=7P]wrϮ-|G,v_gp6Coiőq E$>edKkKHa3H8NS\9y_RuP0!&Na*̫0 _z33*`xγDYWO}/JۧO h: ~r /'?;Dhi?xO0Z:bW qQ =xV׽CNC(l ~mov%t 띝b(n1zzS֔\pU0"_Q+Gɡ>byO _ 66n k$p]^Z09fwZz#L {.ˏ/`OǐaCT@X[B̡>\:Ί՗gR(%O8wAŵDɍg_1wi6ql=.vg SOiFk!fWB|? HP+(q ܇˳҄\V NGq [s!\)A'Kc0C50d:d_3UylWHo zpi7Et,)Wꡠh'TW AПJTv@*rSŖAPE1]P< GxbZkC`+ b+Dȭ/3bZ#{$҅rd* 5}/fưQy)G|)3;˨BAX&1a*E8ffeKuB +a(gr+aiĢ;:bb J'eVRyL ʀ"Cq^_QOiD|UVgW=8x6lXԩHG!Pp֧ఁNhfɢ"fc`NH̍|{[*2u^F›]Y cnW6 [uHa Qn:"'mSJc2zwNIA@5YC1Aľ0>po8YŷB$꧵C ]xH' SO'8*VbBcF:h-/숨DO?%5l8s<( O V|9hzwuM:t搚o@p]#o GwZ$rB)=C*?ySkf賹ܳ Ղn>lkd F.gm\-Yg3!~o(sn<^=Cb=tt\w'gEW=*PBzz}_"Ͽ09/>~RA=>}D k_((h;[:O jm\z$_̧ȾmV|.rhUq*S{dP[S ] u_E SZE/>yOye|@^ԮZϣR]qԛ~ XJ~p~2F U9sc`P)9뇅W~>S.dIu%{PL6W|ehzk8~9n#%_41SΘ}=؟rD񻐢#j%cy{'%{I}z}4+9#c]M/(+R}V^C*ʙb69qeBѬ|S(2+3RlR׏Pj/g&|gqߋp 0ߓqwR x+Jr\z*vUy1YY_縢k- k-;x1A'!.Zث\Άk+b;zj,@JaXsɥ8kΧr 0vdL5DuMҙk ?姩0ZJg#K%a.M J9. >諞urεAۑ=`r*}0=`g~GXu~R]=C}oQ$o9ZD;ttFpvpƻȌ,w#pA' bxE w2 ڕ OW~'.c1q'"hlfC l'!1>-8jΗE(@JPm52b@ 1mz>5>RPI{{ Hѷc^w |'wmIDQQɕS7Մ*٪RW>'83QsU]f :FHJ`I2Z%CpЮ *q%i|@^_ S|b/R2=kPTК+=GmTyUmә%b}$g>V/,doOZAƸVF9^X`\,4J0K_%oF\K0w"'Dj.ִ] PK9le.3\j{R>w}r?O>;ԫ*w{/Gܬ¢rmGy_y@=ΕF\Rdn*|:=|N0z!e9k|0f*y@n]]4ʔzܠH)ad.PR,hO/~F1@4ZUк#3+evjT̡CE< ~Z85FH{Z;lߑ6<˧[T<żLXzN*kaHHoњ("XЦ &ӛiuP2OU1YeEVɓZ/h1bCiDOh#sl]fVAm"M9(^}{Lfl+O?ĜLQs[V| GuLbN+ߪLrHKҘBT y*wyAd'aI:ZbU(HjcU4)?)?lC)_У5Z iz\ y*]=&]%h[uO2L iex;NЏ sLOvc 1naX LEɒxn.2O=QAFd/"X9߳`#9PF%̗2&UΚ}a ʣ"tDj[۰0=wJuS[%`sC[0+T0I"J T@ Mts H+o5e! [ w :W\i`dȉ0FhklQ30tgYH. ڭ)اBhP ׺lt7;l(k .߿+DyK^/??Ng+6Pi#;.\`C.wBYQ{; S쭸:H{9r5f*ߍyt"sMI)a?]n;Φʽ~zN hk(Q3~@Z7(%Gb$OXB[s(W>qY4 ?i=%hobe/F}*=3_NdKQ]N?wӽ$VÌH8fGkO.'kZs䆨<aae(? {!zk˿4( 8C4wFRqznB_?nK{o^N^ؗr OzS+H cW4~>́HnfȐ8~0>ʛ O&lͨ;qVy֢Men=fJea:R2]!M#tСQ4ɼIZ$esie(ؑ*s}^JXx r qͤC).!mAĴ̏jKE2w8PPp$GɷFJpK$15.H i X̟1YCSh2՟Jb +3s| `F~/HJz&2Q+#b숳UR)TSeСB!j"I큟y5GCjģ,mE6{r7(D&q@M֟@~7bS>BukMcXl;ŗbe^wdoS hsj󌀅vA?GHWMulKfH09 qh->jHW<~&(:NzKn0/?]zoL:`O~U_9P;]#X1֑^SJ@$IX#$qZ?sϤW `M_\~O؋{:9wQFO/Z?og'ߌOs wo:_̎;.!:62*߁Z]w9Z~kxT39.h ;-XyV_;ʾ@Z`|98Pa]G_%"[r ~o.X<ztS-+0n0/nfI!IT3s޷!qhܟx cu:+IYZ62"=Qٕ!W:dzXĥ1I+EO+%}nAQagڮLٌ+88f'Qo(}*lTz[ȟ_CȞeF++Bw1@oO`:Lm ⌞Q>WAƣ pɈ@}~%M`>$#4ָIx$YUڌ! fX+mCr<,o#I{Z#T $*&Y(y/${ҭRWxj) iO 'N3ԟ}u`nS\!w TCid^Ľ+IH꣐"NOў|[h+a,З!= =PҵͱKvrʖ&I*!s9=˻@O`+16y盩Po|vQ}?L*}5_?PM4&{0(&NCԫḥwx:3t2BfҔ{O՟5+xﱳH[_*o,Bg~{\':ՑhcHAW7;]2\_.8 \~+c*nec[܄<`3=osDK[ ܭ 1vS]2_baN85 ˧*gj(gp{i/"o=#Ur5WB4G)dw =gB^xJN3Aw/|U$Rt^]>7zk|w|;9.PO 泃UZ}P?+d&oSpRyKԽ-l(ƶ\0}Mx<#9|o] h;kaaaO2^Сx?? 鏔.G julťJ?%$,da(πZ(y3¶Wu6`h|f2|FBI),bm痙uoEΰ]#`7gZ7];dQ4.o'ϠFWaО81*GDb{KK#6ŵ5 cn@%=K M\Z+Bd+A+S,`R _d㑉<1Ejxh',b$1qGsIjxG*F/l (ǹ",3Bd"㤰LrlL}=fZᶾ1-fd!m dC4*T{ $RHW% tۧ b({20eDU)mwz X,bV[L?5b @=yWV B~){RPڎ:Lr$nSƵP?Mu ,sЌWMcGOed'4I6 K>5~ᛅ(c\ݨ<([uNÞ )g+ 4uGӂ9L'yg40n?1Drk?Z58J3g }4W$زB?3\]biQ؟$7oLiPk^EeuCǮgEv#Y^qvwOw9o[%|?p9(S*S;z2xC_%^l=tvJjjNCR⹄e;9Z`1!JZJ ݧ0P{o*=I3U^4}{#_Gov7*sQшOkFڧр-nnwG$? a?nc_{ײ??⛈/J2rz<'a[O=O =`^J}8L:YrB,i텔<5)btٌr}BAE4f8 j@\;r>?5ȭ!80U(mKZl9-H0 @_L$sy$Z 'Z2㽐GIPF֜ =źu3X QDG|[ QVF9}8nW;RoF#LH]uTB}~秒팹J50Ȫ`̂6͆g݄@{Hl+oqr-BJlO A`J}B:;- 㢶aēNi aI:grFZҖ~P.gܔ@Y3ĖW XbWCJLܿe3!g,Wr Sco{T^xGS*<-Jxg% &-)A<ӷx(0}3=P߿2v#O]"iԻ1|s>G_Ks)A oۇ_굖^YX,؜^ O$|+s\UrΧ!wj%/S0_\rw^<' oYsm-%LShfKI.uBrLzUTW0]ʀv+?LcL@Ӱu,@wnrեϩΌ+>N0Y.gR7֊L8WqJVG?|ww|=W^5 -{QX3`(?2:3+}RH47 + r ':BݿJ ѷw^w֚.;00$[]|)\s .}'9Q+[S^-)Sѐ$s[f#nw-R.Cfnxij yN|ۮHh.͆ԃ"W+f4ɯbX.hOӘ_yO> ]6LÞ1llR'ǾFBSb^J FыǾ Q&m-A@mLv>L0teuOWLmdJ(@{xP~RO8 gY;p;l$ w<Afk!] R0v7΂!Է`]&3:kDlCҊs-ںDX @jjΈ}x 9+ Jg !Q֒eBD>GsTfixX5|u@B]N mȖu^X{ec>'jbIA-K; ^HsO=Mb'ri;r8 MiC6i a 32dkPE< ?H!m:fe0 Ho덣+ b9Z9=ԃc-_|R0zwKϻ݊u>#XW[3/ *YxYvmFtmK3@LOkǤ#[&_?3L GY7,CK?ݱru:;ݑy d|56r/5 \2ӆiW#n]J+礫``GQ-t;J˞ D_ow>Ohxqk>kDvkQM:~/&CjrgWuU_q[>?%l^˳2_}wl{//e0ɏw̤kO5('ފ`~^;'2ثÍ}AzFai)@Gܨlw!U`ܧ1G iw0)Ϟ}z1Ndox:O@,1aQ(>R/>EDVqwU=PyZtO s_I"^>S|7dރcS/Lϧ5)O3HUNqbáz֟εPK)"KN6 K7"L[nY{xcoK%`_`ea$NCj(>a;3֕gՅWލdZ(PZ%*SC32?#Bm]SQ1'(!vH&IA]N%TnH癑tZ ld&s_ muLX9H7<j(ӽnI]Jՠ.B8y앟Z^K䟏@s`;s>.\ i+isg[QF.!v>ŕ5P9ůwœ(@x(-U5)?[2Q[,K]z,n' kg`1P4̕e)/vZzA%t|r tCaCu"Gc.]szp Z5|H)D*k8^cd7ي-|)rWr ӯܺg$GsǗG_}規{B<ռ`=JI*JcW6-cF,D]`e |gDѝ10b͎X$KlAۃt <@.+ Rn`~{?u`>aSZXo'7kN0P:+4VB+Rr}";'٧ݚfM{`xN,4xPFL}ǧ{W1"PO!:S]D 'Y‚<Խ}~NTg +t.`DjBO Y'$i\gi(@^a8r֛!JD`tC*?Y$} #P}&'li>)b9Q-"ϭ)j(%|< +d;EMkX%t,}ޕJ:m)"}))q0!T 1ۄŔIjAc4;J i6+*zgPyw)ǢHjb=9Et"J<2i5+Cz7Γo5;l-`2p^VckV VkDB1Tt֘?[J/AGET݆8Sܳ3!@Y ܇ƞ+\g49 - q$K%IDÜ+ϥX@SΘ  Nx=rَVa$l'yț%AnT'ix "듹msrd.³c;%mW[.Α)E u싺*@ zC%#I2'% `{]`-2W>'9ٳ *Mn)Dnsu]81MWŋ$,9h?B']RT'%,ƺM!PQP*9 c~nV\>ϩjIbOXG}u] 1KW9G(ngCb\[xͿgR>{k\V$nwVW;< 0vw 8 ivqssO 1pygб7m3hޞ_ɥ X||z W6@7tSuRx&qrîJ.1~^O ;XyʌpwڃS|wj^‹W F2V5yn $43-TEWFO@WγQ}&I~+%'k0OǼ1]C pU)8$&r.y5V.绅  ծta;&ui!VK[{ռ5$?(-R| PvSj`]0M0"Rc}kUJ`s-}_U)Ve +t iǴv RM=A#Tb6ߑ(R >բ*N'⹘*:"Lq4M mVY.2ԹX]9r^3&F$0w'd&gl ܎;iOr`;#ZB-jXPe7a]1 iRO P`oQdK B4"c \/agMBlm0;scb]mӫ~'NS 7\ >Oũ;DK]6bۅ5쒽%Z- M^q'u\[mw:իL7Qw[qS!wMv}wMދL>lk) ;>?QpN”ݸdd->aI;}`k/bS6doCB%[*uEAA.r?.Jh)G;3y5ߐL_(#`1h;q?s}A)=|=hBdQ+⸾)-C1Z5@{kr6ZK!SDj}8 Y{M|MgPzLC3D-!g.c;t]4ʧg>l=}g~:E@s O%7x]D'ͥ^H*.:bwz67Flrds\|==5r&SCU?px({y?3H-FHՠf)`f]ߌ%8q}fKR{* UkS˔=C;VV|麂HQvD]Њ +vqV7ú"] B ҁ0+ RyXo=arҚ;G`4'^ "߆ړZf"O{hUcb-xܝӝ=xdDJ#:R/F"!ӌ*8xD-2s=(a&w GdƧ@:d֔{)1VAڠPBC3`H˂Uu=DJDoog1":^FKq3G' bFFCh$U"å3# &2e%ȧ܁ka\bLw  i aVt;R[ޑ+x"o\ s3mKҮθ8[>DW77fhsvevLX8%wA]HGT M(a`za'{ ;y6fvT)˦1,(.%Tovam1 XZ^ALA`+d$=*:9 df=\ *JS?E2j=8V[ަ=S*]ϲTMɇXZzɵD&;ڞlAl RϷټvYVg?_ޖLƵ{%ބHRWW^ u$cwBҳ\90Rެ˫9>p[r oY!AGޟ6`~M ӟ >׏L~b+]iZ=aX.x`gؘm%wt(^6}(Q́`~MՈ?ϰWY^jVQP=3 s&3 #oM.evxǣ_R<ޣդՑ#˿$bkD Yp!fm bqPhtj.e'M1L齍䑰GWzy;#@<*@ZJr:3Q~c2'u5E^:E€l`gv忍^-cr`fv7XHlm)6|F6bg sh!{i BZ( 7=#zro&]̽c>wluK86髋{{`8XCrԄj@ \>ʼMTjm0;t&-gOucd;tQSAr>:A=øNmķ1|}#\m,ɝHm%3iBŕ=G s>Bʺ3N};> Gy>%/յ5lsm"3U^ٓ a Q a|  ,k+WHkWp{VX[`rȦ_QnU EO?%rh 'l\Ax.~iK&du1[4غ&i]︋Y9ϭ 5o iwac؄!J F9O f1kڊЌPeN'tTMC<`mDʘFĶ-XvzUӰ6D&!Hty,T\Je&WӷlPE]f*WI.=V~6&G͋G$#AAF+jeԪ.4rD =bT(W+q"xi˵oMZD ^U p*.'Ww]rij=!dn6!,r=zSοeXpB.5BƼ0qrDS M"y)0YFn}q6SNϊ'#ݍ\#[qX*pR#MȺIiWӗil3l8wsSm&~dC)fhxƑ3=7ǹ ŤR,x#wcIe~Mb ӸDl i^,x;wXQ3mAgA; !N7FMr=~l4p3|ooyD46?o]8V]thv";O庳A䈫Pj;n3+&y<q7|PbgIƀoL?7-#֮~z #k)sM=@y2E9$5:"1 jYL ʥCWA!TzeR6tdpZbض܂^qyŀ/Rb**lRAtB]ӕLBD ! T@ ]b12@}iȴig!_]s99 b[Q*VEd, 4QRZ=4g6${kC&YwljθgdӻBYo& \%ۃWx.1&yg[=r@ Z>a\o4kG\J+=b38uKV x11_K]M瀘$s3u'ͫQk6j#clb-=,66ܗrhhh 0r=H JOF)QѰnJ&+ԏ?ZhJʚ`CG ! R Ⱦ{W9(LR;z l${CY b\ rLqOYO㖠hȜPiBk2 {5KJ.pql9b+`HANWL'(V9PSGwMK 0 LVإV봍[һ+{XFcV."2eR312;`ϐJp7NOD8G>U.!Pp!7r0sa6ܩhD̋-R" Q9ͩ@;">Y݅u.FR"#pWbXp9NQBo, dJ9hE‘># 7ǟkpjc? o3p Ƅ#PKJ; =Jx:g۴ݖ%Tw>dc&Ό|%Hߔ.0,R?ņc΀|6$3>A8`uAx`R' 5Y޴6,ktl7=Lؒ{Mahgv[th=8fc3ƣ1K^rŰ>(.{2d[X+,]'oyX>Y1Ki6BZ8#m0l.p(J\6q:2q-U,6j y_ y c;#5v֑)~73-]oI\vpQuthnJ--鵝~u(vGAJgnpFF(|rx9IW1yxWm>P) Mv龲 fw#37éu%-3թb_Scy:~Uh C;wmt=Qo>_39s$H'*m'9ڮ?⫴{3"&>BrL:Ӎԣp]+Oui_ߋc>[FWSɥ߸tvۉ@]rx'V8EG|@>ڝCoy<$`w߂ƕLP<%83O g%;i`Qwt5`[,<^J9q]'ae$wieѩkL0BIK=|+rsH:NbJY%%S5?uE*DJ03sW X:\_IwfA &3CijC G]IV?&"Ѹ~>xi 's[^Tb8wCGsE̠Tgu/s8ˇƎ<õsaz.cXW崔<+9|*G> Cn.~?z0ݕV p :XԮ %v)z]z*C(\YVx>ItkաǞqbGn]-aK+x[9O=м1+;@A(aJpm5@#τkyP"Www'Jk=Y\g\7ؙx(keH$*6_3)bnb5mnVOܢzo,&SMSm\l^B@u,C,9=7[ȍO1X]6]e (ÿIZ5s'(;t' ^APw .G[8N`N#1;\`o)JOx}jǽ).0AMƦn͕?tz~M)i5}ȯ{8Kx.qKL]2a5=hDsVlBu-gC^_L'! GiC1^F&1+ Ri_,r3䒑ֽiY?ww2 bX*VG]8jl7j5KW-1"^F_aLmȞZ_l7 hz$ՉZLU[*:*S_>욍W˳ DmS7z< c5= NM6]bG?R6 "2⯦bm %r.Fࠂ^S/-­3zȇ9qؖk4UKgTǧC×b1 o./MN7%+=9*Wq J+`zakT-C>-np _K?1#,Em6lI#b4Tl"΍q3#'i <x@($?A&*Y=$- D\DL2##S(u3r`FqF^ Iʈ&>G&ߋbO+s35A:k-Iv!RȘG%tV0[6plw(&:nMMbh-y+&E|sϧ!u]2Cz7v)ꑮLsCC_kPW;l\MsF=3%Fo(֓+* ;\`dWΌr_ٴ]?b1c6Pw=1ud& cz^gl/)Iʶ͈nh1"t>$X Fܚ 'Шx-Y=Vᘹ?ńl(Hr>k+80SфL7qgS3'jg׍"Y~Sbg0 J!io&ڟ: 8d9'E1t T^Ys}~LOW@|C#xT'g5{HI)bDcu{Z̢ef=j(BUZlY my XczPcҌ'gtso/=w:r4384*#sqzTVI/ Ogs>an:KD쉤8B$`:TL6 $ڧµUb?|{qmVC*b mv!ngyݥ Ӝj*TO7oߺy+zgh \9ض啓ӵ,G0lCRm`I"ld!`tj-Ji2uO<exˮMtG:<y0ඓ#g:(ZNK ?G0-DpWKC;>l'Ε]Gw ,O)2zB8b[$K筰Lp4~8}Uˑ)Ws.[`b(@̖.ڰ꨻f𖃩MH}J4kڠ9ws;rr Ywې_txL}l7oԧۗO%6G&&9H MQi6~o Y5H,;Q]-rc&p͎]![#Z:OMDiE>S*g'hCY͚N1w4y6p26ԤO_o5.D?:x[]<[FZϊ[M@z&HJJ.5 F@j Gw֌/pTBq|N'FX՝(vs6%q:Dbu+t XqJimcCQ_X (]ZD nC\^85{~ V*N i u1qW'Bu-cP+f$vg\|!hfwљ QW8 ^B7A=DN`FOHleGdt9!JU 4qώ' Q~*ཷia_MNrG(l{waAJ{u&e8[da5FӟmP .AYNS쮂iD'QMJFw0l0$ԆĕrMVifbro @bgH;=`UCk >`w;rxTg7Q*Fmh pmah4ݺH;xgL~Jȭ w6m$4o=P}ӣO#xygebӻm&p\ߕ2W'yߜ#w]g*+3-VɚC;S;A挵eݜ9i+C^ݽΕy5DI824r; DoN^^M~0@V'Jg vZ` vgúֻ nFS^yt]DtWs;|E:$&w[!0We7|[i/A0,cwc_8OBl װ)WR Unak@^ץgtǹ"gubq%7 ߃-AiU  MHkNgOE.dܿ ;&~egy#e԰OebWܓdrAh'Iz|4>Uh>|B[I$>BuUϤ2${5֘m#I+G{}F؇1<#w=-PlÇ̄p5Dbm|0^h0\y1LL%rKh_Mh+pĤp^'ɨޓBMYJzj;3R;#j?OV=ٞ"}E0m6t9루UbyX idNXv!D{<RKn]}~';IP'ac5Ihx!:sV]=Y@]F6Ke@f}Ve vu&;3Eq@O5M8ڼJڟ,ĄU Q;nf0%ctn؇;UO汓3;RXn >vWdȖFsL$@Ku7Ddrzg-T8hTvv,< xC&kUoА׵WOtG k H;^}U`kWgkx/xte{83J{7n^Kԁ6C^JbO'i:M͕xrK>..".E6Kwx\Øz盘oL!]e{4~G'gמ7О|~-K7FVO5ΰ?5^ jvarr|ԍDI?t_{8p- }OxeϮ-?J{:aW]nq߉A@zec;=|\'3N:sw0kr>+y\_w{}r7 0e4v&T{TQ=r+Em(cVZQk W|:Ӹ:p.K;wxI*=܇_o}ͤV?+ )Xq8i Ӊ|8ɇ%6KXqJ{(I*h+@]|1J%>XG)]V '2ώ6M00bS 5+ٌQ0QUG !M,xY9YX@Ox P w'mLq.#Pfvg2Ҁ(Jd7S@-]ɴtXTs593Rl#c л0]BAjD -5Jz8}I2wl"EWD&ʬ_wA& hܳO2!LLp l@zfұq&O |\~:I4v WЎQ9|&sfmr7r\ %eгkty|?NosxJ`{&bU:y^qLz,JFدfB߃}z-i*z~7b̀jYW m,Mk3( 5!.p+ўwtp*fϴz!Q<&Op]uN[, NNqJ>\}l>FkjD^q@5ן~;8OPXM醱4BaE٬XUJenӠ" 9Q⬡U!1Ŧ[Ih㝩WzTbjxU)nƜ=:AV* WgJD5F̢t tɖ̌%PG JMFPۅļ v@ԅ 830u/g,8aDBrq@Ѷ9"3I 'P> }e2]-B=8}XYa'RԠc:!@;$Iqf䦣`=œPudŭg]eNaf6}⟂󧰠m{Dǜvg-QAϭ`+(( 6Lg!<Akʯ5ߟ{H2?stۋw{mN;ȴljW5<3f'Cɴ R+W PjWNy?qzY7g*?rIaF>|;aF߂47vY؟r']f#WUYF*\-4OsFr~O._wl zoY_To'Ec e$_`ORz7?\7Gc~jg%_U=nFwI_Kk(ο]h!]͜^ 2+CrUMk16Woח9ʸ7 ʯy==tuRӝzU_%Σ][y'BaW_Y,oʈce7UNvӢ|G/K,#p5G7NgEV5?Ѐ)A\ޝt@Eidg?f*n= Ii\}vha-#VNCZ죁. ]+&TO)1gG\$|&ЬTvE|& $4j tVYEu&.N$b]@H!s<6ʜDp@L#'Pۉ!cN3EmbV'˘z7ڈBJX:Sg",;s-B\'; /d&ȟMk)(eB ԩBE6ٻL3yÿ)%T FFz'8/sBHa{ hyʏyrҎȢMdLa~,U& DS05OaNe[ Bg\ UPvZߨqbP+XqQfƯCoJA<M93(c5Ȫ ِWԄuHYm^!8}3Њm 5 Bv#8PpUpzw*V ̝%Aʮ5 i.$=@} >Y .b8ҪG22<泫R7Z}.Ä&9IENDB`kramdown-1.17.0/doc/documentation.page0000644000004100000410000000541413321140127017724 0ustar www-datawww-data--- title: Documentation in_menu: true sort_info: 7 --- # kramdown Documentation ## Overview kramdown is first and foremost a library for converting text written in a superset of Markdown to HTML. However, due to its modular architecture it is able to support additional input and output formats. The following input and output formats are currently supported: * Input: [kramdown](parser/kramdown.html) (a superset of Markdown), [Markdown](parser/markdown.html), [Github Flavored Markdown](parser/gfm.html), [HTML](parser/html.html) * Output: [HTML](converter/html.html), [LaTeX](converter/latex.html), [kramdown](converter/kramdown.html), [RemoveHtmlTags](converter/remove_html_tags.html) (a special converter which removes HTML tags, normally used in conjunction with the LaTeX or kramdown converters) The [kramdown syntax page](syntax.html) describes in detail what is supported and how it differs from standard Markdown. For all available options have a look at the [options documentation](options.html) or have a look at a parser/converter page to see which options they support! ## Usage {:ruby: .language-ruby} The kramdown package provides two ways for using it: * **As a library** kramdown uses basically the same API as [RedCloth], [BlueCloth] and [Maruku]: require 'kramdown' puts Kramdown::Document.new(text).to_html {:ruby} The second parameter to the `new` call is an options hash for (de)activating certain features. For example, to disable automatic header ID generation, you can do the following: puts Kramdown::Document.new(text, :auto_ids => false).to_html {:ruby} The default parser used is `kramdown`, however, you can select a different one with the `:input` option: puts Kramdown::Document.new(text, :input => 'html').to_latex {:ruby} You can also reuse the created document object to produce multiple outputs: doc = Kramdown::Document.new(text, :input => 'html') puts doc.to_html puts doc.to_latex {:ruby} More information on how to use or extend kramdown can be found in the [API documentation](rdoc/index.html)! * **As an application** Together with the library files a binary called `kramdown` is shipped which can be used to convert text in any supported input format to any supported output format. It either reads from the files specified as the command line arguments or from the standard input. For example: kramdown path/to/kramdown/doc/syntax.page The input and output formats as well as all available kramdown options are supported through command line switches. ## Tests kramdown uses various test suites to verify the correct working of the parsers and converters. For more information, have a look at the [tests document](tests.html). {include_file: doc/links.markdown} kramdown-1.17.0/doc/quickref.page0000644000004100000410000003666313321140127016676 0ustar www-datawww-data--- title: Quick Reference in_menu: true sort_info: 9 --- name:sidebar

    Contents

    {menu: {options: {descendants: true, levels: [2,6]}}} --- name:content # Quick Reference Below are examples of all available structural elements that can be used in a kramdown text. Since the kramdown syntax is a superset of the Markdown syntax, only a small part of the available syntax is not available in standard Markdown syntax. Note, that only the most basic syntax information is given. However, a link to the detailed syntax for each element is provided (which also details the differences to the standard Markdown syntax). The quick reference is for version **<%= ::Kramdown::VERSION %>** of the syntax documentation. kramdown has two main classes of elements: block and span-level elements. Block-level elements are used to create paragraphs, headers, lists and so on whereas span-level elements are used to markup text phrases as emphasized, as a link and so on. All examples below feature the kramdown source, the converted HTML source (shown when hovering over the kramdown source) and the output as it appears in the browser. This looks like this:
    kramdown example code
    Example code converted to HTML
    Live browser view of example code
    # Block-level Elements - Main Structural Elements ## Paragraphs {kdlink: {oid: paragraphs, part: "paragraphs"}} Consecutive lines of text are considered to be one paragraph. As with other block level elements you have to add a blank line to separate it from the following block-level element: {kdexample::} The first paragraph. Another paragraph {kdexample} Explicit line breaks in a paragraph can be made by using two spaces or two backslashes at the end of a line: {kdexample::} This is a paragraph which contains a hard line break. {kdexample} ## Headers {kdlink: {oid: headers, part: "headers"}} kramdown supports Setext style headers and atx style headers. A header must always be preceded by a blank line except at the beginning of the document: {kdexample::} First level header ================== Second level header ------------------- {kdexample} {kdexample::} # H1 header ## H2 header ### H3 header #### H4 header ##### H5 header ###### H6 header {kdexample} If you set the option `auto_ids` to `false` (for example, by using the `options` extension, see [Extensions](#extensions)), then the automatic header ID generation is turned off: {kdexample::} {::options auto_ids="false" /} # A header without an ID {kdexample} ## Blockquotes {kdlink: {oid: blockquotes, part: "blockquotes"}} A blockquote is started using the `>` marker followed by an optional space; all following lines that are also started with the blockquote marker belong to the blockquote. You can use any block-level elements inside a blockquote: {kdexample::} > A sample blockquote. > > >Nested blockquotes are > >also possible. > > ## Headers work too > This is the outer quote again. {kdexample} You may also be lazy with the `>` markers as long as there is no blank line: {kdexample::} > This is a blockquote continued on this and this line. But this is a separate paragraph. {kdexample} ## Code Blocks {kdlink: {oid: code-blocks, part: "code blocks"}} kramdown supports two different code block styles. One uses lines indented with either four spaces or one tab whereas the other uses lines with tilde characters as delimiters -- therefore the content does not need to be indented: {kdexample::} This is a sample code block. Continued here. {kdexample} {kdexample::} ~~~~~~ This is also a code block. ~~~ Ending lines must have at least as many tildes as the starting line. ~~~~~~~~~~~~ {kdexample} The following is a code block with a language specified: {kdexample::} ~~~ ruby def what? 42 end ~~~ {kdexample} ## Horizontal Rules {kdlink: {oid: horizontal-rules, part: "horizontal rules"}} It is easy to insert a horizontal rule in kramdown: just use three or more asterisks, dashes or underscores, optionally separated by spaces or tabs, on an otherwise blank line: {kdexample::} * * * \--- _ _ _ _ --------------- {kdexample} ## Lists {kdlink: {oid: lists, part: "lists"}} kramdown supports ordered and unordered lists. Ordered lists are started by using a number followed by a period, a space and then the list item text. The content of a list item consists of block-level elements. All lines which have the same indent as the text of the line with the list marker belong to the list item: {kdexample::} 1. This is a list item 2. And another item 2. And the third one with additional text {kdexample} As with block quotes, you may be lazy when using the list item marker: {kdexample::} * A list item with additional text {kdexample} As the content consists of block-level elements you can do things like the following: {kdexample::} 1. This is a list item > with a blockquote # And a header 2. Followed by another item {kdexample} Nested lists are also easy to create: {kdexample::} 1. Item one 1. sub item one 2. sub item two 3. sub item three 2. Item two {kdexample} Lists can occur directly after other block-level elements, however, there has to be at least one blank line if you want to follow a paragraph with a list: {kdexample::} This is a paragraph. 1. This is NOT a list. 1. This is a list! {kdexample} Unordered lists are started by using an asterisk, a dash or a plus sign (they can be mixed) and a space. Apart from that unordered lists follow the same rules as ordered lists: {kdexample::} * Item one + Item two - Item three {kdexample} ## Definition Lists {kdlink: {oid: definition-lists, part: "definition lists"}} A definition list works similar to a normal list and is used to associate definitions with terms. Definition lists are started when a normal paragraph is followed by a line starting with a colon and then the definition text. One term can have many definitions and multiple terms can have the same definition. Each line of the preceding paragraph is assumed to contain one term, for example: {kdexample::} term : definition : another definition another term and another term : and a definition for the term {kdexample} If you insert a blank line before a definition (note: there must only be one blank line between the terms and the first definition), the definition will be wrapped in a paragraph: {kdexample::} term : definition : definition {kdexample} Each term can be styled using span-level elements and each definition is parsed as block-level elements, i.e. you can use any block-level in a definition. Just use the same indent for the lines following the definition line: {kdexample::} This *is* a term : This will be a para > a blockquote # A header {kdexample} ## Tables {kdlink: {oid: tables, part: "tables"}} kramdown supports a syntax for creating simple tables. A line starting with a pipe character (`|`) starts a table row. However, if the pipe characters is immediately followed by a dash (`-`), a separator line is created. Separator lines are used to split the table header from the table body (and optionally align the table columns) and to split the table body into multiple parts. If the pipe character is followed by an equal sign (`=`), the tables rows below it are part of the table footer. {kdexample::} | A simple | table | | with multiple | lines| {kdexample} {kdexample::} | Header1 | Header2 | Header3 | |:--------|:-------:|--------:| | cell1 | cell2 | cell3 | | cell4 | cell5 | cell6 | |---- | cell1 | cell2 | cell3 | | cell4 | cell5 | cell6 | |===== | Foot1 | Foot2 | Foot3 {: rules="groups"} {kdexample} ## HTML elements {kdlink: {oid: html-blocks, part: "HTML blocks"}} kramdown allows you to use block-level HTML tags (`div`, `p`, `pre`, ...) to markup whole blocks of text -- just start a line with a block-level HTML tag. kramdown syntax is normally not processed inside an HTML tag but this can be changed with the `parse_block_html` option. If this options is set to `true`, then the content of a block-level HTML tag is parsed by kramdown either as block level or span-level text, depending on the tag: {kdexample::}
    Something that stays right and is not wrapped in a para.
    {::options parse_block_html="true" /}
    This is wrapped in a para.

    This can contain only *span* level elements.

    {kdexample} ## Block Attributes {kdlink: {oid: block-ials, part: "block IALs"}} {kdlink: {oid: attribute-list-definitions, part: "ALDs"}} You can assign any attribute to a block-level element. Just directly follow the block with a *block inline attribute list* (or short: block IAL). A block IAL consists of a left curly brace, followed by a colon, the attribute definitions and a right curly brace. Here is a simple example which sets the `title` attribute of a block quote: {kdexample::} > A nice blockquote {: title="Blockquote title"} {kdexample} As one often wants to set one or more CSS classes on an element, there is an easy shortcut: {kdexample::} > A nice blockquote {: .class1 .class2} {kdexample} A shortcut for setting the ID is also provided. Just prefix the ID with a hash symbol: {kdexample::} > A nice blockquote {: #with-an-id} {kdexample} Sometimes one wants to use the same attributes for many elements. kramdown allows you to define the attributes in one place with an *attribute list definition* (or short: ALD) and just reference this definition in a block IAL. An ALD has the same structure as a block IAL but the colon has to be replace with a colon, the reference name and another colon. By just using the reference name as-is in a block IAL, one can include the attributes of the referenced ALD: {kdexample::} {:refdef: .c1 #id .c2 title="title"} paragraph {: refdef} {kdexample} The order in a block IAL or ALD is important because later defined attributes overwrite (with the exception of the shortcut for CSS classes) prior defined attributes: {kdexample::} {:refdef: .c1 #id .c2 title="title"} paragraph {: refdef .c3 title="t" #para} {kdexample} ## Extensions {kdlink: {oid: extensions, part: "extensions"}} kramdown provides some less used functionality through a common syntax. This will allow the easy addition of other extensions if need arises. Currently, there are extensions for ignoring text (i.e. treating text as comment), for inserting arbitrary text as-is into the output and for setting kramdown options. Here is an example that shows how to insert comments into text: {kdexample::} This is a paragraph {::comment} This is a comment which is completely ignored. {:/comment} ... paragraph continues here. Extensions can also be used inline {::nomarkdown}**see**{:/}! {kdexample} As one can see from the above example, the syntax for extensions is nearly identical to that of ALDs. However, there is no trailing colon after the extension name and the extension end tag needs a slash between the colon and the extension name. One can also use the short form of the end tag, i.e. `{:/}`. Attribute definitions can be specified on the start tag by separating them with a space from the extension name. Also, if the extension does not have a body, there needs to be a slash right before the closing brace: {kdexample::} {::options auto_ids="false" /} # Header without id {kdexample} # Span-Level Elements - Text Modifiers ## Emphasis {kdlink: {oid: emphasis, part: "emphasis"}} Emphasis can be added to text by surrounding the text with either asterisks or underscores: {kdexample::} This is *emphasized*, _this_ too! {kdexample} Strong emphasis can be done by doubling the delimiters: {kdexample::} This is **strong**, __this__ too! {kdexample} The form with the asterisks can also be used to markup parts of words: {kdexample::} This w**ork**s as expected! {kdexample} ## Links and Images {kdlink: {oid: links-and-images, part: "links and images"}} A simple link can be created by surrounding the text with square brackets and the link URL with parentheses: {kdexample::} A [link](http://kramdown.gettalong.org) to the kramdown homepage. {kdexample} You can also add title information to the link: {kdexample::} A [link](http://kramdown.gettalong.org "hp") to the homepage. {kdexample} There is another way to create links which does not interrupt the text flow. The URL and title are defined using a reference name and this reference name is then used in square brackets instead of the link URL: {kdexample::} A [link][kramdown hp] to the homepage. [kramdown hp]: http://kramdown.gettalong.org "hp" {kdexample} If the link text itself is the reference name, the second set of square brackets can be omitted: {kdexample::} A link to the [kramdown hp]. [kramdown hp]: http://kramdown.gettalong.org "hp" {kdexample} Images can be created in a similar way: just use an exclamation mark before the square brackets. The link text will become the alternative text of the image and the link URL specifies the image source: {kdexample::} An image: ![gras](img/image.jpg) {kdexample} ## Inline Code {kdlink: {oid: code-spans, part: "code spans"}} Text phrases can be easily marked up as code by surrounding them with backticks: {kdexample::} Use `Kramdown::Document.new(text).to_html` to convert the `text` in kramdown syntax to HTML. {kdexample} If you want to use literal backticks in your code, just use two or more backticks as delimiters. The space right after the beginning delimiter and the one right before the closing delimiter are ignored: {kdexample::} Use backticks to markup code, e.g. `` `code` ``. {kdexample} ## Footnotes {kdlink: {oid: footnotes, part: "footnotes"}} Footnotes can easily be used in kramdown. Just set a footnote marker (consists of square brackets with a caret and the footnote name inside) in the text and somewhere else the footnote definition (which basically looks like a reference link definition): {kdexample::} This is a text with a footnote[^1]. [^1]: And here is the definition. {kdexample} The footnote definition can contain any block-level element, all lines following a footnote definition indented with four spaces or one tab belong to the definition: {kdexample::} This is a text with a footnote[^2]. [^2]: And here is the definition. > With a quote! {kdexample} As can be seen above the footnote name is only used for the anchors and the numbering is done automatically in document order. Repeated footnote markers will link to the same footnote definition. ## Abbreviations {kdlink: {oid: abbreviations, part: "abbreviations"}} Abbreviations will work out of the box once you add an abbreviation definition. So you can just write the text and add the definitions later on. {kdexample::} This is an HTML example. *[HTML]: Hyper Text Markup Language {kdexample} ## HTML Elements {kdlink: {oid: html-spans, part: "HTML spans"}} HTML is not only supported on the block-level but also on the span-level: {kdexample::} This is written in red. {kdexample} ## Inline Attributes {kdlink: {oid: span-ials, part: "span IALs"}} As with a block-level element you can assign any attribute to a span-level elements using a *span inline attribute list* (or short: span IAL). A span IAL has the same syntax as a block IAL and must immediately follow the span-level element: {kdexample::} This is *red*{: style="color: red"}. {kdexample} kramdown-1.17.0/doc/sidebar.template0000644000004100000410000000166613321140127017370 0ustar www-datawww-data

    Support kramdown

    If you like kramdown and would like to support it, you are welcome to make a small donation (Patreon or PayPal) -- it will surely be appreciated! Thanks!

    Sponsors

    GROSSWEBER provides software development consulting and training services. We like to work on open source. We use it heavily. We love kramdown!

    kramdown-1.17.0/doc/documentation.template0000644000004100000410000000217113321140127020620 0ustar www-datawww-data--- name:sidebar pipeline:erb,tags,kramdown

    Documentation

    * Parsers * [kramdown](parser/kramdown.html) * [GFM](parser/gfm.html) * [Markdown](parser/markdown.html) * [HTML](parser/html.html) * Converters * [HTML](converter/html.html) * [LaTeX](converter/latex.html) * [man](converter/man.html) * [kramdown](converter/kramdown.html) * [RemoveHtmlTags](converter/remove_html_tags.html) * Syntax Highlighters * [Rouge](syntax_highlighter/rouge.html) * [Coderay](syntax_highlighter/coderay.html) * Math Engines * [MathJax](math_engine/mathjax.html) * [KaTeX](math_engine/katex.html) * [SsKaTeX](math_engine/sskatex.html) * [Mathjax-Node](math_engine/mathjaxnode.html) * [Ritex](math_engine/ritex.html) * [itex2MML](math_engine/itex2mml.html) * [Configuration Options](options.html) * [Tests](tests.html) <% if context.node.children.first && context.node.children.first.children.length > 1 %>

    Contents

    <% end %> {menu: {options: {descendants: true, levels: [3,6]}}} kramdown-1.17.0/doc/news.page0000644000004100000410000000154013321140127016023 0ustar www-datawww-data--- title: News in_menu: false sort_info: 30 --- pipeline:tags,blocks,fragments

    News

    Atom-Feed --- name:newsdata pipeline:erb <% opts = {:alcn => '/news/*.html', :sort => 'sort_info', :reverse => true, :flatten => true} context.website.ext.item_tracker.add(context.dest_node, :nodes, :node_finder_option_set, {:opts => opts, :ref_alcn => context.node.alcn}, :content) context.website.ext.node_finder.find(opts, context.node).each do |node| # context.options['contentprocessor.kramdown.options'] = {:auto_id_prefix => node.lcn.tr('.', '-')} %>
    Published on <%= node['created_at'].strftime("%A, %d %B %Y") %>
    <%= context.render_block(:name => 'content', :chain => [node]) %>
    <% end %> kramdown-1.17.0/doc/tests.page0000644000004100000410000001152513321140127016215 0ustar www-datawww-data--- title: Tests and Benchmark --- # Tests and Benchmark ## Tests There exist several test suites for testing the correctness of a Markdown implementation. The original [Markdown Test Suite] is the standard which one needs to test against. The [PHP Markdown suite][MDTest] contains the original test suite and several more tests (some specifically geared towards the extension of the PHP Markdown Extra package). I have used the latter test tool to roughly verify that kramdown is able to parse standard Markdown. However, since the syntax used by kramdown varies slightly from standard Markdown most of the tests fail - which is fine. When looking at the differences one can see that the failures result from these differences. Besides using the above mentioned test suite kramdown comes with its own set of tests which is used to verify that the implementation matches the kramdown specification. If you believe you have found a bug in the implementation, please follow these steps: * Check the [syntax page](syntax.html) and see if the behaviour is not intended. * If the behaviour is not intended and it seems that kramdown should parse some text in another fashion, please open a [bug report] and attach two files: one with the text and one with the HTML conversion you think is correct. [bug report]: http://github.com/gettalong/kramdown/issues ## Benchmark kramdown comes with a small benchmark to test how fast it is in regard to four other Ruby Markdown implementations: Maruku, BlueFeather, BlueCloth, RDiscount and Redcarpet. The first two are written using only Ruby, the latter three are written in C and need to be compiled. As one can see below, kramdown is currently (September 2014) ~3x faster than Maruku, ~4.5x faster than BlueFeather but ~30x slower than RDiscount and ~150x slower than Redcarpet:
    
    Running tests on 2014-09-16 under ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
    
    Test using file mdsyntax.text and 20 runs
    Rehearsal ----------------------------------------------------
    kramdown 1.4.2     0.900000   0.010000   0.910000 (  0.914992)
    Maruku 0.7.1       2.360000   0.040000   2.400000 (  2.403571)
    BlueFeather 0.41   3.760000   0.010000   3.770000 (  3.776421)
    BlueCloth 2.2.0    0.050000   0.000000   0.050000 (  0.050221)
    RDiscount 2.1.7    0.020000   0.000000   0.020000 (  0.024180)
    redcarpet 3.1.2    0.010000   0.000000   0.010000 (  0.004579)
    ------------------------------------------- total: 7.160000sec
    
                           user     system      total        real
    kramdown 1.4.2     0.830000   0.000000   0.830000 (  0.834144)
    Maruku 0.7.1       2.250000   0.030000   2.280000 (  2.286579)
    BlueFeather 0.41   3.680000   0.010000   3.690000 (  3.693769)
    BlueCloth 2.2.0    0.050000   0.000000   0.050000 (  0.044831)
    RDiscount 2.1.7    0.020000   0.000000   0.020000 (  0.022847)
    redcarpet 3.1.2    0.010000   0.000000   0.010000 (  0.004601)
    
    Real time of X divided by real time of kramdown
    Maruku             2.7412
    BlueFeather        4.4282
    BlueCloth          0.0537
    RDiscount          0.0274
    redcarpet          0.0055
    
    Test using file mdbasics.text and 20 runs
    Rehearsal ----------------------------------------------------
    kramdown 1.4.2     0.150000   0.000000   0.150000 (  0.149989)
    Maruku 0.7.1       0.580000   0.010000   0.590000 (  0.584910)
    BlueFeather 0.41   0.780000   0.000000   0.780000 (  0.788740)
    BlueCloth 2.2.0    0.020000   0.000000   0.020000 (  0.014700)
    RDiscount 2.1.7    0.000000   0.000000   0.000000 (  0.007692)
    redcarpet 3.1.2    0.010000   0.000000   0.010000 (  0.002064)
    ------------------------------------------- total: 1.550000sec
    
                           user     system      total        real
    kramdown 1.4.2     0.150000   0.000000   0.150000 (  0.151586)
    Maruku 0.7.1       0.520000   0.000000   0.520000 (  0.525707)
    BlueFeather 0.41   0.770000   0.010000   0.780000 (  0.763559)
    BlueCloth 2.2.0    0.020000   0.000000   0.020000 (  0.015509)
    RDiscount 2.1.7    0.010000   0.000000   0.010000 (  0.006545)
    redcarpet 3.1.2    0.000000   0.000000   0.000000 (  0.001475)
    
    Real time of X divided by real time of kramdown
    Maruku             3.468
    BlueFeather        5.0371
    BlueCloth          0.1023
    RDiscount          0.0432
    redcarpet          0.0097
    
    And here are some graphs which show the execution times of the various kramdown releases on different Ruby interpreters: ![ruby 1.8.7p302]({relocatable: img/graph-ruby-1.8.7-302.png}) ![ruby 1.9.3p448]({relocatable: img/graph-ruby-1.9.3p448-448.png}) ![ruby 2.0.0p247]({relocatable: img/graph-ruby-2.0.0p247-247.png}) ![ruby 2.1.2p95]({relocatable: img/graph-ruby-2.1.2p95-95.png}) ![jruby 1.7.15]({relocatable: img/graph-jruby-1.7.15-392.png}) ![rubinius 2.2.10]({relocatable: img/graph-rubinius-2.2.10-0.png}) [Markdown Test Suite]: http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip [MDTest]: http://www.michelf.com/docs/projets/mdtest-1.0.zip kramdown-1.17.0/doc/options.page0000644000004100000410000000257213321140127016550 0ustar www-datawww-data--- title: Options --- ## Options The behaviour of kramdown can be adjusted via the available options. Options can be specified in multiple ways: On the command line : The `kramdown` binary allows setting any option by using command line switches. For example, the following command will disable automatic header ID generation and defines the first footnote number as 5: ~~~ $ kramdown --no-auto-ids --footnote-nr 5 ~~~ As you can see all underscores in option names have to be replaced with dashes. The built-in help of the binary as well as the man-page show all available options. Within a kramdown document : By using the special extension syntax, it is possible to set options within a document. Using the above example, the options would be set like this within a document: ~~~ {::options auto_ids="false" footnote_nr="5" /} ~~~ Using Ruby code : If you are using kramdown as a library, you can pass any options as second parameter to the `Kramdown::Document.new` method. Again, using the above example you would initalize the kramdown document class as follows: ~~~ ruby Kramdown::Document.new(source_text, \{auto_ids: false, footnote_nr: 5}) ~~~ ## Available Options Below is a list of all currently available options. Have a look at the documentation of a converter or parser to see directly which options they support! {options: {items: all}} kramdown-1.17.0/doc/_design.scss0000644000004100000410000002220513321140127016517 0ustar www-datawww-data/* Based on the Less Framework 4 http://lessframework.com by Joni Korpi License: http://opensource.org/licenses/mit-license.php */ /***** Variables for easy customization *****/ /* the baseline height in px */ $baseline-height: 24; /* The overlay color for the background image */ $bg-grad-color: rgba(255,255,128,0.1); /* The font size of the logo in px */ $logo-size: 36; /* Color settings */ $link-color: #1666A3; /* Resets ------ */ html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, hr, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figure, figcaption, hgroup, menu, footer, header, nav, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; } article, aside, canvas, figure, figure img, figcaption, hgroup, footer, header, nav, section, audio, video { display: block; } a img {border: 0;} /* Typography presets ------------------ */ .gigantic { font-size: 59px; line-height: 72px; } .huge { font-size: 36px; line-height: 48px; } .large { font-size: 23px; line-height: 24px; } .bigger { font-size: 18px; line-height: 24px; } .big { font-size: 14px; line-height: 24px; } body { font: 14px/24px 'Palatino Linotype', 'Book Antiqua', Palatino, serif; } .small, small { font-size: 12px; line-height: 24px; } *:target::after { content: " ☜"; } /* Typographics grid overlay */ .grid{ background-image: -moz-linear-gradient(top, rgba(0,0,0,0) 95%, rgba(0,0,0,0.3) 100%); /* FF3.6+ */ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(95%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0.3))); /* Chrome,Safari4+ */ background-image: -webkit-linear-gradient(top, rgba(0,0,0,0) 95%,rgba(0,0,0,0.3) 100%); /* Chrome10+,Safari5.1+ */ background-image: -o-linear-gradient(top, rgba(0,0,0,0) 95%, rgba(0,0,0,0.3) 100%); /* Opera11.10+ */ background-image: -ms-linear-gradient(top, rgba(0,0,0,0) 95%,rgba(0,0,0,0.3) 100%); /* IE10+ */ background-image: linear-gradient(top, rgba(0,0,0,0.3) 95%,rgba(0,0,0,0.3) 100%); /* W3C */ -webkit-background-size: 100% #{$baseline-height}px; -o-background-size: 100% #{$baseline-height}px; background-size: 100% #{$baseline-height}px; } /* Basic mixins */ @mixin background { background-image: -moz-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png'); background-image: -webkit-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png'); background-image: -o-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png'); background-image: -ms-linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png'); background-image: linear-gradient($bg-grad-color, $bg-grad-color), url('bg.png'); } @mixin typography($size: big) { h3, h4, h5, h6, p, ul, ol, dl, pre, blockquote, table { margin-top: 24px; margin-bottom: 24px; } @if $size == big { h1 { @extend .huge } h2 { @extend .large } h3 { @extend .bigger } h4,h5,h6 { @extend .big } } @else { h1 { @extend .large } h2 { @extend .bigger } h3,h4,h5,h6 { @extend .big } } h1, h2, h3, h4, h5, h6 { font-weight: normal; padding-left: 48px; margin-left: -48px; margin-top: 36px; margin-bottom: -12px; } ul, ol, dd { padding-left: 24px; } ul ul, ul ol, ol ul, ol ol { margin-top: 0; margin-bottom: 0; } pre { padding-left: 12px; padding-right: 12px; border: 1px solid #ccc; font-family: "Bitstream Vera Sans Mono", Consolas, monospace; } dt { font-weight: bold; } a { color: $link-color; text-decoration: underline; } a:hover, a:link { color: scale-color($link-color, $lightness: -50%); } } /* Default Layout: 992px. Gutters: 24px. Outer margins: 48px. Leftover space for scrollbars @1024px: 32px. ------------------------------------------------------------------------------- cols 1 2 3 4 5 6 7 8 9 10 px 68 160 252 344 436 528 620 712 804 896 */ body { width: 992px; margin: 0 auto 48px; color: rgb(60,60,60); -webkit-text-size-adjust: 100%; /* Stops Mobile Safari from auto-adjusting font-sizes */ @include background; } body > header { position: relative; padding: 12px; font-family: Verdana; color: #eee; -moz-box-shadow: 0 0 24px rgba(0,0,0,0.6); -webkit-box-shadow: 0 0 24px rgba(0,0,0,0.6); box-shadow: 0 0 24px rgba(0,0,0,0.6); z-index: 1; } #logo { font-size: #{$logo-size}px; line-height: #{$baseline-height * (floor($logo-size / $baseline-height) + 1)}px; margin: 12px; text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5); a { color: #eee; text-decoration: none; &:hover { color: #fff; } } } #slogan { font-size: 100%; margin: 12px; text-shadow: 0px 2px 5px rgba(0, 0, 0, 0.5); } nav { position: absolute; bottom: 0px; right: 0px; background-color: rgba(255,255,255,0.1); li { display: inline-block; } ul { margin: 0; padding: 0; } a, span { display: block; padding: 12px; color: #ccc; text-decoration: none; } span { background-color: rgba(255,255,255,0.3); } a:hover { background-color: rgba(255,255,255,0.3); } } #wrapper { clear: both; position: relative; background-color: white; -moz-box-shadow: 0 0 24px rgba(0,0,0,0.6); -webkit-box-shadow: 0 0 24px rgba(0,0,0,0.6); box-shadow: 0 0 24px rgba(0,0,0,0.6); } aside { float: right; right: 0; background-color: white; width: 252px; padding: 24px; @include typography(small); h1, h2, h3, h4, h5, h6 { padding-left: 48px; margin-left: -48px; } } aside.banner { @include background; position: relative; width: inherit; margin: 0; float: none; padding: 24px; border: 10px solid rgba(255,255,255,0.1); color: #ccc; font-size: 36px; line-height: 48px; a { color: #ccc; text-decoration: underline; } a:hover { background-color: rgba(255,255,255,0.3); } p { margin: 0; } p + p { margin-top: 24px; } } #content { width: 620px; padding: 24px 48px; @include typography(big); } footer { background-color: rgba(255,255,255,0.1); min-height: 24px; color: #eee; } /* Tablet Layout: 768px. Gutters: 24px. Outer margins: 28px. Inherits styles from: Default Layout. ----------------------------------------------------------------- cols 1 2 3 4 5 6 7 8 px 68 160 252 344 436 528 620 712 */ @media only screen and (min-width: 768px) and (max-width: 1005px) { body { width: 716px; } body > header { padding: 0; } aside { position: static; float: right; } nav { position: relative; margin-top: 12px; } } /* Mobile Layout: 320px. Gutters: 24px. Outer margins: 34px. Inherits styles from: Default Layout. --------------------------------------------- cols 1 2 3 px 68 160 252 */ @media only screen and (max-width: 767px) { body { width: 320px; } body > header { padding: 0; } nav { position: relative; margin-top: 12px; } aside { position: relative; } #content, aside { width: 296px; padding: 24px 12px; } #content { h1, h2, h3, h4, h5, h6 { padding-left: 12px; margin-left: -12px; } } } /* Wide Mobile Layout: 480px. Gutters: 24px. Outer margins: 22px. Inherits styles from: Default Layout, Mobile Layout. ------------------------------------------------------------ cols 1 2 3 4 5 px 68 160 252 344 436 */ @media only screen and (min-width: 480px) and (max-width: 767px) { body { width: 90%; } aside { position: relative; } #content, aside { width: inherit; padding: 24px 48px; } #content { h1, h2, h3, h4, h5, h6 { padding-left: 48px; margin-left: -48px; } } } /* Retina media query. Overrides styles for devices with a device-pixel-ratio of 2+, such as iPhone 4. ----------------------------------------------- */ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { body { } } kramdown-1.17.0/doc/links.markdown0000644000004100000410000000041713321140127017077 0ustar www-datawww-data[Maruku]: http://maruku.rubyforge.org [PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/ [Pandoc]: http://johnmacfarlane.net/pandoc/ [MathJax]: http://www.mathjax.org [BlueCloth]: http://deveiate.org/projects/BlueCloth [RedCloth]: http://redcloth.org/ kramdown-1.17.0/doc/index.page0000644000004100000410000001115513321140127016161 0ustar www-datawww-data--- title: Home in_menu: true sort_info: 1 --- ## Overview If you want to get started with kramdown, have a look at the [installation page](installation.html) to see how you can install it on your system. Then look through the [documentation](documentation.html) for finding information about how to actually use kramdown and its parsers/converters. The [quick reference](quickref.html) provides a overview of the syntax -- if you need a more detailed description of the superset of Markdown which kramdown supports the [syntax page](syntax.html) is the place to go! {tikz:: path: overview.png img_attr: {style: 'background:transparent'} content_processor.tikz.libraries: [mindmap, trees, arrows] content_processor.tikz.transparent: true content_processor.tikz.resolution: 300 100 content_processor.tikz.opts: | mindmap, concept color=black, text=white, root concept/.append style={font=\Large}, level 1 concept/.append style={font=\Large, minimum size=2.6cm}, level 2 concept/.append style={font=\Large}, } \node[concept, font=\Large] (lib) {kramdown's internal representation} child[concept color=orange, grow=120, ->] {node[concept] (i-kramdown) {kramdown}} child[concept color=orange, grow=160] {node[concept] (i-html) {HTML}} child[concept color=orange, grow=200] {node[concept] (i-gfm) {GFM}} child[concept color=orange, grow=240] {node[concept] (i-markdown) {Markdown}} child[concept color=green!50!black, grow=60] {node[concept] (o-html) {HTML}} child[concept color=green!50!black, grow=20] {node[concept] (o-kramdown) {kramdown}} child[concept color=green!50!black, grow=-20] { node[concept] (o-latex) {\LaTeX} child[grow=0] { node[concept] (o-latex-pdf) {PDF} } } child[concept color=green!50!black, grow=-60] {node[concept] (o-pdf) {PDF}} ; \draw [dash pattern=on 0pt off 2pt,line width=5pt,arrows=-angle 60,shorten >=15pt,shorten <=10pt,color=orange] (i-kramdown) edge(lib) (i-markdown) edge(lib) (i-html) edge (lib) (i-gfm) edge (lib); \draw [dash pattern=on 0pt off 2pt,line width=5pt,arrows=-angle 60,shorten >=10pt,shorten <=15pt,color=green!50!black] (lib) edge(o-html) (lib) edge (o-kramdown) (lib) edge (o-latex) (lib) edge (o-pdf); {tikz} {: style="text-align: center"} ## Bugs, Forums, Mailing Lists If you have found a bug, you should [report it here][bug_report]. Also, there is the [kramdown-users google group][ml] available if you have any questions! [bug_report]: http://github.com/gettalong/kramdown/issues [ml]: https://groups.google.com/forum/#!forum/kramdown-users ## Thanks kramdown would not be possible without the prior work of many other people. I want to thank everyone involved with making Markdown such a nice markup language and especially the developers of other Markdown implementations because kramdown borrowed many ideas from existing packages. ## Author * Thomas Leitner * e-Mail: [PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/ [Maruku]: http://maruku.rubyforge.org [BlueFeather]: http://ruby.morphball.net/bluefeather/index_en.html --- intro
    **kramdown**{:itemprop="name"} (sic, not Kramdown or KramDown, just kramdown) is a *free* [MIT](https://github.com/gettalong/kramdown/blob/master/COPYING){:itemprop="license"}-licensed [Ruby](http://www.ruby-lang.org) library for parsing and converting a superset of Markdown. It is completely written in Ruby, supports standard Markdown (with some minor modifications) and various extensions that have been made popular by the [PHP Markdown Extra] package and [Maruku]. {:itemprop="description"} It is probably the fastest pure-Ruby Markdown converter available (September 2014), being about 3x faster than [Maruku] and about 4.5x faster than [BlueFeather]. Version **1.17.0**{:itemprop="softwareVersion"} released on **2018-05-31**{:itemprop="datePublished"}, [more news](news.html) {: style="text-align: center; font-size: 80%"}
    Support kramdown development and become a patron!
    [PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/ [Maruku]: http://maruku.rubyforge.org [BlueFeather]: http://ruby.morphball.net/bluefeather/index_en.html kramdown-1.17.0/doc/sitemap.sitemap0000644000004100000410000000010113321140127017227 0ustar www-datawww-data--- entries: alcn: /**/*.html default_change_freq: monthly --- kramdown-1.17.0/doc/news.feed0000644000004100000410000000037413321140127016016 0ustar www-datawww-data--- title: kramdown News description: kramdown - a fast, pure Ruby Markdown-superset converter author: Thomas Leitner author_url: https://kramdown.gettalong.org entries: {alcn: news/*.html, sort: sort_info, reverse: true, limit: 10} versions: atom: kramdown-1.17.0/doc/syntax.page0000644000004100000410000022256613321140127016412 0ustar www-datawww-data--- title: Syntax in_menu: true sort_info: 10 --- name:sidebar

    Contents

    {menu: {options: {descendants: true, levels: [2,6]}}} --- name:content # kramdown Syntax This is version **<%= ::Kramdown::VERSION %>** of the syntax documentation. The kramdown syntax is based on the Markdown syntax and has been enhanced with features that are found in other Markdown implementations like [Maruku], [PHP Markdown Extra] and [Pandoc]. However, it strives to provide a strict syntax with definite rules and therefore isn't completely compatible with Markdown. Nonetheless, most Markdown documents should work fine when parsed with kramdown. All places where the kramdown syntax differs from the Markdown syntax are highlighted. Following is the complete syntax definition for all elements kramdown supports. Together with the documentation on the available converters, it is clearly specified what you will get when a kramdown document is converted. ## Source Text Formatting A kramdown document may be in any encoding, for example ASCII, UTF-8 or ISO-8859-1, and the output will have the same encoding as the source. The document consists of two types of elements, block-level elements and span-level elements: * Block-level elements define the main structure of the content, for example, what part of the text should be a paragraph, a list, a blockquote and so on. * Span-level elements mark up small text parts as, for example, emphasized text or a link. Thus span-level elements can only occur inside block-level elements or other span-level elements. You will often find references to the "first column" or "first character" of a line in a block-level element descriptions. Such a reference is always to be taken relative to the current indentation level because some block-level elements open up a new indentation level (e.g. blockquotes). The beginning of a kramdown document opens up the default indentation level which begins at the first column of the text. ### Line Wrapping Some lightweight markup syntax don't work well in environments where lines are hard-wrapped. For example, this is the case with many email programs. Therefore kramdown allows content like paragraphs or blockquotes to be hard-wrapped, i.e. broken across lines. This is sometimes referred to as "lazy syntax" since the indentation or line prefix required for the first line of content is not required for the consecutive lines. Block-level elements that support line wrapping always end when one of the following conditions is met: * a [blank line](#blank-lines), an [EOB marker line](#eob-marker), a [block IAL](#block-ials) or the end of the document (i.e. a [block boundary](#block-boundaries)), * or an [HTML block](#html-blocks). Line wrapping is allowed throughout a kramdown document but there are some block-level elements that do *not* support being hard-wrapped: [headers](#headers) : This is not an issue in most situations since headers normally fit on one line. If a header text gets too long for one line, you need to use HTML syntax instead. [fenced code blocks](#fenced-code-blocks) : The delimiting lines of a fenced code block do not support hard-wrapping. Since everything between the delimiting lines is taken as is, the content of a fenced code block does also not support hard-wrapping. [definition list terms](#definition-lists) : Each definition term has to appear on a separate line. Hard-wrapping would therefore introduce additional definition terms. The definitions themselves, however, do support hard-wrapping. [tables](#tables) : Since each line of a kramdown table describes one table row or a separator, it is not possible to hard-wrap tables. **Note** that it is **NOT** recommended to use lazy syntax to write a kramdown document. The flexibility that the kramdown syntax offers due to the issue of line wrapping hinders readability and should therefore not be used. ### Usage of Tabs kramdown assumes that tab stops are set at multiples of four. This is especially important when using tabs for indentation in lists. Also, tabs may only be used at the beginning of a line when indenting text and must not be preceded by spaces. Otherwise the results may be unexpected. ### Automatic and Manual Escaping Depending on the output format, there are often characters that need special treatment. For example, when converting a kramdown document to HTML one needs to take care of the characters `<`, `>` and `&`. To ease working with these special characters, they are automatically and correctly escaped depending on the output format. This means, for example, that you can just use `<`, `>` and `&` in a kramdown document and need not think about when to use their HTML entity counterparts. However, if you *do use* HTML entities or HTML tags which use one of the characters, the result will be correct nonetheless! Since kramdown also uses some characters to mark-up the text, there needs to be a way to escape these special characters so that they can have their normal meaning. This can be done by using backslash escapes. For example, you can use a literal back tick like this: This \`is not a code\` span! Following is a list of all the characters (character sequences) that can be escaped: \ backslash . period * asterisk _ underscore + plus - minus = equal sign ` back tick ()[]{}<> left and right parens/brackets/braces/angle brackets # hash ! bang << left guillemet >> right guillemet : colon | pipe " double quote ' single quote $ dollar sign ## Block Boundaries Some block-level elements have to start and/or end on so called block boundaries, as stated in their documentation. There are two cases where block boundaries come into play: * If a block-level element has to start on a block boundary, it has to be preceded by either a [blank line](#blank-lines), an [EOB marker](#eob-marker), a [block IAL](#block-ials) or it has to be the first element. * If a block-level element has to end on a block boundary, it has to be followed by either a [blank line](#blank-lines), an [EOB marker](#eob-marker), a [block IAL](#block-ials) or it has to be the last element. # Structural Elements All structural elements are block-level elements and they are used to structure the content. They can mark up some text as, for example, a simple paragraph, a quote or as a list item. ## Blank lines Any line that just contains white space characters such as spaces and tabs is considered a blank line by kramdown. One or more consecutive blank lines are handled as one empty blank line. Blank lines are used to separate block-level elements from each other and in this case they don't have semantic meaning. However, there are some cases where blank lines do have a semantic meaning: * When used in headers -- see the [headers section](#headers) * When used in code blocks -- see the [code blocks section](#code-blocks) * When used in lists -- see the [lists section](#lists) * When used in math blocks -- see the [math blocks section](#math-blocks) * When used for elements that have to start/end on [block boundaries](#block-boundaries) ## Paragraphs Paragraphs are the most used block-level elements. One or more consecutive lines of text are interpreted as one paragraph. The first line of a paragraph may be indented up to three spaces, the other lines can have any amount of indentation because paragraphs support [line wrapping](#line-wrapping). In addition to the rules outlined in the section about line wrapping, a paragraph ends when a [definition list line](#definition-lists) is encountered. You can separate two consecutive paragraphs from each other by using one or more blank lines. Notice that a line break in the source does not mean a line break in the output (due to the [lazy syntax](#line-wrapping))!. If you want to have an explicit line break (i.e. a `
    ` tag) you need to end a line with two or more spaces or two backslashes! Note, however, that a line break on the last text line of a paragraph is not possible and will be ignored. Leading and trailing spaces will be stripped from the paragraph text. The following gives you an example of how paragraphs look like: This para line starts at the first column. However, the following lines can be indented any number of spaces/tabs. The para continues here. This is another paragraph, not connected to the above one. But with a hard line break. \\ And another one. {: .show-whitespaces .ws-lr} ## Headers kramdown supports so called Setext style and atx style headers. Both forms can be used inside a single document. ### Setext Style Setext style headers have to start on a [block boundary](#block-boundaries) with a line of text (the header text) and a line with only equal signs (for a first level header) or dashes (for a second level header). The header text may be indented up to three spaces but any leading or trailing spaces are stripped from the header text. The amount of equal signs or dashes is not significant, just one is enough but more may look better. The equal signs or dashes have to begin at the first column. For example: First level header ================== Second level header ------ Other first level header = Since Setext headers start on block boundaries, this means in most situations that they have to be preceded by a blank line. However, blank lines are not necessary after a Setext header: This is a normal paragraph. And A Header ------------ And a paragraph > This is a blockquote. And A Header ------------ However, it is generally a good idea to also use a blank line after a Setext header because it looks more appropriate and eases reading of the document. > The original Markdown syntax allows one to omit the blank line before a Setext header. However, > this leads to ambiguities and makes reading the document harder than necessary. Therefore it is > not allowed in a kramdown document. {: .markdown-difference} An edge case worth mentioning is the following: header --- para One might ask if this represents two paragraphs separated by a [horizontal rule](#horizontal-rules) or a second level header and a paragraph. As suggested by the wording in the example, the latter is the case. The general rule is that Setext headers are processed before horizontal rules. ### atx Style atx style headers have to start on a [block boundary](#block-boundaries) with a line that contains one or more hash characters and then the header text. No spaces are allowed before the hash characters. The number of hash characters specifies the heading level: one hash character gives you a first level heading, two a second level heading and so on until the maximum of six hash characters for a sixth level heading. You may optionally use any number of hashes at the end of the line to close the header. Any leading or trailing spaces are stripped from the header text. For example: # First level header ### Third level header ### ## Second level header ###### > Again, the original Markdown syntax allows one to omit the blank line before an atx style header. {: .markdown-difference} ### Specifying a Header ID kramdown supports a nice way for explicitly setting the header ID which is taken from [PHP Markdown Extra] and [Maruku]: If you follow the header text with an opening curly bracket (separated from the text with a least one space), a hash, the ID and a closing curly bracket, the ID is set on the header. If you use the trailing hash feature of atx style headers, the header ID has to go after the trailing hashes. For example: Hello {#id} ----- # Hello {#id} # Hello # {#id} > This additional syntax is not part of standard Markdown. {: .markdown-difference} ## Blockquotes A blockquote is started using the `>` marker followed by an optional space and the content of the blockquote. The marker itself may be indented up to three spaces. All following lines, whether they are started with the blockquote marker or just contain text, belong to the blockquote because blockquotes support [line wrapping](#line-wrapping). The contents of a blockquote are block-level elements. This means that if you are just using text as content that it will be wrapped in a paragraph. For example, the following gives you one blockquote with two paragraphs in it: > This is a blockquote. > on multiple lines that may be lazy. > > This is the second paragraph. Since the contents of a blockquote are block-level elements, you can nest blockquotes and use other block-level elements (this is also the reason why blockquotes need to support line wrapping): > This is a paragraph. > > > A nested blockquote. > > ## Headers work > > * lists too > > and all other block-level elements Note that the first space character after the `>` marker does *not* count when counting spaces for the indentation of the block-level elements inside the blockquote! So [code blocks](#code-blocks) will have to be indented with five spaces or one space and one tab, like this: > A code block: > > ruby -e 'puts :works' [Line wrapping](#line-wrapping) allows one to be lazy but hinders readability and should therefore be avoided, especially with blockquotes. Here is an example of using blockquotes with line wrapping: > This is a paragraph inside a blockquote. > > > This is a nested paragraph that continues here > and here > > and here ## Code Blocks Code blocks can be used to represent verbatim text like markup, HTML or a program fragment because no syntax is parsed within a code block. ### Standard Code Blocks A code block can be started by using four spaces or one tab and then the text of the code block. All following lines containing text, whether they adhere to this syntax or not, belong to the code block because code blocks support [line wrapping](#line-wrapping)). A wrapped code line is automatically appended to the preceding code line by substituting the line break with a space character. The indentation (four spaces or one tab) is stripped from each line of the code block. > The original Markdown syntax does not allow line wrapping in code blocks. {: .markdown-difference} Note that consecutive code blocks that are only separate by [blank lines](#blank-lines) are merged together into one code block: Here comes some code This text belongs to the same code block. If you want to have one code block directly after another one, you need to use an [EOB marker](#eob-marker) to separate the two: Here comes some code ^ This one is separate. ### Fenced Code Blocks > This alternative syntax is not part of the original Markdown syntax. The idea and syntax comes > from the [PHP Markdown Extra] package. {: .markdown-difference} kramdown also supports an alternative syntax for code blocks which does not use indented blocks but delimiting lines. The starting line needs to begin with three or more tilde characters (`~`) and the closing line needs to have at least the number of tildes the starting line has. Everything between is taken literally as with the other syntax but there is no need for indenting the text. For example: ~~~~~~~~ Here comes some code. ~~~~~~~~ If you need lines of tildes in such a code block, just start the code block with more tildes. For example: ~~~~~~~~~~~~ ~~~~~~~ code with tildes ~~~~~~~~ ~~~~~~~~~~~~~~~~~~ This type of code block is especially useful for copy-pasted code since you don't need to indent the code. ### Language of Code Blocks You can tell kramdown the language of a code block by using an [IAL](#inline-attribute-lists): ~~~ def what? 42 end ~~~ {: .language-ruby} The specially named class `language-ruby` tells kramdown that this code block is written in the Ruby language. Such information can be used, for example, by converters to do syntax highlighting on the code block. Fenced code blocks provide an easier way to specify the language, namely by appending the language of the code block to the end of the starting line: ~~~ ruby def what? 42 end ~~~ ## Lists kramdown provides syntax elements for creating ordered and unordered lists as well as definition lists. ### Ordered and Unordered lists Both ordered and unordered lists follow the same rules. A list is started with a list marker (in case of unordered lists one of `+`, `-` or `*` -- you can mix them -- and in case of ordered lists a number followed by a period) followed by one tab or at least one space, optionally followed by an [IAL](#inline-attribute-lists) that should be applied to the list item and then the first part of the content of the list item. The leading tabs or spaces are stripped away from this first line of content to allow for a nice alignment with the following content of a list item (see below). All following list items with the same marker type (unordered or ordered) are put into the same list. The numbers used for ordered lists are irrelevant, an ordered list always starts at 1. The following gives you an unordered list and an ordered list: * kram + down - now 1. kram 2. down 3. now > The original Markdown syntax allows the markers of ordered and unordered lists to be mixed, the > first marker specifying the list type (ordered or unordered). This is not allowed in kramdown. As > stated, the above example will give you two lists (an unordered and an ordered) in kramdown and > only one unordered list in Markdown. {: .markdown-difference} The first list marker in a list may be indented up to three spaces. The column number of the first non-space character which appears after the list item marker on the same line specifies the indentation that has to be used for the following lines of content of the list item. If there is no such character, the indentation that needs to be used is four spaces or one tab. Indented lines may be followed by lines containing text with any amount of indentation due to [line wrapping](#line-wrapping). Note, however, that in addition to the rules outlined in the section about line wrapping, a list item also ends when a line with another list item marker is encountered -- see the next paragraph. The indentation is stripped from the content and the content (note that the content naturally also contains the content of the line with the item marker) is processed as text containing block-level elements. All other list markers in the list may be indented up to three spaces or the number of spaces used for the indentation of the last list item minus one, whichever number is smaller. For example: * This is the first line. Since the first non-space characters appears in column 3, all other indented lines have to be indented 2 spaces. However, one could be lazy and not indent a line but this is not recommended. * This is the another item of the list. It uses a different number of spaces for indentation which is okay but should generally be avoided. * The list item marker is indented 3 spaces which is allowed but should also be avoided and starts the third list item. Note that the lazy line in the second list item may make you believe that this is a sub-list which it isn't! So avoid being lazy! So, while the above is possible and creates one list with three items, it is not advised to use different (marker and list content) indents for same level list items as well as lazy indentation! It is much better to write such a list in the following way: * This is the first list item bla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla bla * This is the another item of the list. bla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla blabla > The original Markdown syntax also allows you to indent the marker, however, the behaviour of what > happens with the list items is not clearly specified and may surprise you. > > Also, Markdown uses a fixed number of spaces/tabs to indent the lines that belong to a list item! {: .markdown-difference} Unordered and ordered lists work the same way in regard to the indentation: * list 1 item 1 * list 1 item 2 (indent 1 space) * list 1 item 3 (indent 2 spaces) * list 1 item 4 (indent 3 spaces) * lazy text belonging to above item 4 ^ 1. list 1 item 1 2. list 1 item 2 (indent 1 space) 3. list 1 item 3 (indent 2 spaces) 4. list 1 item 4 (indent 3 spaces) 5. lazy text belonging to above item 4 ^ * list 1 item 1 * nested list item 1 * nested list item 2 * list 1 item 2 * nested list item 1 ^ 1. list 1 item 1 1. nested list item 1 2. nested list item 2 10. list 1 item 2 1. nested list item 1 ^ 1. text for this list item further text (indent 3 spaces) 10. text for this list item further text (indent 4 spaces) When using tabs for indenting the content of a list item, remember that tab stops occur at multiples of four for kramdown. Tabs are correctly converted to spaces for calculating the indentation. For example: * Using a tab to indent this line, the tab only counts as three spaces and therefore the overall indentation is four spaces. 1. The tab after the marker counts here as three spaces. Since the indentation of the marker is three spaces and the marker itself takes two characters, the overall indentation needed for the following lines is eight spaces or two tabs. It is clear that you might get unexpected results if you mix tabs and spaces or if you don't have the tab stops set to multiples of four in your editor! Therefore this should be avoided! The content of a list item is made up of either text or block-level elements. Simple list items only contain text like in the above examples. They are not even wrapped in a paragraph tag. If the first list text is followed by one or more blank lines, it will be wrapped in a paragraph tag: * kram * down * now In the above example, the first list item text will be wrapped in a paragraph tag since it is followed by a blank line whereas the second list item contains just text. There is obviously a problem for doing this with the last list item when it contains only text. You can circumvent this by leaving a blank line after the last list item and using an EOB marker: * Not wrapped in a paragraph * Wrapped in a paragraph due to the following blank line. * Also wrapped in a paragraph due to the following blank line and the EOB marker. ^ The text of the last list item is also wrapped in a paragraph tag if *all* other list items contain a proper paragraph as first element. This makes the following use case work like expected, i.e. *all* the list items are wrapped in paragraphs: * First list item * Second list item * Last list item > The original Markdown syntax page specifies that list items which are separated by one or more > blank lines are wrapped in paragraph tags. This means that the first text will also be wrapped in > a paragraph if you have block-level elements in a list which are separated by blank lines. The > above rule is easy to remember and lets you exactly specify when the first list text should be > wrapped in a paragraph. The idea for the above rule comes from the [Pandoc] package. {: .markdown-difference} As seen in the examples above, blank lines between list items are allowed. Since the content of a list item can contain block-level elements, you can do the following: * First item A second paragraph * nested list > blockquote * Second item However, there is a problem when you want to have a code block immediately after a list item. You can use an EOB marker to circumvent this problem: * This is a list item. The second para of the list item. ^ A code block following the list item. You can have any block-level element as first element in a list item. However, as described above, the leading tabs or spaces of the line with the list item marker are stripped away. This leads to a problem when you want to have a code block as first element. The solution to this problem is the following construct: * This is a code block (indentation needs to be 4(1)+4(1) spaces (tabs)). {: .show-whitespaces .ws-lr} Note that the list marker needs to be followed with at least one space or tab! Otherwise the line is not recognized as the start of a list item but interpreted as a paragraph containing the list marker. If you want to have one list directly after another one (both with the same list type, i.e. ordered or unordered), you need to use an EOB marker to separate the two: * List one ^ * List two Since paragraphs support [line wrapping](#line-wrapping), it would usually not be possible to create compact nested list, i.e. a list where the text is not wrapped in paragraphs because there is no blank line but a sub list after it: * This is just text. * this is a sub list item * this is a sub sub list item * This is just text, spanning two lines * this is a nested list item. However, this is an often used syntax and is therefore support by kramdown. If you want to start a paragraph with something that looks like a list item marker, you need to escape it. This is done by escaping the period in an ordered list or the list item marker in an unordered list: 1984\. It was great \- others say that, too! As mentioned at the beginning, an optional IAL for applying attributes to a list item can be used after the list item marker: * {:.cls} This item has the class "cls". Here continues the above paragraph. * This is a normal list item. ### Definition Lists > This syntax feature is not part of the original Markdown syntax. The idea and syntax comes from > the [PHP Markdown Extra] package. {: .markdown-difference} Definition lists allow you to assign one or more definitions to one or more terms. A definition list is started when a normal paragraph is followed by a line with a definition marker (a colon which may be optionally indented up to three spaces), then at least one tab or one space, optionally followed by an [IAL](#inline-attribute-lists) that should be applied to the list item and then the first part of the definition. The line with the definition marker may optionally be separated from the preceding paragraph by a blank line. The leading tabs or spaces are stripped away from this first line of the definition to allow for a nice alignment with the following definition content. Each line of the preceding paragraph is taken to be a term and the lines separately parsed as span-level elements. Each such term may optionally start with an [IAL](#inline-attribute-lists) that should be applied to the term. The following is a simple definition list: kramdown : A Markdown-superset converter Maruku : Another Markdown-superset converter The column number of the first non-space character which appears after a definition marker on the same line specifies the indentation that has to be used for the following lines of the definition. If there is no such character, the indentation that needs to be used is four spaces or one tab. Indented lines may be followed by lines containing text with any amount of indentation due to [line wrapping](#line-wrapping). Note, however, that in addition to the rules outlined in the section about line wrapping, a list item also ends when a line with another definition marker is encountered. The indentation is stripped from the definition and it (note that the definition naturally also contains the content of the line with the definition marker) is processed as text containing block level elements. If there is more than one definition, all other definition markers for the term may be indented up to three spaces or the number of spaces used for the indentation of the last definition minus one, whichever number is smaller. For example: definition term 1 definition term 2 : This is the first line. Since the first non-space characters appears in column 3, all other lines have to be indented 2 spaces (or lazy syntax may be used after an indented line). This tells kramdown that the lines belong to the definition. : This is the another definition for the same term. It uses a different number of spaces for indentation which is okay but should generally be avoided. : The definition marker is indented 3 spaces which is allowed but should also be avoided. So, while the above is possible and creates a definition list with two terms and three definitions for them, it is not advised to use different (definition marker and definition) indents in the same definition list as well as lazy indentation! The definition for a term is made up of text and/or block-level elements. If a definition is *not* preceded by a blank line, the first part of the definition will just be text if it would be a paragraph otherwise: definition term : This definition will just be text because it would normally be a paragraph and the there is no preceding blank line. > although the definition contains other block-level elements : This definition *will* be a paragraph since it is preceded by a blank line. The rules about having any block-level element as first element in a list item also apply to a definition. As mentioned at the beginning, an optional IAL for applying attributes to a term or a definition can be used: {:#term} Term with id="term" : {:.cls} Definition with class "cls" {:#term1} First term {:#term2} Second term : {:.cls} Definition ## Tables > This syntax feature is not part of the original Markdown syntax. The syntax is based on the one > from the [PHP Markdown Extra] package. {: .markdown-difference} Sometimes one wants to include simple tabular data in a kramdown document for which using a full-blown HTML table is just too much. kramdown supports this with a simple syntax for ASCII tables. Tables can be created with or without a leading pipe character: If the first line of a table contains a pipe character at the start of the line (optionally indented up to three spaces), then all leading pipe characters (i.e. pipe characters that are only preceded by whitespace) are ignored on all table lines. Otherwise they are not ignored and count when dividing a table line into table cells. There are four different line types that can be used in a table: * *Table rows* define the content of a table. A table row is any line that contains at least one pipe character and is not identified as any other type of table line! The table row is divided into individual table cells by pipe characters. An optional trailing pipe character is ignored. Note that literal pipe characters need to be escaped *except* if they occur in code spans or HTML `` elements! Header rows, footer rows and normal rows are all done using these table rows. Table cells can only contain a single line of text, no multi-line text is supported. The text of a table cell is parsed as span-level elements. Here are some example table rows: | First cell|Second cell|Third cell | First | Second | Third | First | Second | | Fourth | * *Separator lines* are used to split the table body into multiple body parts. A separator line is any line that contains only pipes, dashes, pluses, colons and spaces/tabs and which contains at least one dash and one pipe character. The pipe and plus characters can be used to visually separate columns although this is not needed. Multiple separator lines after another are treated as one separator line. Here are some example separator lines: |----+----| +----|----+ |---------| |- | :-----: | -|- * The first separator line after at least one table row is treated specially, namely as *header separator line*. It is used to demarcate header rows from normal table rows and/or to set column alignments. All table rows above the header separator line are considered to be header rows. The header separator line can be specially formatted to contain column alignment definitions: An alignment definition consists of an optional space/tab followed by an optional colon, one or more dashes, an optional colon and another optional space/tab. The colons of an alignment definition are used to set the alignment of a column: if there are no colons, the column uses the default alignment, if there is a colon only before the dashes, the column is left aligned, if there are colons before and after the dashes, the column is center aligned and if there is only a colon after the dashes, the column is right aligned. Each alignment definition sets the alignment for one column, the first alignment definition for the first column, the second alignment definition for the second column and so on. Here are some example header separator lines with alignment definitions: |---+---+---| + :-: |:------| ---:| | :-: :- -: - :-: | :- * A *footer separator line* is used to demarcate footer rows from normal table rows. All table rows below the footer separator line are considered to be footer rows. A footer separator line is like a normal separator line except that dashes are replaced by equal signs. A footer separator line may only appear once in a table. If multiple footer separator lines are used in one table, only the last is treated as footer separator line, all others are treated as normal separator lines. Normal separator lines that are used after the footer separator line are ignored. Here are some example footer separator lines: |====+====| +====|====+ |=========| |= Trailing spaces or tabs are ignored in all cases. To simplify table creation and maintenance, header, footer and normal separator lines need not specify the same number of columns as table rows; even `|-` and `|=` are a valid separators. Given the above components, a table is specified by * an optional separator line, * optionally followed by zero, one or more table rows followed by a header separator line, * one or more table rows, optionally interspersed with separator lines, * optionally followed by a footer separator line and zero, one or more table rows and * an optional trailing separator line. Also note * that the first line of a table must not have more than three spaces of indentation before the first non-space character, * that each line of a table needs to have at least one not escaped pipe character so that kramdown recognizes it as a line belonging to the table and * that tables have to start and end on [block boundaries](#block-boundaries)! > The table syntax differs from the one used in [PHP Markdown Extra] as follows: > > * kramdown tables do not need to have a table header. > * kramdown tables can be structured using separator lines. > * kramdown tables can contain a table footer. > * kramdown tables need to be separated from other block-level elements. {: .markdown-difference} Here is an example for a kramdown table with a table header row, two table bodies and a table footer row: |-----------------+------------+-----------------+----------------| | Default aligned |Left aligned| Center aligned | Right aligned | |-----------------|:-----------|:---------------:|---------------:| | First body part |Second cell | Third cell | fourth cell | | Second line |foo | **strong** | baz | | Third line |quux | baz | bar | |-----------------+------------+-----------------+----------------| | Second body | | | | | 2 line | | | | |=================+============+=================+================| | Footer row | | | | |-----------------+------------+-----------------+----------------| The above example table is rather time-consuming to create without the help of an ASCII table editor. However, the table syntax is flexible and the above table could also be written like this: |--- | Default aligned | Left aligned | Center aligned | Right aligned |-|:-|:-:|-: | First body part | Second cell | Third cell | fourth cell | Second line |foo | **strong** | baz | Third line |quux | baz | bar |--- | Second body | 2 line |=== | Footer row ## Horizontal Rules A horizontal rule for visually separating content is created by using three or more asterisks, dashes or underscores (these may not be mixed on a line), optionally separated by spaces or tabs, on an otherwise blank line. The first asterisk, dash or underscore may optionally be indented up to three spaces. The following examples show different possibilities to create a horizontal rule: * * * --- _ _ _ _ --------------- ## Math Blocks > This syntax feature is not part of the original Markdown syntax. The idea comes from the [Maruku] > and [Pandoc] packages. {: .markdown-difference} kramdown has built-in support for block and span-level mathematics written in LaTeX. A math block needs to start and end on [block boundaries](#block-boundaries). It is started using two dollar signs, optionally indented up to three spaces. The math block continues until the next two dollar signs (which may be on the same line or on one of the next lines) that appear at the end of a line, i.e. they may only be followed by whitespace characters. The content of a math block has to be valid LaTeX math. It is always wrapped inside a `\begin{displaymath}...\end{displaymath}` enviroment except if it begins with a `\begin` statement. The following kramdown fragment $$ \begin{align*} & \phi(x,y) = \phi \left(\sum_{i=1}^n x_ie_i, \sum_{j=1}^n y_je_j \right) = \sum_{i=1}^n \sum_{j=1}^n x_i y_j \phi(e_i, e_j) = \\ & (x_1, \ldots, x_n) \left( \begin{array}{ccc} \phi(e_1, e_1) & \cdots & \phi(e_1, e_n) \\ \vdots & \ddots & \vdots \\ \phi(e_n, e_1) & \cdots & \phi(e_n, e_n) \end{array} \right) \left( \begin{array}{c} y_1 \\ \vdots \\ y_n \end{array} \right) \end{align*} $$ renders (using Javascript library [MathJax](http://www.mathjax.org/)) as $$ \begin{align*} & \phi(x,y) = \phi \left(\sum_{i=1}^n x_ie_i, \sum_{j=1}^n y_je_j \right) = \sum_{i=1}^n \sum_{j=1}^n x_i y_j \phi(e_i, e_j) = \\ & (x_1, \ldots, x_n) \left( \begin{array}{ccc} \phi(e_1, e_1) & \cdots & \phi(e_1, e_n) \\ \vdots & \ddots & \vdots \\ \phi(e_n, e_1) & \cdots & \phi(e_n, e_n) \end{array} \right) \left( \begin{array}{c} y_1 \\ \vdots \\ y_n \end{array} \right) \end{align*} $$ Using inline math is also easy: just surround your math content with two dollar signs, like with a math block. If you don't want to start an inline math statement, just escape the dollar signs and they will be treated as simple dollar signs. > **Note** that LaTeX code that uses the pipe symbol `|` in inline math statements may lead to a > line being recognized as a table line. This problem can be avoided by using the `\vert` command > instead of `|`! {:.information} If you have a paragraph that looks like a math block but should actually be a paragraph with just an inline math statement, you need to escape the first dollar sign: The following is a math block: $$ 5 + 5 $$ But next comes a paragraph with an inline math statement: \$$ 5 + 5 $$ If you don't even want the inline math statement, escape the first two dollar signs: \$\$ 5 + 5 $$ ## HTML Blocks > The original Markdown syntax specifies that an HTML block must start at the left margin, i.e. no > indentation is allowed. Also, the HTML block has to be surrounded by blank lines. Both > restrictions are lifted for kramdown documents. Additionally, the original syntax does not allow > you to use Markdown syntax in HTML blocks which is allowed with kramdown. {: .markdown-difference} An HTML block is potentially started if a line is encountered that begins with a non-span-level HTML tag or a general XML tag (opening or closing) which may be indented up to three spaces. The following HTML tags count as span-level HTML tags and *won't* start an HTML block if found at the beginning of an HTML block line: a abbr acronym b big bdo br button cite code del dfn em i img input ins kbd label option q rb rbc rp rt rtc ruby samp select small span strong sub sup textarea tt var Further parsing of a found start tag depends on the tag and in which of three possible ways its content is parsed: * Parse as raw HTML block: If the HTML/XML tag content should be handled as raw HTML, then only HTML/XML tags are parsed from this point onwards and text is handled as raw, unparsed text until the matching end tag is found or until the end of the document. Each found tag will be parsed as raw HTML again. However, if a tag has a `markdown` attribute, this attribute controls parsing of this one tag (see below). Note that the parser basically supports only correct XHTML! However, there are some exceptions. For example, attributes without values (i.e. boolean attributes) are also supported and elements without content like `
    ` can be written as `
    `. If an invalid closing tag is found, it is ignored. * Parse as block-level elements: If the HTML/XML tag content should be parsed as text containing block-level elements, the remaining text on the line will be parsed by the block-level parser as if it appears on a separate line (**Caution**: This also means that if the line consists of the start tag, text and the end tag, the end tag will not be found!). All following lines are parsed as block-level elements until an HTML block line with the matching end tag is found or until the end of the document. * Parse as span-level elements: If the HTML/XML tag content should be parsed as text containing span level elements, then all text until the *next* matching end tag or until the end of the document will be the content of the tag and will later be parsed by the span-level parser. This also means that if the matching end tag is inside what appears to be a code span, it is still used! If there is text after an end tag, it will be parsed as if it appears on a separate line except when inside a raw HTML block. Also, if an invalid closing tag is found, it is ignored. Note that all HTML tag and attribute names are converted to lowercase! By default, kramdown parses all block HTML tags and all XML tags as raw HTML blocks. However, this can be configured with the `parse_block_html`. If this is set to `true`, then syntax parsing in HTML blocks is globally enabled. It is also possible to enable/disable syntax parsing on a tag per tag basis using the `markdown` attribute: * If an HTML tag has an attribute `markdown="0"`, then the tag is parsed as raw HTML block. * If an HTML tag has an attribute `markdown="1"`, then the default mechanism for parsing syntax in this tag is used. * If an HTML tag has an attribute `markdown="block"`, then the content of the tag is parsed as block level elements. * If an HTML tag has an attribute `markdown="span"`, then the content of the tag is parsed as span level elements. The following list shows which HTML tags are parsed in which mode by default when `markdown="1"` is applied or `parse_block_html` is `true`: Parse as raw HTML : script style math option textarea pre code kbd samp var Also, all general XML tags are parsed as raw HTML blocks. Parse as block-level elements : applet button blockquote body colgroup dd div dl fieldset form iframe li map noscript object ol table tbody thead tfoot tr td ul Parse as span-level elements : a abbr acronym address b bdo big cite caption code del dfn dt em h1 h2 h3 h4 h5 h6 i ins kbd label legend optgroup p pre q rb rbc rp rt rtc ruby samp select small span strong sub sup th tt var > Remember that all span-level HTML tags like `a` or `b` do not start a HTML block! However, the > above lists also include span-level HTML tags in the case the `markdown` attribute is used on a > tag inside a raw HTML block. Here is a simple example input and its HTML output with `parse_block_html` set to `false`: This is a para.
    Something in here.
    Other para. ^

    This is a para.

    Something in here.

    Other para.

    As one can see the content of the `div` tag will be parsed as raw HTML block and left alone. However, if the `markdown="1"` attribute was used on the `div` tag, the content would be parsed as block-level elements and therefore converted to a paragraph. You can also use several HTML tags at once:
    This is some text in the `layer1` div.
    This is some text in the `layers` div.
    This is a para outside the HTML block. However, remember that if the content of a tag is parsed as block-level elements, the content that appears after a start/end tag but on the same line, is processed as if it appears on a new line:
    This is the first part of a para, which is continued here.

    This works without problems because it is parsed as span-level elements

    The end tag is not found because this line is parsed as a paragraph
    Since setting `parse_block_html` to `true` can lead to some not wanted behaviour, it is generally better to selectively enable or disable block/span-level elements parsing by using the `markdown` attribute! Unclosed block-level HTML tags are correctly closed at the end of the document to ensure correct nesting and invalidly used end tags are removed from the output: This is a para.
    Another para.

    ^

    This is a para.

    Another para.

    The parsing of processing instructions and XML comments is also supported. The content of both, PIs and XML comments, may span multiple lines. The start of a PI/XML comment may only appear at the beginning of a line, optionally indented up to three spaces. If there is text after the end of a PI or XML comment, it will be parsed as if it appears on a separate line. kramdown syntax in PIs/XML comments is not processed: This is a para. First part of para, continues here. # Text Markup These elements are all span-level elements and used inside block-level elements to markup text fragments. For example, one can easily create links or apply emphasis to certain text parts. Note that empty span-level elements are not converted to empty HTML tags but are copied as-is to the output. ## Links and Images Three types of links are supported: automatic links, inline links and reference links. ### Automatic Links This is the easiest one to create: Just surround a web address or an email address with angle brackets and the address will be turned into a proper link. The address will be used as link target and as link text. For example: Information can be found on the homepage. You can also mail me: It is not possible to specify a different link text using automatic links -- use the other link types for this! ### Inline Links As the wording suggests, inline links provide all information inline in the text flow. Reference style links only provide the link text in the text flow and everything else is defined elsewhere. This also allows you to reuse link definitions. An inline style link can be created by surrounding the link text with square brackets, followed immediately by the link URL (and an optional title in single or double quotes preceded by at least one space) in normal parentheses. For example: This is [a link](http://rubyforge.org) to a page. A [link](../test "local URI") can also have a title. And [spaces](link with spaces.html)! Notes: * The link text is treated like normal span-level text and therefore is parsed and converted. However, if you use square brackets within the link text, you have to either properly nest them or to escape them. It is not possible to create nested links! The link text may also be omitted, e.g. for creating link anchors. * The link URL has to contain properly nested parentheses if no title is specified, or the link URL must be contained in angle brackets (incorrectly nested parentheses are allowed). * The link title may not contain its delimiters and may not be empty. * Additional link attributes can be added by using a [span IAL](#span-ials) after the inline link, for example: This is a [link](http://example.com){:hreflang="de"} ### Reference Links To create a reference style link, you need to surround the link text with square brackets (as with inline links), followed by optional spaces/tabs/line breaks and then optionally followed with another set of square brackets with the link identifier in them. A link identifier may not contain a closing bracket and, when specified in a link definition, newline characters; it is also not case sensitive, line breaks and tabs are converted to spaces and multiple spaces are compressed into one. For example: This is a [reference style link][linkid] to a page. And [this] [linkid] is also a link. As is [this][] and [THIS]. If you don't specify a link identifier (i.e. only use empty square brackets) or completely omit the second pair of square brackets, the link text is converted to a valid link identifier by removing all invalid characters and inserting spaces for line breaks. If there is a link definition found for the link identifier, a link will be created. Otherwise the text is not converted to a link. As with inline links, additional link attributes can be added by using a [span IAL](#span-ials) after the reference link. ### Link Definitions The link definition can be put anywhere in the document. It does not appear in the output. A link definition looks like this: [linkid]: http://www.example.com/ "Optional Title" > Link definitions are, despite being described here, non-content block-level elements. {: .information} The link definition has the following structure: * The link identifier in square brackets, optionally indented up to three spaces, * then a colon and one or more optional spaces/tabs, * then the link URL which must contain at least one non-space character, or a left angle bracket, the link URL and a right angle bracket, * then optionally the title in single or double quotes, separated from the link URL by one or more spaces or on the next line by itself indented any number of spaces/tabs. > The original Markdown syntax also allowed the title to be specified in parenthesis. This is not > allowed for consistency with the inline title. {: .markdown-difference} If you have some text that looks like a link definition but should really be a link and some text, you can escape the colon after the link identifier: The next paragraph contains a link and some text. [Room 100]\: There you should find everything you need! [Room 100]: link_to_room_100.html Although link definitions are non-content block-level elements, [block IALs](#block-ials) can be used on them to specify additional attributes for the links: [linkid]: http://example.com {:hreflang="de"} ### Images Images can be specified via a syntax that is similar to the one used by links. The difference is that you have to use an exclamation mark before the first square bracket and that the link text of a normal link becomes the alternative text of the image link. As with normal links, image links can be written inline or reference style. For example: Here comes a ![smiley](../images/smiley.png)! And here ![too](../images/other.png 'Title text'). Or ![here]. With empty alt text ![](see.jpg) The link definition for images is exactly the same as the link definition for normal links. Since additional attributes can be added via span and block IALs, it is possible, for example, to specify image width and height: Here is an inline ![smiley](smiley.png){:height="36px" width="36px"}. And here is a referenced ![smile] [smile]: smile.png {: height="36px" width="36px"} ## Emphasis kramdown supports two types of emphasis: light and strong emphasis. Text parts that are surrounded with single asterisks `*` or underscores `_` are treated as text with light emphasis, text parts surrounded with two asterisks or underscores are treated as text with strong emphasis. Surrounded means that the starting delimiter must not be followed by a space and that the stopping delimiter must not be preceded by a space. Here is an example for text with light and strong emphasis: *some text* _some text_ **some text** __some text__ The asterisk form is also allowed within a single word: This is un*believe*able! This d_oe_s not work! Text can be marked up with both light and strong emphasis, possibly using different delimiters. However, it is not possible to nest strong within strong or light within light emphasized text: This is a ***text with light and strong emphasis***. This **is _emphasized_ as well**. This *does _not_ work*. This **does __not__ work either**. If one or two asterisks or underscores are surrounded by spaces, they are treated literally. If you want to force the literal meaning of an asterisk or an underscore you can backslash-escape it: This is a * literal asterisk. These are ** two literal asterisk. As \*are\* these! ## Code Spans This is the span-level equivalent of the [code block](#code-blocks) element. You can markup a text part as code span by surrounding it with backticks `` ` ``. For example: Use `` tags for this. Note that all special characters in a code span are treated correctly. For example, when a code span is converted to HTML, the characters `<`, `>` and `&` are substituted by their respective HTML counterparts. To include a literal backtick in a code span, you need to use two or more backticks as delimiters. You can insert one optional space after the starting and before the ending delimiter (these spaces are not used in the output). For example: Here is a literal `` ` `` backtick. And here is `` `some` `` text (note the two spaces so that one is left in the output!). A single backtick surrounded by spaces is treated as literal backtick. If you want to force the literal meaning of a backtick you can backslash-escape it: This is a ` literal backtick. As \`are\` these! As with [code blocks](#language-of-code-blocks) you can set the language of a code span by using an [IAL](#inline-attribute-lists): This is a Ruby code fragment `x = Class.new`{:.language-ruby} ## HTML Spans HTML tags cannot only be used on the block-level but also on the span-level. Span-level HTML tags can only be used inside one block-level element, it is not possible to use a start tag in one block level element and the end tag in another. Note that only correct XHTML is supported! This means that you have to use, for example, `
    ` instead of `
    ` (although kramdown tries to fix such errors if possible). By default, kramdown parses kramdown syntax inside span HTML tags. However, this behaviour can be configured with the `parse_span_html` option. If this is set to `true`, then syntax parsing in HTML spans is enabled, if it is set to `false`, parsing is disabled. It is also possible to enable/disable syntax parsing on a tag per tag basis using the `markdown` attribute: * If an HTML tag has an attribute `markdown="0"`, then no parsing (except parsing of HTML span tags) is done inside that HTML tag. * If an HTML tag has an attribute `markdown="1"`, then the content of the tag is parsed as span level elements. * If an HTML tag has an attribute `markdown="block"`, then a warning is issued because HTML spans cannot contain block-level elements and the attribute is ignored. * If an HTML tag has an attribute `markdown="span"`, then the content of the tag is parsed as span level elements. The content of a span-level HTML tag is normally parsed as span-level elements. Note, however, that some tags like ` kramdown-1.17.0/setup.rb0000644000004100000410000010650413321140127015137 0ustar www-datawww-data# # setup.rb # # Copyright (c) 2000-2005 Minero Aoki # # This program is free software. # You can distribute/modify this program under the terms of # the GNU LGPL, Lesser General Public License version 2.1. # unless Enumerable.method_defined?(:map) # Ruby 1.4.6 module Enumerable alias map collect end end unless File.respond_to?(:read) # Ruby 1.6 def File.read(fname) open(fname) {|f| return f.read } end end unless Errno.const_defined?(:ENOTEMPTY) # Windows? module Errno class ENOTEMPTY # We do not raise this exception, implementation is not needed. end end end def File.binread(fname) open(fname, 'rb') {|f| return f.read } end # for corrupted Windows' stat(2) def File.dir?(path) File.directory?((path[-1,1] == '/') ? path : path + '/') end class ConfigTable include Enumerable def initialize(rbconfig) @rbconfig = rbconfig @items = [] @table = {} # options @install_prefix = nil @config_opt = nil @verbose = true @no_harm = false end attr_accessor :install_prefix attr_accessor :config_opt attr_writer :verbose def verbose? @verbose end attr_writer :no_harm def no_harm? @no_harm end def [](key) lookup(key).resolve(self) end def []=(key, val) lookup(key).set val end def names @items.map {|i| i.name } end def each(&block) @items.each(&block) end def key?(name) @table.key?(name) end def lookup(name) @table[name] or setup_rb_error "no such config item: #{name}" end def add(item) @items.push item @table[item.name] = item end def remove(name) item = lookup(name) @items.delete_if {|i| i.name == name } @table.delete_if {|name, i| i.name == name } item end def load_script(path, inst = nil) if File.file?(path) MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path end end def savefile '.config' end def load_savefile begin File.foreach(savefile()) do |line| k, v = *line.split(/=/, 2) self[k] = v.strip end rescue Errno::ENOENT setup_rb_error $!.message + "\n#{File.basename($0)} config first" end end def save @items.each {|i| i.value } File.open(savefile(), 'w') {|f| @items.each do |i| f.printf "%s=%s\n", i.name, i.value if i.value? and i.value end } end def load_standard_entries standard_entries(@rbconfig).each do |ent| add ent end end def standard_entries(rbconfig) c = rbconfig rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT']) major = c['MAJOR'].to_i minor = c['MINOR'].to_i teeny = c['TEENY'].to_i version = "#{major}.#{minor}" # ruby ver. >= 1.4.4? newpath_p = ((major >= 2) or ((major == 1) and ((minor >= 5) or ((minor == 4) and (teeny >= 4))))) if c['rubylibdir'] # V > 1.6.3 libruby = "#{c['prefix']}/lib/ruby" librubyver = c['rubylibdir'] librubyverarch = c['archdir'] siteruby = c['sitedir'] siterubyver = c['sitelibdir'] siterubyverarch = c['sitearchdir'] elsif newpath_p # 1.4.4 <= V <= 1.6.3 libruby = "#{c['prefix']}/lib/ruby" librubyver = "#{c['prefix']}/lib/ruby/#{version}" librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" siteruby = c['sitedir'] siterubyver = "$siteruby/#{version}" siterubyverarch = "$siterubyver/#{c['arch']}" else # V < 1.4.4 libruby = "#{c['prefix']}/lib/ruby" librubyver = "#{c['prefix']}/lib/ruby/#{version}" librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby" siterubyver = siteruby siterubyverarch = "$siterubyver/#{c['arch']}" end parameterize = lambda {|path| path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix') } if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } makeprog = arg.sub(/'/, '').split(/=/, 2)[1] else makeprog = 'make' end [ ExecItem.new('installdirs', 'std/site/home', 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\ {|val, table| case val when 'std' table['rbdir'] = '$librubyver' table['sodir'] = '$librubyverarch' when 'site' table['rbdir'] = '$siterubyver' table['sodir'] = '$siterubyverarch' when 'home' setup_rb_error '$HOME was not set' unless ENV['HOME'] table['prefix'] = ENV['HOME'] table['rbdir'] = '$libdir/ruby' table['sodir'] = '$libdir/ruby' end }, PathItem.new('prefix', 'path', c['prefix'], 'path prefix of target environment'), PathItem.new('bindir', 'path', parameterize.call(c['bindir']), 'the directory for commands'), PathItem.new('libdir', 'path', parameterize.call(c['libdir']), 'the directory for libraries'), PathItem.new('datadir', 'path', parameterize.call(c['datadir']), 'the directory for shared data'), PathItem.new('mandir', 'path', parameterize.call(c['mandir']), 'the directory for man pages'), PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), 'the directory for system configuration files'), PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']), 'the directory for local state data'), PathItem.new('libruby', 'path', libruby, 'the directory for ruby libraries'), PathItem.new('librubyver', 'path', librubyver, 'the directory for standard ruby libraries'), PathItem.new('librubyverarch', 'path', librubyverarch, 'the directory for standard ruby extensions'), PathItem.new('siteruby', 'path', siteruby, 'the directory for version-independent aux ruby libraries'), PathItem.new('siterubyver', 'path', siterubyver, 'the directory for aux ruby libraries'), PathItem.new('siterubyverarch', 'path', siterubyverarch, 'the directory for aux ruby binaries'), PathItem.new('rbdir', 'path', '$siterubyver', 'the directory for ruby scripts'), PathItem.new('sodir', 'path', '$siterubyverarch', 'the directory for ruby extentions'), PathItem.new('rubypath', 'path', rubypath, 'the path to set to #! line'), ProgramItem.new('rubyprog', 'name', rubypath, 'the ruby program using for installation'), ProgramItem.new('makeprog', 'name', makeprog, 'the make program to compile ruby extentions'), SelectItem.new('shebang', 'all/ruby/never', 'ruby', 'shebang line (#!) editing mode'), BoolItem.new('without-ext', 'yes/no', 'no', 'does not compile/install ruby extentions') ] end private :standard_entries def load_multipackage_entries multipackage_entries().each do |ent| add ent end end def multipackage_entries [ PackageSelectionItem.new('with', 'name,name...', '', 'ALL', 'package names that you want to install'), PackageSelectionItem.new('without', 'name,name...', '', 'NONE', 'package names that you do not want to install') ] end private :multipackage_entries ALIASES = { 'std-ruby' => 'librubyver', 'stdruby' => 'librubyver', 'rubylibdir' => 'librubyver', 'archdir' => 'librubyverarch', 'site-ruby-common' => 'siteruby', # For backward compatibility 'site-ruby' => 'siterubyver', # For backward compatibility 'bin-dir' => 'bindir', 'bin-dir' => 'bindir', 'rb-dir' => 'rbdir', 'so-dir' => 'sodir', 'data-dir' => 'datadir', 'ruby-path' => 'rubypath', 'ruby-prog' => 'rubyprog', 'ruby' => 'rubyprog', 'make-prog' => 'makeprog', 'make' => 'makeprog' } def fixup ALIASES.each do |ali, name| @table[ali] = @table[name] end @items.freeze @table.freeze @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/ end def parse_opt(opt) m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}" m.to_a[1,2] end def dllext @rbconfig['DLEXT'] end def value_config?(name) lookup(name).value? end class Item def initialize(name, template, default, desc) @name = name.freeze @template = template @value = default @default = default @description = desc end attr_reader :name attr_reader :description attr_accessor :default alias help_default default def help_opt "--#{@name}=#{@template}" end def value? true end def value @value end def resolve(table) @value.gsub(%r<\$([^/]+)>) { table[$1] } end def set(val) @value = check(val) end private def check(val) setup_rb_error "config: --#{name} requires argument" unless val val end end class BoolItem < Item def config_type 'bool' end def help_opt "--#{@name}" end private def check(val) return 'yes' unless val case val when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes' when /\An(o)?\z/i, /\Af(alse)\z/i then 'no' else setup_rb_error "config: --#{@name} accepts only yes/no for argument" end end end class PathItem < Item def config_type 'path' end private def check(path) setup_rb_error "config: --#{@name} requires argument" unless path path[0,1] == '$' ? path : File.expand_path(path) end end class ProgramItem < Item def config_type 'program' end end class SelectItem < Item def initialize(name, selection, default, desc) super @ok = selection.split('/') end def config_type 'select' end private def check(val) unless @ok.include?(val.strip) setup_rb_error "config: use --#{@name}=#{@template} (#{val})" end val.strip end end class ExecItem < Item def initialize(name, selection, desc, &block) super name, selection, nil, desc @ok = selection.split('/') @action = block end def config_type 'exec' end def value? false end def resolve(table) setup_rb_error "$#{name()} wrongly used as option value" end undef set def evaluate(val, table) v = val.strip.downcase unless @ok.include?(v) setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})" end @action.call v, table end end class PackageSelectionItem < Item def initialize(name, template, default, help_default, desc) super name, template, default, desc @help_default = help_default end attr_reader :help_default def config_type 'package' end private def check(val) unless File.dir?("packages/#{val}") setup_rb_error "config: no such package: #{val}" end val end end class MetaConfigEnvironment def initialize(config, installer) @config = config @installer = installer end def config_names @config.names end def config?(name) @config.key?(name) end def bool_config?(name) @config.lookup(name).config_type == 'bool' end def path_config?(name) @config.lookup(name).config_type == 'path' end def value_config?(name) @config.lookup(name).config_type != 'exec' end def add_config(item) @config.add item end def add_bool_config(name, default, desc) @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) end def add_path_config(name, default, desc) @config.add PathItem.new(name, 'path', default, desc) end def set_config_default(name, default) @config.lookup(name).default = default end def remove_config(name) @config.remove(name) end # For only multipackage def packages raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer @installer.packages end # For only multipackage def declare_packages(list) raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer @installer.packages = list end end end # class ConfigTable # This module requires: #verbose?, #no_harm? module FileOperations def mkdir_p(dirname, prefix = nil) dirname = prefix + File.expand_path(dirname) if prefix $stderr.puts "mkdir -p #{dirname}" if verbose? return if no_harm? # Does not check '/', it's too abnormal. dirs = File.expand_path(dirname).split(%r<(?=/)>) if /\A[a-z]:\z/i =~ dirs[0] disk = dirs.shift dirs[0] = disk + dirs[0] end dirs.each_index do |idx| path = dirs[0..idx].join('') Dir.mkdir path unless File.dir?(path) end end def rm_f(path) $stderr.puts "rm -f #{path}" if verbose? return if no_harm? force_remove_file path end def rm_rf(path) $stderr.puts "rm -rf #{path}" if verbose? return if no_harm? remove_tree path end def remove_tree(path) if File.symlink?(path) remove_file path elsif File.dir?(path) remove_tree0 path else force_remove_file path end end def remove_tree0(path) Dir.foreach(path) do |ent| next if ent == '.' next if ent == '..' entpath = "#{path}/#{ent}" if File.symlink?(entpath) remove_file entpath elsif File.dir?(entpath) remove_tree0 entpath else force_remove_file entpath end end begin Dir.rmdir path rescue Errno::ENOTEMPTY # directory may not be empty end end def move_file(src, dest) force_remove_file dest begin File.rename src, dest rescue File.open(dest, 'wb') {|f| f.write File.binread(src) } File.chmod File.stat(src).mode, dest File.unlink src end end def force_remove_file(path) begin remove_file path rescue end end def remove_file(path) File.chmod 0777, path File.unlink path end def install(from, dest, mode, prefix = nil) $stderr.puts "install #{from} #{dest}" if verbose? return if no_harm? realdest = prefix ? prefix + File.expand_path(dest) : dest realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) str = File.binread(from) if diff?(str, realdest) verbose_off { rm_f realdest if File.exist?(realdest) } File.open(realdest, 'wb') {|f| f.write str } File.chmod mode, realdest File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| if prefix f.puts realdest.sub(prefix, '') else f.puts realdest end } end end def diff?(new_content, path) return true unless File.exist?(path) new_content != File.binread(path) end def command(*args) $stderr.puts args.join(' ') if verbose? system(*args) or raise RuntimeError, "system(#{args.map{|a| a.inspect }.join(' ')}) failed" end def ruby(*args) command config('rubyprog'), *args end def make(task = nil) command(*[config('makeprog'), task].compact) end def extdir?(dir) File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb") end def files_of(dir) Dir.open(dir) {|d| return d.select {|ent| File.file?("#{dir}/#{ent}") } } end DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn ) def directories_of(dir) Dir.open(dir) {|d| return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT } end end # This module requires: #srcdir_root, #objdir_root, #relpath module HookScriptAPI def get_config(key) @config[key] end alias config get_config # obsolete: use metaconfig to change configuration def set_config(key, val) @config[key] = val end # # srcdir/objdir (works only in the package directory) # def curr_srcdir "#{srcdir_root()}/#{relpath()}" end def curr_objdir "#{objdir_root()}/#{relpath()}" end def srcfile(path) "#{curr_srcdir()}/#{path}" end def srcexist?(path) File.exist?(srcfile(path)) end def srcdirectory?(path) File.dir?(srcfile(path)) end def srcfile?(path) File.file?(srcfile(path)) end def srcentries(path = '.') Dir.open("#{curr_srcdir()}/#{path}") {|d| return d.to_a - %w(. ..) } end def srcfiles(path = '.') srcentries(path).select {|fname| File.file?(File.join(curr_srcdir(), path, fname)) } end def srcdirectories(path = '.') srcentries(path).select {|fname| File.dir?(File.join(curr_srcdir(), path, fname)) } end end class ToplevelInstaller Version = '3.4.1' Copyright = 'Copyright (c) 2000-2005 Minero Aoki' TASKS = [ [ 'all', 'do config, setup, then install' ], [ 'config', 'saves your configurations' ], [ 'show', 'shows current configuration' ], [ 'setup', 'compiles ruby extentions and others' ], [ 'install', 'installs files' ], [ 'test', 'run all tests in test/' ], [ 'clean', "does `make clean' for each extention" ], [ 'distclean',"does `make distclean' for each extention" ] ] def ToplevelInstaller.invoke config = ConfigTable.new(load_rbconfig()) config.load_standard_entries config.load_multipackage_entries if multipackage? config.fixup klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller) klass.new(File.dirname($0), config).invoke end def ToplevelInstaller.multipackage? File.dir?(File.dirname($0) + '/packages') end def ToplevelInstaller.load_rbconfig if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } ARGV.delete(arg) load File.expand_path(arg.split(/=/, 2)[1]) $".push 'rbconfig.rb' else require 'rbconfig' end ::RbConfig::CONFIG end def initialize(ardir_root, config) @ardir = File.expand_path(ardir_root) @config = config # cache @valid_task_re = nil end def config(key) @config[key] end def inspect "#<#{self.class} #{__id__()}>" end def invoke run_metaconfigs case task = parsearg_global() when nil, 'all' parsearg_config init_installers exec_config exec_setup exec_install else case task when 'config', 'test' ; when 'clean', 'distclean' @config.load_savefile if File.exist?(@config.savefile) else @config.load_savefile end __send__ "parsearg_#{task}" init_installers __send__ "exec_#{task}" end end def run_metaconfigs @config.load_script "#{@ardir}/metaconfig" end def init_installers @installer = Installer.new(@config, @ardir, File.expand_path('.')) end # # Hook Script API bases # def srcdir_root @ardir end def objdir_root '.' end def relpath '.' end # # Option Parsing # def parsearg_global while arg = ARGV.shift case arg when /\A\w+\z/ setup_rb_error "invalid task: #{arg}" unless valid_task?(arg) return arg when '-q', '--quiet' @config.verbose = false when '--verbose' @config.verbose = true when '--help' print_usage $stdout exit 0 when '--version' puts "#{File.basename($0)} version #{Version}" exit 0 when '--copyright' puts Copyright exit 0 else setup_rb_error "unknown global option '#{arg}'" end end nil end def valid_task?(t) valid_task_re() =~ t end def valid_task_re @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/ end def parsearg_no_options unless ARGV.empty? task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1) setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}" end end alias parsearg_show parsearg_no_options alias parsearg_setup parsearg_no_options alias parsearg_test parsearg_no_options alias parsearg_clean parsearg_no_options alias parsearg_distclean parsearg_no_options def parsearg_config evalopt = [] set = [] @config.config_opt = [] while i = ARGV.shift if /\A--?\z/ =~ i @config.config_opt = ARGV.dup break end name, value = *@config.parse_opt(i) if @config.value_config?(name) @config[name] = value else evalopt.push [name, value] end set.push name end evalopt.each do |name, value| @config.lookup(name).evaluate value, @config end # Check if configuration is valid set.each do |n| @config[n] if @config.value_config?(n) end end def parsearg_install @config.no_harm = false @config.install_prefix = '' while a = ARGV.shift case a when '--no-harm' @config.no_harm = true when /\A--prefix=/ path = a.split(/=/, 2)[1] path = File.expand_path(path) unless path[0,1] == '/' @config.install_prefix = path else setup_rb_error "install: unknown option #{a}" end end end def print_usage(out) out.puts 'Typical Installation Procedure:' out.puts " $ ruby #{File.basename $0} config" out.puts " $ ruby #{File.basename $0} setup" out.puts " # ruby #{File.basename $0} install (may require root privilege)" out.puts out.puts 'Detailed Usage:' out.puts " ruby #{File.basename $0} " out.puts " ruby #{File.basename $0} [] []" fmt = " %-24s %s\n" out.puts out.puts 'Global options:' out.printf fmt, '-q,--quiet', 'suppress message outputs' out.printf fmt, ' --verbose', 'output messages verbosely' out.printf fmt, ' --help', 'print this message' out.printf fmt, ' --version', 'print version and quit' out.printf fmt, ' --copyright', 'print copyright and quit' out.puts out.puts 'Tasks:' TASKS.each do |name, desc| out.printf fmt, name, desc end fmt = " %-24s %s [%s]\n" out.puts out.puts 'Options for CONFIG or ALL:' @config.each do |item| out.printf fmt, item.help_opt, item.description, item.help_default end out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" out.puts out.puts 'Options for INSTALL:' out.printf fmt, '--no-harm', 'only display what to do if given', 'off' out.printf fmt, '--prefix=path', 'install path prefix', '' out.puts end # # Task Handlers # def exec_config @installer.exec_config @config.save # must be final end def exec_setup @installer.exec_setup end def exec_install @installer.exec_install end def exec_test @installer.exec_test end def exec_show @config.each do |i| printf "%-20s %s\n", i.name, i.value if i.value? end end def exec_clean @installer.exec_clean end def exec_distclean @installer.exec_distclean end end # class ToplevelInstaller class ToplevelInstallerMulti < ToplevelInstaller include FileOperations def initialize(ardir_root, config) super @packages = directories_of("#{@ardir}/packages") raise 'no package exists' if @packages.empty? @root_installer = Installer.new(@config, @ardir, File.expand_path('.')) end def run_metaconfigs @config.load_script "#{@ardir}/metaconfig", self @packages.each do |name| @config.load_script "#{@ardir}/packages/#{name}/metaconfig" end end attr_reader :packages def packages=(list) raise 'package list is empty' if list.empty? list.each do |name| raise "directory packages/#{name} does not exist"\ unless File.dir?("#{@ardir}/packages/#{name}") end @packages = list end def init_installers @installers = {} @packages.each do |pack| @installers[pack] = Installer.new(@config, "#{@ardir}/packages/#{pack}", "packages/#{pack}") end with = extract_selection(config('with')) without = extract_selection(config('without')) @selected = @installers.keys.select {|name| (with.empty? or with.include?(name)) \ and not without.include?(name) } end def extract_selection(list) a = list.split(/,/) a.each do |name| setup_rb_error "no such package: #{name}" unless @installers.key?(name) end a end def print_usage(f) super f.puts 'Inluded packages:' f.puts ' ' + @packages.sort.join(' ') f.puts end # # Task Handlers # def exec_config run_hook 'pre-config' each_selected_installers {|inst| inst.exec_config } run_hook 'post-config' @config.save # must be final end def exec_setup run_hook 'pre-setup' each_selected_installers {|inst| inst.exec_setup } run_hook 'post-setup' end def exec_install run_hook 'pre-install' each_selected_installers {|inst| inst.exec_install } run_hook 'post-install' end def exec_test run_hook 'pre-test' each_selected_installers {|inst| inst.exec_test } run_hook 'post-test' end def exec_clean rm_f @config.savefile run_hook 'pre-clean' each_selected_installers {|inst| inst.exec_clean } run_hook 'post-clean' end def exec_distclean rm_f @config.savefile run_hook 'pre-distclean' each_selected_installers {|inst| inst.exec_distclean } run_hook 'post-distclean' end # # lib # def each_selected_installers Dir.mkdir 'packages' unless File.dir?('packages') @selected.each do |pack| $stderr.puts "Processing the package `#{pack}' ..." if verbose? Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") Dir.chdir "packages/#{pack}" yield @installers[pack] Dir.chdir '../..' end end def run_hook(id) @root_installer.run_hook id end # module FileOperations requires this def verbose? @config.verbose? end # module FileOperations requires this def no_harm? @config.no_harm? end end # class ToplevelInstallerMulti class Installer FILETYPES = %w( bin lib ext data conf man ) include FileOperations include HookScriptAPI def initialize(config, srcroot, objroot) @config = config @srcdir = File.expand_path(srcroot) @objdir = File.expand_path(objroot) @currdir = '.' end def inspect "#<#{self.class} #{File.basename(@srcdir)}>" end def noop(rel) end # # Hook Script API base methods # def srcdir_root @srcdir end def objdir_root @objdir end def relpath @currdir end # # Config Access # # module FileOperations requires this def verbose? @config.verbose? end # module FileOperations requires this def no_harm? @config.no_harm? end def verbose_off begin save, @config.verbose = @config.verbose?, false yield ensure @config.verbose = save end end # # TASK config # def exec_config exec_task_traverse 'config' end alias config_dir_bin noop alias config_dir_lib noop def config_dir_ext(rel) extconf if extdir?(curr_srcdir()) end alias config_dir_data noop alias config_dir_conf noop alias config_dir_man noop def extconf ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt end # # TASK setup # def exec_setup exec_task_traverse 'setup' end def setup_dir_bin(rel) files_of(curr_srcdir()).each do |fname| update_shebang_line "#{curr_srcdir()}/#{fname}" end end alias setup_dir_lib noop def setup_dir_ext(rel) make if extdir?(curr_srcdir()) end alias setup_dir_data noop alias setup_dir_conf noop alias setup_dir_man noop def update_shebang_line(path) return if no_harm? return if config('shebang') == 'never' old = Shebang.load(path) if old $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1 new = new_shebang(old) return if new.to_s == old.to_s else return unless config('shebang') == 'all' new = Shebang.new(config('rubypath')) end $stderr.puts "updating shebang: #{File.basename(path)}" if verbose? open_atomic_writer(path) {|output| File.open(path, 'rb') {|f| f.gets if old # discard output.puts new.to_s output.print f.read } } end def new_shebang(old) if /\Aruby/ =~ File.basename(old.cmd) Shebang.new(config('rubypath'), old.args) elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' Shebang.new(config('rubypath'), old.args[1..-1]) else return old unless config('shebang') == 'all' Shebang.new(config('rubypath')) end end def open_atomic_writer(path, &block) tmpfile = File.basename(path) + '.tmp' begin File.open(tmpfile, 'wb', &block) File.rename tmpfile, File.basename(path) ensure File.unlink tmpfile if File.exist?(tmpfile) end end class Shebang def Shebang.load(path) line = nil File.open(path) {|f| line = f.gets } return nil unless /\A#!/ =~ line parse(line) end def Shebang.parse(line) cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ') new(cmd, args) end def initialize(cmd, args = []) @cmd = cmd @args = args end attr_reader :cmd attr_reader :args def to_s "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}") end end # # TASK install # def exec_install rm_f 'InstalledFiles' exec_task_traverse 'install' end def install_dir_bin(rel) install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755 end def install_dir_lib(rel) install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644 end def install_dir_ext(rel) return unless extdir?(curr_srcdir()) install_files rubyextentions('.'), "#{config('sodir')}/#{File.dirname(rel)}", 0555 end def install_dir_data(rel) install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644 end def install_dir_conf(rel) # FIXME: should not remove current config files # (rename previous file to .old/.org) install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644 end def install_dir_man(rel) install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644 end def install_files(list, dest, mode) mkdir_p dest, @config.install_prefix list.each do |fname| install fname, dest, mode, @config.install_prefix end end def libfiles glob_reject(%w(*.y *.output), targetfiles()) end def rubyextentions(dir) ents = glob_select("*.#{@config.dllext}", targetfiles()) if ents.empty? setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" end ents end def targetfiles mapdir(existfiles() - hookfiles()) end def mapdir(ents) ents.map {|ent| if File.exist?(ent) then ent # objdir else "#{curr_srcdir()}/#{ent}" # srcdir end } end # picked up many entries from cvs-1.11.1/src/ignore.c JUNK_FILES = %w( core RCSLOG tags TAGS .make.state .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb *~ *.old *.bak *.BAK *.orig *.rej _$* *$ *.org *.in .* ) def existfiles glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.'))) end def hookfiles %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| %w( config setup install clean ).map {|t| sprintf(fmt, t) } }.flatten end def glob_select(pat, ents) re = globs2re([pat]) ents.select {|ent| re =~ ent } end def glob_reject(pats, ents) re = globs2re(pats) ents.reject {|ent| re =~ ent } end GLOB2REGEX = { '.' => '\.', '$' => '\$', '#' => '\#', '*' => '.*' } def globs2re(pats) /\A(?:#{ pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|') })\z/ end # # TASK test # TESTDIR = 'test' def exec_test unless File.directory?('test') $stderr.puts 'no test in this package' if verbose? return end $stderr.puts 'Running tests...' if verbose? begin require 'test/unit' rescue LoadError setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.' end runner = Test::Unit::AutoRunner.new(true) runner.to_run << TESTDIR runner.run end # # TASK clean # def exec_clean exec_task_traverse 'clean' rm_f @config.savefile rm_f 'InstalledFiles' end alias clean_dir_bin noop alias clean_dir_lib noop alias clean_dir_data noop alias clean_dir_conf noop alias clean_dir_man noop def clean_dir_ext(rel) return unless extdir?(curr_srcdir()) make 'clean' if File.file?('Makefile') end # # TASK distclean # def exec_distclean exec_task_traverse 'distclean' rm_f @config.savefile rm_f 'InstalledFiles' end alias distclean_dir_bin noop alias distclean_dir_lib noop def distclean_dir_ext(rel) return unless extdir?(curr_srcdir()) make 'distclean' if File.file?('Makefile') end alias distclean_dir_data noop alias distclean_dir_conf noop alias distclean_dir_man noop # # Traversing # def exec_task_traverse(task) run_hook "pre-#{task}" FILETYPES.each do |type| if type == 'ext' and config('without-ext') == 'yes' $stderr.puts 'skipping ext/* by user option' if verbose? next end traverse task, type, "#{task}_dir_#{type}" end run_hook "post-#{task}" end def traverse(task, rel, mid) dive_into(rel) { run_hook "pre-#{task}" __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') directories_of(curr_srcdir()).each do |d| traverse task, "#{rel}/#{d}", mid end run_hook "post-#{task}" } end def dive_into(rel) return unless File.dir?("#{@srcdir}/#{rel}") dir = File.basename(rel) Dir.mkdir dir unless File.dir?(dir) prevdir = Dir.pwd Dir.chdir dir $stderr.puts '---> ' + rel if verbose? @currdir = rel yield Dir.chdir prevdir $stderr.puts '<--- ' + rel if verbose? @currdir = File.dirname(rel) end def run_hook(id) path = [ "#{curr_srcdir()}/#{id}", "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) } return unless path begin instance_eval File.read(path), path, 1 rescue raise if $DEBUG setup_rb_error "hook #{path} failed:\n" + $!.message end end end # class Installer class SetupError < StandardError; end def setup_rb_error(msg) raise SetupError, msg end if $0 == __FILE__ begin ToplevelInstaller.invoke rescue SetupError raise if $DEBUG $stderr.puts $!.message $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." exit 1 end end kramdown-1.17.0/VERSION0000644000004100000410000000000713321140127014511 0ustar www-datawww-data1.17.0 kramdown-1.17.0/kramdown.gemspec0000644000004100000410000011777213321140127016652 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: kramdown 1.17.0 ruby lib Gem::Specification.new do |s| s.name = "kramdown".freeze s.version = "1.17.0" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Thomas Leitner".freeze] s.date = "2018-05-31" s.description = "kramdown is yet-another-markdown-parser but fast, pure Ruby,\nusing a strict syntax definition and supporting several common extensions.\n".freeze s.email = "t_leitner@gmx.at".freeze s.executables = ["kramdown".freeze] s.files = ["AUTHORS".freeze, "CONTRIBUTERS".freeze, "COPYING".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "benchmark/benchmark.rb".freeze, "benchmark/benchmark.sh".freeze, "benchmark/generate_data.rb".freeze, "benchmark/mdbasics.text".freeze, "benchmark/mdsyntax.text".freeze, "benchmark/testing.sh".freeze, "benchmark/timing.sh".freeze, "bin/kramdown".freeze, "data/kramdown/document.html".freeze, "data/kramdown/document.latex".freeze, "doc/_design.scss".freeze, "doc/bg.png".freeze, "doc/default.scss".freeze, "doc/default.template".freeze, "doc/documentation.page".freeze, "doc/documentation.template".freeze, "doc/index.page".freeze, "doc/installation.page".freeze, "doc/links.markdown".freeze, "doc/metainfo".freeze, "doc/news.feed".freeze, "doc/news.page".freeze, "doc/options.page".freeze, "doc/quickref.page".freeze, "doc/sidebar.template".freeze, "doc/sitemap.sitemap".freeze, "doc/syntax.page".freeze, "doc/tests.page".freeze, "doc/virtual".freeze, "lib/kramdown.rb".freeze, "lib/kramdown/converter.rb".freeze, "lib/kramdown/converter/base.rb".freeze, "lib/kramdown/converter/hash_ast.rb".freeze, "lib/kramdown/converter/html.rb".freeze, "lib/kramdown/converter/kramdown.rb".freeze, "lib/kramdown/converter/latex.rb".freeze, "lib/kramdown/converter/man.rb".freeze, "lib/kramdown/converter/math_engine/itex2mml.rb".freeze, "lib/kramdown/converter/math_engine/katex.rb".freeze, "lib/kramdown/converter/math_engine/mathjax.rb".freeze, "lib/kramdown/converter/math_engine/mathjaxnode.rb".freeze, "lib/kramdown/converter/math_engine/ritex.rb".freeze, "lib/kramdown/converter/math_engine/sskatex.rb".freeze, "lib/kramdown/converter/pdf.rb".freeze, "lib/kramdown/converter/remove_html_tags.rb".freeze, "lib/kramdown/converter/syntax_highlighter.rb".freeze, "lib/kramdown/converter/syntax_highlighter/coderay.rb".freeze, "lib/kramdown/converter/syntax_highlighter/minted.rb".freeze, "lib/kramdown/converter/syntax_highlighter/rouge.rb".freeze, "lib/kramdown/converter/toc.rb".freeze, "lib/kramdown/document.rb".freeze, "lib/kramdown/element.rb".freeze, "lib/kramdown/error.rb".freeze, "lib/kramdown/options.rb".freeze, "lib/kramdown/parser.rb".freeze, "lib/kramdown/parser/base.rb".freeze, "lib/kramdown/parser/gfm.rb".freeze, "lib/kramdown/parser/html.rb".freeze, "lib/kramdown/parser/kramdown.rb".freeze, "lib/kramdown/parser/kramdown/abbreviation.rb".freeze, "lib/kramdown/parser/kramdown/autolink.rb".freeze, "lib/kramdown/parser/kramdown/blank_line.rb".freeze, "lib/kramdown/parser/kramdown/block_boundary.rb".freeze, "lib/kramdown/parser/kramdown/blockquote.rb".freeze, "lib/kramdown/parser/kramdown/codeblock.rb".freeze, "lib/kramdown/parser/kramdown/codespan.rb".freeze, "lib/kramdown/parser/kramdown/emphasis.rb".freeze, "lib/kramdown/parser/kramdown/eob.rb".freeze, "lib/kramdown/parser/kramdown/escaped_chars.rb".freeze, "lib/kramdown/parser/kramdown/extensions.rb".freeze, "lib/kramdown/parser/kramdown/footnote.rb".freeze, "lib/kramdown/parser/kramdown/header.rb".freeze, "lib/kramdown/parser/kramdown/horizontal_rule.rb".freeze, "lib/kramdown/parser/kramdown/html.rb".freeze, "lib/kramdown/parser/kramdown/html_entity.rb".freeze, "lib/kramdown/parser/kramdown/line_break.rb".freeze, "lib/kramdown/parser/kramdown/link.rb".freeze, "lib/kramdown/parser/kramdown/list.rb".freeze, "lib/kramdown/parser/kramdown/math.rb".freeze, "lib/kramdown/parser/kramdown/paragraph.rb".freeze, "lib/kramdown/parser/kramdown/smart_quotes.rb".freeze, "lib/kramdown/parser/kramdown/table.rb".freeze, "lib/kramdown/parser/kramdown/typographic_symbol.rb".freeze, "lib/kramdown/parser/markdown.rb".freeze, "lib/kramdown/utils.rb".freeze, "lib/kramdown/utils/configurable.rb".freeze, "lib/kramdown/utils/entities.rb".freeze, "lib/kramdown/utils/html.rb".freeze, "lib/kramdown/utils/lru_cache.rb".freeze, "lib/kramdown/utils/ordered_hash.rb".freeze, "lib/kramdown/utils/string_scanner.rb".freeze, "lib/kramdown/utils/unidecoder.rb".freeze, "lib/kramdown/version.rb".freeze, "man/man1/kramdown.1".freeze, "setup.rb".freeze, "test/run_tests.rb".freeze, "test/test_files.rb".freeze, "test/test_location.rb".freeze, "test/test_string_scanner_kramdown.rb".freeze, "test/testcases/block/01_blank_line/spaces.html".freeze, "test/testcases/block/01_blank_line/spaces.text".freeze, "test/testcases/block/01_blank_line/tabs.html".freeze, "test/testcases/block/01_blank_line/tabs.text".freeze, "test/testcases/block/02_eob/beginning.html".freeze, "test/testcases/block/02_eob/beginning.text".freeze, "test/testcases/block/02_eob/end.html".freeze, "test/testcases/block/02_eob/end.text".freeze, "test/testcases/block/02_eob/middle.html".freeze, "test/testcases/block/02_eob/middle.text".freeze, "test/testcases/block/03_paragraph/indented.html".freeze, "test/testcases/block/03_paragraph/indented.html.gfm".freeze, "test/testcases/block/03_paragraph/indented.text".freeze, "test/testcases/block/03_paragraph/line_break_last_line.html".freeze, "test/testcases/block/03_paragraph/line_break_last_line.text".freeze, "test/testcases/block/03_paragraph/no_newline_at_end.html".freeze, "test/testcases/block/03_paragraph/no_newline_at_end.text".freeze, "test/testcases/block/03_paragraph/one_para.html".freeze, "test/testcases/block/03_paragraph/one_para.text".freeze, "test/testcases/block/03_paragraph/two_para.html".freeze, "test/testcases/block/03_paragraph/two_para.text".freeze, "test/testcases/block/03_paragraph/with_html_to_native.html".freeze, "test/testcases/block/03_paragraph/with_html_to_native.options".freeze, "test/testcases/block/03_paragraph/with_html_to_native.text".freeze, "test/testcases/block/04_header/atx_header.html".freeze, "test/testcases/block/04_header/atx_header.text".freeze, "test/testcases/block/04_header/atx_header_no_newline_at_end.html".freeze, "test/testcases/block/04_header/atx_header_no_newline_at_end.text".freeze, "test/testcases/block/04_header/header_type_offset.html".freeze, "test/testcases/block/04_header/header_type_offset.kramdown".freeze, "test/testcases/block/04_header/header_type_offset.latex".freeze, "test/testcases/block/04_header/header_type_offset.options".freeze, "test/testcases/block/04_header/header_type_offset.text".freeze, "test/testcases/block/04_header/setext_header.html".freeze, "test/testcases/block/04_header/setext_header.text".freeze, "test/testcases/block/04_header/setext_header_no_newline_at_end.html".freeze, "test/testcases/block/04_header/setext_header_no_newline_at_end.text".freeze, "test/testcases/block/04_header/with_auto_id_prefix.html".freeze, "test/testcases/block/04_header/with_auto_id_prefix.options".freeze, "test/testcases/block/04_header/with_auto_id_prefix.text".freeze, "test/testcases/block/04_header/with_auto_id_stripping.html".freeze, "test/testcases/block/04_header/with_auto_id_stripping.options".freeze, "test/testcases/block/04_header/with_auto_id_stripping.text".freeze, "test/testcases/block/04_header/with_auto_ids.html".freeze, "test/testcases/block/04_header/with_auto_ids.options".freeze, "test/testcases/block/04_header/with_auto_ids.text".freeze, "test/testcases/block/05_blockquote/indented.html".freeze, "test/testcases/block/05_blockquote/indented.text".freeze, "test/testcases/block/05_blockquote/lazy.html".freeze, "test/testcases/block/05_blockquote/lazy.text".freeze, "test/testcases/block/05_blockquote/nested.html".freeze, "test/testcases/block/05_blockquote/nested.text".freeze, "test/testcases/block/05_blockquote/no_newline_at_end.html".freeze, "test/testcases/block/05_blockquote/no_newline_at_end.text".freeze, "test/testcases/block/05_blockquote/very_long_line.html".freeze, "test/testcases/block/05_blockquote/very_long_line.text".freeze, "test/testcases/block/05_blockquote/with_code_blocks.html".freeze, "test/testcases/block/05_blockquote/with_code_blocks.text".freeze, "test/testcases/block/06_codeblock/disable-highlighting.html".freeze, "test/testcases/block/06_codeblock/disable-highlighting.options".freeze, "test/testcases/block/06_codeblock/disable-highlighting.text".freeze, "test/testcases/block/06_codeblock/error.html".freeze, "test/testcases/block/06_codeblock/error.text".freeze, "test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex".freeze, "test/testcases/block/06_codeblock/highlighting-minted-with-opts.options".freeze, "test/testcases/block/06_codeblock/highlighting-minted-with-opts.text".freeze, "test/testcases/block/06_codeblock/highlighting-minted.latex".freeze, "test/testcases/block/06_codeblock/highlighting-minted.options".freeze, "test/testcases/block/06_codeblock/highlighting-minted.text".freeze, "test/testcases/block/06_codeblock/highlighting-opts.html".freeze, "test/testcases/block/06_codeblock/highlighting-opts.options".freeze, "test/testcases/block/06_codeblock/highlighting-opts.text".freeze, "test/testcases/block/06_codeblock/highlighting.html".freeze, "test/testcases/block/06_codeblock/highlighting.options".freeze, "test/testcases/block/06_codeblock/highlighting.text".freeze, "test/testcases/block/06_codeblock/issue_gh45.html".freeze, "test/testcases/block/06_codeblock/issue_gh45.test".freeze, "test/testcases/block/06_codeblock/lazy.html".freeze, "test/testcases/block/06_codeblock/lazy.text".freeze, "test/testcases/block/06_codeblock/no_newline_at_end.html".freeze, "test/testcases/block/06_codeblock/no_newline_at_end.text".freeze, "test/testcases/block/06_codeblock/no_newline_at_end_1.html".freeze, "test/testcases/block/06_codeblock/no_newline_at_end_1.text".freeze, "test/testcases/block/06_codeblock/normal.html".freeze, "test/testcases/block/06_codeblock/normal.text".freeze, "test/testcases/block/06_codeblock/rouge/disabled.html".freeze, "test/testcases/block/06_codeblock/rouge/disabled.options".freeze, "test/testcases/block/06_codeblock/rouge/disabled.text".freeze, "test/testcases/block/06_codeblock/rouge/multiple.html".freeze, "test/testcases/block/06_codeblock/rouge/multiple.options".freeze, "test/testcases/block/06_codeblock/rouge/multiple.text".freeze, "test/testcases/block/06_codeblock/rouge/simple.html".freeze, "test/testcases/block/06_codeblock/rouge/simple.options".freeze, "test/testcases/block/06_codeblock/rouge/simple.text".freeze, "test/testcases/block/06_codeblock/tilde_syntax.html".freeze, "test/testcases/block/06_codeblock/tilde_syntax.text".freeze, "test/testcases/block/06_codeblock/whitespace.html".freeze, "test/testcases/block/06_codeblock/whitespace.text".freeze, "test/testcases/block/06_codeblock/with_blank_line.html".freeze, "test/testcases/block/06_codeblock/with_blank_line.text".freeze, "test/testcases/block/06_codeblock/with_eob_marker.html".freeze, "test/testcases/block/06_codeblock/with_eob_marker.text".freeze, "test/testcases/block/06_codeblock/with_ial.html".freeze, "test/testcases/block/06_codeblock/with_ial.text".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block.html".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block.options".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block.text".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options".freeze, "test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text".freeze, "test/testcases/block/07_horizontal_rule/error.html".freeze, "test/testcases/block/07_horizontal_rule/error.html.19".freeze, "test/testcases/block/07_horizontal_rule/error.text".freeze, "test/testcases/block/07_horizontal_rule/normal.html".freeze, "test/testcases/block/07_horizontal_rule/normal.text".freeze, "test/testcases/block/07_horizontal_rule/sepspaces.html".freeze, "test/testcases/block/07_horizontal_rule/sepspaces.text".freeze, "test/testcases/block/07_horizontal_rule/septabs.html".freeze, "test/testcases/block/07_horizontal_rule/septabs.text".freeze, "test/testcases/block/08_list/brackets_in_item.latex".freeze, "test/testcases/block/08_list/brackets_in_item.text".freeze, "test/testcases/block/08_list/escaping.html".freeze, "test/testcases/block/08_list/escaping.text".freeze, "test/testcases/block/08_list/item_ial.html".freeze, "test/testcases/block/08_list/item_ial.text".freeze, "test/testcases/block/08_list/lazy.html".freeze, "test/testcases/block/08_list/lazy.text".freeze, "test/testcases/block/08_list/lazy_and_nested.html".freeze, "test/testcases/block/08_list/lazy_and_nested.text".freeze, "test/testcases/block/08_list/list_and_hr.html".freeze, "test/testcases/block/08_list/list_and_hr.text".freeze, "test/testcases/block/08_list/list_and_others.html".freeze, "test/testcases/block/08_list/list_and_others.text".freeze, "test/testcases/block/08_list/mixed.html".freeze, "test/testcases/block/08_list/mixed.text".freeze, "test/testcases/block/08_list/nested.html".freeze, "test/testcases/block/08_list/nested.text".freeze, "test/testcases/block/08_list/other_first_element.html".freeze, "test/testcases/block/08_list/other_first_element.text".freeze, "test/testcases/block/08_list/simple_ol.html".freeze, "test/testcases/block/08_list/simple_ol.text".freeze, "test/testcases/block/08_list/simple_ul.html".freeze, "test/testcases/block/08_list/simple_ul.text".freeze, "test/testcases/block/08_list/single_item.html".freeze, "test/testcases/block/08_list/single_item.text".freeze, "test/testcases/block/08_list/special_cases.html".freeze, "test/testcases/block/08_list/special_cases.text".freeze, "test/testcases/block/09_html/comment.html".freeze, "test/testcases/block/09_html/comment.text".freeze, "test/testcases/block/09_html/content_model/deflists.html".freeze, "test/testcases/block/09_html/content_model/deflists.options".freeze, "test/testcases/block/09_html/content_model/deflists.text".freeze, "test/testcases/block/09_html/content_model/tables.html".freeze, "test/testcases/block/09_html/content_model/tables.options".freeze, "test/testcases/block/09_html/content_model/tables.text".freeze, "test/testcases/block/09_html/html5_attributes.html".freeze, "test/testcases/block/09_html/html5_attributes.text".freeze, "test/testcases/block/09_html/html_after_block.html".freeze, "test/testcases/block/09_html/html_after_block.text".freeze, "test/testcases/block/09_html/html_and_codeblocks.html".freeze, "test/testcases/block/09_html/html_and_codeblocks.options".freeze, "test/testcases/block/09_html/html_and_codeblocks.text".freeze, "test/testcases/block/09_html/html_and_headers.html".freeze, "test/testcases/block/09_html/html_and_headers.text".freeze, "test/testcases/block/09_html/html_to_native/code.html".freeze, "test/testcases/block/09_html/html_to_native/code.text".freeze, "test/testcases/block/09_html/html_to_native/comment.html".freeze, "test/testcases/block/09_html/html_to_native/comment.text".freeze, "test/testcases/block/09_html/html_to_native/emphasis.html".freeze, "test/testcases/block/09_html/html_to_native/emphasis.text".freeze, "test/testcases/block/09_html/html_to_native/entity.html".freeze, "test/testcases/block/09_html/html_to_native/entity.text".freeze, "test/testcases/block/09_html/html_to_native/header.html".freeze, "test/testcases/block/09_html/html_to_native/header.options".freeze, "test/testcases/block/09_html/html_to_native/header.text".freeze, "test/testcases/block/09_html/html_to_native/list_dl.html".freeze, "test/testcases/block/09_html/html_to_native/list_dl.text".freeze, "test/testcases/block/09_html/html_to_native/list_ol.html".freeze, "test/testcases/block/09_html/html_to_native/list_ol.text".freeze, "test/testcases/block/09_html/html_to_native/list_ul.html".freeze, "test/testcases/block/09_html/html_to_native/list_ul.text".freeze, "test/testcases/block/09_html/html_to_native/options".freeze, "test/testcases/block/09_html/html_to_native/paragraph.html".freeze, "test/testcases/block/09_html/html_to_native/paragraph.text".freeze, "test/testcases/block/09_html/html_to_native/table_normal.html".freeze, "test/testcases/block/09_html/html_to_native/table_normal.text".freeze, "test/testcases/block/09_html/html_to_native/table_simple.html".freeze, "test/testcases/block/09_html/html_to_native/table_simple.text".freeze, "test/testcases/block/09_html/html_to_native/typography.html".freeze, "test/testcases/block/09_html/html_to_native/typography.html.19".freeze, "test/testcases/block/09_html/html_to_native/typography.text".freeze, "test/testcases/block/09_html/invalid_html_1.html".freeze, "test/testcases/block/09_html/invalid_html_1.text".freeze, "test/testcases/block/09_html/invalid_html_2.html".freeze, "test/testcases/block/09_html/invalid_html_2.text".freeze, "test/testcases/block/09_html/markdown_attr.html".freeze, "test/testcases/block/09_html/markdown_attr.text".freeze, "test/testcases/block/09_html/not_parsed.html".freeze, "test/testcases/block/09_html/not_parsed.text".freeze, "test/testcases/block/09_html/parse_as_raw.html".freeze, "test/testcases/block/09_html/parse_as_raw.htmlinput".freeze, "test/testcases/block/09_html/parse_as_raw.options".freeze, "test/testcases/block/09_html/parse_as_raw.text".freeze, "test/testcases/block/09_html/parse_as_span.html".freeze, "test/testcases/block/09_html/parse_as_span.htmlinput".freeze, "test/testcases/block/09_html/parse_as_span.options".freeze, "test/testcases/block/09_html/parse_as_span.text".freeze, "test/testcases/block/09_html/parse_block_html.html".freeze, "test/testcases/block/09_html/parse_block_html.options".freeze, "test/testcases/block/09_html/parse_block_html.text".freeze, "test/testcases/block/09_html/processing_instruction.html".freeze, "test/testcases/block/09_html/processing_instruction.text".freeze, "test/testcases/block/09_html/simple.html".freeze, "test/testcases/block/09_html/simple.html.19".freeze, "test/testcases/block/09_html/simple.options".freeze, "test/testcases/block/09_html/simple.text".freeze, "test/testcases/block/09_html/textarea.html".freeze, "test/testcases/block/09_html/textarea.text".freeze, "test/testcases/block/09_html/xml.html".freeze, "test/testcases/block/09_html/xml.text".freeze, "test/testcases/block/10_ald/simple.html".freeze, "test/testcases/block/10_ald/simple.text".freeze, "test/testcases/block/11_ial/auto_id_and_ial.html".freeze, "test/testcases/block/11_ial/auto_id_and_ial.options".freeze, "test/testcases/block/11_ial/auto_id_and_ial.text".freeze, "test/testcases/block/11_ial/nested.html".freeze, "test/testcases/block/11_ial/nested.text".freeze, "test/testcases/block/11_ial/simple.html".freeze, "test/testcases/block/11_ial/simple.text".freeze, "test/testcases/block/12_extension/comment.html".freeze, "test/testcases/block/12_extension/comment.text".freeze, "test/testcases/block/12_extension/ignored.html".freeze, "test/testcases/block/12_extension/ignored.text".freeze, "test/testcases/block/12_extension/nomarkdown.html".freeze, "test/testcases/block/12_extension/nomarkdown.kramdown".freeze, "test/testcases/block/12_extension/nomarkdown.latex".freeze, "test/testcases/block/12_extension/nomarkdown.text".freeze, "test/testcases/block/12_extension/options.html".freeze, "test/testcases/block/12_extension/options.text".freeze, "test/testcases/block/12_extension/options2.html".freeze, "test/testcases/block/12_extension/options2.text".freeze, "test/testcases/block/12_extension/options3.html".freeze, "test/testcases/block/12_extension/options3.text".freeze, "test/testcases/block/13_definition_list/auto_ids.html".freeze, "test/testcases/block/13_definition_list/auto_ids.text".freeze, "test/testcases/block/13_definition_list/definition_at_beginning.html".freeze, "test/testcases/block/13_definition_list/definition_at_beginning.text".freeze, "test/testcases/block/13_definition_list/deflist_ial.html".freeze, "test/testcases/block/13_definition_list/deflist_ial.text".freeze, "test/testcases/block/13_definition_list/item_ial.html".freeze, "test/testcases/block/13_definition_list/item_ial.text".freeze, "test/testcases/block/13_definition_list/multiple_terms.html".freeze, "test/testcases/block/13_definition_list/multiple_terms.text".freeze, "test/testcases/block/13_definition_list/no_def_list.html".freeze, "test/testcases/block/13_definition_list/no_def_list.text".freeze, "test/testcases/block/13_definition_list/para_wrapping.html".freeze, "test/testcases/block/13_definition_list/para_wrapping.text".freeze, "test/testcases/block/13_definition_list/separated_by_eob.html".freeze, "test/testcases/block/13_definition_list/separated_by_eob.text".freeze, "test/testcases/block/13_definition_list/simple.html".freeze, "test/testcases/block/13_definition_list/simple.text".freeze, "test/testcases/block/13_definition_list/styled_terms.html".freeze, "test/testcases/block/13_definition_list/styled_terms.text".freeze, "test/testcases/block/13_definition_list/too_much_space.html".freeze, "test/testcases/block/13_definition_list/too_much_space.text".freeze, "test/testcases/block/13_definition_list/with_blocks.html".freeze, "test/testcases/block/13_definition_list/with_blocks.text".freeze, "test/testcases/block/14_table/empty_tag_in_cell.html".freeze, "test/testcases/block/14_table/empty_tag_in_cell.options".freeze, "test/testcases/block/14_table/empty_tag_in_cell.text".freeze, "test/testcases/block/14_table/errors.html".freeze, "test/testcases/block/14_table/errors.text".freeze, "test/testcases/block/14_table/escaping.html".freeze, "test/testcases/block/14_table/escaping.text".freeze, "test/testcases/block/14_table/footer.html".freeze, "test/testcases/block/14_table/footer.text".freeze, "test/testcases/block/14_table/header.html".freeze, "test/testcases/block/14_table/header.text".freeze, "test/testcases/block/14_table/no_table.html".freeze, "test/testcases/block/14_table/no_table.text".freeze, "test/testcases/block/14_table/simple.html".freeze, "test/testcases/block/14_table/simple.text".freeze, "test/testcases/block/14_table/table_with_footnote.html".freeze, "test/testcases/block/14_table/table_with_footnote.latex".freeze, "test/testcases/block/14_table/table_with_footnote.text".freeze, "test/testcases/block/15_math/gh_128.html".freeze, "test/testcases/block/15_math/gh_128.text".freeze, "test/testcases/block/15_math/itex2mml.html".freeze, "test/testcases/block/15_math/itex2mml.options".freeze, "test/testcases/block/15_math/itex2mml.text".freeze, "test/testcases/block/15_math/katex.html.19".freeze, "test/testcases/block/15_math/katex.options".freeze, "test/testcases/block/15_math/katex.text".freeze, "test/testcases/block/15_math/mathjax_preview.html".freeze, "test/testcases/block/15_math/mathjax_preview.options".freeze, "test/testcases/block/15_math/mathjax_preview.text".freeze, "test/testcases/block/15_math/mathjax_preview_as_code.html".freeze, "test/testcases/block/15_math/mathjax_preview_as_code.options".freeze, "test/testcases/block/15_math/mathjax_preview_as_code.text".freeze, "test/testcases/block/15_math/mathjax_preview_simple.html".freeze, "test/testcases/block/15_math/mathjax_preview_simple.options".freeze, "test/testcases/block/15_math/mathjax_preview_simple.text".freeze, "test/testcases/block/15_math/mathjaxnode.html.19".freeze, "test/testcases/block/15_math/mathjaxnode.options".freeze, "test/testcases/block/15_math/mathjaxnode.text".freeze, "test/testcases/block/15_math/mathjaxnode_notexhints.html.19".freeze, "test/testcases/block/15_math/mathjaxnode_notexhints.options".freeze, "test/testcases/block/15_math/mathjaxnode_notexhints.text".freeze, "test/testcases/block/15_math/mathjaxnode_semantics.html.19".freeze, "test/testcases/block/15_math/mathjaxnode_semantics.options".freeze, "test/testcases/block/15_math/mathjaxnode_semantics.text".freeze, "test/testcases/block/15_math/no_engine.html".freeze, "test/testcases/block/15_math/no_engine.options".freeze, "test/testcases/block/15_math/no_engine.text".freeze, "test/testcases/block/15_math/normal.html".freeze, "test/testcases/block/15_math/normal.text".freeze, "test/testcases/block/15_math/ritex.html".freeze, "test/testcases/block/15_math/ritex.options".freeze, "test/testcases/block/15_math/ritex.text".freeze, "test/testcases/block/15_math/sskatex.html.19".freeze, "test/testcases/block/15_math/sskatex.options".freeze, "test/testcases/block/15_math/sskatex.text".freeze, "test/testcases/block/16_toc/no_toc.html".freeze, "test/testcases/block/16_toc/no_toc.text".freeze, "test/testcases/block/16_toc/toc_exclude.html".freeze, "test/testcases/block/16_toc/toc_exclude.options".freeze, "test/testcases/block/16_toc/toc_exclude.text".freeze, "test/testcases/block/16_toc/toc_levels.html".freeze, "test/testcases/block/16_toc/toc_levels.options".freeze, "test/testcases/block/16_toc/toc_levels.text".freeze, "test/testcases/block/16_toc/toc_with_footnotes.html".freeze, "test/testcases/block/16_toc/toc_with_footnotes.options".freeze, "test/testcases/block/16_toc/toc_with_footnotes.text".freeze, "test/testcases/block/16_toc/toc_with_links.html".freeze, "test/testcases/block/16_toc/toc_with_links.options".freeze, "test/testcases/block/16_toc/toc_with_links.text".freeze, "test/testcases/encoding.html".freeze, "test/testcases/encoding.text".freeze, "test/testcases/man/example.man".freeze, "test/testcases/man/example.text".freeze, "test/testcases/man/heading-name-dash-description.man".freeze, "test/testcases/man/heading-name-dash-description.text".freeze, "test/testcases/man/heading-name-description.man".freeze, "test/testcases/man/heading-name-description.text".freeze, "test/testcases/man/heading-name-section-description.man".freeze, "test/testcases/man/heading-name-section-description.text".freeze, "test/testcases/man/heading-name-section.man".freeze, "test/testcases/man/heading-name-section.text".freeze, "test/testcases/man/heading-name.man".freeze, "test/testcases/man/heading-name.text".freeze, "test/testcases/man/sections.man".freeze, "test/testcases/man/sections.text".freeze, "test/testcases/man/text-escaping.man".freeze, "test/testcases/man/text-escaping.text".freeze, "test/testcases/span/01_link/empty.html".freeze, "test/testcases/span/01_link/empty.text".freeze, "test/testcases/span/01_link/empty_title.htmlinput".freeze, "test/testcases/span/01_link/empty_title.text".freeze, "test/testcases/span/01_link/image_in_a.html".freeze, "test/testcases/span/01_link/image_in_a.text".freeze, "test/testcases/span/01_link/imagelinks.html".freeze, "test/testcases/span/01_link/imagelinks.text".freeze, "test/testcases/span/01_link/inline.html".freeze, "test/testcases/span/01_link/inline.html.19".freeze, "test/testcases/span/01_link/inline.text".freeze, "test/testcases/span/01_link/latex_escaping.latex".freeze, "test/testcases/span/01_link/latex_escaping.text".freeze, "test/testcases/span/01_link/link_defs.html".freeze, "test/testcases/span/01_link/link_defs.text".freeze, "test/testcases/span/01_link/link_defs_with_ial.html".freeze, "test/testcases/span/01_link/link_defs_with_ial.text".freeze, "test/testcases/span/01_link/links_with_angle_brackets.html".freeze, "test/testcases/span/01_link/links_with_angle_brackets.text".freeze, "test/testcases/span/01_link/reference.html".freeze, "test/testcases/span/01_link/reference.html.19".freeze, "test/testcases/span/01_link/reference.options".freeze, "test/testcases/span/01_link/reference.text".freeze, "test/testcases/span/02_emphasis/empty.html".freeze, "test/testcases/span/02_emphasis/empty.text".freeze, "test/testcases/span/02_emphasis/errors.html".freeze, "test/testcases/span/02_emphasis/errors.text".freeze, "test/testcases/span/02_emphasis/nesting.html".freeze, "test/testcases/span/02_emphasis/nesting.text".freeze, "test/testcases/span/02_emphasis/normal.html".freeze, "test/testcases/span/02_emphasis/normal.options".freeze, "test/testcases/span/02_emphasis/normal.text".freeze, "test/testcases/span/03_codespan/empty.html".freeze, "test/testcases/span/03_codespan/empty.text".freeze, "test/testcases/span/03_codespan/errors.html".freeze, "test/testcases/span/03_codespan/errors.text".freeze, "test/testcases/span/03_codespan/highlighting-minted.latex".freeze, "test/testcases/span/03_codespan/highlighting-minted.options".freeze, "test/testcases/span/03_codespan/highlighting-minted.text".freeze, "test/testcases/span/03_codespan/highlighting.html".freeze, "test/testcases/span/03_codespan/highlighting.text".freeze, "test/testcases/span/03_codespan/normal.html".freeze, "test/testcases/span/03_codespan/normal.text".freeze, "test/testcases/span/03_codespan/rouge/disabled.html".freeze, "test/testcases/span/03_codespan/rouge/disabled.options".freeze, "test/testcases/span/03_codespan/rouge/disabled.text".freeze, "test/testcases/span/03_codespan/rouge/simple.html".freeze, "test/testcases/span/03_codespan/rouge/simple.options".freeze, "test/testcases/span/03_codespan/rouge/simple.text".freeze, "test/testcases/span/04_footnote/backlink_inline.html".freeze, "test/testcases/span/04_footnote/backlink_inline.options".freeze, "test/testcases/span/04_footnote/backlink_inline.text".freeze, "test/testcases/span/04_footnote/backlink_text.html".freeze, "test/testcases/span/04_footnote/backlink_text.options".freeze, "test/testcases/span/04_footnote/backlink_text.text".freeze, "test/testcases/span/04_footnote/definitions.html".freeze, "test/testcases/span/04_footnote/definitions.latex".freeze, "test/testcases/span/04_footnote/definitions.text".freeze, "test/testcases/span/04_footnote/footnote_nr.html".freeze, "test/testcases/span/04_footnote/footnote_nr.latex".freeze, "test/testcases/span/04_footnote/footnote_nr.options".freeze, "test/testcases/span/04_footnote/footnote_nr.text".freeze, "test/testcases/span/04_footnote/inside_footnote.html".freeze, "test/testcases/span/04_footnote/inside_footnote.text".freeze, "test/testcases/span/04_footnote/markers.html".freeze, "test/testcases/span/04_footnote/markers.latex".freeze, "test/testcases/span/04_footnote/markers.options".freeze, "test/testcases/span/04_footnote/markers.text".freeze, "test/testcases/span/04_footnote/placement.html".freeze, "test/testcases/span/04_footnote/placement.options".freeze, "test/testcases/span/04_footnote/placement.text".freeze, "test/testcases/span/04_footnote/regexp_problem.html".freeze, "test/testcases/span/04_footnote/regexp_problem.options".freeze, "test/testcases/span/04_footnote/regexp_problem.text".freeze, "test/testcases/span/04_footnote/without_backlink.html".freeze, "test/testcases/span/04_footnote/without_backlink.options".freeze, "test/testcases/span/04_footnote/without_backlink.text".freeze, "test/testcases/span/05_html/across_lines.html".freeze, "test/testcases/span/05_html/across_lines.text".freeze, "test/testcases/span/05_html/button.html".freeze, "test/testcases/span/05_html/button.text".freeze, "test/testcases/span/05_html/invalid.html".freeze, "test/testcases/span/05_html/invalid.text".freeze, "test/testcases/span/05_html/link_with_mailto.html".freeze, "test/testcases/span/05_html/link_with_mailto.text".freeze, "test/testcases/span/05_html/mark_element.html".freeze, "test/testcases/span/05_html/mark_element.text".freeze, "test/testcases/span/05_html/markdown_attr.html".freeze, "test/testcases/span/05_html/markdown_attr.text".freeze, "test/testcases/span/05_html/normal.html".freeze, "test/testcases/span/05_html/normal.text".freeze, "test/testcases/span/05_html/raw_span_elements.html".freeze, "test/testcases/span/05_html/raw_span_elements.text".freeze, "test/testcases/span/05_html/xml.html".freeze, "test/testcases/span/05_html/xml.text".freeze, "test/testcases/span/abbreviations/abbrev.html".freeze, "test/testcases/span/abbreviations/abbrev.text".freeze, "test/testcases/span/abbreviations/abbrev_defs.html".freeze, "test/testcases/span/abbreviations/abbrev_defs.text".freeze, "test/testcases/span/abbreviations/in_footnote.html".freeze, "test/testcases/span/abbreviations/in_footnote.text".freeze, "test/testcases/span/autolinks/url_links.html".freeze, "test/testcases/span/autolinks/url_links.text".freeze, "test/testcases/span/escaped_chars/normal.html".freeze, "test/testcases/span/escaped_chars/normal.text".freeze, "test/testcases/span/extension/comment.html".freeze, "test/testcases/span/extension/comment.text".freeze, "test/testcases/span/extension/ignored.html".freeze, "test/testcases/span/extension/ignored.text".freeze, "test/testcases/span/extension/nomarkdown.html".freeze, "test/testcases/span/extension/nomarkdown.text".freeze, "test/testcases/span/extension/options.html".freeze, "test/testcases/span/extension/options.text".freeze, "test/testcases/span/ial/simple.html".freeze, "test/testcases/span/ial/simple.text".freeze, "test/testcases/span/line_breaks/normal.html".freeze, "test/testcases/span/line_breaks/normal.latex".freeze, "test/testcases/span/line_breaks/normal.text".freeze, "test/testcases/span/math/itex2mml.html".freeze, "test/testcases/span/math/itex2mml.options".freeze, "test/testcases/span/math/itex2mml.text".freeze, "test/testcases/span/math/katex.html.19".freeze, "test/testcases/span/math/katex.options".freeze, "test/testcases/span/math/katex.text".freeze, "test/testcases/span/math/mathjaxnode.html.19".freeze, "test/testcases/span/math/mathjaxnode.options".freeze, "test/testcases/span/math/mathjaxnode.text".freeze, "test/testcases/span/math/no_engine.html".freeze, "test/testcases/span/math/no_engine.options".freeze, "test/testcases/span/math/no_engine.text".freeze, "test/testcases/span/math/normal.html".freeze, "test/testcases/span/math/normal.text".freeze, "test/testcases/span/math/ritex.html".freeze, "test/testcases/span/math/ritex.options".freeze, "test/testcases/span/math/ritex.text".freeze, "test/testcases/span/math/sskatex.html.19".freeze, "test/testcases/span/math/sskatex.options".freeze, "test/testcases/span/math/sskatex.text".freeze, "test/testcases/span/text_substitutions/entities.html".freeze, "test/testcases/span/text_substitutions/entities.options".freeze, "test/testcases/span/text_substitutions/entities.text".freeze, "test/testcases/span/text_substitutions/entities_as_char.html".freeze, "test/testcases/span/text_substitutions/entities_as_char.html.19".freeze, "test/testcases/span/text_substitutions/entities_as_char.options".freeze, "test/testcases/span/text_substitutions/entities_as_char.text".freeze, "test/testcases/span/text_substitutions/entities_as_input.html".freeze, "test/testcases/span/text_substitutions/entities_as_input.options".freeze, "test/testcases/span/text_substitutions/entities_as_input.text".freeze, "test/testcases/span/text_substitutions/entities_numeric.html".freeze, "test/testcases/span/text_substitutions/entities_numeric.options".freeze, "test/testcases/span/text_substitutions/entities_numeric.text".freeze, "test/testcases/span/text_substitutions/entities_symbolic.html".freeze, "test/testcases/span/text_substitutions/entities_symbolic.options".freeze, "test/testcases/span/text_substitutions/entities_symbolic.text".freeze, "test/testcases/span/text_substitutions/greaterthan.html".freeze, "test/testcases/span/text_substitutions/greaterthan.text".freeze, "test/testcases/span/text_substitutions/lowerthan.html".freeze, "test/testcases/span/text_substitutions/lowerthan.text".freeze, "test/testcases/span/text_substitutions/typography.html".freeze, "test/testcases/span/text_substitutions/typography.options".freeze, "test/testcases/span/text_substitutions/typography.text".freeze, "test/testcases/span/text_substitutions/typography_subst.html".freeze, "test/testcases/span/text_substitutions/typography_subst.latex".freeze, "test/testcases/span/text_substitutions/typography_subst.options".freeze, "test/testcases/span/text_substitutions/typography_subst.text".freeze, "test/testcases_gfm/atx_header.html".freeze, "test/testcases_gfm/atx_header.text".freeze, "test/testcases_gfm/backticks_disable_highlighting.html".freeze, "test/testcases_gfm/backticks_disable_highlighting.options".freeze, "test/testcases_gfm/backticks_disable_highlighting.text".freeze, "test/testcases_gfm/backticks_syntax.html".freeze, "test/testcases_gfm/backticks_syntax.text".freeze, "test/testcases_gfm/codeblock_fenced.html".freeze, "test/testcases_gfm/codeblock_fenced.options".freeze, "test/testcases_gfm/codeblock_fenced.text".freeze, "test/testcases_gfm/hard_line_breaks.html".freeze, "test/testcases_gfm/hard_line_breaks.text".freeze, "test/testcases_gfm/hard_line_breaks_off.html".freeze, "test/testcases_gfm/hard_line_breaks_off.options".freeze, "test/testcases_gfm/hard_line_breaks_off.text".freeze, "test/testcases_gfm/header_ids.html".freeze, "test/testcases_gfm/header_ids.html.19".freeze, "test/testcases_gfm/header_ids.options".freeze, "test/testcases_gfm/header_ids.text".freeze, "test/testcases_gfm/header_ids_with_prefix.html".freeze, "test/testcases_gfm/header_ids_with_prefix.options".freeze, "test/testcases_gfm/header_ids_with_prefix.text".freeze, "test/testcases_gfm/no_typographic.html".freeze, "test/testcases_gfm/no_typographic.html.19".freeze, "test/testcases_gfm/no_typographic.options".freeze, "test/testcases_gfm/no_typographic.text".freeze, "test/testcases_gfm/paragraph_end-disabled.html".freeze, "test/testcases_gfm/paragraph_end-disabled.options".freeze, "test/testcases_gfm/paragraph_end-disabled.text".freeze, "test/testcases_gfm/paragraph_end.html".freeze, "test/testcases_gfm/paragraph_end.text".freeze, "test/testcases_gfm/strikethrough.html".freeze, "test/testcases_gfm/strikethrough.html.19".freeze, "test/testcases_gfm/strikethrough.text".freeze, "test/testcases_gfm/task_list.html".freeze, "test/testcases_gfm/task_list.text".freeze, "test/testcases_gfm/two_para_hard_line_breaks.html".freeze, "test/testcases_gfm/two_para_hard_line_breaks.text".freeze] s.homepage = "http://kramdown.gettalong.org".freeze s.licenses = ["MIT".freeze] s.rdoc_options = ["--main".freeze, "lib/kramdown/document.rb".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze) s.rubygems_version = "2.5.2.1".freeze s.summary = "kramdown is a fast, pure-Ruby Markdown-superset converter.".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q.freeze, ["~> 1.0.0"]) s.add_development_dependency(%q.freeze, ["~> 2.7"]) s.add_development_dependency(%q.freeze, ["~> 1.5"]) s.add_development_dependency(%q.freeze, ["~> 0.4.3"]) s.add_development_dependency(%q.freeze, ["~> 5.0"]) s.add_development_dependency(%q.freeze, ["~> 2.0"]) s.add_development_dependency(%q.freeze, ["~> 0.2.2"]) s.add_development_dependency(%q.freeze, ["~> 1.0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0.9.37"]) s.add_development_dependency(%q.freeze, ["~> 1.5.1"]) else s.add_dependency(%q.freeze, ["~> 1.0.0"]) s.add_dependency(%q.freeze, ["~> 2.7"]) s.add_dependency(%q.freeze, ["~> 1.5"]) s.add_dependency(%q.freeze, ["~> 0.4.3"]) s.add_dependency(%q.freeze, ["~> 5.0"]) s.add_dependency(%q.freeze, ["~> 2.0"]) s.add_dependency(%q.freeze, ["~> 0.2.2"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0.9.37"]) s.add_dependency(%q.freeze, ["~> 1.5.1"]) end else s.add_dependency(%q.freeze, ["~> 1.0.0"]) s.add_dependency(%q.freeze, ["~> 2.7"]) s.add_dependency(%q.freeze, ["~> 1.5"]) s.add_dependency(%q.freeze, ["~> 0.4.3"]) s.add_dependency(%q.freeze, ["~> 5.0"]) s.add_dependency(%q.freeze, ["~> 2.0"]) s.add_dependency(%q.freeze, ["~> 0.2.2"]) s.add_dependency(%q.freeze, ["~> 1.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0.9.37"]) s.add_dependency(%q.freeze, ["~> 1.5.1"]) end end