12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
# File 'lib/kramdown/parser/pot_markdown/table.rb', line 12
def parse_table_pot
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 = []
= false
columns = 0
add_container = lambda do |type, force|
if ! || 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?
elsif table.options[:alignment].empty? && !
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 add_container.call(:tbody, false)
end
elsif @src.scan(TABLE_FSEP_LINE)
add_container.call(:tbody, true) unless rows.empty?
= true
elsif @src.scan(TABLE_ROW_LINE)
trow = Element.new(:tr)
env = save_env
cells = []
@src[1].split(/(<code.*?>.*?<\/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).map { |t| t.split(/\|/, -1) }.inject([]) do |memo, t|
memo.last << "|#{t.shift}" if memo.size > 0
memo.concat(t)
end
(cells.empty? ? cells : cells.last) << f
cells.concat(l)
else
delim = (c.value.scan(/`+/).max || '') + '`'
tmp = "#{delim}#{' ' if delim.size > 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
env = save_env
l_src = ::Kramdown::Utils::StringScanner.new((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)
pipe_on_line = false
while (c = root.children.shift)
lines = c.value.split(/\n/)
if c.type == :codespan
if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
break
elsif lines.size == 2 && pipe_on_line
pipe_on_line = false
end
else
break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
end
end
@src.revert_pos(saved_pos) && (return false) unless pipe_on_line
add_container.call( ? :tfoot : :tbody, false) unless rows.empty?
unless table.children.any? { |el| el.type == :tbody }
warning("Found table without body on line #{table.options[:location]} - ignoring it")
@src.revert_pos(saved_pos)
return false
end
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
|