kramdown-2.4.0/0000755000004100000410000000000014234044402013364 5ustar www-datawww-datakramdown-2.4.0/COPYING0000644000004100000410000000243714234044402014425 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-2.4.0/test/0000755000004100000410000000000014234044402014343 5ustar www-datawww-datakramdown-2.4.0/test/test_files.rb0000644000004100000410000003744314234044402017044 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'minitest/autorun' require 'kramdown' require 'yaml' require 'tmpdir' require 'open3' 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 module Rouge module Formatters class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class tag 'rouge_html_formatters' def stream(tokens, &b) yield %(
) super yield %(
) end end end end rescue LoadError, SyntaxError, NameError end Encoding.default_external = 'utf-8' class TestFiles < Minitest::Test EXCLUDE_KD_FILES = [].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| output_format = File.extname(output_file)[1..-1] next unless 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') unless 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/block/06_codeblock/highlighting.html', # bc of span elements inside code element 'test/testcases/block/06_codeblock/highlighting-opts.html', # bc of span elements inside code element 'test/testcases/block/06_codeblock/guess_lang_css_class.html', # bc of double surrounding
'test/testcases/block/12_extension/options3.html', # bc of rouge 'test/testcases/block/14_table/empty_tag_in_cell.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/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,htmlinput}'].each do |html_file| next if EXCLUDE_HTML_FILES.any? {|f| html_file =~ /#{f}/ } out_files = [] out_files << [(html_file =~ /\.htmlinput$/ ? html_file.sub(/input$/, '') : html_file), :to_html] if html_file =~ /\.htmlinput$/ && EXCLUDE_HTML_TEXT_FILES.none? {|f| html_file =~ /#{f}/ } out_files << [html_file.sub(/htmlinput$/, '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)?$/, '.options') opts_file = File.join(File.dirname(html_file), 'options') unless 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 -utf8" result, error, status = Open3.capture3(cmd, stdin_data: out) if status.exitstatus == 2 raise "Problem using tidy: #{error}" 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', 'test/testcases/block/03_paragraph/standalone_image.text', # bc of standalone image 'test/testcases/cjk-line-break.text', # latex unicode support ].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/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/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 'test/testcases/block/03_paragraph/standalone_image.text', # bc of standalone image 'test/testcases/cjk-line-break.text', 'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image 'test/testcases/span/abbreviations/abbrev_in_html.text', # bc of invalid abbr tag in SVG ].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') 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') unless 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)) kdtext4 = Kramdown::Document.new(File.read(text_file), options.merge({list_indent: 4})).to_kramdown html = Kramdown::Document.new(kdtext4, 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/12_extension/options3.html', # bc of rouge '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/06_codeblock/guess_lang_css_class.html', # bc of double surrounding
'test/testcases/block/06_codeblock/highlighting.html', # bc of span elements inside code element 'test/testcases/block/06_codeblock/highlighting-opts.html', # bc of span elements inside code element '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/block/14_table/empty_tag_in_cell.html', # bc of tidy '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 'test/testcases/block/03_paragraph/standalone_image.html', # bc of standalone image 'test/testcases/block/15_math/normal.html', # bc of mathjax and HTML parser 'test/testcases/block/15_math/gh_128.html', # bc of mathjax and HTML parser 'test/testcases/span/04_footnote/backlink_inline.html', # bc of mathjax 'test/testcases/block/09_html/standalone_image_in_div.html', # bc of standalone image 'test/testcases/block/09_html/processing_instruction.html', # bc of PI ].compact Dir[File.dirname(__FILE__) + '/testcases/**/*.html'].each do |html_file| next if EXCLUDE_HTML_KD_FILES.any? {|f| html_file =~ /#{f}$/ } 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$/, '.options') opts_file = File.join(File.dirname(html_file), 'options') unless 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_MODIFY = [ 'test/testcases/block/06_codeblock/rouge/multiple.text', # bc of HTMLFormater in options ].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(&:to_sym) - [:Base, :RemoveHtmlTags, :MathEngine, :SyntaxHighlighter]).each do |conv_class| next if EXCLUDE_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-2.4.0/test/run_tests.rb0000644000004100000410000000256114234044402016722 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 = `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') unless File.exist?(opts_file) options = File.exist?(opts_file) ? YAML.safe_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 StandardError 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-2.4.0/test/test_string_scanner_kramdown.rb0000644000004100000410000000151214234044402022647 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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) } assert_equal(expect, str_sc.current_line_number) end end end kramdown-2.4.0/test/testcases/0000755000004100000410000000000014234044402016341 5ustar www-datawww-datakramdown-2.4.0/test/testcases/man/0000755000004100000410000000000014234044402017114 5ustar www-datawww-datakramdown-2.4.0/test/testcases/man/heading-name-description.text0000644000004100000410000000013714234044402024661 0ustar www-datawww-data# name description {: data-section="1" data-date="November 2016" data-extra="Something extra"} kramdown-2.4.0/test/testcases/man/heading-name-dash-description.man0000644000004100000410000000010614234044402025361 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "7" .SH NAME name \- description kramdown-2.4.0/test/testcases/man/sections.man0000644000004100000410000000007514234044402021442 0ustar www-datawww-data.\" generated by kramdown .SH "NAME" works .SS "Sub section" kramdown-2.4.0/test/testcases/man/heading-name.text0000644000004100000410000000000714234044402022334 0ustar www-datawww-data# name kramdown-2.4.0/test/testcases/man/example.text0000644000004100000410000000344514234044402021463 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 $$\lambda = 5$$ inline and in block form: $$\lambda_5 = \alpha + 4$$ kramdown-2.4.0/test/testcases/man/example.man0000644000004100000410000000273414234044402021252 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\elambda = 5\fP inline and in block form: .sp .RS 4 .EX \elambda_5 = \ealpha + 4 .EE .RE kramdown-2.4.0/test/testcases/man/heading-name.man0000644000004100000410000000005114234044402022122 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "7" kramdown-2.4.0/test/testcases/man/text-escaping.man0000644000004100000410000000021214234044402022357 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-2.4.0/test/testcases/man/heading-name-section.text0000644000004100000410000000001214234044402023772 0ustar www-datawww-data# name(1) kramdown-2.4.0/test/testcases/man/heading-name-section.man0000644000004100000410000000005114234044402023564 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" kramdown-2.4.0/test/testcases/man/heading-name-section-description.man0000644000004100000410000000010614234044402026106 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" .SH NAME name \- description kramdown-2.4.0/test/testcases/man/heading-name-description.man0000644000004100000410000000015014234044402024443 0ustar www-datawww-data.\" generated by kramdown .TH "NAME" "1" "November 2016" "Something extra" .SH NAME name \- description kramdown-2.4.0/test/testcases/man/heading-name-section-description.text0000644000004100000410000000003114234044402026314 0ustar www-datawww-data# name(1) -- description kramdown-2.4.0/test/testcases/man/text-escaping.text0000644000004100000410000000014114234044402022571 0ustar www-datawww-data. at the start of the line line with \fB backslash symbol some . other - escaped \' symbols . kramdown-2.4.0/test/testcases/man/heading-name-dash-description.text0000644000004100000410000000002614234044402025573 0ustar www-datawww-data# name -- description kramdown-2.4.0/test/testcases/man/sections.text0000644000004100000410000000011514234044402021646 0ustar www-datawww-data## NAME works ### Sub section #### Ignored ##### Ignored ###### Ignored kramdown-2.4.0/test/testcases/cjk-line-break.options0000644000004100000410000000004214234044402022530 0ustar www-datawww-data:remove_line_breaks_for_cjk: true kramdown-2.4.0/test/testcases/cjk-line-break.html0000644000004100000410000000006014234044402022001 0ustar www-datawww-data

一二三四五

あいうえお

kramdown-2.4.0/test/testcases/encoding.text0000644000004100000410000000120214234044402021030 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-2.4.0/test/testcases/block/0000755000004100000410000000000014234044402017433 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/16_toc/0000755000004100000410000000000014234044402020526 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/16_toc/toc_levels.text0000644000004100000410000000030714234044402023573 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-2.4.0/test/testcases/block/16_toc/toc_levels.html0000644000004100000410000000147714234044402023564 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-2.4.0/test/testcases/block/16_toc/toc_with_links.options0000644000004100000410000000005114234044402025157 0ustar www-datawww-data:auto_ids: true :auto_id_stripping: true kramdown-2.4.0/test/testcases/block/16_toc/toc_levels.options0000644000004100000410000000004214234044402024276 0ustar www-datawww-data:toc_levels: 2..3 :auto_ids: true kramdown-2.4.0/test/testcases/block/16_toc/toc_with_footnotes.html0000644000004100000410000000075514234044402025343 0ustar www-datawww-data

Header1 level 1

  1. Some footnote content here 

kramdown-2.4.0/test/testcases/block/16_toc/toc_with_footnotes.text0000644000004100000410000000014114234044402025350 0ustar www-datawww-data* Here comes the table of content {:toc} # Header[^1] level 1 [^1]: Some footnote content here kramdown-2.4.0/test/testcases/block/16_toc/toc_exclude.html0000644000004100000410000000241614234044402023715 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-2.4.0/test/testcases/block/16_toc/toc_exclude.text0000644000004100000410000000033114234044402023727 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-2.4.0/test/testcases/block/16_toc/toc_exclude.options0000644000004100000410000000002014234044402024431 0ustar www-datawww-data:auto_ids: true kramdown-2.4.0/test/testcases/block/16_toc/toc_with_footnotes.options0000644000004100000410000000002014234044402026053 0ustar www-datawww-data:auto_ids: true kramdown-2.4.0/test/testcases/block/16_toc/toc_with_links.html0000644000004100000410000000041714234044402024436 0ustar www-datawww-data

Header

Header

kramdown-2.4.0/test/testcases/block/16_toc/no_toc.text0000644000004100000410000000030214234044402022710 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-2.4.0/test/testcases/block/16_toc/toc_with_links.text0000644000004100000410000000007214234044402024453 0ustar www-datawww-data# [Header] # [Header] [header]: test.html * toc {:toc} kramdown-2.4.0/test/testcases/block/16_toc/no_toc.html0000644000004100000410000000030114234044402022667 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-2.4.0/test/testcases/block/13_definition_list/0000755000004100000410000000000014234044402023121 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/13_definition_list/with_blocks.text0000644000004100000410000000025014234044402026334 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-2.4.0/test/testcases/block/13_definition_list/too_much_space.html0000644000004100000410000000004414234044402026775 0ustar www-datawww-data

para

: no definition

kramdown-2.4.0/test/testcases/block/13_definition_list/para_wrapping.text0000644000004100000410000000005614234044402026662 0ustar www-datawww-dataterm : definition : definition : definition kramdown-2.4.0/test/testcases/block/13_definition_list/definition_at_beginning.html0000644000004100000410000000002714234044402030642 0ustar www-datawww-data

: no definition

kramdown-2.4.0/test/testcases/block/13_definition_list/item_ial.html0000644000004100000410000000054514234044402025576 0ustar www-datawww-data
item
definition continued
another {:.cls}
code
IAL at last no code bc of text
term
definition
term1
term2
definition
kramdown-2.4.0/test/testcases/block/13_definition_list/separated_by_eob.html0000644000004100000410000000012614234044402027275 0ustar www-datawww-data
kram
down
kram
down
kramdown-2.4.0/test/testcases/block/13_definition_list/styled_terms.html0000644000004100000410000000006414234044402026525 0ustar www-datawww-data
kram
down
kramdown-2.4.0/test/testcases/block/13_definition_list/definition_at_beginning.text0000644000004100000410000000002014234044402030653 0ustar www-datawww-data: no definition kramdown-2.4.0/test/testcases/block/13_definition_list/deflist_ial.text0000644000004100000410000000006314234044402026305 0ustar www-datawww-data{:.dl-horizontal} item : definition {:.dl-other} kramdown-2.4.0/test/testcases/block/13_definition_list/auto_ids.text0000644000004100000410000000015014234044402025632 0ustar www-datawww-data{:auto_ids} item : def item2 : def ^ {:auto_ids-prefix-} item : def item2 : def {:#id} item3 : def kramdown-2.4.0/test/testcases/block/13_definition_list/auto_ids.html0000644000004100000410000000036514234044402025622 0ustar www-datawww-data
item
def
item2
def
item
def
item2
def
item3
def
kramdown-2.4.0/test/testcases/block/13_definition_list/multiple_terms.text0000644000004100000410000000011714234044402027073 0ustar www-datawww-datakram *down* now : definition 1 : definition 2 : definition 3 : definition 4 kramdown-2.4.0/test/testcases/block/13_definition_list/separated_by_eob.text0000644000004100000410000000003214234044402027311 0ustar www-datawww-datakram : down ^ kram : down kramdown-2.4.0/test/testcases/block/13_definition_list/deflist_ial.html0000644000004100000410000000012014234044402026257 0ustar www-datawww-data
item
definition
kramdown-2.4.0/test/testcases/block/13_definition_list/para_wrapping.html0000644000004100000410000000017314234044402026642 0ustar www-datawww-data
term

definition

definition

definition

kramdown-2.4.0/test/testcases/block/13_definition_list/simple.text0000644000004100000410000000006314234044402025317 0ustar www-datawww-datakram : down novalue : kram : down kram : down kramdown-2.4.0/test/testcases/block/13_definition_list/styled_terms.text0000644000004100000410000000001614234044402026542 0ustar www-datawww-data*kram* : down kramdown-2.4.0/test/testcases/block/13_definition_list/too_much_space.text0000644000004100000410000000002714234044402027016 0ustar www-datawww-datapara : no definition kramdown-2.4.0/test/testcases/block/13_definition_list/no_def_list.text0000644000004100000410000000005414234044402026313 0ustar www-datawww-dataThis is a para \: and not a definition list kramdown-2.4.0/test/testcases/block/13_definition_list/simple.html0000644000004100000410000000017714234044402025305 0ustar www-datawww-data
kram
down
novalue
kram
down kram
down
kramdown-2.4.0/test/testcases/block/13_definition_list/no_def_list.html0000644000004100000410000000006214234044402026272 0ustar www-datawww-data

This is a para : and not a definition list

kramdown-2.4.0/test/testcases/block/13_definition_list/item_ial.text0000644000004100000410000000032214234044402025607 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-2.4.0/test/testcases/block/13_definition_list/with_blocks.html0000644000004100000410000000075414234044402026325 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-2.4.0/test/testcases/block/13_definition_list/multiple_terms.html0000644000004100000410000000030114234044402027046 0ustar www-datawww-data
kram
down
now
definition 1
definition 2

definition 3

definition 4

kramdown-2.4.0/test/testcases/block/01_blank_line/0000755000004100000410000000000014234044402022031 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/01_blank_line/tabs.html0000644000004100000410000000000114234044402023637 0ustar www-datawww-data kramdown-2.4.0/test/testcases/block/01_blank_line/tabs.text0000644000004100000410000000001614234044402023665 0ustar www-datawww-data kramdown-2.4.0/test/testcases/block/01_blank_line/spaces.text0000644000004100000410000000002014234044402024205 0ustar www-datawww-data kramdown-2.4.0/test/testcases/block/01_blank_line/spaces.html0000644000004100000410000000000114234044402024164 0ustar www-datawww-data kramdown-2.4.0/test/testcases/block/05_blockquote/0000755000004100000410000000000014234044402022107 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/05_blockquote/indented.html0000644000004100000410000000052614234044402024572 0ustar www-datawww-data

A normal blockquote.

A normal blockquote.

A normal blockquote.

A normal blockquote.

> A codeblock

Blockquote with mixed indents.

kramdown-2.4.0/test/testcases/block/05_blockquote/with_code_blocks.text0000644000004100000410000000020614234044402026315 0ustar www-datawww-data>Example: > > sub status { > print "working"; > } > > Or: > > sub status { > return "working"; > } kramdown-2.4.0/test/testcases/block/05_blockquote/lazy.text0000644000004100000410000000033114234044402023771 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-2.4.0/test/testcases/block/05_blockquote/no_newline_at_end.html0000644000004100000410000000011314234044402026437 0ustar www-datawww-data

This is a block quote with no newline.

kramdown-2.4.0/test/testcases/block/05_blockquote/no_newline_at_end.text0000644000004100000410000000005214234044402026461 0ustar www-datawww-data> This is a block quote > with no newline.kramdown-2.4.0/test/testcases/block/05_blockquote/nested.text0000644000004100000410000000004014234044402024271 0ustar www-datawww-data> foo > > > bar >> baz > > foo kramdown-2.4.0/test/testcases/block/05_blockquote/with_code_blocks.html0000644000004100000410000000027414234044402026302 0ustar www-datawww-data

Example:

sub status {
    print "working";
}

Or:

sub status {
    return "working";
}
kramdown-2.4.0/test/testcases/block/05_blockquote/very_long_line.text0000644000004100000410000001576214234044402026043 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-2.4.0/test/testcases/block/05_blockquote/very_long_line.html0000644000004100000410000001602414234044402026013 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-2.4.0/test/testcases/block/05_blockquote/lazy.html0000644000004100000410000000073114234044402023755 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-2.4.0/test/testcases/block/05_blockquote/nested.html0000644000004100000410000000015214234044402024255 0ustar www-datawww-data

foo

bar baz

foo

kramdown-2.4.0/test/testcases/block/05_blockquote/indented.text0000644000004100000410000000024214234044402024605 0ustar www-datawww-data> A normal blockquote. > A normal blockquote. > A normal blockquote. > A normal blockquote. > A codeblock > Blockquote > with >mixed > indents. kramdown-2.4.0/test/testcases/block/12_extension/0000755000004100000410000000000014234044402021751 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/12_extension/options3.text0000644000004100000410000000017014234044402024433 0ustar www-datawww-data x = Class.new {: .language-ruby} {::options syntax_highlighter_opts="{default_lang: ruby\}" /} x = Class.new kramdown-2.4.0/test/testcases/block/12_extension/ignored.text0000644000004100000410000000011614234044402024304 0ustar www-datawww-dataparagraph {::something} anotherthing {:/something} {::something/} paragraph kramdown-2.4.0/test/testcases/block/12_extension/options2.html0000644000004100000410000000051614234044402024416 0ustar www-datawww-data

Some text1.

  1. Some text. 

kramdown-2.4.0/test/testcases/block/12_extension/nomarkdown.text0000644000004100000410000000046614234044402025044 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-2.4.0/test/testcases/block/12_extension/ignored.html0000644000004100000410000000014314234044402024264 0ustar www-datawww-data

paragraph

{::something} anotherthing {:/something}

{::something/} paragraph

kramdown-2.4.0/test/testcases/block/12_extension/options.text0000644000004100000410000000047114234044402024354 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. {::options template="/etc/passwd" /} kramdown-2.4.0/test/testcases/block/12_extension/nomarkdown.html0000644000004100000410000000022314234044402025013 0ustar www-datawww-data

This is a simple paragraph.

This *is* not processed

And another paragraph

bold

{::nomarkdown} Another paragraph

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

This is a simple paragraph.

And another paragraph

{::comment} Another paragraph

kramdown-2.4.0/test/testcases/block/12_extension/nomarkdown.kramdown0000644000004100000410000000040714234044402025675 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-2.4.0/test/testcases/block/12_extension/options.html0000644000004100000410000000075214234044402024336 0ustar www-datawww-data

No header id

without header id

some *para*

some para

Some text10.

  1. Some text. 

kramdown-2.4.0/test/testcases/block/12_extension/nomarkdown.latex0000644000004100000410000000024414234044402025167 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-2.4.0/test/testcases/block/12_extension/comment.text0000644000004100000410000000030014234044402024312 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-2.4.0/test/testcases/block/12_extension/options3.html0000644000004100000410000000100014234044402024404 0ustar www-datawww-data
x = Class.new
x = Class.new
kramdown-2.4.0/test/testcases/block/03_paragraph/0000755000004100000410000000000014234044402021702 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/03_paragraph/indented.html0000644000004100000410000000035214234044402024362 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-2.4.0/test/testcases/block/03_paragraph/with_html_to_native.html0000644000004100000410000000010314234044402026631 0ustar www-datawww-data

some text

kramdown-2.4.0/test/testcases/block/03_paragraph/standalone_image.text0000644000004100000410000000032114234044402026076 0ustar www-datawww-datapara {:standalone} ![standalone image](some.jpg){:#id .class key="value" standalone} ![standalone image](some.jpg){:#id .class key="value" standalone} {:#block-id .block-class block-key="block-value"} para kramdown-2.4.0/test/testcases/block/03_paragraph/line_break_last_line.text0000644000004100000410000000014114234044402026731 0ustar www-datawww-dataFirst line First line\\ Last Line Last Line\\ kramdown-2.4.0/test/testcases/block/03_paragraph/to_kramdown.text0000644000004100000410000000014714234044402025136 0ustar www-datawww-dataaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa : No definiion list a: *a*: kramdown-2.4.0/test/testcases/block/03_paragraph/indented.html.gfm0000644000004100000410000000040214234044402025126 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-2.4.0/test/testcases/block/03_paragraph/no_newline_at_end.html0000644000004100000410000000012114234044402026231 0ustar www-datawww-data

One paragraph over multiple lines.

Second one without newline.

kramdown-2.4.0/test/testcases/block/03_paragraph/to_kramdown.kramdown0000644000004100000410000000015114234044402025767 0ustar www-datawww-dataaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa \: No definiion list a: *a*: kramdown-2.4.0/test/testcases/block/03_paragraph/with_html_to_native.options0000644000004100000410000000002614234044402027364 0ustar www-datawww-data:html_to_native: true kramdown-2.4.0/test/testcases/block/03_paragraph/no_newline_at_end.text0000644000004100000410000000010414234044402026252 0ustar www-datawww-data One paragraph over multiple lines. Second one without newline.kramdown-2.4.0/test/testcases/block/03_paragraph/one_para.html0000644000004100000410000000005014234044402024347 0ustar www-datawww-data

This is just a normal paragraph.

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

First line
https://example.com

First line
https://example.com

Last Line

Last Line\

kramdown-2.4.0/test/testcases/block/03_paragraph/two_para.html0000644000004100000410000000014414234044402024403 0ustar www-datawww-data

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

Another paragraph.

kramdown-2.4.0/test/testcases/block/03_paragraph/standalone_image.html0000644000004100000410000000056714234044402026072 0ustar www-datawww-data

para

standalone image
standalone image
standalone image
standalone image

para

kramdown-2.4.0/test/testcases/block/03_paragraph/with_html_to_native.text0000644000004100000410000000010314234044402026651 0ustar www-datawww-data

some text kramdown-2.4.0/test/testcases/block/03_paragraph/indented.text0000644000004100000410000000027214234044402024403 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-2.4.0/test/testcases/block/03_paragraph/one_para.text0000644000004100000410000000004114234044402024367 0ustar www-datawww-dataThis is just a normal paragraph. kramdown-2.4.0/test/testcases/block/04_header/0000755000004100000410000000000014234044402021166 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/04_header/with_auto_id_stripping.options0000644000004100000410000000003114234044402027353 0ustar www-datawww-data:auto_id_stripping: true kramdown-2.4.0/test/testcases/block/04_header/setext_header_no_newline_at_end.html0000644000004100000410000000002014234044402030417 0ustar www-datawww-data

header

kramdown-2.4.0/test/testcases/block/04_header/atx_header.html0000644000004100000410000000123014234044402024154 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

Header

Header

Header {#9ab}

Header{#noid}

Header ##{#noid}

Last

kramdown-2.4.0/test/testcases/block/04_header/header_type_offset.kramdown0000644000004100000410000000015014234044402026565 0ustar www-datawww-data## Lorem ipsum ### Lorem ipsum #### Lorem ipsum ###### Lorem ipsum ## Lorem ipsum ### Lorem ipsum kramdown-2.4.0/test/testcases/block/04_header/setext_header_no_newline_at_end.text0000644000004100000410000000001514234044402030443 0ustar www-datawww-dataheader ======kramdown-2.4.0/test/testcases/block/04_header/with_auto_ids.text0000644000004100000410000000031014234044402024730 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-2.4.0/test/testcases/block/04_header/header_type_offset.options0000644000004100000410000000004214234044402026436 0ustar www-datawww-data:header_offset: 1 :auto_ids: falsekramdown-2.4.0/test/testcases/block/04_header/atx_header_no_newline_at_end.text0000644000004100000410000000001014234044402027716 0ustar www-datawww-data# headerkramdown-2.4.0/test/testcases/block/04_header/atx_header_no_newline_at_end.html0000644000004100000410000000002014234044402027677 0ustar www-datawww-data

header

kramdown-2.4.0/test/testcases/block/04_header/with_auto_ids.options0000644000004100000410000000006114234044402025442 0ustar www-datawww-data:auto_ids: true :transliterated_header_ids: true kramdown-2.4.0/test/testcases/block/04_header/with_auto_id_prefix.html0000644000004100000410000000010714234044402026106 0ustar www-datawww-data

Header 1

123

kramdown-2.4.0/test/testcases/block/04_header/with_auto_id_stripping.text0000644000004100000410000000005114234044402026646 0ustar www-datawww-data# This is a header kramdown-2.4.0/test/testcases/block/04_header/with_auto_ids.html0000644000004100000410000000065614234044402024725 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-2.4.0/test/testcases/block/04_header/setext_header.text0000644000004100000410000000043014234044402024715 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-2.4.0/test/testcases/block/04_header/with_auto_id_stripping.html0000644000004100000410000000010614234044402026627 0ustar www-datawww-data

This is a header

kramdown-2.4.0/test/testcases/block/04_header/header_type_offset.html0000644000004100000410000000020314234044402025706 0ustar www-datawww-data

Lorem ipsum

Lorem ipsum

Lorem ipsum

Lorem ipsum

Lorem ipsum

Lorem ipsum

kramdown-2.4.0/test/testcases/block/04_header/header_type_offset.latex0000644000004100000410000000025114234044402026062 0ustar www-datawww-data\subsection*{Lorem ipsum} \subsubsection*{Lorem ipsum} \paragraph*{Lorem ipsum} \subparagraph*{Lorem ipsum} \subsection*{Lorem ipsum} \subsubsection*{Lorem ipsum} kramdown-2.4.0/test/testcases/block/04_header/with_auto_id_prefix.options0000644000004100000410000000005014234044402026632 0ustar www-datawww-data:auto_ids: true :auto_id_prefix: hallo_ kramdown-2.4.0/test/testcases/block/04_header/header_type_offset.text0000644000004100000410000000016514234044402025735 0ustar www-datawww-data# Lorem ipsum ## Lorem ipsum ### Lorem ipsum ###### Lorem ipsum Lorem ipsum =========== Lorem ipsum ----------- kramdown-2.4.0/test/testcases/block/04_header/setext_header.html0000644000004100000410000000056214234044402024703 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-2.4.0/test/testcases/block/04_header/atx_header.text0000644000004100000410000000073014234044402024200 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 {#id} ### Header ## {#Id} ### Header ## {#id} ### Header {#A-Za-z0-9_:t} ### Header {#9ab} ### Header{#noid} ### Header ##{#noid} ### Last kramdown-2.4.0/test/testcases/block/04_header/with_auto_id_prefix.text0000644000004100000410000000002214234044402026122 0ustar www-datawww-data# Header 1 # 123 kramdown-2.4.0/test/testcases/block/08_list/0000755000004100000410000000000014234044402020715 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/08_list/simple_ul.text0000644000004100000410000000055014234044402023614 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-2.4.0/test/testcases/block/08_list/item_ial.html0000644000004100000410000000024414234044402023366 0ustar www-datawww-data
  • IAL at first continued
  • another {:.cls}
  • IAL at last code
  • X test
  • X OK
kramdown-2.4.0/test/testcases/block/08_list/brackets_in_item.latex0000644000004100000410000000007014234044402025253 0ustar www-datawww-data\begin{itemize} \item{} {[}and{]} another \end{itemize} kramdown-2.4.0/test/testcases/block/08_list/lazy.text0000644000004100000410000000043514234044402022604 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-2.4.0/test/testcases/block/08_list/mixed.html0000644000004100000410000000244314234044402022714 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-2.4.0/test/testcases/block/08_list/brackets_in_item.text0000644000004100000410000000002214234044402025117 0ustar www-datawww-data* \[and\] another kramdown-2.4.0/test/testcases/block/08_list/list_and_others.text0000644000004100000410000000022414234044402025002 0ustar www-datawww-data* list item > blockquote para * * * para - no list + item > block ## header * test codeblock test * test codeblock test kramdown-2.4.0/test/testcases/block/08_list/single_item.html0000644000004100000410000000003514234044402024100 0ustar www-datawww-data
  • single
kramdown-2.4.0/test/testcases/block/08_list/list_and_others.html0000644000004100000410000000063314234044402024766 0ustar www-datawww-data
  • list item

blockquote

para * * * para - no list

  • item

    block

    header

  • test

    codeblock
    

    test

  • test

    codeblock
    

    test

kramdown-2.4.0/test/testcases/block/08_list/simple_ol.text0000644000004100000410000000021214234044402023601 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-2.4.0/test/testcases/block/08_list/other_first_element.text0000644000004100000410000000041114234044402025660 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-2.4.0/test/testcases/block/08_list/simple_ol.html0000644000004100000410000000037414234044402023572 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-2.4.0/test/testcases/block/08_list/escaping.html0000644000004100000410000000044214234044402023374 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-2.4.0/test/testcases/block/08_list/escaping.text0000644000004100000410000000037414234044402023420 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-2.4.0/test/testcases/block/08_list/mixed.text0000644000004100000410000000106714234044402022735 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-2.4.0/test/testcases/block/08_list/special_cases.text0000644000004100000410000000046314234044402024424 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-2.4.0/test/testcases/block/08_list/single_item.text0000644000004100000410000000001114234044402024112 0ustar www-datawww-data* single kramdown-2.4.0/test/testcases/block/08_list/lazy_and_nested.text0000644000004100000410000000011214234044402024760 0ustar www-datawww-data1. Root level * Second level * Third level * Back to second level kramdown-2.4.0/test/testcases/block/08_list/other_first_element.html0000644000004100000410000000106314234044402025644 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-2.4.0/test/testcases/block/08_list/special_cases.html0000644000004100000410000000132314234044402024400 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-2.4.0/test/testcases/block/08_list/nested.text0000644000004100000410000000007614234044402023110 0ustar www-datawww-data* some item * nested * last item ^ * some text * nested kramdown-2.4.0/test/testcases/block/08_list/list_and_hr.text0000644000004100000410000000006014234044402024105 0ustar www-datawww-data* Starting a list * * * * Starting a new list kramdown-2.4.0/test/testcases/block/08_list/lazy.html0000644000004100000410000000071014234044402022560 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-2.4.0/test/testcases/block/08_list/nested.html0000644000004100000410000000027214234044402023066 0ustar www-datawww-data
  • some item
    • nested
  • last item
  • some text

    • nested
kramdown-2.4.0/test/testcases/block/08_list/simple_ul.html0000644000004100000410000000104214234044402023571 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-2.4.0/test/testcases/block/08_list/lazy_and_nested.html0000644000004100000410000000020014234044402024736 0ustar www-datawww-data
  1. Root level * Second level
    • Third level * Back to second level
kramdown-2.4.0/test/testcases/block/08_list/item_ial.text0000644000004100000410000000027614234044402023413 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-2.4.0/test/testcases/block/08_list/list_and_hr.html0000644000004100000410000000013114234044402024064 0ustar www-datawww-data
  • Starting a list

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

    special here

kramdown-2.4.0/test/testcases/block/14_table/no_table.text0000644000004100000410000000004314234044402023514 0ustar www-datawww-dataNo table \| Some \| thing \| here kramdown-2.4.0/test/testcases/block/14_table/header.html0000644000004100000410000000362114234044402023146 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-2.4.0/test/testcases/block/14_table/table_with_footnote.latex0000644000004100000410000000023514234044402026124 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-2.4.0/test/testcases/block/14_table/header.text0000644000004100000410000000101614234044402023162 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-2.4.0/test/testcases/block/14_table/empty_tag_in_cell.html0000644000004100000410000000022014234044402025364 0ustar www-datawww-data
first line of cell
second line of cell
another cell
kramdown-2.4.0/test/testcases/block/14_table/errors.html0000644000004100000410000000016314234044402023230 0ustar www-datawww-data

No table body

|-|-|-

|no|table|here|

|no|table|here| paragraph

|-|-| |-|-|

kramdown-2.4.0/test/testcases/block/14_table/escaping.html0000644000004100000410000000140514234044402023505 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-2.4.0/test/testcases/block/14_table/escaping.text0000644000004100000410000000040714234044402023526 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-2.4.0/test/testcases/block/14_table/empty_tag_in_cell.text0000644000004100000410000000007514234044402025414 0ustar www-datawww-data| first line of cell
second line of cell | another cell | kramdown-2.4.0/test/testcases/block/14_table/footer.text0000644000004100000410000000037614234044402023240 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-2.4.0/test/testcases/block/14_table/simple.text0000644000004100000410000000140514234044402023225 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-2.4.0/test/testcases/block/14_table/table_with_footnote.text0000644000004100000410000000012214234044402025766 0ustar www-datawww-data| this is [^1] | a table | with a | footnote [^1]: Something > special here kramdown-2.4.0/test/testcases/block/14_table/footer.html0000644000004100000410000000144514234044402023216 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-2.4.0/test/testcases/block/14_table/no_table.html0000644000004100000410000000005614234044402023500 0ustar www-datawww-data

No table

| Some | thing | here

kramdown-2.4.0/test/testcases/block/14_table/simple.html0000644000004100000410000000513514234044402023211 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-2.4.0/test/testcases/block/14_table/errors.text0000644000004100000410000000013214234044402023244 0ustar www-datawww-dataNo table body |-|-|- [5]: test |no|table|here| |no|table|here| paragraph |-|-| |-|-| kramdown-2.4.0/test/testcases/block/11_ial/0000755000004100000410000000000014234044402020501 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/11_ial/auto_id_and_ial.html0000644000004100000410000000005014234044402024455 0ustar www-datawww-data

A header

kramdown-2.4.0/test/testcases/block/11_ial/simple.text0000644000004100000410000000074714234044402022710 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-2.4.0/test/testcases/block/11_ial/nested.text0000644000004100000410000000014714234044402022673 0ustar www-datawww-data{:.cls}
test
{:#id} {:.cls}
test
{:#id} {:.cls} > para {:#id} kramdown-2.4.0/test/testcases/block/11_ial/auto_id_and_ial.options0000644000004100000410000000002014234044402025201 0ustar www-datawww-data:auto_ids: true kramdown-2.4.0/test/testcases/block/11_ial/auto_id_and_ial.text0000644000004100000410000000003214234044402024475 0ustar www-datawww-data## A header {:#myid .cls} kramdown-2.4.0/test/testcases/block/11_ial/nested.html0000644000004100000410000000022414234044402022647 0ustar www-datawww-data
test

test

para

kramdown-2.4.0/test/testcases/block/11_ial/simple.html0000644000004100000410000000107314234044402022661 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-2.4.0/test/testcases/block/15_math/0000755000004100000410000000000014234044402020671 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/15_math/gh_128.html0000644000004100000410000000013014234044402022541 0ustar www-datawww-data\[<script>alert('a')</script> <script>alert('b<')</script>\] kramdown-2.4.0/test/testcases/block/15_math/no_engine.html0000644000004100000410000000006114234044402023515 0ustar www-datawww-data
$$ 5+5 $$
kramdown-2.4.0/test/testcases/block/15_math/normal.html0000644000004100000410000000051314234044402023046 0ustar www-datawww-data

This 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$$
\[5+5\]
\[5+5\]
\[|x| = 5\] kramdown-2.4.0/test/testcases/block/15_math/gh_128.text0000644000004100000410000000007714234044402022573 0ustar www-datawww-data$$ $$ kramdown-2.4.0/test/testcases/block/15_math/no_engine.text0000644000004100000410000000002514234044402023535 0ustar www-datawww-data{: #math-id} $$5+5$$ kramdown-2.4.0/test/testcases/block/15_math/normal.text0000644000004100000410000000041114234044402023063 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-2.4.0/test/testcases/block/15_math/no_engine.options0000644000004100000410000000002014234044402024237 0ustar www-datawww-data:math_engine: ~ kramdown-2.4.0/test/testcases/block/06_codeblock/0000755000004100000410000000000014234044402021665 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/06_codeblock/with_ial.text0000644000004100000410000000007614234044402024376 0ustar www-datawww-data code block continued here {:.cls} new block here kramdown-2.4.0/test/testcases/block/06_codeblock/whitespace.text0000644000004100000410000000007514234044402024731 0ustar www-datawww-data This is some whitespace {:.show-whitespaces} kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/0000755000004100000410000000000014234044402023006 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/06_codeblock/rouge/disabled.options0000644000004100000410000000012014234044402026163 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: block: disable: true kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/multiple.html0000644000004100000410000000132414234044402025527 0ustar www-datawww-data
puts "Hello"
puts "World"
$foo = new Bar;
kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/disabled.text0000644000004100000410000000002214234044402025455 0ustar www-datawww-data x = Class.new kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/multiple.text0000644000004100000410000000014014234044402025542 0ustar www-datawww-data~~~ ruby puts "Hello" ~~~ ~~~ ruby puts "World" ~~~ ~~~ php?start_inline=1 $foo = new Bar; ~~~kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/simple.options0000644000004100000410000000011214234044402025706 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: default_lang: ruby kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/disabled.html0000644000004100000410000000004714234044402025444 0ustar www-datawww-data
x = Class.new
kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/simple.text0000644000004100000410000000014414234044402025204 0ustar www-datawww-data x = Class.new ^ href {: .language-html} ~~~ php?start_inline=1 $foo = new Bar; ~~~ kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/multiple.options0000644000004100000410000000015314234044402026255 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: default_lang: ruby formatter: RougeHTMLFormatters kramdown-2.4.0/test/testcases/block/06_codeblock/rouge/simple.html0000644000004100000410000000130414234044402025163 0ustar www-datawww-data
x = Class.new
<a>href</a>
$foo = new Bar;
kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.html0000644000004100000410000000025314234044402031537 0ustar www-datawww-data
text
text
text
kramdown-2.4.0/test/testcases/block/06_codeblock/no_newline_at_end_1.html0000644000004100000410000000004514234044402026441 0ustar www-datawww-data
test   test
kramdown-2.4.0/test/testcases/block/06_codeblock/with_eob_marker.html0000644000004100000410000000013414234044402025712 0ustar www-datawww-data
code block

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

paragraph

code block

continued here

ended

next blank line has 4 spaces

paragraph

kramdown-2.4.0/test/testcases/block/06_codeblock/issue_gh45.test0000644000004100000410000000726314234044402024555 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-2.4.0/test/testcases/block/06_codeblock/lazy.text0000644000004100000410000000006414234044402023552 0ustar www-datawww-data This is some code This is some other code kramdown-2.4.0/test/testcases/block/06_codeblock/disable-highlighting.text0000644000004100000410000000006414234044402026641 0ustar www-datawww-data x = Class.new ^ href {: lang="html"} kramdown-2.4.0/test/testcases/block/06_codeblock/error.text0000644000004100000410000000004014234044402023716 0ustar www-datawww-dataSome para ~~~~~~ not codeblock kramdown-2.4.0/test/testcases/block/06_codeblock/tilde_syntax.html0000644000004100000410000000015314234044402025261 0ustar www-datawww-data
Here comes some code.
~~~~~~~
code with tildes
~~~~~~~~
kramdown-2.4.0/test/testcases/block/06_codeblock/whitespace.html0000644000004100000410000000070214234044402024706 0ustar www-datawww-data
This	issome
whitespace
kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.text0000644000004100000410000000007514234044402032747 0ustar www-datawww-data~~~ act-iii s1'dim'a'500'm'500'q'500'' index'j'j+1'j-1'' ~~~ kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-minted.options0000644000004100000410000000011314234044402027220 0ustar www-datawww-data:syntax_highlighter: minted :syntax_highlighter_opts: default_lang: ruby kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-minted-with-opts.latex0000644000004100000410000000037314234044402030606 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-2.4.0/test/testcases/block/06_codeblock/disable-highlighting.options0000644000004100000410000000002714234044402027347 0ustar www-datawww-data:enable_coderay: false kramdown-2.4.0/test/testcases/block/06_codeblock/issue_gh45.html0000644000004100000410000000671114234044402024537 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-2.4.0/test/testcases/block/06_codeblock/no_newline_at_end.html0000644000004100000410000000004014234044402026214 0ustar www-datawww-data
test  
kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting.text0000644000004100000410000000006714234044402025243 0ustar www-datawww-data x = Class.new ^ href {: .language-html} kramdown-2.4.0/test/testcases/block/06_codeblock/guess_lang_css_class.html0000644000004100000410000000047314234044402026743 0ustar www-datawww-data
class Foo
  def bar
    puts 'Hello'
  end
end
class Foo
  def bar
    puts 'Hello'
  end
end
kramdown-2.4.0/test/testcases/block/06_codeblock/tilde_syntax.text0000644000004100000410000000015314234044402025301 0ustar www-datawww-data~~~~~~~~ Here comes some code. ~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~ code with tildes ~~~~~~~~ ~~~~~~~~~~~~~~~~~~ kramdown-2.4.0/test/testcases/block/06_codeblock/with_ial.html0000644000004100000410000000015014234044402024347 0ustar www-datawww-data
code block

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

paragraph

other code  
with samples 

paragraph

  ending code
kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.options0000644000004100000410000000003014234044402033445 0ustar www-datawww-data:enable_coderay: false kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-minted.text0000644000004100000410000000006714234044402026521 0ustar www-datawww-data x = Class.new ^ href {: .language-html} kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-minted.latex0000644000004100000410000000014414234044402026646 0ustar www-datawww-data\begin{minted}[]{ruby} x = Class.new \end{minted} \begin{minted}[]{html} href \end{minted} kramdown-2.4.0/test/testcases/block/06_codeblock/no_newline_at_end.text0000644000004100000410000000001214234044402026233 0ustar www-datawww-data test kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block.text0000644000004100000410000000035614234044402027717 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-2.4.0/test/testcases/block/06_codeblock/no_newline_at_end_1.text0000644000004100000410000000002014234044402026452 0ustar www-datawww-data test test kramdown-2.4.0/test/testcases/block/06_codeblock/error.html0000644000004100000410000000005614234044402023705 0ustar www-datawww-data

Some para

~~~~~~ not codeblock

kramdown-2.4.0/test/testcases/block/06_codeblock/guess_lang_css_class.text0000644000004100000410000000017314234044402026760 0ustar www-datawww-data~~~ class Foo def bar puts 'Hello' end end ~~~ class Foo def bar puts 'Hello' end end kramdown-2.4.0/test/testcases/block/06_codeblock/guess_lang_css_class.options0000644000004100000410000000005514234044402027466 0ustar www-datawww-data:syntax_highlighter_opts: guess_lang: true kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block.html0000644000004100000410000000061514234044402027675 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-2.4.0/test/testcases/block/06_codeblock/highlighting-minted-with-opts.options0000644000004100000410000000013014234044402031153 0ustar www-datawww-data:syntax_highlighter: minted :syntax_highlighter_opts: wrap: true line_numbers: true kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block.options0000644000004100000410000000003314234044402030416 0ustar www-datawww-data:syntax_highlighter: null kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-minted-with-opts.text0000644000004100000410000000027314234044402030454 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-2.4.0/test/testcases/block/06_codeblock/normal.text0000644000004100000410000000013714234044402024064 0ustar www-datawww-data starting code paragraph other code with samples paragraph ending code kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-opts.options0000644000004100000410000000015214234044402026730 0ustar www-datawww-data:syntax_highlighter_opts: block: css: class default_lang: ruby wrap: span line_numbers: null kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.text0000644000004100000410000000010514234044402031553 0ustar www-datawww-data~~~ asn.1 text ~~~ ~~~ asn#w1 text ~~~ ~~~ русский text ~~~ kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-opts.html0000644000004100000410000000070314234044402026203 0ustar www-datawww-data
x = Class.new
<a>href</a>
kramdown-2.4.0/test/testcases/block/06_codeblock/with_eob_marker.text0000644000004100000410000000007014234044402025731 0ustar www-datawww-data code block continued here ^ new block here kramdown-2.4.0/test/testcases/block/06_codeblock/lazy.html0000644000004100000410000000010514234044402023526 0ustar www-datawww-data
This is some code

This is some  other code
kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting.options0000644000004100000410000000013614234044402025747 0ustar www-datawww-data:coderay_default_lang: ruby :coderay_wrap: span :coderay_line_numbers: ~ :coderay_css: class kramdown-2.4.0/test/testcases/block/06_codeblock/disable-highlighting.html0000644000004100000410000000014414234044402026620 0ustar www-datawww-data
x = Class.new
<a>href</a>
kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_name_with_dash.html0000644000004100000410000000013714234044402032726 0ustar www-datawww-data
s1'dim'a'500'm'500'q'500''
index'j'j+1'j-1''
kramdown-2.4.0/test/testcases/block/06_codeblock/with_blank_line.text0000644000004100000410000000015314234044402025723 0ustar www-datawww-dataparagraph code block continued here ended next blank line has 4 spaces paragraph kramdown-2.4.0/test/testcases/block/06_codeblock/with_lang_in_fenced_block_any_char.options0000644000004100000410000000003014234044402032257 0ustar www-datawww-data:enable_coderay: false kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting-opts.text0000644000004100000410000000006714234044402026226 0ustar www-datawww-data x = Class.new ^ href {: .language-html} kramdown-2.4.0/test/testcases/block/06_codeblock/highlighting.html0000644000004100000410000000035314234044402025221 0ustar www-datawww-data
x = Class.new
<a>href</a>
kramdown-2.4.0/test/testcases/block/09_html/0000755000004100000410000000000014234044402020707 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/09_html/textarea.text0000644000004100000410000000012014234044402023423 0ustar www-datawww-dataThis is a kramdown-2.4.0/test/testcases/block/09_html/xml.text0000644000004100000410000000021114234044402022407 0ustar www-datawww-data doit doit doit kramdown-2.4.0/test/testcases/block/09_html/parse_as_span.htmlinput0000644000004100000410000000024514234044402025474 0ustar www-datawww-data

This text should be parsed as span

This produces `

` an unwanted result.</p>

This text too

some text

kramdown-2.4.0/test/testcases/block/09_html/table.text0000644000004100000410000000007614234044402022707 0ustar www-datawww-data
test
kramdown-2.4.0/test/testcases/block/09_html/html_and_codeblocks.html0000644000004100000410000000023714234044402025555 0ustar www-datawww-data

para

codeblock

test

<p>codeblock</p>

test

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

codeblock

test
kramdown-2.4.0/test/testcases/block/09_html/html_and_headers.html0000644000004100000410000000004514234044402025055 0ustar www-datawww-data

header

======
kramdown-2.4.0/test/testcases/block/09_html/html_and_codeblocks.options0000644000004100000410000000003014234044402026273 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/09_html/parse_as_span.text0000644000004100000410000000020314234044402024426 0ustar www-datawww-data

This *text should* be parsed as span

This produces `

` an unwanted result.

This *text* too

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

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

para

</div>

para

kramdown-2.4.0/test/testcases/block/09_html/parse_block_html.options0000644000004100000410000000003014234044402025625 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/09_html/parse_as_raw.text0000644000004100000410000000076014234044402024266 0ustar www-datawww-data

baz { |qux| quux }

This is some para.

*parsed* This too

kramdown-2.4.0/test/testcases/block/09_html/html_and_headers.text0000644000004100000410000000004314234044402025073 0ustar www-datawww-dataheader ======
======
kramdown-2.4.0/test/testcases/block/09_html/table.kramdown0000644000004100000410000000007714234044402023546 0ustar www-datawww-data
test
kramdown-2.4.0/test/testcases/block/09_html/invalid_html_2.text0000644000004100000410000000002114234044402024501 0ustar www-datawww-datapara
para kramdown-2.4.0/test/testcases/block/09_html/content_model/0000755000004100000410000000000014234044402023541 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/09_html/content_model/deflists.options0000644000004100000410000000003014234044402026764 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/09_html/content_model/tables.html0000644000004100000410000000027714234044402025707 0ustar www-datawww-data
Usage Output
Some data

Some more

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

para

kramdown-2.4.0/test/testcases/block/09_html/content_model/tables.options0000644000004100000410000000003014234044402026421 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/09_html/content_model/deflists.text0000644000004100000410000000005314234044402026262 0ustar www-datawww-data
*text*
para
kramdown-2.4.0/test/testcases/block/09_html/content_model/tables.text0000644000004100000410000000030014234044402025712 0ustar www-datawww-data
*Usage* Output
Some *data* # Some more
kramdown-2.4.0/test/testcases/block/09_html/markdown_attr.html0000644000004100000410000000044514234044402024454 0ustar www-datawww-data

para

para

para

*para*

para

para

para

*para*

emphasize

para

kramdown-2.4.0/test/testcases/block/09_html/html5_attributes.text0000644000004100000410000000050514234044402025114 0ustar www-datawww-data

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

kramdown-2.4.0/test/testcases/block/09_html/xml.html0000644000004100000410000000022714234044402022376 0ustar www-datawww-data doit doit doit</some> kramdown-2.4.0/test/testcases/block/09_html/html_to_native/0000755000004100000410000000000014234044402023723 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/09_html/html_to_native/emphasis.text0000644000004100000410000000022114234044402026435 0ustar www-datawww-dataThis is sizedhallo. This is strongitalic, yes!. This is not converted, as is this. kramdown-2.4.0/test/testcases/block/09_html/html_to_native/list_dl.text0000644000004100000410000000015314234044402026262 0ustar www-datawww-data
kram
down
kram
down
kram
down
kramdown-2.4.0/test/testcases/block/09_html/html_to_native/list_ul.text0000644000004100000410000000043314234044402026304 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-2.4.0/test/testcases/block/09_html/html_to_native/options0000644000004100000410000000002614234044402025337 0ustar www-datawww-data:html_to_native: true kramdown-2.4.0/test/testcases/block/09_html/html_to_native/header.html0000644000004100000410000000031314234044402026036 0ustar www-datawww-data

Some headerhere!

hallo

hallo

hallo

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

This is *raw* HTML text containing < entities!

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

Some more

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

Some headerhere!

hallo

hallo

hallo

hallo
hallo
kramdown-2.4.0/test/testcases/block/09_html/html_to_native/header.options0000644000004100000410000000004614234044402026570 0ustar www-datawww-data:auto_ids: true :html_to_native: true kramdown-2.4.0/test/testcases/block/09_html/html_to_native/list_ol.html0000644000004100000410000000035514234044402026261 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-2.4.0/test/testcases/block/09_html/html_to_native/typography.text0000644000004100000410000000007514234044402027041 0ustar www-datawww-data

This is … something “to remember”!

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

This is *raw* HTML text containing < entities!

kramdown-2.4.0/test/testcases/block/09_html/html_to_native/code.text0000644000004100000410000000041314234044402025541 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-2.4.0/test/testcases/block/09_html/html_to_native/table_simple.text0000644000004100000410000000135114234044402027271 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-2.4.0/test/testcases/block/09_html/html_to_native/paragraph.text0000644000004100000410000000011114234044402026567 0ustar www-datawww-data

Some text here and end

Some other text here

kramdown-2.4.0/test/testcases/block/09_html/html_to_native/list_ol.text0000644000004100000410000000035714234044402026303 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-2.4.0/test/testcases/block/09_html/html_to_native/comment.html0000644000004100000410000000006314234044402026252 0ustar www-datawww-data
kramdown-2.4.0/test/testcases/block/09_html/html_to_native/paragraph.html0000644000004100000410000000011014234044402026546 0ustar www-datawww-data

Some text here and end

Some other text here

kramdown-2.4.0/test/testcases/block/09_html/html_to_native/list_ul.html0000644000004100000410000000043114234044402026262 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-2.4.0/test/testcases/block/09_html/html_to_native/typography.html0000644000004100000410000000006014234044402027013 0ustar www-datawww-data

This is … something “to remember”!

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

This is sizedhallo.

This is strongitalic, yes!.

This is not converted, as is this.

kramdown-2.4.0/test/testcases/block/09_html/html_to_native/code.html0000644000004100000410000000040514234044402025522 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-2.4.0/test/testcases/block/09_html/html_to_native/comment.text0000644000004100000410000000006414234044402026273 0ustar www-datawww-data
kramdown-2.4.0/test/testcases/block/09_html/html_to_native/table_simple.html0000644000004100000410000000156314234044402027256 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-2.4.0/test/testcases/block/09_html/html_to_native/table_normal.text0000644000004100000410000000022514234044402027267 0ustar www-datawww-data
Usage Other
Some *data*

Some more

kramdown-2.4.0/test/testcases/block/09_html/html_to_native/list_dl.html0000644000004100000410000000015314234044402026242 0ustar www-datawww-data
kram
down
kram
down
kram
down
kramdown-2.4.0/test/testcases/block/09_html/not_parsed.html0000644000004100000410000000041314234044402023731 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-2.4.0/test/testcases/block/09_html/invalid_html_1.text0000644000004100000410000000002314234044402024502 0ustar www-datawww-datapara
para kramdown-2.4.0/test/testcases/block/09_html/html_after_block.text0000644000004100000410000000012014234044402025105 0ustar www-datawww-dataPara
division
> Quote
division
kramdown-2.4.0/test/testcases/block/09_html/parse_as_raw.html0000644000004100000410000000104614234044402024244 0ustar www-datawww-data

baz { |qux| quux }

This is some para.

parsed This too

http://example.com

kramdown-2.4.0/test/testcases/block/09_html/parse_as_span.html0000644000004100000410000000024514234044402024414 0ustar www-datawww-data

This text should be parsed as span

This produces `

` an unwanted result.</p>

This text too

some text

kramdown-2.4.0/test/testcases/block/09_html/textarea.html0000644000004100000410000000012714234044402023412 0ustar www-datawww-data

This is a

kramdown-2.4.0/test/testcases/block/09_html/simple.options0000644000004100000410000000003014234044402023606 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/09_html/simple.text0000644000004100000410000000063114234044402023106 0ustar www-datawww-data
test

para2

tes

test weiter

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

Test

Test

kramdown-2.4.0/test/testcases/block/09_html/standalone_image_in_div.text0000644000004100000410000000020214234044402026431 0ustar www-datawww-data
![inside](src.png)
[text](website.html)
kramdown-2.4.0/test/testcases/block/09_html/parse_block_html.html0000644000004100000410000000035514234044402025110 0ustar www-datawww-data

test

test
test
code block with </div>

No matching end tag

kramdown-2.4.0/test/testcases/block/09_html/comment.html0000644000004100000410000000023514234044402023237 0ustar www-datawww-data

para1

para2

para

This is

kramdown-2.4.0/test/testcases/block/09_html/parse_as_raw.htmlinput0000644000004100000410000000104514234044402025323 0ustar www-datawww-data

baz { |qux| quux }

This is some para.

parsed This too

http://example.com

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

Foo

This is some text

kramdown-2.4.0/test/testcases/block/09_html/standalone_image_in_div.htmlinput0000644000004100000410000000020614234044402027475 0ustar www-datawww-data
inside
kramdown-2.4.0/test/testcases/block/09_html/html5_attributes.html0000644000004100000410000000053214234044402025074 0ustar www-datawww-data

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

paragraph

kramdown-2.4.0/test/testcases/block/09_html/processing_instruction.text0000644000004100000410000000013114234044402026425 0ustar www-datawww-data para para other kramdown-2.4.0/test/testcases/block/09_html/invalid_html_2.html0000644000004100000410000000004114234044402024463 0ustar www-datawww-data

para


para

kramdown-2.4.0/test/testcases/block/09_html/parse_as_raw.options0000644000004100000410000000003014234044402024763 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/09_html/comment.text0000644000004100000410000000015014234044402023253 0ustar www-datawww-data para1 para2 para > This is > kramdown-2.4.0/test/testcases/block/09_html/processing_instruction.html0000644000004100000410000000023114234044402026406 0ustar www-datawww-data

<?xml version=”1.0”?>

para

<? test ?> para

other

<? multiline text is allowed ?>

kramdown-2.4.0/test/testcases/block/09_html/html_after_block.html0000644000004100000410000000017114234044402025073 0ustar www-datawww-data

Para

division

Quote

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

*para*

*para*

*para*

*para*

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

test

para2

tes

test weiter

para4

foo

bar 

para5

id

test

hallo

hallo

para6

Another para.

Test

Test

Test

kramdown-2.4.0/test/testcases/block/09_html/parse_as_span.options0000644000004100000410000000003014234044402025133 0ustar www-datawww-data:parse_block_html: true kramdown-2.4.0/test/testcases/block/07_horizontal_rule/0000755000004100000410000000000014234044402023161 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/07_horizontal_rule/septabs.html0000644000004100000410000000002514234044402025505 0ustar www-datawww-data


kramdown-2.4.0/test/testcases/block/07_horizontal_rule/error.text0000644000004100000410000000011514234044402025215 0ustar www-datawww-data_ * _ --- * * * _ - * ---------------------------------------------- test kramdown-2.4.0/test/testcases/block/07_horizontal_rule/normal.html0000644000004100000410000000022014234044402025331 0ustar www-datawww-data


d- -




para

text


- - -

kramdown-2.4.0/test/testcases/block/07_horizontal_rule/error.html0000644000004100000410000000015114234044402025175 0ustar www-datawww-data

_ * _

— * * *

_ - *

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

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


kramdown-2.4.0/test/testcases/block/07_horizontal_rule/septabs.text0000644000004100000410000000003314234044402025524 0ustar www-datawww-data- - - * * * _ _ _ _ _ kramdown-2.4.0/test/testcases/block/07_horizontal_rule/sepspaces.text0000644000004100000410000000004514234044402026054 0ustar www-datawww-data- - - * * * _ _ _ _ _ kramdown-2.4.0/test/testcases/block/10_ald/0000755000004100000410000000000014234044402020473 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/10_ald/simple.text0000644000004100000410000000025614234044402022675 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-2.4.0/test/testcases/block/10_ald/simple.html0000644000004100000410000000002714234044402022651 0ustar www-datawww-data

Some paragraph

kramdown-2.4.0/test/testcases/block/02_eob/0000755000004100000410000000000014234044402020501 5ustar www-datawww-datakramdown-2.4.0/test/testcases/block/02_eob/beginning.text0000644000004100000410000000000414234044402023341 0ustar www-datawww-data^ kramdown-2.4.0/test/testcases/block/02_eob/middle.text0000644000004100000410000000000614234044402022641 0ustar www-datawww-data ^ kramdown-2.4.0/test/testcases/block/02_eob/beginning.html0000644000004100000410000000000114234044402023316 0ustar www-datawww-data kramdown-2.4.0/test/testcases/block/02_eob/middle.html0000644000004100000410000000000114234044402022614 0ustar www-datawww-data kramdown-2.4.0/test/testcases/block/02_eob/end.text0000644000004100000410000000000414234044402022147 0ustar www-datawww-data ^ kramdown-2.4.0/test/testcases/block/02_eob/end.html0000644000004100000410000000000114234044402022124 0ustar www-datawww-data kramdown-2.4.0/test/testcases/span/0000755000004100000410000000000014234044402017302 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/03_codespan/0000755000004100000410000000000014234044402021400 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/03_codespan/rouge/0000755000004100000410000000000014234044402022521 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/03_codespan/rouge/disabled.options0000644000004100000410000000011714234044402025704 0ustar www-datawww-data:syntax_highlighter: rouge :syntax_highlighter_opts: span: disable: true kramdown-2.4.0/test/testcases/span/03_codespan/rouge/disabled.text0000644000004100000410000000004614234044402025176 0ustar www-datawww-dataYou can say `Class`{:.language-ruby}. kramdown-2.4.0/test/testcases/span/03_codespan/rouge/simple.options0000644000004100000410000000003314234044402025423 0ustar www-datawww-data:syntax_highlighter: rouge kramdown-2.4.0/test/testcases/span/03_codespan/rouge/disabled.html0000644000004100000410000000007514234044402025160 0ustar www-datawww-data

You can say Class.

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

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

kramdown-2.4.0/test/testcases/span/03_codespan/empty.text0000644000004100000410000000007014234044402023441 0ustar www-datawww-dataThis is `` empty. This is ``empty. This is ````empty. kramdown-2.4.0/test/testcases/span/03_codespan/highlighting-minted.options0000644000004100000410000000003414234044402026735 0ustar www-datawww-data:syntax_highlighter: minted kramdown-2.4.0/test/testcases/span/03_codespan/empty.html0000644000004100000410000000011514234044402023421 0ustar www-datawww-data

This is `` empty.

This is ``empty.

This is ````empty.

kramdown-2.4.0/test/testcases/span/03_codespan/highlighting.text0000644000004100000410000000007314234044402024753 0ustar www-datawww-dataYou can say `x = Class.new`{:.language-ruby}, for example. kramdown-2.4.0/test/testcases/span/03_codespan/normal.html0000644000004100000410000000056514234044402023564 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

` `

a ` `

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

Not ended `span.

kramdown-2.4.0/test/testcases/span/03_codespan/normal.text0000644000004100000410000000034714234044402023602 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` ` ` a ` ` kramdown-2.4.0/test/testcases/span/03_codespan/normal-css-class.text0000644000004100000410000000002614234044402025465 0ustar www-datawww-dataThis is a `code-span` kramdown-2.4.0/test/testcases/span/03_codespan/normal-css-class.html0000644000004100000410000000010214234044402025440 0ustar www-datawww-data

This is a code-span

kramdown-2.4.0/test/testcases/span/03_codespan/normal-css-class.options0000644000004100000410000000005514234044402026176 0ustar www-datawww-data:syntax_highlighter_opts: guess_lang: true kramdown-2.4.0/test/testcases/span/03_codespan/errors.text0000644000004100000410000000002114234044402023613 0ustar www-datawww-dataNot ended `span. kramdown-2.4.0/test/testcases/span/03_codespan/highlighting.html0000644000004100000410000000033114234044402024730 0ustar www-datawww-data

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

kramdown-2.4.0/test/testcases/span/text_substitutions/0000755000004100000410000000000014234044402023305 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/text_substitutions/typography_subst.html0000644000004100000410000000015714234044402027624 0ustar www-datawww-data

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

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

kramdown-2.4.0/test/testcases/span/text_substitutions/entities_symbolic.html0000644000004100000410000000010214234044402027711 0ustar www-datawww-data

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

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

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

kramdown-2.4.0/test/testcases/span/text_substitutions/entities.text0000644000004100000410000000024414234044402026037 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 <span> is BS&T; done! kramdown-2.4.0/test/testcases/span/text_substitutions/entities_symbolic.text0000644000004100000410000000006614234044402027742 0ustar www-datawww-dataThis is the A&O. © 2008 by me ŗ and λ kramdown-2.4.0/test/testcases/span/text_substitutions/entities_numeric.text0000644000004100000410000000006614234044402027563 0ustar www-datawww-dataThis is the A&O. © 2008 by me ŗ and λ kramdown-2.4.0/test/testcases/span/text_substitutions/typography_subst.options0000644000004100000410000000021014234044402030341 0ustar www-datawww-datatypographic_symbols: hellip: '...' mdash: '---' ndash: '--' laquo: '<<' raquo: '>>' laquo_space: '<< ' raquo_space: ' >>' kramdown-2.4.0/test/testcases/span/text_substitutions/greaterthan.html0000644000004100000410000000002714234044402026476 0ustar www-datawww-data

2 > 1 > 0

kramdown-2.4.0/test/testcases/span/text_substitutions/entities.options0000644000004100000410000000003214234044402026541 0ustar www-datawww-data:entity_output: :as_input kramdown-2.4.0/test/testcases/span/text_substitutions/entities_as_char.options0000644000004100000410000000007414234044402030227 0ustar www-datawww-data:entity_output: :as_char :smart_quotes: apos,apos,quot,quot kramdown-2.4.0/test/testcases/span/text_substitutions/entities_as_char.html0000644000004100000410000000007014234044402027474 0ustar www-datawww-data

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

kramdown-2.4.0/test/testcases/span/text_substitutions/typography.text0000644000004100000410000000122114234044402026415 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-2.4.0/test/testcases/span/text_substitutions/lowerthan.html0000644000004100000410000000002714234044402026175 0ustar www-datawww-data

0 < 1 < 2

kramdown-2.4.0/test/testcases/span/text_substitutions/typography.options0000644000004100000410000000003114234044402027122 0ustar www-datawww-data:entity_output: symbolic kramdown-2.4.0/test/testcases/span/text_substitutions/entities_as_input.html0000644000004100000410000000010114234044402027711 0ustar www-datawww-data

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

kramdown-2.4.0/test/testcases/span/text_substitutions/entities_numeric.options0000644000004100000410000000003114234044402030262 0ustar www-datawww-data:entity_output: :numeric kramdown-2.4.0/test/testcases/span/text_substitutions/entities.html0000644000004100000410000000030214234044402026012 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 <span> is BS&T; done!

kramdown-2.4.0/test/testcases/span/text_substitutions/greaterthan.text0000644000004100000410000000001214234044402026510 0ustar www-datawww-data2 > 1 > 0 kramdown-2.4.0/test/testcases/span/text_substitutions/typography.html0000644000004100000410000000233414234044402026403 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-2.4.0/test/testcases/span/text_substitutions/lowerthan.text0000644000004100000410000000001214234044402026207 0ustar www-datawww-data0 < 1 < 2 kramdown-2.4.0/test/testcases/span/text_substitutions/typography_subst.text0000644000004100000410000000011114234044402027632 0ustar www-datawww-dataThis ... something---this too--! This <> some text, << this >> too! kramdown-2.4.0/test/testcases/span/text_substitutions/entities_symbolic.options0000644000004100000410000000003214234044402030442 0ustar www-datawww-data:entity_output: :symbolic kramdown-2.4.0/test/testcases/span/math/0000755000004100000410000000000014234044402020233 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/math/no_engine.html0000644000004100000410000000006514234044402023063 0ustar www-datawww-data

$5+5$ inline math

kramdown-2.4.0/test/testcases/span/math/normal.html0000644000004100000410000000031614234044402022411 0ustar www-datawww-data

This 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-2.4.0/test/testcases/span/math/no_engine.text0000644000004100000410000000002414234044402023076 0ustar www-datawww-data$$5+5$$ inline math kramdown-2.4.0/test/testcases/span/math/normal.text0000644000004100000410000000025614234044402022434 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-2.4.0/test/testcases/span/math/no_engine.options0000644000004100000410000000002014234044402023601 0ustar www-datawww-data:math_engine: ~ kramdown-2.4.0/test/testcases/span/autolinks/0000755000004100000410000000000014234044402021313 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/autolinks/url_links.html0000644000004100000410000000213514234044402024204 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-2.4.0/test/testcases/span/autolinks/url_links.text0000644000004100000410000000110714234044402024222 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-2.4.0/test/testcases/span/02_emphasis/0000755000004100000410000000000014234044402021414 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/02_emphasis/empty.text0000644000004100000410000000004714234044402023461 0ustar www-datawww-dataThis __is **empty. This ****is empty. kramdown-2.4.0/test/testcases/span/02_emphasis/empty.html0000644000004100000410000000007414234044402023441 0ustar www-datawww-data

This __is **empty.

This **is empty.

kramdown-2.4.0/test/testcases/span/02_emphasis/normal.html0000644000004100000410000000263014234044402023573 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

it–by design–cannot have side-effects.

it—by design—cannot have side-effects.

kramdown-2.4.0/test/testcases/span/02_emphasis/errors.html0000644000004100000410000000021314234044402023612 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-2.4.0/test/testcases/span/02_emphasis/nesting.text0000644000004100000410000000073614234044402023777 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-2.4.0/test/testcases/span/02_emphasis/normal.text0000644000004100000410000000140014234044402023605 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_“ it--by design--_cannot have side-effects_. it---by design---_cannot have side-effects_. kramdown-2.4.0/test/testcases/span/02_emphasis/nesting.html0000644000004100000410000000224314234044402023752 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-2.4.0/test/testcases/span/02_emphasis/errors.text0000644000004100000410000000014214234044402023633 0ustar www-datawww-dataThis is a *star. This is a **star. This is **a *star*. This is *a star\*. This** is** a star. kramdown-2.4.0/test/testcases/span/02_emphasis/normal.options0000644000004100000410000000003114234044402024313 0ustar www-datawww-data:entity_output: :numeric kramdown-2.4.0/test/testcases/span/04_footnote/0000755000004100000410000000000014234044402021442 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/04_footnote/backlink_text.options0000644000004100000410000000005214234044402025676 0ustar www-datawww-data:footnote_backlink: 'text &8617; ' kramdown-2.4.0/test/testcases/span/04_footnote/without_backlink.options0000644000004100000410000000002714234044402026417 0ustar www-datawww-data:footnote_backlink: '' kramdown-2.4.0/test/testcases/span/04_footnote/inside_footnote.text0000644000004100000410000000026114234044402025537 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-2.4.0/test/testcases/span/04_footnote/footnote_nr.text0000644000004100000410000000012614234044402024703 0ustar www-datawww-dataThis is a footnote[^ab]. And another[^bc]. [^ab]: Some text. [^bc]: Some other text. kramdown-2.4.0/test/testcases/span/04_footnote/without_backlink.text0000644000004100000410000000005714234044402025713 0ustar www-datawww-dataSome footnote here[^fn] [^fn]: Some text here kramdown-2.4.0/test/testcases/span/04_footnote/placement.html0000644000004100000410000000057514234044402024307 0ustar www-datawww-data
  1. Footnote \` text 

Some para with a1 footnote.

And another para.

kramdown-2.4.0/test/testcases/span/04_footnote/regexp_problem.options0000644000004100000410000000005314234044402026067 0ustar www-datawww-data:auto_ids: false :entity_output: :symbolic kramdown-2.4.0/test/testcases/span/04_footnote/footnote_prefix.text0000644000004100000410000000013314234044402025557 0ustar www-datawww-dataThis is a[^ab] footnote[^ab]. And another[^bc]. [^ab]: Some text. [^bc]: Some other text. kramdown-2.4.0/test/testcases/span/04_footnote/regexp_problem.text0000644000004100000410000000016514234044402025364 0ustar www-datawww-data# Something something[^note1]. # Footnotes [^note1]: A note # Test kramdown-2.4.0/test/testcases/span/04_footnote/backlink_inline.text0000644000004100000410000000072514234044402025470 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-2.4.0/test/testcases/span/04_footnote/markers.html0000644000004100000410000000405314234044402023776 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-2.4.0/test/testcases/span/04_footnote/footnote_nr.html0000644000004100000410000000115614234044402024667 0ustar www-datawww-data

This is a footnote35. And another36.

  1. Some text. 

  2. Some other text. 

kramdown-2.4.0/test/testcases/span/04_footnote/backlink_text.text0000644000004100000410000000005714234044402025174 0ustar www-datawww-dataSome footnote here[^fn] [^fn]: Some text here kramdown-2.4.0/test/testcases/span/04_footnote/backlink_inline.options0000644000004100000410000000003714234044402026173 0ustar www-datawww-datafootnote_backlink_inline: true kramdown-2.4.0/test/testcases/span/04_footnote/regexp_problem.html0000644000004100000410000000061714234044402025346 0ustar www-datawww-data

Something

something1.

Footnotes

Test

  1. A note 

kramdown-2.4.0/test/testcases/span/04_footnote/markers.latex0000644000004100000410000000076114234044402024151 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-2.4.0/test/testcases/span/04_footnote/markers.options0000644000004100000410000000005314234044402024521 0ustar www-datawww-data:auto_ids: false :entity_output: :symbolic kramdown-2.4.0/test/testcases/span/04_footnote/definitions.text0000644000004100000410000000036714234044402024671 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-2.4.0/test/testcases/span/04_footnote/without_backlink.html0000644000004100000410000000041414234044402025670 0ustar www-datawww-data

Some footnote here1

  1. Some text here

kramdown-2.4.0/test/testcases/span/04_footnote/placement.options0000644000004100000410000000003114234044402025021 0ustar www-datawww-data:entity_output: :numeric kramdown-2.4.0/test/testcases/span/04_footnote/markers.text0000644000004100000410000000054714234044402024022 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-2.4.0/test/testcases/span/04_footnote/definitions.latex0000644000004100000410000000030514234044402025012 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-2.4.0/test/testcases/span/04_footnote/inside_footnote.html0000644000004100000410000000166614234044402025531 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-2.4.0/test/testcases/span/04_footnote/definitions.html0000644000004100000410000000026014234044402024641 0ustar www-datawww-data

Some para.

blockquote

  • a list with some text
  • other list
code
kramdown-2.4.0/test/testcases/span/04_footnote/footnote_prefix.html0000644000004100000410000000155514234044402025550 0ustar www-datawww-data

This is a1 footnote1. And another2.

  1. Some text.  2

  2. Some other text. 

kramdown-2.4.0/test/testcases/span/04_footnote/backlink_text.html0000644000004100000410000000055314234044402025155 0ustar www-datawww-data

Some footnote here1

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

kramdown-2.4.0/test/testcases/span/04_footnote/backlink_inline.html0000644000004100000410000000604414234044402025450 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. \[x + 2\]

  7. test

kramdown-2.4.0/test/testcases/span/04_footnote/footnote_prefix.options0000644000004100000410000000003214234044402026264 0ustar www-datawww-data:footnote_prefix: adf123- kramdown-2.4.0/test/testcases/span/04_footnote/footnote_nr.options0000644000004100000410000000002114234044402025404 0ustar www-datawww-data:footnote_nr: 35 kramdown-2.4.0/test/testcases/span/04_footnote/footnote_nr.latex0000644000004100000410000000012214234044402025030 0ustar www-datawww-dataThis is a footnote\footnote{Some text.}. And another\footnote{Some other text.}. kramdown-2.4.0/test/testcases/span/04_footnote/placement.text0000644000004100000410000000017214234044402024320 0ustar www-datawww-data* footnotes will be placed here {:footnotes} Some para with a[^1] footnote. [^1]: Footnote \\\` text And another para. kramdown-2.4.0/test/testcases/span/05_html/0000755000004100000410000000000014234044402020552 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/05_html/xml.text0000644000004100000410000000021114234044402022252 0ustar www-datawww-dataThis doit test This doit test This doit test kramdown-2.4.0/test/testcases/span/05_html/button.html0000644000004100000410000000037514234044402022760 0ustar www-datawww-data

First some text and then a

and then text.

A it.

kramdown-2.4.0/test/testcases/span/05_html/button.text0000644000004100000410000000027114234044402022773 0ustar www-datawww-data First some text and then a and then text. A it. kramdown-2.4.0/test/testcases/span/05_html/markdown_attr.html0000644000004100000410000000040514234044402024313 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-2.4.0/test/testcases/span/05_html/raw_span_elements.html0000644000004100000410000000017114234044402025145 0ustar www-datawww-data

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

kramdown-2.4.0/test/testcases/span/05_html/xml.html0000644000004100000410000000025314234044402022240 0ustar www-datawww-data

This doit test

This doit test

This doit</some> test

kramdown-2.4.0/test/testcases/span/05_html/mark_element.html0000644000004100000410000000005614234044402024104 0ustar www-datawww-data

Lorem ipsum.

Test

kramdown-2.4.0/test/testcases/span/05_html/raw_span_elements.text0000644000004100000410000000016214234044402025165 0ustar www-datawww-dataThis is raw --version and --version and --version and ---version. kramdown-2.4.0/test/testcases/span/05_html/normal.html0000644000004100000410000000156014234044402022732 0ustar www-datawww-data

Empty !

title is a title.

This is <? a PI ?>.

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-2.4.0/test/testcases/span/05_html/mark_element.text0000644000004100000410000000004014234044402024115 0ustar www-datawww-dataLorem ipsum. Test kramdown-2.4.0/test/testcases/span/05_html/across_lines.text0000644000004100000410000000004214234044402024140 0ustar www-datawww-dataLink: test kramdown-2.4.0/test/testcases/span/05_html/normal.text0000644000004100000410000000124714234044402022754 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-2.4.0/test/testcases/span/05_html/across_lines.html0000644000004100000410000000005114234044402024120 0ustar www-datawww-data

Link: test

kramdown-2.4.0/test/testcases/span/05_html/invalid.text0000644000004100000410000000003014234044402023077 0ustar www-datawww-dataThis is some text kramdown-2.4.0/test/testcases/span/05_html/markdown_attr.text0000644000004100000410000000047614234044402024343 0ustar www-datawww-dataThis is *text* This is *text* This is *text* This is *text* This is *nothing* to *fear* about. This is . kramdown-2.4.0/test/testcases/span/05_html/link_with_mailto.html0000644000004100000410000000007014234044402024772 0ustar www-datawww-data

Link: text

kramdown-2.4.0/test/testcases/span/05_html/invalid.html0000644000004100000410000000004614234044402023066 0ustar www-datawww-data

This is some text

kramdown-2.4.0/test/testcases/span/05_html/link_with_mailto.text0000644000004100000410000000006114234044402025012 0ustar www-datawww-dataLink: text kramdown-2.4.0/test/testcases/span/abbreviations/0000755000004100000410000000000014234044402022132 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/abbreviations/abbrev.text0000644000004100000410000000103614234044402024301 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-2.4.0/test/testcases/span/abbreviations/abbrev.html0000644000004100000410000000155214234044402024264 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-2.4.0/test/testcases/span/abbreviations/in_footnote.html0000644000004100000410000000063014234044402025342 0ustar www-datawww-data

There is a TXT file here. 1

  1. A TXT file. 

kramdown-2.4.0/test/testcases/span/abbreviations/in_footnote.text0000644000004100000410000000010514234044402025357 0ustar www-datawww-dataThere is a TXT file here. [^1] *[TXT]: Text File [^1]: A TXT file. kramdown-2.4.0/test/testcases/span/abbreviations/abbrev_in_html.html0000644000004100000410000000064014234044402025773 0ustar www-datawww-data

This is some TEST to check.

This TEST fails. This TEST fails. kramdown-2.4.0/test/testcases/span/abbreviations/abbrev_defs.text0000644000004100000410000000017314234044402025303 0ustar www-datawww-data*[ABBR]: Some abbreviations *[one abbr]: one abbrev *[2 and other]: another *[3]: yet another *[4]: noabbrev kramdown-2.4.0/test/testcases/span/abbreviations/abbrev_defs.html0000644000004100000410000000005014234044402025255 0ustar www-datawww-data
*[4]: noabbrev
kramdown-2.4.0/test/testcases/span/abbreviations/abbrev_in_html.text0000644000004100000410000000056114234044402026015 0ustar www-datawww-dataThis is some TEST to check. This TEST fails. This TEST fails. *[TEST]: This Escapes SVG Text. kramdown-2.4.0/test/testcases/span/escaped_chars/0000755000004100000410000000000014234044402022066 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/escaped_chars/normal.html0000644000004100000410000000040314234044402024241 0ustar www-datawww-data

\

.

*

_

+

-

`

(

)

[

]

{

}

#

!

<<

>>

:

|

"

'

=

>

<

kramdown-2.4.0/test/testcases/span/escaped_chars/normal.text0000644000004100000410000000014114234044402024260 0ustar www-datawww-data\\ \. \* \_ \+ \- \` \( \) \[ \] \{ \} \# \! \<< \>> \: \| \" \' \= \> \< kramdown-2.4.0/test/testcases/span/ial/0000755000004100000410000000000014234044402020047 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/ial/simple.text0000644000004100000410000000023014234044402022241 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-2.4.0/test/testcases/span/ial/simple.html0000644000004100000410000000031614234044402022226 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-2.4.0/test/testcases/span/extension/0000755000004100000410000000000014234044402021316 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/extension/ignored.text0000644000004100000410000000004314234044402023650 0ustar www-datawww-dataThis is {::something}paragraph{:/} kramdown-2.4.0/test/testcases/span/extension/nomarkdown.text0000644000004100000410000000004714234044402024404 0ustar www-datawww-dataThis is {::nomarkdown}*some*{:/} text. kramdown-2.4.0/test/testcases/span/extension/ignored.html0000644000004100000410000000005214234044402023630 0ustar www-datawww-data

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

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

This is *some* text.

kramdown-2.4.0/test/testcases/span/extension/comment.html0000644000004100000410000000034414234044402023647 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-2.4.0/test/testcases/span/extension/options.html0000644000004100000410000000005714234044402023701 0ustar www-datawww-data

This is an option *true*!

kramdown-2.4.0/test/testcases/span/extension/comment.text0000644000004100000410000000041114234044402023662 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-2.4.0/test/testcases/span/01_link/0000755000004100000410000000000014234044402020537 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/01_link/link_defs_with_ial.text0000644000004100000410000000045314234044402025265 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-2.4.0/test/testcases/span/01_link/imagelinks.html0000644000004100000410000000103414234044402023546 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-2.4.0/test/testcases/span/01_link/link_defs.html0000644000004100000410000000050014234044402023356 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-2.4.0/test/testcases/span/01_link/link_defs.text0000644000004100000410000000116514234044402023406 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-2.4.0/test/testcases/span/01_link/empty_title.htmlinput0000644000004100000410000000025214234044402025043 0ustar www-datawww-data

Image with empty title: alt text

Link reference with empty title.

kramdown-2.4.0/test/testcases/span/01_link/empty.text0000644000004100000410000000010514234044402022577 0ustar www-datawww-dataThis is [] empty. This is [][] empty. This is [](test.html) empty. kramdown-2.4.0/test/testcases/span/01_link/latex_escaping.latex0000644000004100000410000000035214234044402024564 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-2.4.0/test/testcases/span/01_link/inline.text0000644000004100000410000000176214234044402022731 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-2.4.0/test/testcases/span/01_link/empty.html0000644000004100000410000000014514234044402022563 0ustar www-datawww-data

This is [] empty.

This is [][] empty.

This is empty.

kramdown-2.4.0/test/testcases/span/01_link/reference.options0000644000004100000410000000010614234044402024107 0ustar www-datawww-data:link_defs: predefined: [predefined.html] URI: [uri.html, My URI] kramdown-2.4.0/test/testcases/span/01_link/reference.text0000644000004100000410000000144014234044402023402 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-2.4.0/test/testcases/span/01_link/links_with_angle_brackets.text0000644000004100000410000000012714234044402026644 0ustar www-datawww-dataThis is a [link](). This is a [link]( 'and title'). kramdown-2.4.0/test/testcases/span/01_link/imagelinks.text0000644000004100000410000000053114234044402023567 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-2.4.0/test/testcases/span/01_link/link_defs_with_ial.html0000644000004100000410000000051414234044402025243 0ustar www-datawww-data

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

test

kramdown-2.4.0/test/testcases/span/01_link/inline.html0000644000004100000410000000260614234044402022707 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-2.4.0/test/testcases/span/01_link/image_in_a.html0000644000004100000410000000047214234044402023500 0ustar www-datawww-data

Simple: Some alt text

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

Simple: Some text alt text text

kramdown-2.4.0/test/testcases/span/01_link/links_with_angle_brackets.html0000644000004100000410000000017514234044402026627 0ustar www-datawww-data

This is a link.

This is a link.

kramdown-2.4.0/test/testcases/span/01_link/image_in_a.text0000644000004100000410000000031514234044402023514 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-2.4.0/test/testcases/span/01_link/empty_title.text0000644000004100000410000000017114234044402024003 0ustar www-datawww-dataImage with empty title: ![alt text](/images/other.png) Link [reference][1] with empty title. [1]: http://example.tld kramdown-2.4.0/test/testcases/span/01_link/latex_escaping.text0000644000004100000410000000014614234044402024434 0ustar www-datawww-data kramdown-2.4.0/test/testcases/span/01_link/reference.html0000644000004100000410000000211014234044402023355 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-2.4.0/test/testcases/span/line_breaks/0000755000004100000410000000000014234044402021560 5ustar www-datawww-datakramdown-2.4.0/test/testcases/span/line_breaks/normal.html0000644000004100000410000000026714234044402023743 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-2.4.0/test/testcases/span/line_breaks/normal.text0000644000004100000410000000022414234044402023754 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-2.4.0/test/testcases/span/line_breaks/normal.latex0000644000004100000410000000026114234044402024106 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-2.4.0/test/testcases/cjk-line-break.text0000644000004100000410000000005214234044402022022 0ustar www-datawww-data一 二 三 四 五 あ い う え お kramdown-2.4.0/test/testcases/encoding.html0000644000004100000410000000174514234044402021024 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-2.4.0/test/test_location.rb0000644000004100000410000001453514234044402017547 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'minitest/autorun' require 'kramdown' Encoding.default_external = 'utf-8' 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 assert_equal(expected_line, element.options[:location]) 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) assert_equal(["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"], doc.warnings) 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 end kramdown-2.4.0/README.md0000644000004100000410000000575014234044402014652 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 sponsor**](https://github.com/sponsors/gettalong/) or [**a patron**](https://www.patreon.com/gettalong) - thanks! Sponsors: * **GROSSWEBER** provides software development consulting and training services. ## 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-2.4.0/bin/0000755000004100000410000000000014234044402014134 5ustar www-datawww-datakramdown-2.4.0/bin/kramdown0000755000004100000410000001061314234044402015705 0ustar www-datawww-data#!/usr/bin/env ruby # -*- coding: utf-8 -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'optparse' require 'rbconfig' require 'yaml' require 'kramdown' def add_kramdown_options(opts, parsed_options, banner: [], ignore: []) banner_shown = false defined_options = [] Kramdown::Options.definitions.sort.each do |n, definition| next if ignore.include?(n) unless banner_shown opts.separator("") banner.each {|part| opts.separator(part) } opts.separator("") banner_shown = true end defined_options << n no = n.to_s.tr('_', '-') if definition.type == Kramdown::Options::Boolean opts.on("--[no-]#{no}") {|v| parsed_options[n] = Kramdown::Options.parse(n, v) } else type = definition.type type = String if type == Symbol || type == Object opts.on("--#{no} ARG", type) {|v| parsed_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 defined_options end 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 StandardError end options = {} format = ['html'] defined_options = [] 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, 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, man or remove_html_tags") {|v| format = v } opts.on("-x", "--extension EXT", Array, "Load one or more extensions (without the 'kramdown-' " \ "prefix) separated", "by commas (e.g. parser-gfm,syntax-coderay)", "Note: Use this option before other options!") do |exts| exts.each do |ext| begin require "kramdown-#{ext}" new_options = add_kramdown_options(opts, options, banner: ["#{ext} options:"], ignore: defined_options) defined_options.concat(new_options) rescue LoadError $stderr.puts "Couldn't load extension #{ext}, ignoring" end end end 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 new_options = add_kramdown_options(opts, options, banner: ["kramdown options:"]) defined_options.concat(new_options) 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-2.4.0/CONTRIBUTERS0000644000004100000410000000717014234044402015237 0ustar www-datawww-data Count Name ======= ==== 964 Thomas Leitner 18 Ashwin Maroli 7 Christian Cornelssen 6 Gioele Barabucci 5 Gleb Mazovetskiy 4 Ted Pak 4 Shuanglei Tao 4 Dan Allen 4 Arne Brasseur 3 Henning Perl 3 gettalong 3 Carsten Bormann 3 Brandur 3 Ben Armston 3 Ashwin Maroli 3 Alex Marandon 2 Tom Thorogood 2 Parker Moore 2 Nathanael Jones 2 Max Meyer 2 Jo Hund 2 Bran 1 winniehell 1 William 1 Uwe Kubosch 1 utenmiki 1 Trevor Wennblom 1 tomykaira 1 tom93 1 Tobin Yehle 1 timcraft 1 Tim Blair 1 Tim Besard 1 Tim Bates 1 Sun Yaozhu 1 Stephen 1 Stephen Crosby 1 Stan Hu 1 Simon Lydell 1 Simon Coffey 1 Shusaku NAKAZATO 1 Sebastian Boehm 1 scherr 1 Postmodern 1 Pete Michaud 1 Noah Doersing 1 myqlarson 1 milo.simpson 1 Michal Till 1 Maxime Kjaer 1 Matt Hickford 1 Martyn Chamberlin 1 Marek Tuchowski 1 Marcus Stollsteimer 1 Luca Barbato 1 l3kn 1 Kir Kolyshkin 1 Jun Aruga 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 Fangyi Zhou 1 Diego Galeota 1 David Rodríguez 1 Daniel Bair 1 Damien Pollet 1 Christopher Jefferson 1 Cédric Boutillier 1 Bob Lail 1 Ashe Connor 1 aschmitz <29508+aschmitz@users.noreply.github.com> 1 Antoine Cotten 1 Andrew 1 Alpha Chen 1 Alex Tomlins 1 Alexey Vasiliev 1 284km kramdown-2.4.0/AUTHORS0000644000004100000410000000007514234044402014436 0ustar www-datawww-dataThe author of kramdown is Thomas Leitner . kramdown-2.4.0/data/0000755000004100000410000000000014234044402014275 5ustar www-datawww-datakramdown-2.4.0/data/kramdown/0000755000004100000410000000000014234044402016117 5ustar www-datawww-datakramdown-2.4.0/data/kramdown/document.html0000644000004100000410000000117314234044402020625 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-2.4.0/data/kramdown/document.latex0000644000004100000410000000236414234044402021001 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-2.4.0/man/0000755000004100000410000000000014234044402014137 5ustar www-datawww-datakramdown-2.4.0/man/man1/0000755000004100000410000000000014234044402014773 5ustar www-datawww-datakramdown-2.4.0/man/man1/kramdown.10000644000004100000410000003360714234044402016710 0ustar www-datawww-data.\" generated by kramdown .TH "KRAMDOWN" "1" "January 2019" .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, or \fIhtml\fP\&\. The input format \fIGFM\fP is available through the \fBkramdown\-parser\-gfm\fP gem\. .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, \fIman\fP or \fIremove_html_tags\fP\&\. The converter \fIpdf\fP is available through the \fBkramdown\-converter\-pdf\fP gem\. .TP \fB\-x\fP \fIEXT\fP, \fB\-\-extension\fP \fIEXT\fP Load one or more extensions\. The name of the extension should not include the \fBkramdown\-\fP prefix, e\.g\. just \fBparser\-gfm\fP\&\. Multiple extensions can be loaded by separating them with commas\. .RS .P Note: This option has to be used before any other options that rely on the extension already being loaded\. .RE .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\-\-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\-\-footnote\-prefix\fP \fIARG\fP Prefix used for footnote IDs .RS .P This option can be used to set a prefix for footnote IDs\. This is useful when rendering multiple documents into the same output file to avoid duplicate IDs\. The prefix should only contain characters that are valid in an ID! .P Default: \[u2018]\[u2019] Used by: HTML .RE .TP \fB\-\-forbidden\-inline\-options\fP \fIARG\fP Defines the options that may not be set using the {::options} extension .RS .P The value needs to be an array of option names\. .P Default: [template] Used by: HTML converter .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\-\-list\-indent\fP \fIARG\fP Sets the number of spaces to use for list indentation .RS .P Default: 2 Used by: Kramdown converter .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\-line\-breaks\-for\-cjk\fP Specifies whether line breaks should be removed between CJK characters .RS .P Default: false Used by: HTML 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: rouge 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-2.4.0/lib/0000755000004100000410000000000014234044402014132 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown.rb0000644000004100000410000000033514234044402016302 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/document' kramdown-2.4.0/lib/kramdown/0000755000004100000410000000000014234044402015754 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/parser/0000755000004100000410000000000014234044402017250 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/parser/base.rb0000644000004100000410000001116414234044402020512 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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") source.chomp! source << "\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? location = (last && last.options[:location] || tree.options[:location]) tree.children << Element.new(type, text, nil, location: 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-2.4.0/lib/kramdown/parser/markdown.rb0000644000004100000410000000372114234044402021422 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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/x 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 { 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-2.4.0/lib/kramdown/parser/kramdown.rb0000644000004100000410000003230614234044402021423 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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] @span_pattern_cache ||= Hash.new { |h, k| h[k] = {} } 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 footnote_count = 0 @footnotes.each do |name, data| (footnote_count += 1; next) if data.key?(:marker) line = data[:content].options[:location] warning("Footnote definition for '#{name}' on line #{line} is unreferenced - ignoring") end @root.options[:footnote_count] = footnote_count 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 until @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 def span_pattern_cache(stop_re, span_start) @span_pattern_cache[stop_re][span_start] ||= /(?=#{Regexp.union(stop_re, span_start)})/ end private :span_pattern_cache # 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 ||= @span_parsers used_re = (stop_re.nil? ? span_start_re : span_pattern_cache(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 ial.each do |k, v| if k == IAL_CLASS_ATTR attr[k] = "#{attr[k]} #{v}".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.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.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-2.4.0/lib/kramdown/parser/html.rb0000644000004100000410000005632414234044402020553 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 an 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*(?:(\p{Word}+)|("|')(.*?)\3))?/m HTML_TAG_RE = /<((?>#{REXML::Parsers::BaseParser::UNAME_STR}))\s*((?>\s+#{REXML::Parsers::BaseParser::UNAME_STR}(?:\s*=\s*(?:\p{Word}+|("|').*?\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 = {} str.scan(HTML_ATTRIBUTE_RE).each do |attr, val, _sep, quoted_val| attr.downcase! if in_html_tag if attrs.key?(attr) warning("Duplicate HTML attribute '#{attr}' on line #{line || '?'} - overwriting previous one") end attrs[attr] = val || quoted_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 if @tree.type == :html_element warning("Found no end tag for '#{@tree.value}' on line " \ "#{@tree.options[:location]} - auto-closing it") end 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.map! do |c| if c.type == :text process_text(c.value, !do_conversion) else process(c) c end end.flatten! 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 = [] until src.eos? if (tmp = src.scan_until(/(?=#{HTML_ENTITY_RE})/o)) result << Element.new(:text, tmp) src.scan(HTML_ENTITY_RE) val = src[1] || (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 !c.block? || c.type == :text unless 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 || ((el.children[i - 1]).block? && (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 mem << if [60, 62, 34, 38].include?(c.value.code_point) c.value.code_point.chr else 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 StandardError 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*/, '') 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) unless 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 do |c| if c.value == 'th' || c.value == 'td' return false unless 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 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}/o)) @tree.children << Element.new(:xml_pi, result.strip, nil, category: :block) elsif (result = @src.scan(/\s*#{HTML_DOCTYPE_RE}/o)) # ignore the doctype elsif (result = @src.scan(/\s*#{HTML_COMMENT_RE}/o)) @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-2.4.0/lib/kramdown/parser/kramdown/0000755000004100000410000000000014234044402021072 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/parser/kramdown/list.rb0000644000004100000410000002475614234044402022410 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 PATTERN_TAIL = /[\t| ].*?\n/ LIST_START_UL = /^(#{OPT_SPACE}[+*-])(#{PATTERN_TAIL})/ LIST_START_OL = /^(#{OPT_SPACE}\d+\.)(#{PATTERN_TAIL})/ 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 until @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) list.options[:first_list_marker] ||= @src[1].strip 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 parse_attribute_list($1, item.options[:ial] ||= {}) '' end list_start_re = fetch_pattern(type, indentation) 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 it_children = it.children next if it_children.empty? # 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 last = (it_children.last.type == :blank ? it_children.pop : nil) end @tree.children << last if !last.nil? && !eob_found true end define_parser(:list, LIST_START) DEFINITION_LIST_START = /^(#{OPT_SPACE}:)(#{PATTERN_TAIL})/ # 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 # take location from preceding para which is the first definition term deflist.options[:location] = para.options[:location] 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 until @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 = fetch_pattern(:dl, indentation) 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 it_children = it.children next if it_children.empty? last = (it_children.last.type == :blank ? it_children.pop : nil) 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 children = @tree.children if children.length >= 1 && children.last.type == :dl children[-1].children.concat(deflist.children) elsif children.length >= 2 && children[-1].type == :blank && children[-2].type == :dl children.pop children[-1].children.concat(deflist.children) else children << deflist end children << last if last true end define_parser(:definition_list, DEFINITION_LIST_START) private # precomputed patterns for indentations 1..4 and fallback expression # to compute pattern when indentation is outside the 1..4 range. def fetch_pattern(type, indentation) if type == :ul case indentation when 1 then %r/^( {0}[+*-])(#{PATTERN_TAIL})/o when 2 then %r/^( {0,1}[+*-])(#{PATTERN_TAIL})/o when 3 then %r/^( {0,2}[+*-])(#{PATTERN_TAIL})/o else %r/^( {0,3}[+*-])(#{PATTERN_TAIL})/o end elsif type == :ol case indentation when 1 then %r/^( {0}\d+\.)(#{PATTERN_TAIL})/o when 2 then %r/^( {0,1}\d+\.)(#{PATTERN_TAIL})/o when 3 then %r/^( {0,2}\d+\.)(#{PATTERN_TAIL})/o else %r/^( {0,3}\d+\.)(#{PATTERN_TAIL})/o end elsif type == :dl case indentation when 1 then %r/^( {0}:)(#{PATTERN_TAIL})/o when 2 then %r/^( {0,1}:)(#{PATTERN_TAIL})/o when 3 then %r/^( {0,2}:)(#{PATTERN_TAIL})/o else %r/^( {0,3}:)(#{PATTERN_TAIL})/o end end end end end end kramdown-2.4.0/lib/kramdown/parser/kramdown/escaped_chars.rb0000644000004100000410000000105514234044402024204 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/block_boundary.rb0000644000004100000410000000156614234044402024424 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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? last_child = @tree.children.last !last_child || last_child.type == :blank || (last_child.type == :eob && last_child.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-2.4.0/lib/kramdown/parser/kramdown/line_break.rb0000644000004100000410000000111014234044402023503 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/codespan.rb0000644000004100000410000000320214234044402023210 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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|\A\Z/ && @src.match?(/\s/) add_text(result) return end # assign static regex to avoid allocating the same on every instance # where +result+ equals a single-backtick. Interpolate otherwise. if result == '`' scan_pattern = /`/ str_sub_pattern = /`\Z/ else scan_pattern = /#{result}/ str_sub_pattern = /#{result}\Z/ end if (text = @src.scan_until(scan_pattern)) text.sub!(str_sub_pattern, '') unless 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, { codespan_delimiter: result, location: start_line_number }) else @src.revert_pos(saved_pos) add_text(result) end end define_parser(:codespan, CODESPAN_DELIMITER, '`') end end end kramdown-2.4.0/lib/kramdown/parser/kramdown/paragraph.rb0000644000004100000410000000413514234044402023367 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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) until @src.match?(paragraph_end) result << @src.scan(PARAGRAPH_MATCH) end result.rstrip! if (last_child = @tree.children.last) && last_child.type == :p last_item_in_para = last_child.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, last_child) 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-2.4.0/lib/kramdown/parser/kramdown/header.rb0000644000004100000410000000377714234044402022665 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # require 'kramdown/parser/kramdown/block_boundary' require 'rexml/xmltokens' 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 unless 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 unless after_block_boundary? text, id = parse_header_contents text.sub!(/(?#{REXML::XMLTokens::NAME_START_CHAR}#{REXML::XMLTokens::NAME_CHAR}*)}\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-2.4.0/lib/kramdown/parser/kramdown/autolink.rb0000644000004100000410000000156414234044402023253 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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}]+?)>" 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-2.4.0/lib/kramdown/parser/kramdown/codeblock.rb0000644000004100000410000000356314234044402023353 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/footnote.rb0000644000004100000410000000436414234044402023263 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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, '')) if @footnotes[@src[1]] warning("Duplicate footnote name '#{@src[1]}' on line #{start_line_number} - overwriting") end @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-2.4.0/lib/kramdown/parser/kramdown/html_entity.rb0000644000004100000410000000207514234044402023763 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 value = ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2]&.to_i) || @src[3].hex) @tree.children << Element.new(:entity, value, 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-2.4.0/lib/kramdown/parser/kramdown/blank_line.rb0000644000004100000410000000126414234044402023520 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 (last_child = @tree.children.last) && last_child.type == :blank last_child.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-2.4.0/lib/kramdown/parser/kramdown/abbreviation.rb0000644000004100000410000000565714234044402024101 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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! if @root.options[:abbrev_defs][abbrev_id] warning("Duplicate abbreviation ID '#{abbrev_id}' on line #{start_line_number} " \ "- overwriting") end @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? unless 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 && el.options[:content_model] != :raw 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-2.4.0/lib/kramdown/parser/kramdown/extensions.rb0000644000004100000410000001714314234044402023624 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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}".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.empty? end # Update the +ial+ with the information from the inline attribute list +opts+. def update_ial_with_ial(ial, opts) (ial[:refs] ||= []).concat(opts[:refs]) if opts.key?(:refs) opts.each do |k, v| if k == IAL_CLASS_ATTR ial[k] = "#{ial[k]} #{v}".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) unless @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' if body.kind_of?(String) @tree.children << Element.new(:comment, body, nil, category: type, location: line_no) end true when 'nomarkdown' if body.kind_of?(String) @tree.children << Element.new(:raw, body, nil, category: type, location: line_no, type: opts['type'].to_s.split(/\s+/)) end true when 'options' opts.select do |k, v| k = k.to_sym if Kramdown::Options.defined?(k) if @options[:forbidden_inline_options].include?(k) || k == :forbidden_inline_options warning("Option #{k} may not be set inline") next false end begin val = Kramdown::Options.parse(k, v) @options[k] = val (@root.options[:options] ||= {})[k] = val rescue StandardError 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]] ||= {}) @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 (last_child = @tree.children.last) && last_child.type != :blank && (last_child.type != :eob || [:link_def, :abbrev_def, :footnote_def].include?(last_child.value)) parse_attribute_list(@src[1], last_child.options[:ial] ||= {}) @tree.children << new_block_el(:eob, :ial) unless @src.check(IAL_BLOCK_START) else parse_attribute_list(@src[1], @block_ial ||= {}) 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 (last_child = @tree.children.last) && last_child.type != :text @src.pos += @src.matched_size attr = {} parse_attribute_list(@src[1], attr) update_ial_with_ial(last_child.options[:ial] ||= {}, attr) update_attr_with_ial(last_child.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-2.4.0/lib/kramdown/parser/kramdown/table.rb0000644000004100000410000001430114234044402022505 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 unless 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 until @src.eos? break unless @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) unless 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.odd? (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 unless 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}/o pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/o) end end @src.revert_pos(saved_pos) and return false unless pipe_on_line add_container.call(has_footer ? :tfoot : :tbody, false) unless rows.empty? if table.children.none? {|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-2.4.0/lib/kramdown/parser/kramdown/smart_quotes.rb0000644000004100000410000001404514234044402024151 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/math.rb0000644000004100000410000000270714234044402022356 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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}\\/o) 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-2.4.0/lib/kramdown/parser/kramdown/eob.rb0000644000004100000410000000102014234044402022155 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/horizontal_rule.rb0000644000004100000410000000123714234044402024642 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/html.rb0000644000004100000410000001451314234044402022367 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 unless 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 unless @tree.type == :html_element && @tree.options[:content_model] == :raw @src.scan(TRAILING_WHITESPACE) end 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 else if @src.check(/^#{OPT_SPACE}#{HTML_TAG_RE}/o) && !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 @src.check(/^#{OPT_SPACE}#{HTML_TAG_CLOSE_RE}/o) && !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_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_value {|value| value.gsub!(/\n+/, ' ') unless value.empty? } do_parsing = if HTML_CONTENT_MODEL[tag_name] == :raw || @tree.options[:content_model] == :raw false else @options[:parse_span_html] end 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-2.4.0/lib/kramdown/parser/kramdown/blockquote.rb0000644000004100000410000000173014234044402023570 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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) until @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-2.4.0/lib/kramdown/parser/kramdown/typographic_symbol.rb0000644000004100000410000000354514234044402025344 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/parser/kramdown/emphasis.rb0000644000004100000410000000352114234044402023231 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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:]]-?[[: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.empty? 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-2.4.0/lib/kramdown/parser/kramdown/link.rb0000644000004100000410000001134014234044402022353 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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] if @link_defs[link_id] warning("Duplicate link ID '#{link_id}' on line #{@src.current_line_number} - overwriting") end @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, _| 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 += (@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.key?(link_id) link_def = @link_defs[link_id] add_link(el, link_def[0], link_def[1], alt_text, link_def[2] && link_def[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-2.4.0/lib/kramdown/version.rb0000644000004100000410000000040514234044402017765 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # This file is part of kramdown which is licensed under the MIT. #++ # module Kramdown # The kramdown version. VERSION = '2.4.0' end kramdown-2.4.0/lib/kramdown/document.rb0000644000004100000410000001165514234044402020127 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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")) unless 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, "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-2.4.0/lib/kramdown/utils/0000755000004100000410000000000014234044402017114 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/utils/configurable.rb0000644000004100000410000000262514234044402022106 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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) unless respond_to?(:configurables) singleton_class.send(:define_method, :configurables) do @_configurables ||= Hash.new {|h, k| h[k] = {} } end end 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-2.4.0/lib/kramdown/utils/entities.rb0000644000004100000410000002012414234044402021264 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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+. Entity = Struct.new(:code_point, :name) do # 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-2.4.0/lib/kramdown/utils/lru_cache.rb0000644000004100000410000000210014234044402021357 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/utils/string_scanner.rb0000644000004100000410000000517214234044402022465 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/utils/unidecoder.rb0000644000004100000410000000234014234044402021561 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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' path = $:.find do |dir| File.directory?(File.join(File.expand_path(dir), "stringex", "unidecoder_data")) end 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[sprintf("x%02x", unpacked >> 8)][unpacked & 255] rescue StandardError "?" end end end end end end end kramdown-2.4.0/lib/kramdown/utils/html.rb0000644000004100000410000000557714234044402020423 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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.key?(c)) c elsif (entity_output == :as_input || entity_output == :as_char) && original original elsif (entity_output == :symbolic || ESCAPE_MAP.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) return '' if attr.empty? attr.map do |k, v| v.nil? || (k == 'id' && v.strip.empty?) ? '' : " #{k}=\"#{escape_html(v.to_s, :attribute)}\"" end.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 REDUNDANT_LINE_BREAK_REGEX = /([\p{Han}\p{Hiragana}\p{Katakana}]+)\n([\p{Han}\p{Hiragana}\p{Katakana}]+)/u def fix_cjk_line_break(str) while str.gsub!(REDUNDANT_LINE_BREAK_REGEX, '\1\2') end str end end end end kramdown-2.4.0/lib/kramdown/converter/0000755000004100000410000000000014234044402017763 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/converter/man.rb0000644000004100000410000002160214234044402021064 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/converter/syntax_highlighter/0000755000004100000410000000000014234044402023667 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/converter/syntax_highlighter/rouge.rb0000644000004100000410000000455414234044402025345 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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] return nil unless lang || opts[:default_lang] || opts[:guess_lang] lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text) return nil if opts[:disable] || !lexer || (lexer.tag == "plaintext" && !opts[:guess_lang]) 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 || {} normalize_keys(span_opts) normalize_keys(block_opts) cache[:span] = opts.merge(span_opts) cache[:span][:wrap] = false cache[:block] = opts.merge(block_opts) end def self.normalize_keys(hash) return if hash.empty? hash.keys.each do |k| hash[k.kind_of?(String) ? Kramdown::Options.str_to_sym(k) : k] = hash.delete(k) end end def self.formatter_class(opts = {}) case formatter = opts[:formatter] when Class formatter when /\A[[:upper:]][[:alnum:]_]*\z/ ::Rouge::Formatters.const_get(formatter, false) 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-2.4.0/lib/kramdown/converter/syntax_highlighter/minted.rb0000644000004100000410000000161614234044402025500 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/converter/base.rb0000644000004100000410000002317114234044402021226 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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] || {}))) if !converter.options[:template].empty? && converter.apply_template_before? apply_template(converter, '') end result = converter.convert(tree) if result.respond_to?(:encode!) && result.encoding != Encoding::BINARY result.encode!(tree.options[:encoding] || (raise ::Kramdown::Error, "Missing encoding option on root element")) end if !converter.options[:template].empty? && converter.apply_template_after? result = apply_template(converter, result) end [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) # :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.empty? @used_ids ||= {} if @used_ids.key?(gen_id) gen_id += "-#{@used_ids[gen_id] += 1}" 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-2.4.0/lib/kramdown/converter/latex.rb0000644000004100000410000004641614234044402021440 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 << (show_whitespace ? "showspaces=true,showtabs=true" : "showspaces=false,showtabs=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.dig(:ial, :refs)&.include?('toc') @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_value {|v| v[0] = "#{v[0]}{}" } 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}\"" }.compact.sort.join('') attrs = " % #{attrs}" unless attrs.empty? attrs end ESCAPE_MAP = { "^" => "\\^{}", "\\" => "\\textbackslash{}", "~" => "\\ensuremath{\\sim}", "|" => "\\textbar{}", "<" => "\\textless{}", ">" => "\\textgreater{}", "[" => "{[}", "]" => "{]}", }.merge(Hash[*("{}$%&_#".each_char.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-2.4.0/lib/kramdown/converter/hash_ast.rb0000644000004100000410000000154014234044402022102 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/converter/toc.rb0000644000004100000410000000352414234044402021101 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 until 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-2.4.0/lib/kramdown/converter/kramdown.rb0000644000004100000410000003552014234044402022137 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 = [] @list_indent = @options[:list_indent] @list_spacing = ' ' * (@list_indent - 2) end def convert(el, opts = {indent: 0}) res = send("convert_#{el.type}", el, opts) res = res.dup if res.frozen? if ![:html_element, :li, :dt, :dd, :td].include?(el.type) && (ial = ial_for_element(el)) res << ial res << "\n\n" if 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 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) do $1 || !opts[:prev] || opts[:prev].type == :br ? "\\#{$1 || $2}" : $& end 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}\\." } second&.gsub!(/^([=-]+\s*?)$/, "\\\1") res = [first, second, *rest].compact.join("\n") + "\n" res.gsub!(/^[ ]{0,3}:/, "\\:") 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 ['* ' + @list_spacing, el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent] 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 = ": " + @list_spacing, (el.children.first && el.children.first.type == :codeblock ? 4 : @list_indent) 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', 'th', 'td'] HTML_ELEMENT_TYPES = [:entity, :text, :html_element].freeze private_constant :HTML_ELEMENT_TYPES 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] || c.children.any? {|t| !HTML_ELEMENT_TYPES.member?(t.type) }) && 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}\"" unless attr.empty? 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" unless @linkrefs.empty? @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}\"" end end.compact.join('') res = "toc" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) && el.options.dig(:ial, :refs)&.include?('toc') res = "footnotes" + (res.strip.empty? ? '' : " #{res}") if (el.type == :ul || el.type == :ol) && el.options.dig(:ial, :refs)&.include?('footnotes') if el.type == :dl && el.options[:ial] && el.options[:ial][:refs] auto_ids = el.options[:ial][:refs].select {|ref| ref.start_with?('auto_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-2.4.0/lib/kramdown/converter/syntax_highlighter.rb0000644000004100000410000000413114234044402024213 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 an 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-2.4.0/lib/kramdown/converter/remove_html_tags.rb0000644000004100000410000000325614234044402023655 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/converter/html.rb0000644000004100000410000004573514234044402021272 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 = [] # stash string representation of symbol to avoid allocations from multiple interpolations. @highlighter_class = " highlighter-#{options[:syntax_highlighter]}" @dispatcher = Hash.new {|h, k| h[k] = :"convert_#{k}" } end # 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) escaped = escape_html(el.value, :text) @options[:remove_line_breaks_for_cjk] ? fix_cjk_line_break(escaped) : escaped end def convert_p(el, indent) if el.options[:transparent] inner(el, indent) elsif el.children.size == 1 && el.children.first.type == :img && el.children.first.options[:ial]&.[](:refs)&.include?('standalone') convert_standalone_image(el, indent) else format_as_block_html("p", el.attr, inner(el, indent), indent) end end # Helper method used by +convert_p+ to convert a paragraph that only contains a single :img # element. def convert_standalone_image(el, indent) figure_attr = el.attr.dup image_attr = el.children.first.attr.dup figure_attr['class'] = image_attr.delete('class') if image_attr.key?('class') and not figure_attr.key?('class') figure_attr['id'] = image_attr.delete('id') if image_attr.key?('id') and not figure_attr.key?('id') body = "#{' ' * (indent + @indent)}\n" \ "#{' ' * (indent + @indent)}
#{image_attr['alt']}
\n" format_as_indented_block_html("figure", figure_attr, body, indent) 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("blockquote", 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 ZERO_TO_ONETWENTYEIGHT = (0..128).to_a.freeze private_constant :ZERO_TO_ONETWENTYEIGHT def convert_ul(el, indent) if !@toc_code && el.options.dig(:ial, :refs)&.include?('toc') @toc_code = [el.type, el.attr, ZERO_TO_ONETWENTYEIGHT.map { rand(36).to_s(36) }.join] @toc_code.last elsif !@footnote_location && el.options.dig(:ial, :refs)&.include?('footnotes') @footnote_location = ZERO_TO_ONETWENTYEIGHT.map { 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("dl", 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}#{basic_generate_id(el.options[:raw_text])}".lstrip break end end if !attr['id'] && @stack.last.options[:ial] && @stack.last.options[:ial][:refs] format_as_block_html("dt", 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 = +'' if @stack.last.type != :html_element || @stack.last.options[:content_model] != :raw output << ' ' * indent end 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.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("a", 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, lang || 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 = '' name = @options[:footnote_prefix] + el.options[:name] if (footnote = @footnotes_by_name[name]) number = footnote[2] repeat = ":#{footnote[3] += 1}" else number = @footnote_counter @footnote_counter += 1 @footnotes << [name, el.value, number, 0] @footnotes_by_name[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.empty? 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_class).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.dup) 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 until 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 if item.children.last.children.empty? end end end until stack.empty? item = stack.pop item.children.pop if item.children.last.children.empty? 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 : sprintf("&#%03d;", b)) end result.force_encoding(text.encoding) result end FOOTNOTE_BACKLINK_FMT = "%s%s" # Return an 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}", 'role' => 'doc-endnote') 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) value = sprintf(FOOTNOTE_BACKLINK_FMT, (insert_space ? nbsp : ''), name, backlink_text) para.children << Element.new(:raw, value) (1..repeat).each do |index| value = sprintf(FOOTNOTE_BACKLINK_FMT, nbsp, "#{name}:#{index}", "#{backlink_text}#{index + 1}") para.children << Element.new(:raw, value) end end ol.children << Element.new(:raw, convert(li, 4)) i += 1 end if ol.children.empty? '' else format_as_indented_block_html('div', {class: "footnotes", role: "doc-endnotes"}, convert(ol, 2), 0) end end end end end kramdown-2.4.0/lib/kramdown/converter/math_engine/0000755000004100000410000000000014234044402022241 5ustar www-datawww-datakramdown-2.4.0/lib/kramdown/converter/math_engine/mathjax.rb0000644000004100000410000000162314234044402024224 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # 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) value = converter.escape_html(el.value) result = el.options[:category] == :block ? "\\[#{value}\\]\n" : "\\(#{value}\\)" if el.attr.empty? result elsif el.options[:category] == :block converter.format_as_block_html('div', el.attr, result, opts[:indent]) else converter.format_as_span_html('span', el.attr, "$#{el.value}$") end end end end kramdown-2.4.0/lib/kramdown/error.rb0000644000004100000410000000064114234044402017433 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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-2.4.0/lib/kramdown/element.rb0000644000004100000410000004065514234044402017744 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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. # # The root of a kramdown element tree has to be an element of type :root. It needs to have certain # option keys set so that conversions work correctly. If only a part of a tree should be # converted, duplicate the root node and assign the #children appropriately, e.g: # # root = doc.root # new_root = root.dup # new_root.children = [root.children[0]] # assign new array with elements to convert # # 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. # # :footnote_count:: This key stores the number of actually referenced footnotes 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, attr, options @children = [] end # The attributes of the element. def attr @attr ||= {} end # The options hash for the element. It is used for storing arbitray options. def options @options ||= {} end def inspect #:nodoc: " # # 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 = {} @cached_defaults = nil # 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.key?(name) raise ArgumentError, "Invalid option type #{type} specified" unless 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) @cached_defaults = nil end # Return all option definitions. def self.definitions @options end # Return +true+ if an option called +name+ is defined. def self.defined?(name) @options.key?(name.to_sym) end # Return a Hash with the default values for all options. def self.defaults @cached_defaults ||= begin temp = {} @options.each {|_n, o| temp[o.name] = o.default } temp.freeze end 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.dup hash.each do |k, v| k = k.to_sym temp[k] = @options.key?(k) ? parse(k, v) : 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" unless @options.key?(name) unless @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.safe_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}" unless Hash === val val end # ---------------------------- # :section: Option Definitions # # This sections contains all option definitions that are used by the included # parsers/converters. # ---------------------------- define(:template, String, '', <<~EOF) The name of an ERB template file that should be used to wrap the output or the ERB template itself. 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. 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 'string://' and if it does, this prefix is removed and the rest is used as template content. kramdown provides a default template named 'document' for each converter. Default: '' Used by: all converters EOF define(:auto_ids, Boolean, true, <<~EOF) Use automatic header ID generation If this option is `true`, ID values for all headers are automatically generated if no ID is explicitly specified. Default: true Used by: HTML/Latex converter EOF define(:auto_id_stripping, Boolean, false, <<~EOF) Strip all formatting from header text for automatic ID generation If this option is `true`, only the text elements of a header are used for generating the ID later (in contrast to just using the raw header text line). This option will be removed in version 2.0 because this will be the default then. Default: false Used by: kramdown parser EOF define(:auto_id_prefix, String, '', <<~EOF) Prefix used for automatically generated header IDs 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! Default: '' Used by: HTML/Latex converter EOF define(:transliterated_header_ids, Boolean, false, <<~EOF) Transliterate the header text before generating the ID 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. The stringex library needs to be installed for this feature to work! Default: false Used by: HTML/Latex converter EOF define(:parse_block_html, Boolean, false, <<~EOF) Process kramdown syntax in block HTML tags If this option is `true`, 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 `false`. It is normally better to selectively enable kramdown processing via the markdown attribute. Default: false Used by: kramdown parser EOF define(:parse_span_html, Boolean, true, <<~EOF) Process kramdown syntax in span HTML tags If this option is `true`, the kramdown parser processes the content of span HTML tags as text containing span-level elements. Default: true Used by: kramdown parser EOF define(:html_to_native, Boolean, false, <<~EOF) Convert HTML elements to native elements If this option is `true`, the parser converts HTML elements to native elements. For example, when parsing `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, {}, <<~EOF) do |val| Pre-defines link definitions 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. If the value is a String, it has to contain a valid YAML hash and the hash has to follow the above guidelines. Default: {} Used by: kramdown parser EOF val = simple_hash_validator(val, :link_defs) val.each do |_k, v| if !(Array === v) || v.size > 2 || v.empty? 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, <<~EOF) The number of the first footnote This option can be used to specify the number that is used for the first footnote. Default: 1 Used by: HTML converter EOF define(:entity_output, Symbol, :as_char, <<~EOF) Defines how entities are output 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). Default: :as_char Used by: HTML converter, kramdown converter EOF TOC_LEVELS_RANGE = (1..6).freeze TOC_LEVELS_ARRAY = TOC_LEVELS_RANGE.to_a.freeze private_constant :TOC_LEVELS_RANGE, :TOC_LEVELS_ARRAY define(:toc_levels, Object, TOC_LEVELS_ARRAY, <<~EOF) do |val| Defines the levels that are used for the table of contents 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. Default: 1..6 Used by: HTML/Latex converter EOF case val when String if val =~ /^(\d)\.\.(\d)$/ val = Range.new($1.to_i, $2.to_i).to_a elsif val =~ /^\d(?:,\d)*$/ val = val.split(/,/).map(&:to_i).uniq else raise Kramdown::Error, "Invalid syntax for option toc_levels" end when Array unless val.eql?(TOC_LEVELS_ARRAY) val = val.map(&:to_i).uniq end when Range if val.eql?(TOC_LEVELS_RANGE) val = TOC_LEVELS_ARRAY else val = val.map(&:to_i).uniq end else raise Kramdown::Error, "Invalid type #{val.class} for option toc_levels" end if val.any? {|i| !TOC_LEVELS_RANGE.cover?(i) } raise Kramdown::Error, "Level numbers for option toc_levels have to be integers from 1 to 6" end val end define(:line_width, Integer, 72, <<~EOF) Defines the line width to be used when outputting a document Default: 72 Used by: kramdown converter EOF define(:latex_headers, Object, %w[section subsection subsubsection paragraph subparagraph subparagraph], <<~EOF) do |val| Defines the LaTeX commands for different header levels The commands for the header levels one to six can be specified by separating them with commas. Default: section,subsection,subsubsection,paragraph,subparagraph,subparagraph Used by: Latex converter EOF simple_array_validator(val, :latex_headers, 6) end SMART_QUOTES_ENTITIES = %w[lsquo rsquo ldquo rdquo].freeze SMART_QUOTES_STR = SMART_QUOTES_ENTITIES.join(',').freeze private_constant :SMART_QUOTES_ENTITIES, :SMART_QUOTES_STR define(:smart_quotes, Object, SMART_QUOTES_ENTITIES, <<~EOF) do |val| Defines the HTML entity names or code points for smart quote output 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. Default: lsquo,rsquo,ldquo,rdquo Used by: HTML/Latex converter EOF if val == SMART_QUOTES_STR || val == SMART_QUOTES_ENTITIES SMART_QUOTES_ENTITIES else val = simple_array_validator(val, :smart_quotes, 4) val.map! {|v| Integer(v) rescue v } val end end define(:typographic_symbols, Object, {}, <<~EOF) do |val| Defines a mapping from typographical symbol to output characters 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. 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. The available typographical symbol names are: * hellip: ellipsis * mdash: em-dash * ndash: en-dash * laquo: left guillemet * raquo: right guillemet * laquo_space: left guillemet followed by a space * raquo_space: right guillemet preceeded by a space Default: {} Used by: HTML/Latex converter EOF val = simple_hash_validator(val, :typographic_symbols) val.keys.each do |k| val[k.kind_of?(String) ? str_to_sym(k) : k] = val.delete(k).to_s end val end define(:remove_block_html_tags, Boolean, true, <<~EOF) Remove block HTML tags If this option is `true`, the RemoveHtmlTags converter removes block HTML tags. Default: true Used by: RemoveHtmlTags converter EOF define(:remove_span_html_tags, Boolean, false, <<~EOF) Remove span HTML tags If this option is `true`, the RemoveHtmlTags converter removes span HTML tags. Default: false Used by: RemoveHtmlTags converter EOF define(:header_offset, Integer, 0, <<~EOF) Sets the output offset for headers 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. Default: 0 Used by: HTML converter, Kramdown converter, Latex converter EOF define(:syntax_highlighter, Symbol, :rouge, <<~EOF) Set the syntax highlighter 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. Options for the syntax highlighter can be set with the syntax_highlighter_opts configuration option. Default: rouge Used by: HTML/Latex converter EOF define(:syntax_highlighter_opts, Object, {}, <<~EOF) do |val| Set the syntax highlighter options Specifies options for the syntax highlighter set via the syntax_highlighter configuration option. The value needs to be a hash with key-value pairs that are understood by the used syntax highlighter. Default: {} Used by: HTML/Latex converter EOF val = simple_hash_validator(val, :syntax_highlighter_opts) val.keys.each do |k| val[k.kind_of?(String) ? str_to_sym(k) : k] = val.delete(k) end val end define(:math_engine, Symbol, :mathjax, <<~EOF) Set the math engine 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. Options for the selected math engine can be set with the math_engine_opts configuration option. Default: mathjax Used by: HTML converter EOF define(:math_engine_opts, Object, {}, <<~EOF) do |val| Set the math engine options Specifies options for the math engine set via the math_engine configuration option. The value needs to be a hash with key-value pairs that are understood by the used math engine. Default: {} Used by: HTML converter EOF val = simple_hash_validator(val, :math_engine_opts) val.keys.each do |k| val[k.kind_of?(String) ? str_to_sym(k) : k] = val.delete(k) end val end define(:footnote_backlink, String, '↩', <<~EOF) Defines the text that should be used for the footnote backlinks The footnote backlink is just text, so any special HTML characters will be escaped. If the footnote backlint text is an empty string, no footnote backlinks will be generated. Default: '&8617;' Used by: HTML converter EOF define(:footnote_backlink_inline, Boolean, false, <<~EOF) Specifies whether the footnote backlink should always be inline 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. 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. Default: false Used by: HTML converter EOF define(:footnote_prefix, String, '', <<~EOF) Prefix used for footnote IDs This option can be used to set a prefix for footnote IDs. This is useful when rendering multiple documents into the same output file to avoid duplicate IDs. The prefix should only contain characters that are valid in an ID! Default: '' Used by: HTML EOF define(:remove_line_breaks_for_cjk, Boolean, false, <<~EOF) Specifies whether line breaks should be removed between CJK characters Default: false Used by: HTML converter EOF define(:forbidden_inline_options, Object, %w[template], <<~EOF) do |val| Defines the options that may not be set using the {::options} extension The value needs to be an array of option names. Default: [template] Used by: HTML converter EOF val.map! {|item| item.kind_of?(String) ? str_to_sym(item) : item } simple_array_validator(val, :forbidden_inline_options) end define(:list_indent, Integer, 2, <<~EOF) Sets the number of spaces to use for list indentation Default: 2 Used by: Kramdown converter EOF end end kramdown-2.4.0/lib/kramdown/parser.rb0000644000004100000410000000132414234044402017575 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 Thomas Leitner # # 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' end end kramdown-2.4.0/lib/kramdown/converter.rb0000644000004100000410000000461614234044402020317 0ustar www-datawww-data# -*- coding: utf-8; frozen_string_literal: true -*- # #-- # Copyright (C) 2009-2019 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 :HashAST, 'kramdown/converter/hash_ast' autoload :HashAst, 'kramdown/converter/hash_ast' autoload :Man, 'kramdown/converter/man' extend ::Kramdown::Utils::Configurable configurable(:syntax_highlighter) ['Minted', "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) { nil } end syntax_highlighter(kn_down).call(converter, text, lang, type, opts) end end configurable(:math_engine) ["Mathjax"].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) { nil } end math_engine(kn_down).call(converter, el, opts) end end end end kramdown-2.4.0/VERSION0000644000004100000410000000000614234044402014430 0ustar www-datawww-data2.4.0 kramdown-2.4.0/kramdown.gemspec0000644000004100000410000010350714234044402016561 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: kramdown 2.4.0 ruby lib Gem::Specification.new do |s| s.name = "kramdown".freeze s.version = "2.4.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 = "2022-04-25" 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, "VERSION".freeze, "bin/kramdown".freeze, "data/kramdown/document.html".freeze, "data/kramdown/document.latex".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/mathjax.rb".freeze, "lib/kramdown/converter/remove_html_tags.rb".freeze, "lib/kramdown/converter/syntax_highlighter.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/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/string_scanner.rb".freeze, "lib/kramdown/utils/unidecoder.rb".freeze, "lib/kramdown/version.rb".freeze, "man/man1/kramdown.1".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/standalone_image.html".freeze, "test/testcases/block/03_paragraph/standalone_image.text".freeze, "test/testcases/block/03_paragraph/to_kramdown.kramdown".freeze, "test/testcases/block/03_paragraph/to_kramdown.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/guess_lang_css_class.html".freeze, "test/testcases/block/06_codeblock/guess_lang_css_class.options".freeze, "test/testcases/block/06_codeblock/guess_lang_css_class.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.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.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.options".freeze, "test/testcases/block/09_html/simple.text".freeze, "test/testcases/block/09_html/standalone_image_in_div.htmlinput".freeze, "test/testcases/block/09_html/standalone_image_in_div.text".freeze, "test/testcases/block/09_html/table.kramdown".freeze, "test/testcases/block/09_html/table.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/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/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/cjk-line-break.html".freeze, "test/testcases/cjk-line-break.options".freeze, "test/testcases/cjk-line-break.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.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.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-css-class.html".freeze, "test/testcases/span/03_codespan/normal-css-class.options".freeze, "test/testcases/span/03_codespan/normal-css-class.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/footnote_prefix.html".freeze, "test/testcases/span/04_footnote/footnote_prefix.options".freeze, "test/testcases/span/04_footnote/footnote_prefix.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/abbrev_in_html.html".freeze, "test/testcases/span/abbreviations/abbrev_in_html.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/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/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.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] 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.3".freeze) s.rubygems_version = "3.2.5".freeze s.summary = "kramdown is a fast, pure-Ruby Markdown-superset converter.".freeze if s.respond_to? :specification_version then s.specification_version = 4 end if s.respond_to? :add_runtime_dependency then s.add_development_dependency(%q.freeze, ["~> 5.0"]) s.add_runtime_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, ["~> 3.0", ">= 3.26.0"]) s.add_development_dependency(%q.freeze, ["~> 1.5.1"]) else s.add_dependency(%q.freeze, ["~> 5.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["~> 3.0", ">= 3.26.0"]) s.add_dependency(%q.freeze, ["~> 1.5.1"]) end end