pseudohikiparser 0.0.0.14.develop → 0.0.1
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 +4 -4
- data/README.ja.md +435 -0
- data/README.md +187 -79
- data/lib/pseudohiki/blockparser.rb +27 -64
- data/lib/pseudohiki/htmlformat.rb +0 -24
- data/lib/pseudohiki/markdownformat.rb +3 -9
- data/lib/pseudohiki/version.rb +1 -1
- data/lib/pseudohikiparser.rb +0 -2
- data/test/test_blockparser.rb +0 -29
- data/test/test_htmlformat.rb +0 -63
- data/test/test_markdownformat.rb +7 -60
- metadata +5 -5
- data/lib/pseudohiki/sinatra_helpers.rb +0 -23
@@ -37,15 +37,15 @@ module PseudoHiki
|
|
37
37
|
end
|
38
38
|
|
39
39
|
class BlockStack < TreeStack
|
40
|
-
def
|
41
|
-
self.current_node.parse_leafs
|
42
|
-
|
40
|
+
def pop
|
41
|
+
self.current_node.parse_leafs
|
42
|
+
super
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
class BlockLeaf < BlockStack::Leaf
|
47
47
|
@@head_re = {}
|
48
|
-
attr_accessor :nominal_level, :node_id
|
48
|
+
attr_accessor :nominal_level, :node_id
|
49
49
|
|
50
50
|
def self.head_re=(head_regex)
|
51
51
|
@self_head_re = @@head_re[self] = head_regex
|
@@ -85,7 +85,7 @@ module PseudoHiki
|
|
85
85
|
super(stack)
|
86
86
|
end
|
87
87
|
|
88
|
-
def parse_leafs
|
88
|
+
def parse_leafs
|
89
89
|
parsed = InlineParser.parse(self.join)
|
90
90
|
self.clear
|
91
91
|
self.concat(parsed)
|
@@ -135,10 +135,6 @@ module PseudoHiki
|
|
135
135
|
first.nominal_level if first # @cached_nominal_level ||= (first.nominal_level if first)
|
136
136
|
end
|
137
137
|
|
138
|
-
def decorator
|
139
|
-
first.decorator if first
|
140
|
-
end
|
141
|
-
|
142
138
|
def push_self(stack)
|
143
139
|
@stack = stack
|
144
140
|
super(stack)
|
@@ -148,7 +144,7 @@ module PseudoHiki
|
|
148
144
|
not (kind_of?(breaker.block) and nominal_level == breaker.nominal_level)
|
149
145
|
end
|
150
146
|
|
151
|
-
def parse_leafs
|
147
|
+
def parse_leafs; end
|
152
148
|
|
153
149
|
def in_link_tag?(preceding_str)
|
154
150
|
preceding_str[-2, 2] == "[[".freeze or preceding_str[-1, 1] == "|".freeze
|
@@ -160,7 +156,7 @@ module PseudoHiki
|
|
160
156
|
|
161
157
|
def add_leaf(line, blockparser)
|
162
158
|
leaf = create_leaf(line, blockparser)
|
163
|
-
blockparser.stack.
|
159
|
+
blockparser.stack.pop while blockparser.breakable?(leaf)
|
164
160
|
blockparser.stack.push leaf
|
165
161
|
end
|
166
162
|
|
@@ -172,8 +168,8 @@ module PseudoHiki
|
|
172
168
|
end
|
173
169
|
|
174
170
|
class NonNestedBlockNode < BlockNode
|
175
|
-
def parse_leafs
|
176
|
-
self.each {|leaf| leaf.parse_leafs
|
171
|
+
def parse_leafs
|
172
|
+
self.each {|leaf| leaf.parse_leafs }
|
177
173
|
end
|
178
174
|
end
|
179
175
|
|
@@ -193,11 +189,11 @@ module PseudoHiki
|
|
193
189
|
|
194
190
|
module BlockElement
|
195
191
|
{
|
196
|
-
BlockLeaf => %w(DescLeaf VerbatimLeaf TableLeaf CommentOutLeaf BlockNodeEnd HrLeaf
|
192
|
+
BlockLeaf => %w(DescLeaf VerbatimLeaf TableLeaf CommentOutLeaf BlockNodeEnd HrLeaf),
|
197
193
|
NonNestedBlockLeaf => %w(QuoteLeaf ParagraphLeaf),
|
198
194
|
NestedBlockLeaf => %w(HeadingLeaf),
|
199
195
|
ListTypeLeaf => %w(ListLeaf EnumLeaf),
|
200
|
-
BlockNode => %w(DescNode VerbatimNode TableNode CommentOutNode HrNode
|
196
|
+
BlockNode => %w(DescNode VerbatimNode TableNode CommentOutNode HrNode),
|
201
197
|
NonNestedBlockNode => %w(QuoteNode ParagraphNode),
|
202
198
|
NestedBlockNode => %w(HeadingNode),
|
203
199
|
ListTypeBlockNode => %w(ListNode EnumNode),
|
@@ -222,43 +218,15 @@ module PseudoHiki
|
|
222
218
|
attr_accessor :in_block_tag
|
223
219
|
|
224
220
|
def add_leaf(line, blockparser)
|
225
|
-
return @stack.
|
221
|
+
return @stack.pop if LINE_PAT::VERBATIM_END =~ line
|
226
222
|
return super(line, blockparser) unless @in_block_tag
|
227
223
|
line = " ".concat(line) if BlockElement::BlockNodeEnd.head_re =~ line and not @in_block_tag
|
228
224
|
@stack.push BlockElement::VerbatimLeaf.create(line, @in_block_tag)
|
229
225
|
end
|
230
226
|
end
|
231
227
|
|
232
|
-
class BlockElement::DecoratorNode
|
233
|
-
DECORATOR_PAT = /\A(?:([^\[\]:]+))?(?:\[([^\[\]]+)\])?(?::\s*(\S.*))?/o
|
234
|
-
|
235
|
-
class DecoratorItem < Struct.new(:string, :type, :id, :value)
|
236
|
-
def initialize(*args)
|
237
|
-
super
|
238
|
-
self.value = InlineParser.parse(self.value) if self.value
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def parse_leafs(breaker)
|
243
|
-
decorator = {}
|
244
|
-
breaker.decorator = decorator
|
245
|
-
@stack.remove_current_node.each do |leaf|
|
246
|
-
m = DECORATOR_PAT.match(leaf.join)
|
247
|
-
return nil unless m
|
248
|
-
item = DecoratorItem.new(*(m.to_a))
|
249
|
-
decorator[item.type||:id] = item
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
def breakable?(breaker)
|
254
|
-
return super if breaker.kind_of?(BlockElement::DecoratorLeaf)
|
255
|
-
parse_leafs(breaker)
|
256
|
-
@stack.current_node.breakable?(breaker)
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
228
|
class BlockElement::QuoteNode
|
261
|
-
def parse_leafs
|
229
|
+
def parse_leafs
|
262
230
|
self[0] = BlockParser.parse(self[0])
|
263
231
|
end
|
264
232
|
end
|
@@ -316,8 +284,7 @@ module PseudoHiki
|
|
316
284
|
[ParagraphLeaf, ParagraphNode],
|
317
285
|
[HrLeaf, HrNode],
|
318
286
|
[ListLeaf, ListNode],
|
319
|
-
[EnumLeaf, EnumNode]
|
320
|
-
[DecoratorLeaf, DecoratorNode]
|
287
|
+
[EnumLeaf, EnumNode]
|
321
288
|
].each do |leaf, node|
|
322
289
|
ParentNode[leaf] = node
|
323
290
|
end
|
@@ -326,31 +293,28 @@ module PseudoHiki
|
|
326
293
|
|
327
294
|
def self.assign_head_re
|
328
295
|
irregular_leafs = [BlockNodeEnd, VerbatimLeaf, HrLeaf]
|
329
|
-
|
296
|
+
head_pats, leaf_types = [], [:entire_matched_part]
|
330
297
|
[['\r?\n?$', BlockNodeEnd],
|
331
|
-
['\s', VerbatimLeaf],
|
332
|
-
['*', ListLeaf],
|
333
|
-
['#', EnumLeaf],
|
334
298
|
[':', DescLeaf],
|
335
|
-
['
|
299
|
+
['\s', VerbatimLeaf],
|
336
300
|
['""', QuoteLeaf],
|
337
301
|
['||', TableLeaf],
|
338
|
-
['//@', DecoratorLeaf],
|
339
302
|
['//', CommentOutLeaf],
|
303
|
+
['!', HeadingLeaf],
|
304
|
+
['*', ListLeaf],
|
305
|
+
['#', EnumLeaf],
|
340
306
|
['----\s*$', HrLeaf]
|
341
307
|
].each do |head, leaf|
|
342
308
|
escaped_head = irregular_leafs.include?(leaf) ? head : Regexp.escape(head)
|
343
309
|
head_pat = leaf.with_depth? ? "#{escaped_head}+" : "#{escaped_head}"
|
344
310
|
leaf.head_re = Regexp.new('\\A'+head_pat)
|
345
|
-
|
346
|
-
|
347
|
-
regular_leaf_types.push head unless irregular_leafs.include?(leaf)
|
311
|
+
head_pats.push "(#{escaped_head})"
|
312
|
+
leaf_types.push leaf
|
348
313
|
end
|
349
|
-
|
350
|
-
return Regexp.new('\\A(?:'+irregular_head_pats.join('|')+')'), regular_leaf_types, head_to_leaf, irregular_leaf_types, irregular_leafs.length
|
314
|
+
return Regexp.new('\\A(?:'+head_pats.join('|')+')'), leaf_types, leaf_types.length - 1
|
351
315
|
end
|
352
316
|
|
353
|
-
|
317
|
+
LEAF_HEAD_PAT, NOT_PARAGRAPH_LEAF_TYPES, NUMBER_OF_NOT_PARAGRAPH_LEAF_TYPES = assign_head_re
|
354
318
|
|
355
319
|
def initialize
|
356
320
|
root_node = BlockNode.new
|
@@ -365,16 +329,15 @@ module PseudoHiki
|
|
365
329
|
end
|
366
330
|
|
367
331
|
def select_leaf_type(line)
|
368
|
-
matched =
|
369
|
-
|
370
|
-
|
371
|
-
ParagraphLeaf
|
332
|
+
matched = LEAF_HEAD_PAT.match(line)
|
333
|
+
return ParagraphLeaf unless matched
|
334
|
+
1.upto(NUMBER_OF_NOT_PARAGRAPH_LEAF_TYPES) {|i| return NOT_PARAGRAPH_LEAF_TYPES[i] if matched[i] }
|
372
335
|
end
|
373
336
|
|
374
337
|
def read_lines(lines)
|
375
338
|
each_line = lines.respond_to?(:each_line) ? :each_line : :each
|
376
339
|
lines.send(each_line) {|line| @stack.current_node.add_leaf(line, self) }
|
377
|
-
@stack.
|
340
|
+
@stack.pop
|
378
341
|
end
|
379
342
|
end
|
380
343
|
end
|
@@ -61,7 +61,6 @@ module PseudoHiki
|
|
61
61
|
|
62
62
|
def visit(tree)
|
63
63
|
htmlelement = create_self_element(tree)
|
64
|
-
decorate(htmlelement, tree)
|
65
64
|
push_visited_results(htmlelement, tree)
|
66
65
|
htmlelement
|
67
66
|
end
|
@@ -79,21 +78,6 @@ module PseudoHiki
|
|
79
78
|
chunks.push tree
|
80
79
|
end
|
81
80
|
|
82
|
-
def decorate(htmlelement, tree)
|
83
|
-
each_decorator(htmlelement, tree) do |element, decorator|
|
84
|
-
element[CLASS] = HtmlElement.escape(decorator[CLASS].id) if decorator[CLASS]
|
85
|
-
if id_item = decorator[ID]||decorator[:id]
|
86
|
-
element[ID] = HtmlElement.escape(id_item.id).upcase
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def each_decorator(element, tree)
|
92
|
-
return unless element.kind_of? HtmlElement
|
93
|
-
return unless tree.kind_of? BlockParser::BlockNode and tree.decorator
|
94
|
-
tree.decorator.tap {|decorator| yield element, decorator }
|
95
|
-
end
|
96
|
-
|
97
81
|
class ListLeafNodeFormatter < self
|
98
82
|
def create_self_element(tree)
|
99
83
|
super(tree).tap do |element|
|
@@ -191,14 +175,6 @@ module PseudoHiki
|
|
191
175
|
|
192
176
|
#for BlockParser
|
193
177
|
|
194
|
-
class << Formatter[TableNode]
|
195
|
-
def decorate(htmlelement, tree)
|
196
|
-
each_decorator(htmlelement, tree) do |element, decorator|
|
197
|
-
htmlelement["summary"] = HtmlElement.escape(decorator["summary"].value.join) if decorator["summary"]
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
178
|
class << Formatter[VerbatimNode]
|
203
179
|
def visit(tree)
|
204
180
|
create_self_element.tap do |element|
|
@@ -140,6 +140,7 @@ module PseudoHiki
|
|
140
140
|
|
141
141
|
class LinkNodeFormatter < self
|
142
142
|
def visit(tree)
|
143
|
+
not_from_thumbnail = tree.first.class != LinkNode
|
143
144
|
tree = tree.dup
|
144
145
|
element = create_self_element
|
145
146
|
caption = get_caption(tree)
|
@@ -149,7 +150,7 @@ module PseudoHiki
|
|
149
150
|
raise NoMethodError unless tree.empty?
|
150
151
|
STDERR.puts "No uri is specified for #{caption}"
|
151
152
|
end
|
152
|
-
element.push "!" if ImageSuffix =~ ref
|
153
|
+
element.push "!" if ImageSuffix =~ ref and not_from_thumbnail
|
153
154
|
element.push "[#{(caption||tree).join}](#{tree.join})"
|
154
155
|
element
|
155
156
|
end
|
@@ -243,14 +244,13 @@ module PseudoHiki
|
|
243
244
|
class VerbatimNodeFormatter < self
|
244
245
|
def visit(tree)
|
245
246
|
element = super(tree)
|
246
|
-
@language_name = language_name(tree)
|
247
247
|
return gfm_verbatim(element) if @options.gfm_style
|
248
248
|
md_verbatim(element)
|
249
249
|
end
|
250
250
|
|
251
251
|
def gfm_verbatim(element)
|
252
252
|
element.tap do |lines|
|
253
|
-
lines.unshift "```#{
|
253
|
+
lines.unshift "```#{$/}"
|
254
254
|
lines.push "```#{$/ * 2}"
|
255
255
|
end
|
256
256
|
end
|
@@ -258,12 +258,6 @@ module PseudoHiki
|
|
258
258
|
def md_verbatim(element)
|
259
259
|
element.join.gsub(/^/o, " ").sub(/ \Z/o, "").concat $/
|
260
260
|
end
|
261
|
-
|
262
|
-
def language_name(tree)
|
263
|
-
tree.decorator.tap do |decorator|
|
264
|
-
return decorator ? decorator["code"].id : ""
|
265
|
-
end
|
266
|
-
end
|
267
261
|
end
|
268
262
|
|
269
263
|
class QuoteNodeFormatter < self
|
data/lib/pseudohiki/version.rb
CHANGED
data/lib/pseudohikiparser.rb
CHANGED
data/test/test_blockparser.rb
CHANGED
@@ -311,35 +311,6 @@ TEXT
|
|
311
311
|
assert_equal([[[["heading"]]]],parsed)
|
312
312
|
end
|
313
313
|
|
314
|
-
|
315
|
-
def test_decorator
|
316
|
-
text = <<TEXT
|
317
|
-
//@class[section_name]
|
318
|
-
!!title of section
|
319
|
-
|
320
|
-
//@summary: Summary of the table
|
321
|
-
||!header 1||! header 2
|
322
|
-
||cell 1||cell 2
|
323
|
-
|
324
|
-
a paragraph.
|
325
|
-
|
326
|
-
//@class[class_name]
|
327
|
-
//@[id_name]
|
328
|
-
another paragraph.
|
329
|
-
TEXT
|
330
|
-
|
331
|
-
tree = PseudoHiki::BlockParser.parse(text.lines.to_a.map {|line| line.chomp })
|
332
|
-
assert_equal(PseudoHiki::BlockParser::BlockNode, tree.class)
|
333
|
-
assert_equal("section_name", tree[0].decorator["class"].id)
|
334
|
-
assert_equal(PseudoHiki::BlockParser::BlockElement::HeadingNode, tree[0].class)
|
335
|
-
assert_equal([[["title of section"]], [[[["header 1"]], [[" header 2"]]], [[["cell 1"]], [["cell 2"]]]], [[["a paragraph."]]], [[["another paragraph."]]]], tree[0])
|
336
|
-
assert_equal([["Summary of the table"]], tree[0][1].decorator["summary"].value)
|
337
|
-
assert_equal(PseudoHiki::BlockParser::BlockElement::TableNode, tree[0][1].class)
|
338
|
-
assert_equal(nil, tree[0][2].decorator)
|
339
|
-
assert_equal('id_name', tree[0][3].decorator[:id].id)
|
340
|
-
assert_equal('class_name', tree[0][3].decorator["class"].id)
|
341
|
-
end
|
342
|
-
|
343
314
|
def test_comment_out_followed_by_a_verbatim_block
|
344
315
|
text = <<TEXT
|
345
316
|
the first paragraph
|
data/test/test_htmlformat.rb
CHANGED
@@ -696,69 +696,6 @@ HTML
|
|
696
696
|
assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
|
697
697
|
end
|
698
698
|
|
699
|
-
def test_decorator
|
700
|
-
text = <<TEXT
|
701
|
-
//@class[section_type]
|
702
|
-
!!title of section
|
703
|
-
|
704
|
-
a paragraph.
|
705
|
-
|
706
|
-
//@class[class_name]
|
707
|
-
//@id[id_name]
|
708
|
-
another paragraph.
|
709
|
-
TEXT
|
710
|
-
|
711
|
-
xhtml = <<HTML
|
712
|
-
<div class="section_type">
|
713
|
-
<h2>title of section</h2>
|
714
|
-
<p>
|
715
|
-
a paragraph.</p>
|
716
|
-
<p class="class_name" id="ID_NAME">
|
717
|
-
another paragraph.</p>
|
718
|
-
<!-- end of section_type -->
|
719
|
-
</div>
|
720
|
-
HTML
|
721
|
-
tree = BlockParser.parse(text.lines.to_a.map {|line| line.chomp })
|
722
|
-
assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
|
723
|
-
end
|
724
|
-
|
725
|
-
def test_decorator_for_table
|
726
|
-
text = <<TEXT
|
727
|
-
//@summary: Summary of the table
|
728
|
-
||!header 1||! header 2
|
729
|
-
||cell 1||cell 2
|
730
|
-
TEXT
|
731
|
-
|
732
|
-
xhtml = <<HTML
|
733
|
-
<table summary="Summary of the table">
|
734
|
-
<tr><th>header 1</th><th> header 2</th></tr>
|
735
|
-
<tr><td>cell 1</td><td>cell 2</td></tr>
|
736
|
-
</table>
|
737
|
-
HTML
|
738
|
-
tree = BlockParser.parse(text.lines.to_a.map {|line| line.chomp })
|
739
|
-
assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
|
740
|
-
end
|
741
|
-
|
742
|
-
def test_decorator_for_verbatim
|
743
|
-
text = <<TEXT
|
744
|
-
//@code[ruby]
|
745
|
-
def bonjour!
|
746
|
-
puts "Bonjour!"
|
747
|
-
end
|
748
|
-
TEXT
|
749
|
-
|
750
|
-
xhtml = <<HTML
|
751
|
-
<pre>
|
752
|
-
def bonjour!
|
753
|
-
puts "Bonjour!"
|
754
|
-
end
|
755
|
-
</pre>
|
756
|
-
HTML
|
757
|
-
|
758
|
-
tree = BlockParser.parse(text.lines.to_a)
|
759
|
-
assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
|
760
|
-
end
|
761
|
-
|
762
699
|
def test_comment_out_followed_by_a_verbatim_block
|
763
700
|
text = <<TEXT
|
764
701
|
the first paragraph
|
data/test/test_markdownformat.rb
CHANGED
@@ -68,6 +68,13 @@ IMAGE
|
|
68
68
|
assert_equal("A test for a link to \n#{$/}", @formatter.format(tree).to_s)
|
69
69
|
end
|
70
70
|
|
71
|
+
def test_link_from_image
|
72
|
+
text = "[[[[thumbnail of an image|http://www.example.org/image_thumb.png]]|http://www.example.org/image.png]]"
|
73
|
+
|
74
|
+
tree = BlockParser.parse(text.lines.to_a)
|
75
|
+
assert_equal("[](http://www.example.org/image.png)#{$/}", @formatter.format(tree).to_s)
|
76
|
+
end
|
77
|
+
|
71
78
|
def test_em
|
72
79
|
text = "string with ''emphasis'' "
|
73
80
|
tree = BlockParser.parse(text.lines.to_a)
|
@@ -501,65 +508,5 @@ TEXT
|
|
501
508
|
tree = BlockParser.parse(text.lines.to_a)
|
502
509
|
assert_equal(md_text, @formatter.format(tree).to_s)
|
503
510
|
end
|
504
|
-
|
505
|
-
def test_decorator_for_verbatim
|
506
|
-
text = <<TEXT
|
507
|
-
//@code[ruby]
|
508
|
-
def bonjour!
|
509
|
-
puts "Bonjour!"
|
510
|
-
end
|
511
|
-
TEXT
|
512
|
-
|
513
|
-
gfm_text =<<TEXT
|
514
|
-
```ruby
|
515
|
-
def bonjour!
|
516
|
-
puts "Bonjour!"
|
517
|
-
end
|
518
|
-
```
|
519
|
-
|
520
|
-
TEXT
|
521
|
-
|
522
|
-
md_text = <<TEXT
|
523
|
-
def bonjour!
|
524
|
-
puts "Bonjour!"
|
525
|
-
end
|
526
|
-
|
527
|
-
TEXT
|
528
|
-
|
529
|
-
tree = BlockParser.parse(text.lines.to_a)
|
530
|
-
assert_equal(gfm_text, @gfm_formatter.format(tree).to_s)
|
531
|
-
assert_equal(md_text, @formatter.format(tree).to_s)
|
532
|
-
end
|
533
|
-
|
534
|
-
def test_decorator_for_verbatim_block
|
535
|
-
text = <<TEXT
|
536
|
-
//@code[ruby]
|
537
|
-
<<<
|
538
|
-
def bonjour!
|
539
|
-
puts "Bonjour!"
|
540
|
-
end
|
541
|
-
>>>
|
542
|
-
TEXT
|
543
|
-
|
544
|
-
gfm_text =<<TEXT
|
545
|
-
```ruby
|
546
|
-
def bonjour!
|
547
|
-
puts "Bonjour!"
|
548
|
-
end
|
549
|
-
```
|
550
|
-
|
551
|
-
TEXT
|
552
|
-
|
553
|
-
md_text = <<TEXT
|
554
|
-
def bonjour!
|
555
|
-
puts "Bonjour!"
|
556
|
-
end
|
557
|
-
|
558
|
-
TEXT
|
559
|
-
|
560
|
-
tree = BlockParser.parse(text.lines.to_a)
|
561
|
-
assert_equal(gfm_text, @gfm_formatter.format(tree).to_s)
|
562
|
-
assert_equal(md_text, @formatter.format(tree).to_s)
|
563
|
-
end
|
564
511
|
end
|
565
512
|
|