kramdown 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of kramdown might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CONTRIBUTERS +5 -1
- data/README.md +5 -1
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/benchmark/generate_data.rb +1 -1
- data/doc/default.template +2 -2
- data/doc/index.page +3 -4
- data/doc/news.feed +1 -1
- data/doc/quickref.page +4 -4
- data/doc/sidebar.template +7 -8
- data/doc/syntax.page +10 -3
- data/doc/tests.page +1 -1
- data/lib/kramdown/converter.rb +1 -0
- data/lib/kramdown/converter/base.rb +57 -9
- data/lib/kramdown/converter/kramdown.rb +4 -2
- data/lib/kramdown/converter/pdf.rb +638 -0
- data/lib/kramdown/document.rb +1 -1
- data/lib/kramdown/element.rb +4 -0
- data/lib/kramdown/options.rb +44 -8
- data/lib/kramdown/parser/base.rb +4 -2
- data/lib/kramdown/parser/gfm.rb +25 -18
- data/lib/kramdown/parser/html.rb +2 -2
- data/lib/kramdown/parser/kramdown.rb +24 -2
- data/lib/kramdown/parser/kramdown/abbreviation.rb +3 -2
- data/lib/kramdown/parser/kramdown/autolink.rb +2 -1
- data/lib/kramdown/parser/kramdown/blockquote.rb +2 -1
- data/lib/kramdown/parser/kramdown/codeblock.rb +4 -2
- data/lib/kramdown/parser/kramdown/codespan.rb +2 -1
- data/lib/kramdown/parser/kramdown/emphasis.rb +2 -1
- data/lib/kramdown/parser/kramdown/extensions.rb +5 -4
- data/lib/kramdown/parser/kramdown/footnote.rb +6 -4
- data/lib/kramdown/parser/kramdown/header.rb +4 -2
- data/lib/kramdown/parser/kramdown/horizontal_rule.rb +2 -1
- data/lib/kramdown/parser/kramdown/html_entity.rb +4 -2
- data/lib/kramdown/parser/kramdown/link.rb +3 -2
- data/lib/kramdown/parser/kramdown/list.rb +9 -5
- data/lib/kramdown/parser/kramdown/math.rb +5 -3
- data/lib/kramdown/parser/kramdown/paragraph.rb +2 -1
- data/lib/kramdown/parser/kramdown/table.rb +5 -3
- data/lib/kramdown/parser/kramdown/typographic_symbol.rb +10 -5
- data/lib/kramdown/utils.rb +1 -0
- data/lib/kramdown/utils/string_scanner.rb +52 -0
- data/lib/kramdown/version.rb +1 -1
- data/man/man1/kramdown.1 +41 -6
- data/test/test_files.rb +2 -2
- data/test/test_location.rb +158 -0
- data/test/test_string_scanner_kramdown.rb +22 -0
- data/test/testcases/block/04_header/with_auto_id_stripping.html +1 -0
- data/test/testcases/block/04_header/with_auto_id_stripping.options +1 -0
- data/test/testcases/block/04_header/with_auto_id_stripping.text +1 -0
- data/test/testcases/span/math/normal.html +2 -1
- data/test/testcases/span/math/normal.text +2 -1
- data/test/testcases_gfm/hard_line_breaks_off.html +2 -0
- data/test/testcases_gfm/hard_line_breaks_off.options +1 -0
- data/test/testcases_gfm/hard_line_breaks_off.text +2 -0
- metadata +27 -3
@@ -20,10 +20,11 @@ module Kramdown
|
|
20
20
|
def parse_setext_header
|
21
21
|
return false if !after_block_boundary?
|
22
22
|
|
23
|
+
start_line_number = @src.current_line_number
|
23
24
|
@src.pos += @src.matched_size
|
24
25
|
text, id, level = @src[1], @src[2], @src[3]
|
25
26
|
text.strip!
|
26
|
-
el = new_block_el(:header, nil, nil, :level => (level == '-' ? 2 : 1), :raw_text => text)
|
27
|
+
el = new_block_el(:header, nil, nil, :level => (level == '-' ? 2 : 1), :raw_text => text, :location => start_line_number)
|
27
28
|
add_text(text, el)
|
28
29
|
el.attr['id'] = id if id
|
29
30
|
@tree.children << el
|
@@ -39,12 +40,13 @@ module Kramdown
|
|
39
40
|
def parse_atx_header
|
40
41
|
return false if !after_block_boundary?
|
41
42
|
|
43
|
+
start_line_number = @src.current_line_number
|
42
44
|
@src.check(ATX_HEADER_MATCH)
|
43
45
|
level, text, id = @src[1], @src[2].to_s.strip, @src[3]
|
44
46
|
return false if text.empty?
|
45
47
|
|
46
48
|
@src.pos += @src.matched_size
|
47
|
-
el = new_block_el(:header, nil, nil, :level => level.length, :raw_text => text)
|
49
|
+
el = new_block_el(:header, nil, nil, :level => level.length, :raw_text => text, :location => start_line_number)
|
48
50
|
add_text(text, el)
|
49
51
|
el.attr['id'] = id if id
|
50
52
|
@tree.children << el
|
@@ -15,8 +15,9 @@ module Kramdown
|
|
15
15
|
|
16
16
|
# Parse the horizontal rule at the current location.
|
17
17
|
def parse_horizontal_rule
|
18
|
+
start_line_number = @src.current_line_number
|
18
19
|
@src.pos += @src.matched_size
|
19
|
-
@tree.children << new_block_el(:hr)
|
20
|
+
@tree.children << new_block_el(:hr, nil, nil, :location => start_line_number)
|
20
21
|
true
|
21
22
|
end
|
22
23
|
define_parser(:horizontal_rule, HR_START)
|
@@ -15,12 +15,14 @@ module Kramdown
|
|
15
15
|
|
16
16
|
# Parse the HTML entity at the current location.
|
17
17
|
def parse_html_entity
|
18
|
+
start_line_number = @src.current_line_number
|
18
19
|
@src.pos += @src.matched_size
|
19
20
|
begin
|
20
21
|
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity(@src[1] || (@src[2] && @src[2].to_i) || @src[3].hex),
|
21
|
-
nil, :original => @src.matched)
|
22
|
+
nil, :original => @src.matched, :location => start_line_number)
|
22
23
|
rescue ::Kramdown::Error
|
23
|
-
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp')
|
24
|
+
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('amp'),
|
25
|
+
nil, :location => start_line_number)
|
24
26
|
add_text(@src.matched[1..-1])
|
25
27
|
end
|
26
28
|
end
|
@@ -22,7 +22,7 @@ module Kramdown
|
|
22
22
|
def parse_link_definition
|
23
23
|
@src.pos += @src.matched_size
|
24
24
|
link_id, link_url, link_title = normalize_link_id(@src[1]), @src[2] || @src[3], @src[5]
|
25
|
-
warning("Duplicate link ID '#{link_id}' - overwriting") if @link_defs[link_id]
|
25
|
+
warning("Duplicate link ID '#{link_id}' on line #{@src.current_line_number} - overwriting") if @link_defs[link_id]
|
26
26
|
@link_defs[link_id] = [link_url, link_title]
|
27
27
|
@tree.children << Element.new(:eob, :link_def)
|
28
28
|
true
|
@@ -53,6 +53,7 @@ module Kramdown
|
|
53
53
|
# Parse the link at the current scanner position. This method is used to parse normal links as
|
54
54
|
# well as image links.
|
55
55
|
def parse_link
|
56
|
+
start_line_number = @src.current_line_number
|
56
57
|
result = @src.scan(LINK_START)
|
57
58
|
reset_pos = @src.pos
|
58
59
|
|
@@ -63,7 +64,7 @@ module Kramdown
|
|
63
64
|
add_text(result)
|
64
65
|
return
|
65
66
|
end
|
66
|
-
el = Element.new(link_type)
|
67
|
+
el = Element.new(link_type, nil, nil, :location => start_line_number)
|
67
68
|
|
68
69
|
count = 1
|
69
70
|
found = parse_spans(el, LINK_BRACKET_STOP_RE) do
|
@@ -46,8 +46,9 @@ module Kramdown
|
|
46
46
|
|
47
47
|
# Parse the ordered or unordered list at the current location.
|
48
48
|
def parse_list
|
49
|
+
start_line_number = @src.current_line_number
|
49
50
|
type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
|
50
|
-
list = new_block_el(type)
|
51
|
+
list = new_block_el(type, nil, nil, :location => start_line_number)
|
51
52
|
|
52
53
|
item = nil
|
53
54
|
content_re, lazy_re, indent_re = nil
|
@@ -55,13 +56,14 @@ module Kramdown
|
|
55
56
|
nested_list_found = false
|
56
57
|
last_is_blank = false
|
57
58
|
while !@src.eos?
|
59
|
+
start_line_number = @src.current_line_number
|
58
60
|
if last_is_blank && @src.check(HR_START)
|
59
61
|
break
|
60
62
|
elsif @src.scan(EOB_MARKER)
|
61
63
|
eob_found = true
|
62
64
|
break
|
63
65
|
elsif @src.scan(list_start_re)
|
64
|
-
item = Element.new(:li)
|
66
|
+
item = Element.new(:li, nil, nil, :location => start_line_number)
|
65
67
|
item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
66
68
|
list.children << item
|
67
69
|
|
@@ -96,7 +98,7 @@ module Kramdown
|
|
96
98
|
|
97
99
|
last = nil
|
98
100
|
list.children.each do |it|
|
99
|
-
temp = Element.new(:temp)
|
101
|
+
temp = Element.new(:temp, nil, nil, :location => it.options[:location])
|
100
102
|
parse_blocks(temp, it.value)
|
101
103
|
it.children = temp.children
|
102
104
|
it.value = nil
|
@@ -146,8 +148,9 @@ module Kramdown
|
|
146
148
|
para = @tree.children.pop
|
147
149
|
first_as_para = true
|
148
150
|
end
|
151
|
+
deflist.options[:location] = para.options[:location] # take location from preceding para which is the first definition term
|
149
152
|
para.children.first.value.split(/\n/).each do |term|
|
150
|
-
el = Element.new(:dt)
|
153
|
+
el = Element.new(:dt, nil, nil, :location => @src.current_line_number)
|
151
154
|
el.children << Element.new(:raw_text, term)
|
152
155
|
deflist.children << el
|
153
156
|
end
|
@@ -158,8 +161,9 @@ module Kramdown
|
|
158
161
|
def_start_re = DEFINITION_LIST_START
|
159
162
|
last_is_blank = false
|
160
163
|
while !@src.eos?
|
164
|
+
start_line_number = @src.current_line_number
|
161
165
|
if @src.scan(def_start_re)
|
162
|
-
item = Element.new(:dd)
|
166
|
+
item = Element.new(:dd, nil, nil, :location => start_line_number)
|
163
167
|
item.options[:first_as_para] = first_as_para
|
164
168
|
item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2])
|
165
169
|
deflist.children << item
|
@@ -17,6 +17,7 @@ module Kramdown
|
|
17
17
|
|
18
18
|
# Parse the math block at the current location.
|
19
19
|
def parse_block_math
|
20
|
+
start_line_number = @src.current_line_number
|
20
21
|
if !after_block_boundary?
|
21
22
|
return false
|
22
23
|
elsif @src[1]
|
@@ -28,7 +29,7 @@ module Kramdown
|
|
28
29
|
@src.pos += @src.matched_size
|
29
30
|
data = @src[2]
|
30
31
|
if before_block_boundary?
|
31
|
-
@tree.children << new_block_el(:math, data, nil, :category => :block)
|
32
|
+
@tree.children << new_block_el(:math, data, nil, :category => :block, :location => start_line_number)
|
32
33
|
true
|
33
34
|
else
|
34
35
|
@src.pos = orig_pos
|
@@ -38,12 +39,13 @@ module Kramdown
|
|
38
39
|
define_parser(:block_math, BLOCK_MATH_START)
|
39
40
|
|
40
41
|
|
41
|
-
INLINE_MATH_START = /\$\$(.*?)\$\$/
|
42
|
+
INLINE_MATH_START = /\$\$(.*?)\$\$/m
|
42
43
|
|
43
44
|
# Parse the inline math at the current location.
|
44
45
|
def parse_inline_math
|
46
|
+
start_line_number = @src.current_line_number
|
45
47
|
@src.pos += @src.matched_size
|
46
|
-
@tree.children << Element.new(:math, @src[1], nil, :category => :span)
|
48
|
+
@tree.children << Element.new(:math, @src[1], nil, :category => :span, :location => start_line_number)
|
47
49
|
end
|
48
50
|
define_parser(:inline_math, INLINE_MATH_START, '\$')
|
49
51
|
|
@@ -29,6 +29,7 @@ module Kramdown
|
|
29
29
|
|
30
30
|
# Parse the paragraph at the current location.
|
31
31
|
def parse_paragraph
|
32
|
+
start_line_number = @src.current_line_number
|
32
33
|
result = @src.scan(PARAGRAPH_MATCH)
|
33
34
|
while !@src.match?(self.class::PARAGRAPH_END)
|
34
35
|
result << @src.scan(PARAGRAPH_MATCH)
|
@@ -37,7 +38,7 @@ module Kramdown
|
|
37
38
|
if @tree.children.last && @tree.children.last.type == :p
|
38
39
|
@tree.children.last.children.first.value << "\n" << result
|
39
40
|
else
|
40
|
-
@tree.children << new_block_el(:p)
|
41
|
+
@tree.children << new_block_el(:p, nil, nil, :location => start_line_number)
|
41
42
|
result.lstrip!
|
42
43
|
@tree.children.last.children << Element.new(@text_type, result)
|
43
44
|
end
|
@@ -26,7 +26,7 @@ module Kramdown
|
|
26
26
|
return false if !after_block_boundary?
|
27
27
|
|
28
28
|
orig_pos = @src.pos
|
29
|
-
table = new_block_el(:table, nil, nil, :alignment => [])
|
29
|
+
table = new_block_el(:table, nil, nil, :alignment => [], :location => @src.current_line_number)
|
30
30
|
leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
|
31
31
|
@src.scan(TABLE_SEP_LINE)
|
32
32
|
|
@@ -66,7 +66,7 @@ module Kramdown
|
|
66
66
|
if i % 2 == 1
|
67
67
|
(cells.empty? ? cells : cells.last) << str
|
68
68
|
else
|
69
|
-
reset_env(:src => StringScanner.new(str))
|
69
|
+
reset_env(:src => Kramdown::Utils::StringScanner.new(str, @src.current_line_number))
|
70
70
|
root = Element.new(:root)
|
71
71
|
parse_spans(root, nil, [:codespan])
|
72
72
|
|
@@ -110,7 +110,9 @@ module Kramdown
|
|
110
110
|
|
111
111
|
# Parse all lines of the table with the code span parser
|
112
112
|
env = save_env
|
113
|
-
|
113
|
+
l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src),
|
114
|
+
@src.current_line_number)
|
115
|
+
reset_env(:src => l_src)
|
114
116
|
root = Element.new(:root)
|
115
117
|
parse_spans(root, nil, [:codespan])
|
116
118
|
restore_env(env)
|
@@ -20,16 +20,21 @@ module Kramdown
|
|
20
20
|
|
21
21
|
# Parse the typographic symbols at the current location.
|
22
22
|
def parse_typographic_syms
|
23
|
+
start_line_number = @src.current_line_number
|
23
24
|
@src.pos += @src.matched_size
|
24
25
|
val = TYPOGRAPHIC_SYMS_SUBST[@src.matched]
|
25
26
|
if val.kind_of?(Symbol)
|
26
|
-
@tree.children << Element.new(:typographic_sym, val)
|
27
|
+
@tree.children << Element.new(:typographic_sym, val, nil, :location => start_line_number)
|
27
28
|
elsif @src.matched == '\\<<'
|
28
|
-
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt')
|
29
|
-
|
29
|
+
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'),
|
30
|
+
nil, :location => start_line_number)
|
31
|
+
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'),
|
32
|
+
nil, :location => start_line_number)
|
30
33
|
else
|
31
|
-
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt')
|
32
|
-
|
34
|
+
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'),
|
35
|
+
nil, :location => start_line_number)
|
36
|
+
@tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'),
|
37
|
+
nil, :location => start_line_number)
|
33
38
|
end
|
34
39
|
end
|
35
40
|
define_parser(:typographic_syms, TYPOGRAPHIC_SYMS_RE, '--|\\.\\.\\.|(?:\\\\| )?(?:<<|>>)')
|
data/lib/kramdown/utils.rb
CHANGED
@@ -19,6 +19,7 @@ module Kramdown
|
|
19
19
|
autoload :Html, 'kramdown/utils/html'
|
20
20
|
autoload :OrderedHash, 'kramdown/utils/ordered_hash'
|
21
21
|
autoload :Unidecoder, 'kramdown/utils/unidecoder'
|
22
|
+
autoload :StringScanner, 'kramdown/utils/string_scanner'
|
22
23
|
|
23
24
|
# Treat +name+ as if it were snake cased (e.g. snake_case) and camelize it (e.g. SnakeCase).
|
24
25
|
def self.camelize(name)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'strscan'
|
4
|
+
|
5
|
+
module Kramdown
|
6
|
+
module Utils
|
7
|
+
|
8
|
+
# This patched StringScanner adds line number information for current scan position and a
|
9
|
+
# start_line_number override for nested StringScanners.
|
10
|
+
class StringScanner < ::StringScanner
|
11
|
+
|
12
|
+
# The start line number. Used for nested StringScanners that scan a sub-string of the source
|
13
|
+
# document. The kramdown parser uses this, e.g., for span level parsers.
|
14
|
+
attr_reader :start_line_number
|
15
|
+
|
16
|
+
# Takes the start line number as optional second argument.
|
17
|
+
#
|
18
|
+
# Note: The original second argument is no longer used so this should be safe.
|
19
|
+
def initialize(string, start_line_number = 1)
|
20
|
+
super(string)
|
21
|
+
@start_line_number = start_line_number || 1
|
22
|
+
end
|
23
|
+
|
24
|
+
# To make this unicode (multibyte) aware, we have to use #charpos which was added in Ruby
|
25
|
+
# version 2.0.0.
|
26
|
+
#
|
27
|
+
# This method will work with older versions of Ruby, however it will report incorrect line
|
28
|
+
# numbers if the scanned string contains multibyte characters.
|
29
|
+
if instance_methods.include?(:charpos)
|
30
|
+
def best_pos
|
31
|
+
charpos
|
32
|
+
end
|
33
|
+
else
|
34
|
+
def best_pos
|
35
|
+
pos
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the line number for current charpos.
|
40
|
+
#
|
41
|
+
# NOTE: Requires that all line endings are normalized to '\n'
|
42
|
+
#
|
43
|
+
# NOTE: Normally we'd have to add one to the count of newlines to get the correct line number.
|
44
|
+
# However we add the one indirectly by using a one-based start_line_number.
|
45
|
+
def current_line_number
|
46
|
+
string[0..best_pos].count("\n") + start_line_number
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
data/lib/kramdown/version.rb
CHANGED
data/man/man1/kramdown.1
CHANGED
@@ -38,6 +38,7 @@ Show the help.
|
|
38
38
|
.B \-\-template ARG
|
39
39
|
|
40
40
|
The name of an ERB template file that should be used to wrap the output
|
41
|
+
or the ERB template itself.
|
41
42
|
|
42
43
|
This is used to wrap the output in an environment so that the output can
|
43
44
|
be used as a stand-alone document. For example, an HTML template would
|
@@ -46,10 +47,13 @@ valid HTML file. If no template is specified, the output will be just
|
|
46
47
|
the converted text.
|
47
48
|
|
48
49
|
When resolving the template file, the given template name is used first.
|
49
|
-
If such a file is not found, the converter extension
|
50
|
-
file still cannot be found, the
|
51
|
-
template name that is provided by
|
52
|
-
extension).
|
50
|
+
If such a file is not found, the converter extension (the same as the
|
51
|
+
converter name) is appended. If the file still cannot be found, the
|
52
|
+
templates name is interpreted as a template name that is provided by
|
53
|
+
kramdown (without the converter extension). If the file is still not
|
54
|
+
found, the template name is checked if it starts with 'string://' and if
|
55
|
+
it does, this prefix is removed and the rest is used as template
|
56
|
+
content.
|
53
57
|
|
54
58
|
kramdown provides a default template named 'document' for each converter.
|
55
59
|
|
@@ -69,10 +73,26 @@ Default: true
|
|
69
73
|
Used by: HTML/Latex converter
|
70
74
|
|
71
75
|
|
76
|
+
.TP
|
77
|
+
.B \-\-[no\-]auto-id-stripping
|
78
|
+
|
79
|
+
Strip all formatting from header text for automatic ID generation
|
80
|
+
|
81
|
+
If this option is `true`, only the text elements of a header are used
|
82
|
+
for generating the ID later (in contrast to just using the raw header
|
83
|
+
text line).
|
84
|
+
|
85
|
+
This option will be removed in version 2.0 because this will be the
|
86
|
+
default then.
|
87
|
+
|
88
|
+
Default: false
|
89
|
+
Used by: kramdown parser
|
90
|
+
|
91
|
+
|
72
92
|
.TP
|
73
93
|
.B \-\-auto-id-prefix ARG
|
74
94
|
|
75
|
-
Prefix used for automatically generated
|
95
|
+
Prefix used for automatically generated header IDs
|
76
96
|
|
77
97
|
This option can be used to set a prefix for the automatically generated
|
78
98
|
header IDs so that there is no conflict when rendering multiple kramdown
|
@@ -227,6 +247,9 @@ Used by: HTML converter
|
|
227
247
|
|
228
248
|
Defines how often a line number should be made bold
|
229
249
|
|
250
|
+
Can either be an integer or false (to turn off bold line numbers
|
251
|
+
completely).
|
252
|
+
|
230
253
|
Default: 10
|
231
254
|
Used by: HTML converter
|
232
255
|
|
@@ -357,10 +380,22 @@ Default: 0
|
|
357
380
|
Used by: HTML converter, Kramdown converter, Latex converter
|
358
381
|
|
359
382
|
|
383
|
+
.TP
|
384
|
+
.B \-\-[no\-]hard-wrap
|
385
|
+
|
386
|
+
Interprets line breaks literally
|
387
|
+
|
388
|
+
Insert HTML `<br />` tags inside paragraphs where the original Markdown
|
389
|
+
document had newlines (by default, Markdown ignores these newlines).
|
390
|
+
|
391
|
+
Default: true
|
392
|
+
Used by: GFM parser
|
393
|
+
|
394
|
+
|
360
395
|
.SH EXIT STATUS
|
361
396
|
The exit status is 0 if no error happened. Otherwise it is 1.
|
362
397
|
.SH SEE ALSO
|
363
|
-
The kramdown website, http://kramdown.
|
398
|
+
The kramdown website, http://kramdown.gettalong.org/ for more information, especially on the supported
|
364
399
|
input syntax.
|
365
400
|
.SH AUTHOR
|
366
401
|
kramdown was written by Thomas Leitner <t_leitner@gmx.at>.
|
data/test/test_files.rb
CHANGED
@@ -7,14 +7,14 @@
|
|
7
7
|
#++
|
8
8
|
#
|
9
9
|
|
10
|
-
require '
|
10
|
+
require 'minitest/autorun'
|
11
11
|
require 'kramdown'
|
12
12
|
require 'yaml'
|
13
13
|
require 'tmpdir'
|
14
14
|
|
15
15
|
Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9'
|
16
16
|
|
17
|
-
class TestFiles < Test
|
17
|
+
class TestFiles < Minitest::Test
|
18
18
|
|
19
19
|
EXCLUDE_KD_FILES = [('test/testcases/block/04_header/with_auto_ids.text' if RUBY_VERSION <= '1.8.6'), # bc of dep stringex not working
|
20
20
|
].compact
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'kramdown'
|
5
|
+
|
6
|
+
Encoding.default_external = 'utf-8' if RUBY_VERSION >= '1.9'
|
7
|
+
|
8
|
+
describe 'location' do
|
9
|
+
|
10
|
+
# checks that +element+'s :location option corresponds to the location stored
|
11
|
+
# in the element.attr['class']
|
12
|
+
def check_element_for_location(element)
|
13
|
+
if (match = /^line-(\d+)/.match(element.attr['class'] || ''))
|
14
|
+
expected_line = match[1].to_i
|
15
|
+
element.options[:location].must_equal(expected_line)
|
16
|
+
end
|
17
|
+
element.children.each do |child|
|
18
|
+
check_element_for_location(child)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Test cases consist of a kramdown string that uses IALs to specify the expected
|
23
|
+
# line numbers for a given element.
|
24
|
+
test_cases = {
|
25
|
+
'autolink' => %(testing autolinks\n\n<http://kramdown.org>{:.line-3}),
|
26
|
+
'blockquote' => %(
|
27
|
+
> block quote1
|
28
|
+
>
|
29
|
+
> * {:.line-3} list item in block quote
|
30
|
+
> * {:.line-4} list item in block quote
|
31
|
+
> {:.line-3}
|
32
|
+
{:.line-1}
|
33
|
+
|
34
|
+
> block quote2
|
35
|
+
{:.line-8}
|
36
|
+
),
|
37
|
+
'codeblock' => %(\na para\n\n~~~~\ntest code 1\n~~~~\n{:.line-3}\n\n test code 2\n{:.line-8}\n),
|
38
|
+
'codespan' => %(a para\n\nanother para `<code>`{:.line-3} with code\n),
|
39
|
+
'emphasis' => %(
|
40
|
+
para *span*{:.line-1}
|
41
|
+
{:.line-1}
|
42
|
+
|
43
|
+
## header *span*{:.line-4}
|
44
|
+
{:.line-4}
|
45
|
+
|
46
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
47
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
48
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
49
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
50
|
+
cillum *short span on single line*{:.line-11}
|
51
|
+
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
52
|
+
*long span over multiple lines - proident, sunt in culpa qui officia deserunt
|
53
|
+
mollit anim id est laborum.*{:.line-13}
|
54
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
55
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
56
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
57
|
+
`code span`{:.line-18}
|
58
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
59
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
60
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
61
|
+
{:.line-7}
|
62
|
+
),
|
63
|
+
'header' => %(
|
64
|
+
# header1
|
65
|
+
{:.line-1}
|
66
|
+
|
67
|
+
## header2
|
68
|
+
{:.line-4}
|
69
|
+
|
70
|
+
## header3
|
71
|
+
{:.line-7}
|
72
|
+
|
73
|
+
header4
|
74
|
+
=======
|
75
|
+
{:.line-10}
|
76
|
+
|
77
|
+
header5
|
78
|
+
-------
|
79
|
+
{:.line-14}
|
80
|
+
),
|
81
|
+
'horizontal_rule' => %(\na para\n\n----\n{:.line-3}\n),
|
82
|
+
'html_entity' => "a para\n\nanother para with &{:.line-3} html entity.\n",
|
83
|
+
'link' => %(
|
84
|
+
a para
|
85
|
+
|
86
|
+
This is [a link](http://rubyforge.org){:.line-3} to a page.
|
87
|
+
|
88
|
+
Here comes a ![smiley](../images/smiley.png){:.line-5}
|
89
|
+
),
|
90
|
+
'list' => %(
|
91
|
+
* {:.line-1} list item
|
92
|
+
* {:.line-2} list item
|
93
|
+
* {:.line-3} list item
|
94
|
+
{:.line-1}
|
95
|
+
|
96
|
+
{:.line-7}
|
97
|
+
1. {:.line-7} list item
|
98
|
+
2. {:.line-8} list item
|
99
|
+
3. {:.line-9} list item
|
100
|
+
|
101
|
+
{:.line-12}
|
102
|
+
definition term 1
|
103
|
+
: {:.line-13} definition definition 1
|
104
|
+
definition term 2
|
105
|
+
: {:.line-15} definition definition 2
|
106
|
+
),
|
107
|
+
'math_block' => %(\na para\n\n$$5+5$$\n{:.line-3}\n),
|
108
|
+
'math_inline' => %(\na para\n\nanother para with inline math $$5+5$${:.line-3}\n),
|
109
|
+
'paragraph' => %(
|
110
|
+
para1
|
111
|
+
{:.line-1}
|
112
|
+
|
113
|
+
para2
|
114
|
+
{:.line-4}
|
115
|
+
|
116
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
117
|
+
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
118
|
+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
119
|
+
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
120
|
+
{:.line-7}
|
121
|
+
|
122
|
+
{:.line-14}
|
123
|
+
para with leading IAL
|
124
|
+
),
|
125
|
+
'table' => %(
|
126
|
+
a para
|
127
|
+
|
128
|
+
|first|second|third|
|
129
|
+
|-----|------|-----|
|
130
|
+
|a |b |c |
|
131
|
+
{:.line-3}
|
132
|
+
),
|
133
|
+
'typographic_symbol' => %(
|
134
|
+
a para
|
135
|
+
|
136
|
+
another para ---{:.line-3}
|
137
|
+
|
138
|
+
another para ...{:.line-5}
|
139
|
+
)
|
140
|
+
}
|
141
|
+
test_cases.each do |name, test_string|
|
142
|
+
it "Handles #{ name }" do
|
143
|
+
doc = Kramdown::Document.new(test_string.gsub(/^ /, '').strip)
|
144
|
+
check_element_for_location(doc.root)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'adds location info to duplicate abbreviation definition warnings' do
|
149
|
+
test_string = %(This snippet contains a duplicate abbreviation definition
|
150
|
+
|
151
|
+
*[duplicate]: The first definition
|
152
|
+
*[duplicate]: The second definition
|
153
|
+
)
|
154
|
+
doc = Kramdown::Document.new(test_string.strip)
|
155
|
+
doc.warnings.must_equal ["Duplicate abbreviation ID 'duplicate' on line 4 - overwriting"]
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|