motion-kramdown 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +84 -0
- data/lib/kramdown/compatibility.rb +36 -0
- data/lib/kramdown/converter/base.rb +259 -0
- data/lib/kramdown/converter/html.rb +461 -0
- data/lib/kramdown/converter/kramdown.rb +423 -0
- data/lib/kramdown/converter/latex.rb +600 -0
- data/lib/kramdown/converter/math_engine/itex2mml.rb +39 -0
- data/lib/kramdown/converter/math_engine/mathjax.rb +33 -0
- data/lib/kramdown/converter/math_engine/ritex.rb +38 -0
- data/lib/kramdown/converter/pdf.rb +624 -0
- data/lib/kramdown/converter/remove_html_tags.rb +53 -0
- data/lib/kramdown/converter/syntax_highlighter/coderay.rb +78 -0
- data/lib/kramdown/converter/syntax_highlighter/rouge.rb +37 -0
- data/lib/kramdown/converter/toc.rb +69 -0
- data/lib/kramdown/converter.rb +69 -0
- data/lib/kramdown/document.rb +144 -0
- data/lib/kramdown/element.rb +515 -0
- data/lib/kramdown/error.rb +17 -0
- data/lib/kramdown/options.rb +584 -0
- data/lib/kramdown/parser/base.rb +130 -0
- data/lib/kramdown/parser/gfm.rb +55 -0
- data/lib/kramdown/parser/html.rb +575 -0
- data/lib/kramdown/parser/kramdown/abbreviation.rb +67 -0
- data/lib/kramdown/parser/kramdown/autolink.rb +37 -0
- data/lib/kramdown/parser/kramdown/blank_line.rb +30 -0
- data/lib/kramdown/parser/kramdown/block_boundary.rb +33 -0
- data/lib/kramdown/parser/kramdown/blockquote.rb +39 -0
- data/lib/kramdown/parser/kramdown/codeblock.rb +56 -0
- data/lib/kramdown/parser/kramdown/codespan.rb +44 -0
- data/lib/kramdown/parser/kramdown/emphasis.rb +61 -0
- data/lib/kramdown/parser/kramdown/eob.rb +26 -0
- data/lib/kramdown/parser/kramdown/escaped_chars.rb +25 -0
- data/lib/kramdown/parser/kramdown/extensions.rb +201 -0
- data/lib/kramdown/parser/kramdown/footnote.rb +56 -0
- data/lib/kramdown/parser/kramdown/header.rb +59 -0
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +27 -0
- data/lib/kramdown/parser/kramdown/html.rb +160 -0
- data/lib/kramdown/parser/kramdown/html_entity.rb +33 -0
- data/lib/kramdown/parser/kramdown/line_break.rb +25 -0
- data/lib/kramdown/parser/kramdown/link.rb +139 -0
- data/lib/kramdown/parser/kramdown/list.rb +256 -0
- data/lib/kramdown/parser/kramdown/math.rb +54 -0
- data/lib/kramdown/parser/kramdown/paragraph.rb +54 -0
- data/lib/kramdown/parser/kramdown/smart_quotes.rb +174 -0
- data/lib/kramdown/parser/kramdown/table.rb +171 -0
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +44 -0
- data/lib/kramdown/parser/kramdown.rb +359 -0
- data/lib/kramdown/parser/markdown.rb +56 -0
- data/lib/kramdown/parser.rb +27 -0
- data/lib/kramdown/utils/configurable.rb +44 -0
- data/lib/kramdown/utils/entities.rb +347 -0
- data/lib/kramdown/utils/html.rb +75 -0
- data/lib/kramdown/utils/ordered_hash.rb +87 -0
- data/lib/kramdown/utils/string_scanner.rb +74 -0
- data/lib/kramdown/utils/unidecoder.rb +51 -0
- data/lib/kramdown/utils.rb +58 -0
- data/lib/kramdown/version.rb +15 -0
- data/lib/kramdown.rb +10 -0
- data/lib/motion-kramdown.rb +47 -0
- data/lib/rubymotion/encodings.rb +37 -0
- data/lib/rubymotion/rexml_shim.rb +25 -0
- data/lib/rubymotion/set.rb +1349 -0
- data/lib/rubymotion/version.rb +6 -0
- data/spec/document_tree.rb +48 -0
- data/spec/gfm_to_html.rb +95 -0
- data/spec/helpers/it_behaves_like.rb +27 -0
- data/spec/helpers/option_file.rb +46 -0
- data/spec/helpers/spec_options.rb +37 -0
- data/spec/helpers/tidy.rb +12 -0
- data/spec/html_to_html.rb +40 -0
- data/spec/html_to_kramdown_to_html.rb +46 -0
- data/spec/kramdown_to_xxx.rb +40 -0
- data/spec/test_location.rb +203 -0
- data/spec/test_string_scanner_kramdown.rb +19 -0
- data/spec/text_to_kramdown_to_html.rb +52 -0
- data/spec/text_to_latex.rb +33 -0
- metadata +164 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
describe "asserting that converters don't modify the document tree" do
|
2
|
+
|
3
|
+
EXCLUDE_TREE_FILES = [
|
4
|
+
'test/testcases/block/15_math/gh_128.text', # bc no math support yet
|
5
|
+
'test/testcases/block/15_math/itex2mml.text', # bc no math support yet
|
6
|
+
'test/testcases/block/15_math/normal.text', # bc no math support yet
|
7
|
+
'test/testcases/block/15_math/ritex.text', # bc no math support yet
|
8
|
+
'test/testcases/span/math/normal.text', # bc no math support yet
|
9
|
+
'test/testcases/span/math/ritex.text', # bc no math support yet
|
10
|
+
'test/testcases/span/math/itex2mml.text', # bc no math support yet
|
11
|
+
]
|
12
|
+
|
13
|
+
Dir["#{focus_files(testcase_dir)}.text"].each do |text_file|
|
14
|
+
next if EXCLUDE_TREE_FILES.any? {|f| text_file =~ /#{f}$/}
|
15
|
+
opts_file = text_file.sub(/\.text$/, '.options')
|
16
|
+
options = load_options(opts_file)
|
17
|
+
|
18
|
+
(Kramdown::Converter.constants(true).map {|c| c.to_sym} - [:Latex, :Base, :RemoveHtmlTags, :MathEngine, :SyntaxHighlighter]).each do |conv_class|
|
19
|
+
next if conv_class == :Pdf && RUBY_VERSION < '1.9'
|
20
|
+
|
21
|
+
it "#{short_name(text_file)} --> #{conv_class} modifies tree with file?" do
|
22
|
+
options = load_options(opts_file)
|
23
|
+
doc = Kramdown::Document.new(File.read(text_file), options)
|
24
|
+
options_before = Marshal.load(Marshal.dump(doc.options))
|
25
|
+
tree_before = Marshal.load(Marshal.dump(doc.root))
|
26
|
+
Kramdown::Converter.const_get(conv_class).convert(doc.root, doc.options)
|
27
|
+
expect(options_before).to eq doc.options
|
28
|
+
assert_tree_not_changed(tree_before, doc.root)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_tree_not_changed(oldtree, newtree)
|
34
|
+
expect(oldtree.type).to eq newtree.type # type mismatch
|
35
|
+
if oldtree.value.kind_of?(Kramdown::Element)
|
36
|
+
assert_tree_not_changed(oldtree.value, newtree.value)
|
37
|
+
else
|
38
|
+
expect(oldtree.value).to eq newtree.value # value mismatch
|
39
|
+
end
|
40
|
+
expect(oldtree.attr).to eq newtree.attr # attr mismatch
|
41
|
+
# TODO bug in the Marshaling the options - expect(oldtree.options).to eq newtree.options # options mismatch
|
42
|
+
expect(oldtree.children.length).to eq newtree.children.length # children count mismatch
|
43
|
+
|
44
|
+
oldtree.children.each_with_index do |child, index|
|
45
|
+
assert_tree_not_changed(child, newtree.children[index])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/gfm_to_html.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
describe "gfm-to-html conversion" do
|
2
|
+
|
3
|
+
EXCLUDE_GFM_FILES = [
|
4
|
+
'test/testcases/block/03_paragraph/no_newline_at_end.text',
|
5
|
+
'test/testcases/block/03_paragraph/indented.text',
|
6
|
+
'test/testcases/block/03_paragraph/two_para.text',
|
7
|
+
'test/testcases/block/04_header/atx_header.text',
|
8
|
+
'test/testcases/block/04_header/setext_header.text',
|
9
|
+
'test/testcases/block/05_blockquote/indented.text',
|
10
|
+
'test/testcases/block/05_blockquote/lazy.text',
|
11
|
+
'test/testcases/block/05_blockquote/nested.text',
|
12
|
+
'test/testcases/block/05_blockquote/no_newline_at_end.text',
|
13
|
+
'test/testcases/block/06_codeblock/error.text',
|
14
|
+
'test/testcases/block/07_horizontal_rule/error.text',
|
15
|
+
'test/testcases/block/08_list/escaping.text',
|
16
|
+
'test/testcases/block/08_list/item_ial.text',
|
17
|
+
'test/testcases/block/08_list/lazy.text',
|
18
|
+
'test/testcases/block/08_list/list_and_others.text',
|
19
|
+
'test/testcases/block/08_list/other_first_element.text',
|
20
|
+
'test/testcases/block/08_list/simple_ul.text',
|
21
|
+
'test/testcases/block/08_list/special_cases.text',
|
22
|
+
'test/testcases/block/09_html/comment.text',
|
23
|
+
'test/testcases/block/09_html/html_to_native/code.text',
|
24
|
+
'test/testcases/block/09_html/html_to_native/emphasis.text',
|
25
|
+
'test/testcases/block/09_html/html_to_native/typography.text',
|
26
|
+
'test/testcases/block/09_html/parse_as_raw.text',
|
27
|
+
'test/testcases/block/09_html/simple.text',
|
28
|
+
'test/testcases/block/12_extension/comment.text',
|
29
|
+
'test/testcases/block/12_extension/ignored.text',
|
30
|
+
'test/testcases/block/12_extension/nomarkdown.text',
|
31
|
+
'test/testcases/block/13_definition_list/item_ial.text',
|
32
|
+
'test/testcases/block/13_definition_list/multiple_terms.text',
|
33
|
+
'test/testcases/block/13_definition_list/no_def_list.text',
|
34
|
+
'test/testcases/block/13_definition_list/simple.text',
|
35
|
+
'test/testcases/block/13_definition_list/with_blocks.text',
|
36
|
+
'test/testcases/block/14_table/errors.text',
|
37
|
+
'test/testcases/block/14_table/escaping.text',
|
38
|
+
'test/testcases/block/14_table/simple.text',
|
39
|
+
'test/testcases/block/15_math/normal.text',
|
40
|
+
'test/testcases/encoding.text',
|
41
|
+
'test/testcases/span/01_link/inline.text',
|
42
|
+
'test/testcases/span/01_link/link_defs.text',
|
43
|
+
'test/testcases/span/01_link/reference.text',
|
44
|
+
'test/testcases/span/02_emphasis/normal.text',
|
45
|
+
'test/testcases/span/03_codespan/normal.text',
|
46
|
+
'test/testcases/span/04_footnote/definitions.text',
|
47
|
+
'test/testcases/span/04_footnote/markers.text',
|
48
|
+
'test/testcases/span/05_html/across_lines.text',
|
49
|
+
'test/testcases/span/05_html/markdown_attr.text',
|
50
|
+
'test/testcases/span/05_html/normal.text',
|
51
|
+
'test/testcases/span/05_html/raw_span_elements.text',
|
52
|
+
'test/testcases/span/autolinks/url_links.text',
|
53
|
+
'test/testcases/span/extension/comment.text',
|
54
|
+
'test/testcases/span/ial/simple.text',
|
55
|
+
'test/testcases/span/line_breaks/normal.text',
|
56
|
+
'test/testcases/span/text_substitutions/entities_as_char.text',
|
57
|
+
'test/testcases/span/text_substitutions/entities.text',
|
58
|
+
'test/testcases/span/text_substitutions/typography.text',
|
59
|
+
('test/testcases/span/03_codespan/highlighting-rouge.text' if RUBY_VERSION < '2.0'),
|
60
|
+
('test/testcases/block/06_codeblock/highlighting-rouge.text' if RUBY_VERSION < '2.0'), #bc of rouge
|
61
|
+
|
62
|
+
'test/testcases/block/04_header/with_auto_ids.text', # bc no transliteration support yet
|
63
|
+
'test/testcases/block/06_codeblock/highlighting-opts.text', # bc no highlight support yet
|
64
|
+
'test/testcases/block/06_codeblock/highlighting.text', # bc no highlight support yet
|
65
|
+
'test/testcases/block/12_extension/options3.text', # bc no highlight support yet
|
66
|
+
'test/testcases/block/15_math/gh_128.text', # bc no math support yet
|
67
|
+
'test/testcases/block/15_math/itex2mml.text', # bc no math support yet
|
68
|
+
'test/testcases/block/15_math/normal.text', # bc no math support yet
|
69
|
+
'test/testcases/block/15_math/ritex.text', # bc no math support yet
|
70
|
+
'test/testcases/span/math/itex2mml.text', # bc no math support yet
|
71
|
+
'test/testcases/span/math/normal.text', # bc no math support yet
|
72
|
+
'test/testcases/span/math/ritex.text', # bc no math support yet
|
73
|
+
'test/testcases/span/03_codespan/highlighting-rouge.text', # bc no highlight support yet
|
74
|
+
'test/testcases/span/03_codespan/highlighting.text', # bc no highlight support yet
|
75
|
+
'test/testcases_gfm/backticks_syntax.text', # bc no highlight support yet
|
76
|
+
]
|
77
|
+
|
78
|
+
['testcases', 'testcases_gfm'].each do |item|
|
79
|
+
Dir["#{focus_files(testcase_dir(item))}.text"].each do |text_file|
|
80
|
+
next if EXCLUDE_GFM_FILES.any? {|f| text_file =~ /#{f}$/}
|
81
|
+
basename = text_file.sub(/\.text$/, '')
|
82
|
+
opts_file = basename + '.options'
|
83
|
+
|
84
|
+
html_file = [(".html.19" if RUBY_VERSION >= '1.9'), ".html"].compact.
|
85
|
+
map {|ext| basename + ext }.
|
86
|
+
detect {|file| File.exist?(file) }
|
87
|
+
|
88
|
+
it "gfm #{short_name(text_file)} --> html" do
|
89
|
+
options = load_options(opts_file)
|
90
|
+
doc = Kramdown::Document.new(File.read(text_file), options.merge(:input => 'GFM'))
|
91
|
+
expect(File.read(html_file)).to eq doc.to_html
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
def it_behaves_like(name, method = nil)
|
3
|
+
@method = method
|
4
|
+
behaves_like(name)
|
5
|
+
end
|
6
|
+
|
7
|
+
class Should
|
8
|
+
|
9
|
+
# usage: .should.be_true and .should.be_false
|
10
|
+
#------------------------------------------------------------------------------
|
11
|
+
def be_true
|
12
|
+
self == true
|
13
|
+
end
|
14
|
+
|
15
|
+
def be_false
|
16
|
+
self == false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# usage: .should.be truthy and .should.be falsey
|
21
|
+
#------------------------------------------------------------------------------
|
22
|
+
def truthy
|
23
|
+
lambda { |obj| obj == true }
|
24
|
+
end
|
25
|
+
def falsey
|
26
|
+
lambda { |obj| obj == false }
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
def testcase_dir(dir = 'testcases')
|
3
|
+
File.join(File.dirname(__FILE__), '../../test', dir)
|
4
|
+
end
|
5
|
+
|
6
|
+
#------------------------------------------------------------------------------
|
7
|
+
def focus_files(dir)
|
8
|
+
focus = ENV["focus"] ? File.join(dir, ENV["focus"]) : dir
|
9
|
+
File.directory?(focus) ? File.join(focus, '**/*') : "#{focus}"
|
10
|
+
end
|
11
|
+
|
12
|
+
#------------------------------------------------------------------------------
|
13
|
+
def load_options(opts_file)
|
14
|
+
opts_file = File.join(File.dirname(opts_file), 'options') if !File.exist?(opts_file)
|
15
|
+
options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {:auto_ids => false, :footnote_nr => 1}
|
16
|
+
|
17
|
+
# change {":autoids" => false} to {:autoids => false}
|
18
|
+
options.tap do |o|
|
19
|
+
o.keys.each { |k| o[(k.to_s[0] == ':' ? k[1..-1] : k).to_sym] = o.delete(k) }
|
20
|
+
end
|
21
|
+
|
22
|
+
# YAML isn't hanldling integers correctly, is giving doubles instead
|
23
|
+
options[:header_offset] = options[:header_offset].to_int if options[:header_offset]
|
24
|
+
options[:footnote_nr] = options[:footnote_nr].to_int if options[:footnote_nr]
|
25
|
+
options
|
26
|
+
end
|
27
|
+
|
28
|
+
#------------------------------------------------------------------------------
|
29
|
+
def short_name(text_file)
|
30
|
+
text_file.split(File.join(File.dirname(__FILE__), '../../test') + '/').last
|
31
|
+
end
|
32
|
+
|
33
|
+
#------------------------------------------------------------------------------
|
34
|
+
def convert_to_format(file)
|
35
|
+
File.extname(file.sub(/\.19$/, ''))[1..-1]
|
36
|
+
end
|
37
|
+
|
38
|
+
#------------------------------------------------------------------------------
|
39
|
+
def converter_supported?(format)
|
40
|
+
Kramdown::Converter.const_defined?(format[0..0].upcase + format[1..-1])
|
41
|
+
end
|
42
|
+
|
43
|
+
#------------------------------------------------------------------------------
|
44
|
+
def skip_file_ruby_19?(file)
|
45
|
+
(RUBY_VERSION >= '1.9' && File.exist?(file + '.19')) || (RUBY_VERSION < '1.9' && file =~ /\.19$/)
|
46
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Add following abilities
|
2
|
+
#
|
3
|
+
# rake spec filter="name of spec" # To filter by spec name
|
4
|
+
# rake spec files=foo_spec filter="name of spec"
|
5
|
+
# rake spec filter_context="this doesn't work yet" # To filter by context name (doesn't work until MacBacon implements it)
|
6
|
+
# rake spec hide_backtraces=yes # Hide backtraces
|
7
|
+
# rake spec focus=block/03_paragraph # Focus on only certain testcase files
|
8
|
+
|
9
|
+
|
10
|
+
# From http://chen.do/blog/2013/06/03/running-individual-specs-with-rubymotion/
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
def silence_warnings(&block)
|
13
|
+
warn_level = $VERBOSE
|
14
|
+
$VERBOSE = nil
|
15
|
+
begin
|
16
|
+
result = block.call
|
17
|
+
ensure
|
18
|
+
$VERBOSE = warn_level
|
19
|
+
end
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
silence_warnings do
|
24
|
+
module Bacon
|
25
|
+
if ENV['filter']
|
26
|
+
$stderr.puts "Filtering specs that match: #{ENV['filter']}"
|
27
|
+
RestrictName = Regexp.new(ENV['filter'])
|
28
|
+
end
|
29
|
+
|
30
|
+
if ENV['filter_context']
|
31
|
+
$stderr.puts "Filtering contexts that match: #{ENV['filter_context']}"
|
32
|
+
RestrictContext = Regexp.new(ENV['filter_context'])
|
33
|
+
end
|
34
|
+
|
35
|
+
Backtraces = false if ENV['hide_backtraces']
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
def tidy_output(out)
|
2
|
+
cmd = "tidy -q --doctype omit #{RUBY_VERSION >= '1.9' ? '-utf8' : '-raw'} 2>/dev/null"
|
3
|
+
result = IO.popen(cmd, 'r+') do |io|
|
4
|
+
io.write(out)
|
5
|
+
io.close_write
|
6
|
+
io.read
|
7
|
+
end
|
8
|
+
if $?.exitstatus == 2
|
9
|
+
raise "Problem using tidy"
|
10
|
+
end
|
11
|
+
result
|
12
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
describe "html-to-html conversion" do
|
2
|
+
|
3
|
+
`tidy -v 2>&1`
|
4
|
+
if $?.exitstatus != 0
|
5
|
+
warn("Skipping html-to-html tests because tidy executable is missing")
|
6
|
+
else
|
7
|
+
EXCLUDE_HTML_FILES = [
|
8
|
+
'test/testcases/block/06_codeblock/whitespace.html', # bc of span inside pre
|
9
|
+
'test/testcases/block/09_html/simple.html', # bc of xml elements
|
10
|
+
'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element
|
11
|
+
'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option
|
12
|
+
'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option
|
13
|
+
'test/testcases/block/06_codeblock/highlighting-rouge.html', # bc of double surrounding <div>
|
14
|
+
('test/testcases/span/03_codespan/highlighting-rouge.html' if RUBY_VERSION < '2.0'),
|
15
|
+
'test/testcases/block/15_math/ritex.html', # bc of tidy
|
16
|
+
'test/testcases/span/math/ritex.html', # bc of tidy
|
17
|
+
'test/testcases/block/15_math/itex2mml.html', # bc of tidy
|
18
|
+
'test/testcases/span/math/itex2mml.html', # bc of tidy
|
19
|
+
|
20
|
+
'test/testcases/block/15_math/gh_128.html', # bc no math support yet
|
21
|
+
'test/testcases/block/15_math/normal.html', # bc no math support yet
|
22
|
+
'test/testcases/span/math/normal.html', # bc no math support yet
|
23
|
+
]
|
24
|
+
|
25
|
+
Dir["#{focus_files(testcase_dir)}.{html,html.19,htmlinput,htmlinput.19}"].each do |html_file|
|
26
|
+
next if EXCLUDE_HTML_FILES.any? {|f| html_file =~ /#{f}(\.19)?$/}
|
27
|
+
next if skip_file_ruby_19?(html_file)
|
28
|
+
|
29
|
+
out_file = (html_file =~ /\.htmlinput(\.19)?$/ ? html_file.sub(/input(\.19)?$/, '') : html_file)
|
30
|
+
opts_file = html_file.sub(/\.html(input)?(\.19)?$/, '.options')
|
31
|
+
|
32
|
+
it "#{short_name(html_file)} --> html" do
|
33
|
+
options = load_options(opts_file)
|
34
|
+
doc = Kramdown::Document.new(File.read(html_file), options.merge(:input => 'html'))
|
35
|
+
expect(tidy_output(File.read(out_file))).to eq tidy_output(doc.to_html)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
describe "html-to-kramdown-to-html conversion" do
|
2
|
+
|
3
|
+
`tidy -v 2>&1`
|
4
|
+
if $?.exitstatus != 0
|
5
|
+
warn("Skipping html-to-kramdown-to-html tests because tidy executable is missing")
|
6
|
+
else
|
7
|
+
EXCLUDE_HTML_KD_FILES = [
|
8
|
+
'test/testcases/span/extension/options.html', # bc of parse_span_html option
|
9
|
+
'test/testcases/span/05_html/normal.html', # bc of br tag before closing p tag
|
10
|
+
'test/testcases/block/12_extension/nomarkdown.html', # bc of nomarkdown extension
|
11
|
+
'test/testcases/block/09_html/simple.html', # bc of webgen:block elements
|
12
|
+
'test/testcases/block/09_html/markdown_attr.html', # bc of markdown attr
|
13
|
+
'test/testcases/block/09_html/html_to_native/table_simple.html', # bc of invalidly converted simple table
|
14
|
+
'test/testcases/block/06_codeblock/whitespace.html', # bc of entity to char conversion
|
15
|
+
'test/testcases/block/06_codeblock/highlighting-rouge.html', # bc of double surrounding <div>
|
16
|
+
'test/testcases/block/11_ial/simple.html', # bc of change of ordering of attributes in header
|
17
|
+
'test/testcases/span/03_codespan/highlighting.html', # bc of span elements inside code element
|
18
|
+
'test/testcases/block/04_header/with_auto_ids.html', # bc of auto_ids=true option
|
19
|
+
'test/testcases/block/04_header/header_type_offset.html', # bc of header_offset option
|
20
|
+
'test/testcases/block/16_toc/toc_exclude.html', # bc of different attribute ordering
|
21
|
+
'test/testcases/span/autolinks/url_links.html', # bc of quot entity being converted to char
|
22
|
+
('test/testcases/span/03_codespan/highlighting-rouge.html' if RUBY_VERSION < '2.0'),
|
23
|
+
'test/testcases/block/15_math/ritex.html', # bc of tidy
|
24
|
+
'test/testcases/span/math/ritex.html', # bc of tidy
|
25
|
+
'test/testcases/block/15_math/itex2mml.html', # bc of tidy
|
26
|
+
'test/testcases/span/math/itex2mml.html', # bc of tidy
|
27
|
+
|
28
|
+
'testcases/block/15_math/gh_128.html', # bc no math support yet
|
29
|
+
'test/testcases/block/15_math/normal.html', # bc no math support yet
|
30
|
+
'test/testcases/span/math/normal.html', # bc no math support yet
|
31
|
+
]
|
32
|
+
|
33
|
+
Dir["#{focus_files(testcase_dir)}.{html,html.19}"].each do |html_file|
|
34
|
+
next if EXCLUDE_HTML_KD_FILES.any? {|f| html_file =~ /#{f}(\.19)?$/}
|
35
|
+
next if skip_file_ruby_19?(html_file)
|
36
|
+
opts_file = html_file.sub(/\.html(\.19)?$/, '.options')
|
37
|
+
|
38
|
+
it "#{short_name(html_file)} --> kramdown --> html" do
|
39
|
+
kd = Kramdown::Document.new(File.read(html_file), :input => 'html', :auto_ids => false, :footnote_nr => 1).to_kramdown
|
40
|
+
options = load_options(opts_file)
|
41
|
+
doc = Kramdown::Document.new(kd, options)
|
42
|
+
expect(tidy_output(File.read(html_file))).to eq tidy_output(doc.to_html)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
describe "kramdown-to-xxx conversion" do
|
2
|
+
|
3
|
+
EXCLUDE_FILES = [
|
4
|
+
'test/testcases/block/04_header/with_auto_ids.text', # bc no transliteration support yet
|
5
|
+
'test/testcases/block/06_codeblock/highlighting-opts.text', # bc no highlight support yet
|
6
|
+
'test/testcases/block/06_codeblock/highlighting-rouge.text', # bc no highlight support yet
|
7
|
+
'test/testcases/block/06_codeblock/highlighting.text', # bc no highlight support yet
|
8
|
+
'test/testcases/block/12_extension/options3.text', # bc no highlight support yet
|
9
|
+
'test/testcases/block/15_math/gh_128.text', # bc no math support yet
|
10
|
+
'test/testcases/block/15_math/itex2mml.text', # bc no math support yet
|
11
|
+
'test/testcases/block/15_math/normal.text', # bc no math support yet
|
12
|
+
'test/testcases/block/15_math/ritex.text', # bc no math support yet
|
13
|
+
'test/testcases/span/math/itex2mml.text', # bc no math support yet
|
14
|
+
'test/testcases/span/math/normal.text', # bc no math support yet
|
15
|
+
'test/testcases/span/math/ritex.text', # bc no math support yet
|
16
|
+
'test/testcases/span/03_codespan/highlighting-rouge.text', # bc no highlight support yet
|
17
|
+
'test/testcases/span/03_codespan/highlighting.text', # bc no highlight support yet
|
18
|
+
]
|
19
|
+
|
20
|
+
Dir["#{focus_files(testcase_dir)}.text"].each do |text_file|
|
21
|
+
next if EXCLUDE_FILES.any? {|f| text_file =~ /#{f}$/}
|
22
|
+
base_name = text_file.sub(/\.text$/, '')
|
23
|
+
html_file = text_file.sub('.text', '.html')
|
24
|
+
opts_file = text_file.sub(/\.text$/, '.options')
|
25
|
+
|
26
|
+
(Dir[base_name + ".*"] - [text_file, opts_file]).each do |output_file|
|
27
|
+
output_format = convert_to_format(output_file)
|
28
|
+
next unless converter_supported?(output_format)
|
29
|
+
next if skip_file_ruby_19?(output_file)
|
30
|
+
|
31
|
+
it "#{short_name(text_file)} --> #{output_format}" do
|
32
|
+
options = load_options(opts_file)
|
33
|
+
doc = Kramdown::Document.new(File.read(text_file), options)
|
34
|
+
expect(doc.send("to_#{output_format}")).to eq File.read(output_file)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9'
|
4
|
+
|
5
|
+
describe 'location' do
|
6
|
+
|
7
|
+
# checks that +element+'s :location option corresponds to the location stored
|
8
|
+
# in the element.attr['class']
|
9
|
+
def check_element_for_location(element)
|
10
|
+
if (match = /^line-(\d+)/.match(element.attr['class'] || ''))
|
11
|
+
expected_line = match[1].to_i
|
12
|
+
element.options[:location].should.equal(expected_line)
|
13
|
+
end
|
14
|
+
element.children.each do |child|
|
15
|
+
check_element_for_location(child)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Test cases consist of a kramdown string that uses IALs to specify the expected
|
20
|
+
# line numbers for a given element.
|
21
|
+
test_cases = {
|
22
|
+
'autolink' => %(testing autolinks\n\n<http://kramdown.org>{:.line-3}),
|
23
|
+
'blockquote' => %(
|
24
|
+
> block quote1
|
25
|
+
>
|
26
|
+
> * {:.line-3} list item in block quote
|
27
|
+
> * {:.line-4} list item in block quote
|
28
|
+
> {:.line-3}
|
29
|
+
{:.line-1}
|
30
|
+
|
31
|
+
> block quote2
|
32
|
+
{:.line-8}
|
33
|
+
),
|
34
|
+
'codeblock' => %(\na para\n\n~~~~\ntest code 1\n~~~~\n{:.line-3}\n\n test code 2\n{:.line-8}\n),
|
35
|
+
'codespan' => %(a para\n\nanother para `<code>`{:.line-3} with code\n),
|
36
|
+
'emphasis' => %(
|
37
|
+
para *span*{:.line-1}
|
38
|
+
{:.line-1}
|
39
|
+
|
40
|
+
## header *span*{:.line-4}
|
41
|
+
{:.line-4}
|
42
|
+
|
43
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
44
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
45
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
46
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
47
|
+
cillum *short span on single line*{:.line-11}
|
48
|
+
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
49
|
+
*long span over multiple lines - proident, sunt in culpa qui officia deserunt
|
50
|
+
mollit anim id est laborum.*{:.line-13}
|
51
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
52
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
53
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
54
|
+
`code span`{:.line-18}
|
55
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
56
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
57
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
58
|
+
{:.line-7}
|
59
|
+
),
|
60
|
+
'header' => %(
|
61
|
+
# header1
|
62
|
+
{:.line-1}
|
63
|
+
|
64
|
+
## header2
|
65
|
+
{:.line-4}
|
66
|
+
|
67
|
+
## header3
|
68
|
+
{:.line-7}
|
69
|
+
|
70
|
+
header4
|
71
|
+
=======
|
72
|
+
{:.line-10}
|
73
|
+
|
74
|
+
^
|
75
|
+
|
76
|
+
header5
|
77
|
+
-------
|
78
|
+
{:.line-16}
|
79
|
+
),
|
80
|
+
'horizontal_rule' => %(\na para\n\n----\n{:.line-3}\n),
|
81
|
+
'html_entity' => "a para\n\nanother para with &{:.line-3} html entity.\n",
|
82
|
+
'link' => %(
|
83
|
+
a para
|
84
|
+
|
85
|
+
This is [a link](http://rubyforge.org){:.line-3} to a page.
|
86
|
+
|
87
|
+
Here comes a {:.line-5}
|
88
|
+
),
|
89
|
+
'list' => %(
|
90
|
+
* {:.line-1} list item
|
91
|
+
* {:.line-2} list item
|
92
|
+
* {:.line-3} list item
|
93
|
+
{:.line-1}
|
94
|
+
|
95
|
+
{:.line-7}
|
96
|
+
1. {:.line-7} list item
|
97
|
+
2. {:.line-8} list item
|
98
|
+
3. {:.line-9} list item
|
99
|
+
|
100
|
+
{:.line-12}
|
101
|
+
definition term 1
|
102
|
+
: {:.line-13} definition definition 1
|
103
|
+
definition term 2
|
104
|
+
: {:.line-15} definition definition 2
|
105
|
+
),
|
106
|
+
'math_block' => %(\na para\n\n$$5+5$$\n{:.line-3}\n),
|
107
|
+
'math_inline' => %(\na para\n\nanother para with inline math $$5+5$${:.line-3}\n),
|
108
|
+
'paragraph' => %(
|
109
|
+
para1
|
110
|
+
{:.line-1}
|
111
|
+
|
112
|
+
para2
|
113
|
+
{:.line-4}
|
114
|
+
|
115
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
116
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
117
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
118
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
119
|
+
{:.line-7}
|
120
|
+
|
121
|
+
{:.line-14}
|
122
|
+
para with leading IAL
|
123
|
+
),
|
124
|
+
'table' => %(
|
125
|
+
a para
|
126
|
+
|
127
|
+
|first|second|third|
|
128
|
+
|-----|------|-----|
|
129
|
+
|a |b |c |
|
130
|
+
{:.line-3}
|
131
|
+
),
|
132
|
+
'typographic_symbol' => %(
|
133
|
+
a para
|
134
|
+
|
135
|
+
another para ---{:.line-3}
|
136
|
+
|
137
|
+
another para ...{:.line-5}
|
138
|
+
),
|
139
|
+
'gh issue 129' => %(
|
140
|
+
`|`
|
141
|
+
{:.line-1}
|
142
|
+
),
|
143
|
+
'gh issue 131' => %(
|
144
|
+
* {:.line-1} test
|
145
|
+
line 2
|
146
|
+
* {:.line-3} second
|
147
|
+
* {:.line-4} third
|
148
|
+
* {:.line-5} * {:.line-5} one
|
149
|
+
* {:.line-6} two
|
150
|
+
),
|
151
|
+
'gh issue 158' => %(
|
152
|
+
😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁
|
153
|
+
{:.line-1}
|
154
|
+
|
155
|
+
- {:.line-4} T
|
156
|
+
{:.line-4}
|
157
|
+
|
158
|
+
# T
|
159
|
+
{:.line-7}
|
160
|
+
),
|
161
|
+
}
|
162
|
+
test_cases.each do |name, test_string|
|
163
|
+
it "Handles #{ name }" do
|
164
|
+
doc = Kramdown::Document.new(test_string.gsub(/^ /, '').strip)
|
165
|
+
check_element_for_location(doc.root)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'adds location info to duplicate abbreviation definition warnings' do
|
170
|
+
test_string = %(This snippet contains a duplicate abbreviation definition
|
171
|
+
|
172
|
+
*[duplicate]: The first definition
|
173
|
+
*[duplicate]: The second definition
|
174
|
+
)
|
175
|
+
doc = Kramdown::Document.new(test_string.strip)
|
176
|
+
doc.warnings.should.equal ["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"]
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'handles abbreviations' do
|
180
|
+
str = "This *is* ABC and\n**and** ABC second\nanother ABC\nas ABC as\nABC at the end.\n\n*[ABC]: ABC"
|
181
|
+
doc = Kramdown::Document.new(str)
|
182
|
+
doc.root.children.first.children.select {|e| e.type == :abbreviation}.each_with_index do |e, i|
|
183
|
+
expect(i + 1).to eq e.options[:location]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'handles line breaks' do
|
188
|
+
str = "First \nsecond\\\\\nthird \n"
|
189
|
+
doc = Kramdown::Document.new(str)
|
190
|
+
doc.root.children.first.children.select {|e| e.type == :br}.each_with_index do |e, i|
|
191
|
+
expect(i + 1).to eq e.options[:location]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'handles smart quotes' do
|
196
|
+
str = "This is 'first'\nand 'second' and\n'third'"
|
197
|
+
doc = Kramdown::Document.new(str)
|
198
|
+
doc.root.children.first.children.select {|e| e.type == :smart_quote}.each_with_index do |e, i|
|
199
|
+
expect(((i + 1) /2.0).ceil).to eq e.options[:location]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
describe Kramdown::Utils::StringScanner do
|
4
|
+
|
5
|
+
[
|
6
|
+
["...........X............", [/X/], 1],
|
7
|
+
["1\n2\n3\n4\n5\n6X", [/X/], 6],
|
8
|
+
["1\n2\n3\n4\n5\n6X\n7\n8X", [/X/,/X/], 8],
|
9
|
+
[(".\n" * 1000) + 'X', [/X/], 1001]
|
10
|
+
].each_with_index do |test_data, i|
|
11
|
+
test_string, scan_regexes, line_number = test_data
|
12
|
+
it "computes the correct current_line_number for example ##{i+1}" do
|
13
|
+
str_sc = Kramdown::Utils::StringScanner.new(test_string)
|
14
|
+
scan_regexes.each { |scan_re| str_sc.scan_until(scan_re) }
|
15
|
+
expect(str_sc.current_line_number).to eq line_number
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|