pseudohikiparser 0.0.3 → 0.0.4.develop
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.ja.md +132 -8
- data/README.md +134 -10
- data/lib/htmlelement.rb +42 -42
- data/lib/pseudohiki/autolink.rb +60 -0
- data/lib/pseudohiki/blockparser.rb +233 -125
- data/lib/pseudohiki/converter.rb +140 -81
- data/lib/pseudohiki/htmlformat.rb +156 -82
- data/lib/pseudohiki/htmlplugin.rb +9 -28
- data/lib/pseudohiki/inlineparser.rb +21 -24
- data/lib/pseudohiki/markdownformat.rb +94 -98
- data/lib/pseudohiki/plaintextformat.rb +67 -57
- data/lib/pseudohiki/sinatra_helpers.rb +23 -0
- data/lib/pseudohiki/treestack.rb +4 -4
- data/lib/pseudohiki/utils.rb +1 -2
- data/lib/pseudohiki/version.rb +1 -1
- data/lib/pseudohikiparser.rb +49 -28
- data/test/test_autolink.rb +104 -0
- data/test/test_blockparser.rb +78 -11
- data/test/test_htmlformat.rb +436 -0
- data/test/test_htmlplugin.rb +43 -0
- data/test/test_markdownformat.rb +156 -3
- data/test/test_plaintextformat.rb +85 -0
- data/test/test_pseudohiki2html.rb +82 -0
- data/test/test_pseudohikiparser.rb +286 -0
- data/test/test_utils.rb +1 -1
- metadata +22 -4
@@ -10,24 +10,31 @@ module PseudoHiki
|
|
10
10
|
include BlockParser::BlockElement
|
11
11
|
include TableRowParser::InlineElement
|
12
12
|
|
13
|
-
#for InlineParser
|
13
|
+
# for InlineParser
|
14
14
|
LINK, LITERAL, PLUGIN = %w(a code span)
|
15
15
|
BLANK, SPACE = "", " "
|
16
16
|
HREF, SRC, ALT, ID, CLASS, ROWSPAN, COLSPAN = %w(href src alt id class rowspan colspan)
|
17
|
-
#for BlockParser
|
17
|
+
# for BlockParser
|
18
18
|
DT, DD, LI = %w(dt dd li)
|
19
|
-
DescSep = [InlineParser::DescSep]
|
19
|
+
DescSep, LinkSep = [InlineParser::DescSep], [InlineParser::LinkSep]
|
20
20
|
|
21
21
|
Formatter = {}
|
22
22
|
|
23
|
+
class << self
|
24
|
+
attr_accessor :auto_link_in_verbatim
|
25
|
+
end
|
26
|
+
|
27
|
+
@auto_link_in_verbatim = true
|
28
|
+
|
23
29
|
attr_reader :element_name
|
24
|
-
attr_writer :generator, :formatter
|
30
|
+
attr_writer :generator, :formatter, :format_class
|
25
31
|
|
26
32
|
def self.setup_new_formatter(new_formatter, generator)
|
27
33
|
new_formatter.each do |node_class, formatter|
|
28
34
|
new_formatter[node_class] = formatter.clone
|
29
35
|
new_formatter[node_class].generator = generator
|
30
36
|
new_formatter[node_class].formatter = new_formatter
|
37
|
+
new_formatter[node_class].format_class = self
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
@@ -39,19 +46,29 @@ module PseudoHiki
|
|
39
46
|
self
|
40
47
|
end
|
41
48
|
|
42
|
-
def self.
|
43
|
-
|
49
|
+
def self.default_options
|
50
|
+
{ :auto_link_in_verbatim => @auto_link_in_verbatim }
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.format(tree, options=nil)
|
54
|
+
cur_auto_link_setting = @auto_link_in_verbatim
|
55
|
+
options = default_options unless options
|
56
|
+
@auto_link_in_verbatim = options[:auto_link_in_verbatim]
|
57
|
+
formatter = get_plain
|
44
58
|
tree.accept(formatter)
|
59
|
+
ensure
|
60
|
+
@auto_link_in_verbatim = cur_auto_link_setting
|
45
61
|
end
|
46
62
|
|
47
63
|
def initialize(element_name, generator=HtmlElement)
|
48
64
|
@element_name = element_name
|
49
65
|
@generator = generator
|
50
66
|
@formatter = Formatter
|
67
|
+
@format_class = self.class
|
51
68
|
end
|
52
69
|
|
53
70
|
def visited_result(element)
|
54
|
-
visitor = @formatter[element.class]
|
71
|
+
visitor = @formatter[element.class] || @formatter[PlainNode]
|
55
72
|
element.accept(visitor)
|
56
73
|
end
|
57
74
|
|
@@ -60,17 +77,19 @@ module PseudoHiki
|
|
60
77
|
end
|
61
78
|
|
62
79
|
def visit(tree)
|
63
|
-
htmlelement =
|
80
|
+
htmlelement = create_element(tree)
|
81
|
+
decorate(htmlelement, tree)
|
64
82
|
push_visited_results(htmlelement, tree)
|
65
83
|
htmlelement
|
66
84
|
end
|
67
85
|
|
68
|
-
def
|
86
|
+
def create_element(tree=nil)
|
69
87
|
@generator.create(@element_name)
|
70
88
|
end
|
71
89
|
|
72
90
|
def split_into_parts(tree, separator)
|
73
91
|
chunks = []
|
92
|
+
tree = tree.dup
|
74
93
|
while sep_index = tree.index(separator)
|
75
94
|
chunks.push tree.shift(sep_index)
|
76
95
|
tree.shift
|
@@ -78,45 +97,61 @@ module PseudoHiki
|
|
78
97
|
chunks.push tree
|
79
98
|
end
|
80
99
|
|
100
|
+
def decorate(htmlelement, tree)
|
101
|
+
each_decorator(htmlelement, tree) do |elm, decorator|
|
102
|
+
elm[CLASS] = HtmlElement.escape(decorator[CLASS].id) if decorator[CLASS]
|
103
|
+
if id_item = decorator[ID] || decorator[:id]
|
104
|
+
elm[ID] = HtmlElement.escape(id_item.id).upcase
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def each_decorator(element, tree)
|
110
|
+
return unless element.kind_of? HtmlElement
|
111
|
+
return unless tree.kind_of? BlockParser::BlockNode and tree.decorator
|
112
|
+
tree.decorator.tap {|decorator| yield element, decorator }
|
113
|
+
end
|
114
|
+
|
81
115
|
class ListLeafNodeFormatter < self
|
82
|
-
def
|
83
|
-
super(tree).tap do |
|
84
|
-
|
116
|
+
def create_element(tree)
|
117
|
+
super(tree).tap do |elm|
|
118
|
+
elm[ID] = tree.node_id.upcase if tree.node_id
|
85
119
|
end
|
86
120
|
end
|
87
121
|
end
|
88
122
|
|
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
|
-
|
123
|
+
[[EmNode, "em"],
|
124
|
+
[StrongNode, "strong"],
|
125
|
+
[DelNode, "del"],
|
126
|
+
[LiteralNode, LITERAL],
|
127
|
+
[PluginNode, PLUGIN],
|
128
|
+
[LinkNode, LINK],
|
129
|
+
[InlineLeaf, nil],
|
130
|
+
[PlainNode, nil], # Until here is for InlineParser
|
131
|
+
[DescNode, "dl"],
|
132
|
+
[QuoteNode, "blockquote"],
|
133
|
+
[TableNode, "table"],
|
134
|
+
[ParagraphNode, "p"],
|
135
|
+
[HrNode, "hr"],
|
136
|
+
[ListNode, "ul"],
|
137
|
+
[EnumNode, "ol"],
|
138
|
+
[TableLeaf, "tr"],
|
139
|
+
[VerbatimNode, "pre"],
|
140
|
+
[SectioningNode, "section"],
|
141
|
+
[CommentOutNode, nil],
|
142
|
+
[HeadingNode, "section"],
|
143
|
+
[DescLeaf, DT],
|
144
|
+
[TableCellNode, nil],
|
145
|
+
[HeadingLeaf, "h"], # Until here is for BlockParser
|
146
|
+
].each {|node_class, elm| Formatter[node_class] = new(elm) }
|
147
|
+
|
148
|
+
# for InlineParser
|
149
|
+
ImgFormat = new("img")
|
150
|
+
# for BlockParser
|
116
151
|
Formatter[ListWrapNode] = ListLeafNodeFormatter.new(LI)
|
117
152
|
Formatter[EnumWrapNode] = ListLeafNodeFormatter.new(LI)
|
118
153
|
|
119
|
-
#for InlineParser
|
154
|
+
# for InlineParser
|
120
155
|
|
121
156
|
class << Formatter[PluginNode]
|
122
157
|
def visit(tree)
|
@@ -134,31 +169,26 @@ module PseudoHiki
|
|
134
169
|
class << Formatter[LinkNode]
|
135
170
|
def visit(tree)
|
136
171
|
not_from_thumbnail = tree.first.class != LinkNode
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
rescue NoMethodError
|
142
|
-
raise NoMethodError unless tree.empty?
|
143
|
-
STDERR.puts "No uri is specified for #{caption}"
|
144
|
-
end
|
145
|
-
if ImageSuffix =~ ref and not_from_thumbnail
|
146
|
-
htmlelement = ImgFormat.create_self_element
|
147
|
-
htmlelement[SRC] = tree.join
|
172
|
+
caption, ref = caption_and_ref(tree)
|
173
|
+
if IMAGE_SUFFIX_RE =~ ref and not_from_thumbnail
|
174
|
+
htmlelement = ImgFormat.create_element
|
175
|
+
htmlelement[SRC] = ref
|
148
176
|
htmlelement[ALT] = caption.join if caption
|
149
177
|
else
|
150
|
-
htmlelement =
|
151
|
-
|
152
|
-
htmlelement
|
153
|
-
htmlelement.push caption||url
|
178
|
+
htmlelement = create_element
|
179
|
+
htmlelement[HREF] = ref.start_with?("#".freeze) ? ref.upcase : ref
|
180
|
+
htmlelement.push caption || ref
|
154
181
|
end
|
155
182
|
htmlelement
|
156
183
|
end
|
157
184
|
|
158
|
-
def
|
159
|
-
|
160
|
-
|
161
|
-
|
185
|
+
def caption_and_ref(tree)
|
186
|
+
caption, ref = split_into_parts(tree, LinkSep)
|
187
|
+
caption = ref ? caption.map {|token| visited_result(token) } : nil
|
188
|
+
return caption, (ref || tree).join
|
189
|
+
rescue NoMethodError
|
190
|
+
raise NoMethodError unless (ref || tree).empty?
|
191
|
+
STDERR.puts "No uri is specified for #{caption}"
|
162
192
|
end
|
163
193
|
end
|
164
194
|
|
@@ -169,20 +199,63 @@ module PseudoHiki
|
|
169
199
|
end
|
170
200
|
|
171
201
|
class << Formatter[PlainNode]
|
172
|
-
def
|
202
|
+
def create_element(tree=nil)
|
173
203
|
@generator::Children.new
|
174
204
|
end
|
175
205
|
end
|
176
206
|
|
177
|
-
#for BlockParser
|
207
|
+
# for BlockParser
|
208
|
+
|
209
|
+
class << Formatter[TableNode]
|
210
|
+
def decorate(htmlelement, tree)
|
211
|
+
each_decorator(htmlelement, tree) do |elm, decorator|
|
212
|
+
summary = decorator["summary"] && decorator["summary"].value.join
|
213
|
+
htmlelement["summary"] = HtmlElement.escape(summary) if summary
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
178
217
|
|
179
218
|
class << Formatter[VerbatimNode]
|
180
219
|
def visit(tree)
|
181
|
-
|
182
|
-
|
183
|
-
|
220
|
+
contents = add_link(@generator.escape(tree.join))
|
221
|
+
create_element.tap {|elm| elm.push contents }
|
222
|
+
end
|
223
|
+
|
224
|
+
def add_link(verbatim)
|
225
|
+
return verbatim unless @format_class.auto_link_in_verbatim
|
226
|
+
verbatim.gsub(AutoLink::URI_RE) do |url|
|
227
|
+
@generator.create(LINK, url, HREF => url).to_s
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
class << Formatter[SectioningNode]
|
233
|
+
ID_MARK = "#"
|
234
|
+
|
235
|
+
alias :orig_create_element :create_element
|
236
|
+
|
237
|
+
def section_with_id(tree, node_id)
|
238
|
+
orig_create_element(tree).tap do |elm|
|
239
|
+
elm[ID] = node_id[1..-1] # remove the first charactor from node_id
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def section_for_class(tree, node_id)
|
244
|
+
if HtmlElement::HTML5_TAGS.include? node_id
|
245
|
+
@generator.create(node_id)
|
246
|
+
else
|
247
|
+
orig_create_element(tree).tap do |elm|
|
248
|
+
elm[CLASS] = elm[CLASS] ? "#{elm[CLASS]} #{node_id}" : node_id
|
184
249
|
end
|
185
|
-
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def create_element(tree)
|
254
|
+
node_id = tree.node_id
|
255
|
+
if node_id.start_with? ID_MARK
|
256
|
+
section_with_id(tree, node_id)
|
257
|
+
else
|
258
|
+
section_for_class(tree, node_id)
|
186
259
|
end
|
187
260
|
end
|
188
261
|
end
|
@@ -192,46 +265,45 @@ module PseudoHiki
|
|
192
265
|
end
|
193
266
|
|
194
267
|
class << Formatter[HeadingNode]
|
195
|
-
def
|
196
|
-
super(tree).tap do |
|
197
|
-
heading_level = "h#{tree.first.
|
198
|
-
|
199
|
-
|
268
|
+
def create_element(tree)
|
269
|
+
super(tree).tap do |elm|
|
270
|
+
heading_level = "h#{tree.first.level}"
|
271
|
+
elm[CLASS] ||= heading_level
|
272
|
+
elm[CLASS] += SPACE + heading_level unless elm[CLASS] == heading_level
|
200
273
|
end
|
201
274
|
end
|
202
275
|
end
|
203
276
|
|
204
277
|
class << Formatter[DescLeaf]
|
205
278
|
def visit(tree)
|
206
|
-
|
207
|
-
element = @generator::Children.new
|
279
|
+
elm = @generator::Children.new
|
208
280
|
dt_part, dd_part = split_into_parts(tree, DescSep)
|
209
281
|
dt = super(dt_part)
|
210
|
-
|
282
|
+
elm.push dt
|
211
283
|
unless dd_part.nil? or dd_part.empty?
|
212
284
|
dd = @generator.create(DD)
|
213
285
|
push_visited_results(dd, dd_part)
|
214
|
-
|
286
|
+
elm.push dd
|
215
287
|
end
|
216
|
-
|
288
|
+
elm
|
217
289
|
end
|
218
290
|
end
|
219
291
|
|
220
292
|
class << Formatter[TableCellNode]
|
221
293
|
def visit(tree)
|
222
294
|
@element_name = tree.cell_type
|
223
|
-
super(tree).tap do |
|
224
|
-
|
225
|
-
|
226
|
-
#
|
295
|
+
super(tree).tap do |elm|
|
296
|
+
elm[ROWSPAN] = tree.rowspan if tree.rowspan > 1
|
297
|
+
elm[COLSPAN] = tree.colspan if tree.colspan > 1
|
298
|
+
# elm.push " " if elm.empty? #   = this line would be necessary for HTML 4 or XHTML 1.0
|
227
299
|
end
|
228
300
|
end
|
229
301
|
end
|
230
302
|
|
231
303
|
class << Formatter[HeadingLeaf]
|
232
|
-
def
|
233
|
-
@generator.create(@element_name+tree.
|
234
|
-
|
304
|
+
def create_element(tree)
|
305
|
+
@generator.create(@element_name + tree.level.to_s).tap do |elm|
|
306
|
+
elm[ID] = tree.node_id.upcase if tree.node_id
|
235
307
|
end
|
236
308
|
end
|
237
309
|
end
|
@@ -240,10 +312,12 @@ module PseudoHiki
|
|
240
312
|
class XhtmlFormat < HtmlFormat
|
241
313
|
Formatter = HtmlFormat::Formatter.dup
|
242
314
|
setup_new_formatter(Formatter, XhtmlElement)
|
315
|
+
@auto_link_in_verbatim = true
|
243
316
|
end
|
244
317
|
|
245
318
|
class Xhtml5Format < XhtmlFormat
|
246
319
|
Formatter = HtmlFormat::Formatter.dup
|
247
320
|
setup_new_formatter(Formatter, Xhtml5Element)
|
321
|
+
@auto_link_in_verbatim = true
|
248
322
|
end
|
249
323
|
end
|
@@ -9,7 +9,7 @@ module PseudoHiki
|
|
9
9
|
class HtmlFormat
|
10
10
|
class << Formatter[PluginNode]
|
11
11
|
def visit(leaf)
|
12
|
-
escape_inline_tags(leaf) { HtmlPlugin.new(@element_name,leaf.join).apply }
|
12
|
+
escape_inline_tags(leaf) { HtmlPlugin.new(@element_name, leaf.join).apply }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -30,20 +30,19 @@ module PseudoHiki
|
|
30
30
|
NUMBER_RE = /(\d+)/
|
31
31
|
|
32
32
|
def parse(data)
|
33
|
-
result =
|
33
|
+
result = "".freeze
|
34
34
|
if PLUGIN_PAT =~ data
|
35
35
|
@plugin_name = $1
|
36
36
|
@with_paren = true if $2.chomp == "("
|
37
|
-
result = data.chomp.sub(PLUGIN_PAT,"")
|
38
|
-
result[-1,1] = "" if @with_paren
|
37
|
+
result = data.chomp.sub(PLUGIN_PAT, "")
|
38
|
+
result[-1, 1] = "" if @with_paren
|
39
39
|
else
|
40
40
|
@plugin_name = data.chomp
|
41
|
-
result = ""
|
42
41
|
end
|
43
42
|
result
|
44
43
|
end
|
45
44
|
|
46
|
-
def initialize(tag_type,parsed_data)
|
45
|
+
def initialize(tag_type, parsed_data)
|
47
46
|
@tag_type = tag_type
|
48
47
|
@plugin_name = nil
|
49
48
|
@with_paren = nil
|
@@ -66,14 +65,14 @@ module PseudoHiki
|
|
66
65
|
# end
|
67
66
|
|
68
67
|
def anchor
|
69
|
-
name, anchor_mark = @data.split(/,\s*/o,2)
|
68
|
+
name, anchor_mark = @data.split(/,\s*/o, 2)
|
70
69
|
anchor_mark = "_" if (anchor_mark.nil? or anchor_mark.empty?)
|
71
70
|
HtmlElement.create("a", anchor_mark,
|
72
71
|
"name" => name,
|
73
|
-
"href" => "#"+name)
|
72
|
+
"href" => "#" + name)
|
74
73
|
end
|
75
74
|
|
76
|
-
def HtmlPlugin.add_chemical_formula(chemical_formula="CO2",en_word="carbon dioxide")
|
75
|
+
def HtmlPlugin.add_chemical_formula(chemical_formula="CO2", en_word="carbon dioxide")
|
77
76
|
eval(<<-End)
|
78
77
|
def #{chemical_formula.downcase}
|
79
78
|
#(display=":cf",second_display=nil)
|
@@ -130,7 +129,7 @@ module PseudoHiki
|
|
130
129
|
@data.scan(/\A(\d+)([^\d].*)/o) do |data|
|
131
130
|
weight, molecule = data
|
132
131
|
if self.respond_to? molecule
|
133
|
-
return "<sup>#{weight}</sup>" + HtmlPlugin.new("",molecule).apply
|
132
|
+
return "<sup>#{weight}</sup>" + HtmlPlugin.new("", molecule).apply
|
134
133
|
else
|
135
134
|
return "<sup>#{weight}</sup>" + molecule
|
136
135
|
end
|
@@ -145,21 +144,3 @@ module PseudoHiki
|
|
145
144
|
end
|
146
145
|
end
|
147
146
|
end
|
148
|
-
|
149
|
-
if $0 == __FILE__
|
150
|
-
p HtmlPlugin.new("div","html(
|
151
|
-
<ul>
|
152
|
-
<li>list
|
153
|
-
<li>list
|
154
|
-
</ul>)").apply
|
155
|
-
p HtmlPlugin.new("div","inline(
|
156
|
-
*list
|
157
|
-
*list
|
158
|
-
)").apply
|
159
|
-
|
160
|
-
p HtmlPlugin.new("div","co2").apply
|
161
|
-
p HtmlPlugin.new("div","co2 :en").apply
|
162
|
-
p HtmlPlugin.new("div","cb(3km)").apply
|
163
|
-
p HtmlPlugin.new("div","per m").apply
|
164
|
-
p HtmlPlugin.new("div","iso 18co2").apply
|
165
|
-
end
|
@@ -7,11 +7,7 @@ module PseudoHiki
|
|
7
7
|
RELATIVE_PATH = /^\./o
|
8
8
|
ROOT_PATH = /^(\/|\\\\|[A-Za-z]:\\)/o
|
9
9
|
FILE_MARK = "file:///"
|
10
|
-
|
11
|
-
|
12
|
-
def self.subclass_of(parent_class, bound_env, subclass_names)
|
13
|
-
subclass_names. each {|name| eval "class #{name} < #{parent_class}; end", bound_env }
|
14
|
-
end
|
10
|
+
IMAGE_SUFFIX_RE = /\.(jpg|jpeg|gif|png|bmp)$/io
|
15
11
|
|
16
12
|
def self.compile_token_pat(*token_sets)
|
17
13
|
tokens = token_sets.flatten.uniq.sort do |x, y|
|
@@ -35,10 +31,11 @@ module PseudoHiki
|
|
35
31
|
module InlineElement
|
36
32
|
class InlineNode < InlineParser::Node; end
|
37
33
|
class InlineLeaf < InlineParser::Leaf; end
|
38
|
-
#
|
34
|
+
# class LinkSepLeaf < InlineLeaf; end
|
39
35
|
|
40
|
-
|
41
|
-
|
36
|
+
%w(LinkNode EmNode StrongNode DelNode PlainNode LiteralNode PluginNode).each do |subclass|
|
37
|
+
const_set(subclass, Class.new(InlineNode))
|
38
|
+
end
|
42
39
|
|
43
40
|
LinkSep, TableSep, DescSep = %w(| || :)
|
44
41
|
end
|
@@ -48,7 +45,7 @@ module PseudoHiki
|
|
48
45
|
TAIL = {}
|
49
46
|
NodeTypeToHead = {}
|
50
47
|
TokenPat = {}
|
51
|
-
|
48
|
+
|
52
49
|
[[LinkNode, "[[", "]]"],
|
53
50
|
[EmNode, "''", "''"],
|
54
51
|
[StrongNode, "'''", "'''"],
|
@@ -60,7 +57,7 @@ module PseudoHiki
|
|
60
57
|
NodeTypeToHead[type] = head
|
61
58
|
end
|
62
59
|
|
63
|
-
TokenPat[self] = PseudoHiki.compile_token_pat(HEAD.keys,TAIL.keys,[LinkSep, TableSep, DescSep])
|
60
|
+
TokenPat[self] = PseudoHiki.compile_token_pat(HEAD.keys, TAIL.keys, [LinkSep, TableSep, DescSep])
|
64
61
|
|
65
62
|
def initialize(str)
|
66
63
|
@tokens = PseudoHiki.split_into_tokens(str, TokenPat[self.class])
|
@@ -70,8 +67,8 @@ module PseudoHiki
|
|
70
67
|
def convert_last_node_into_leaf
|
71
68
|
last_node = remove_current_node
|
72
69
|
tag_head = NodeTypeToHead[last_node.class]
|
73
|
-
|
74
|
-
last_node.each {|leaf|
|
70
|
+
push InlineLeaf.create(tag_head)
|
71
|
+
last_node.each {|leaf| push_as_leaf leaf }
|
75
72
|
end
|
76
73
|
|
77
74
|
def node_in_ancestors?(node_class)
|
@@ -79,23 +76,23 @@ module PseudoHiki
|
|
79
76
|
end
|
80
77
|
|
81
78
|
def treated_as_node_end(token)
|
82
|
-
return
|
79
|
+
return pop if current_node.class == TAIL[token]
|
83
80
|
return nil unless node_in_ancestors?(TAIL[token])
|
84
81
|
convert_last_node_into_leaf until current_node.class == TAIL[token]
|
85
|
-
|
82
|
+
pop
|
86
83
|
end
|
87
84
|
|
88
85
|
def parse
|
89
86
|
while token = @tokens.shift
|
90
87
|
next if TAIL[token] and treated_as_node_end(token)
|
91
|
-
next if HEAD[token] and
|
92
|
-
|
88
|
+
next if HEAD[token] and push HEAD[token].new
|
89
|
+
push InlineLeaf.create(token)
|
93
90
|
end
|
94
91
|
self
|
95
92
|
end
|
96
93
|
|
97
94
|
def self.parse(str)
|
98
|
-
new(str).parse.tree #parser = new(str)
|
95
|
+
new(str).parse.tree # parser = new(str)
|
99
96
|
end
|
100
97
|
end
|
101
98
|
|
@@ -120,9 +117,9 @@ module PseudoHiki
|
|
120
117
|
|
121
118
|
class InlineElement::TableCellNode
|
122
119
|
def parse_cellspan(token_str)
|
123
|
-
|
124
|
-
|
125
|
-
@cell_type = TH if cell_modifiers
|
120
|
+
m = MODIFIED_CELL_PAT.match(token_str) and cell_modifiers = m[0]
|
121
|
+
return token_str if cell_modifiers.empty?
|
122
|
+
@cell_type = TH if cell_modifiers.start_with? TH_PAT
|
126
123
|
@rowspan = cell_modifiers.count(ROW_EXPANDER) + 1
|
127
124
|
@colspan = cell_modifiers.count(COL_EXPANDER) + 1
|
128
125
|
m.post_match
|
@@ -134,19 +131,19 @@ module PseudoHiki
|
|
134
131
|
end
|
135
132
|
|
136
133
|
def push(token)
|
137
|
-
return super(token) unless
|
134
|
+
return super(token) unless empty?
|
138
135
|
super(parse_first_token(token))
|
139
136
|
end
|
140
137
|
end
|
141
138
|
|
142
139
|
def treated_as_node_end(token)
|
143
140
|
return super(token) unless token == TableSep
|
144
|
-
|
145
|
-
|
141
|
+
pop
|
142
|
+
push TableCellNode.new
|
146
143
|
end
|
147
144
|
|
148
145
|
def parse
|
149
|
-
|
146
|
+
push TableCellNode.new
|
150
147
|
super
|
151
148
|
end
|
152
149
|
end
|