pseudohikiparser 0.0.3 → 0.0.4.develop

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.
@@ -3,6 +3,7 @@
3
3
  require "pseudohiki/htmlformat"
4
4
  require "pseudohiki/plaintextformat"
5
5
  require "pseudohiki/markdownformat"
6
+ require 'pseudohiki/autolink'
6
7
  require "pseudohiki/version"
7
8
 
8
9
  # = PseudoHikiParser -- A converter of texts written in a Hiki-like notation into HTML or other formats.
@@ -13,25 +14,41 @@ module PseudoHiki
13
14
  # This class provides class methods for converting texts written in a Hiki-like notation into HTML or other formats.
14
15
  #
15
16
  class Format
16
- @@formatter = {}
17
- @@preset_options = {}
18
- @@type_to_formatter = {}
17
+ @formatter = {}
18
+ @preset_options = {}
19
+ @type_to_formatter = {}
20
+ @html_types = [:html, :xhtml, :html5]
19
21
 
20
22
  [
21
23
  [:html, HtmlFormat, nil],
22
24
  [:xhtml, XhtmlFormat, nil],
23
25
  [:html5, Xhtml5Format, nil],
24
- [:plain, PlainTextFormat, {:verbose_mode => false }],
25
- [:plain_verbose, PlainTextFormat, {:verbose_mode => true }],
26
- [:markdown, MarkDownFormat, { :strict_mode=> false, :gfm_style => false }],
27
- [:gfm, MarkDownFormat, { :strict_mode=> false, :gfm_style => true }]
26
+ [:plain, PlainTextFormat, { :verbose_mode => false }],
27
+ [:plain_verbose, PlainTextFormat, { :verbose_mode => true }],
28
+ [:markdown, MarkDownFormat, { :strict_mode => false, :gfm_style => false }],
29
+ [:gfm, MarkDownFormat, { :strict_mode => false, :gfm_style => true }]
28
30
  ].each do |type, formatter, options|
29
31
  preset_options = [type, nil]
30
- @@formatter[preset_options] = formatter.create(options)
31
- @@preset_options[type] = preset_options
32
- @@type_to_formatter[type] = formatter
32
+ @formatter[preset_options] = formatter.create(options)
33
+ @preset_options[type] = preset_options
34
+ @type_to_formatter[type] = formatter
33
35
  end
34
36
 
37
+ def self.select_formatter(format_type, options)
38
+ if options
39
+ @formatter[[format_type, options]] ||= @type_to_formatter[format_type].create(options)
40
+ else
41
+ @formatter[@preset_options[format_type]]
42
+ end
43
+ end
44
+
45
+ def self.auto_link_url?(auto_linker)
46
+ return true if auto_linker.nil?
47
+ auto_linker.auto_link_url?
48
+ end
49
+
50
+ private_class_method :select_formatter, :auto_link_url?
51
+
35
52
  # Converts <hiki_data> into a format specified by <format_type>
36
53
  #
37
54
  # <hiki_data> should be a string or an array of strings
@@ -45,14 +62,16 @@ module PseudoHiki
45
62
  # [:markdown] Markdown
46
63
  # [:gfm] GitHub Flavored Markdown
47
64
  #
48
- def self.format(hiki_data, format_type, options=nil, &block)
49
- tree = BlockParser.parse(hiki_data)
65
+ def self.format(hiki_data, format_type, options=nil,
66
+ auto_linker=BlockParser.auto_linker, &block)
67
+ tree = BlockParser.parse(hiki_data, auto_linker)
68
+ formatter = select_formatter(format_type, options)
50
69
 
51
- if options
52
- @@formatter[[format_type, options]] ||= @@type_to_formatter[format_type].create(options)
70
+ if @html_types.include? format_type
71
+ formatter.format(tree, { :auto_link_in_verbatim => auto_link_url?(auto_linker) })
53
72
  else
54
- @@formatter[@@preset_options[format_type]]
55
- end.format(tree).tap do |formatted|
73
+ formatter.format(tree)
74
+ end.tap do |formatted|
56
75
  block.call(formatted) if block
57
76
  end.to_s
58
77
  end
@@ -92,42 +111,44 @@ module PseudoHiki
92
111
  # <!-- end of section h2 -->
93
112
  # </div>
94
113
  #
95
- def self.to_html(hiki_data, &block)
96
- format(hiki_data, :html, options=nil, &block)
114
+ def self.to_html(hiki_data, auto_linker=BlockParser.auto_linker, &block)
115
+ format(hiki_data, :html, nil, auto_linker, &block)
97
116
  end
98
117
 
99
118
  # Converts <hiki_data> into XHTML1.0
100
119
  #
101
120
  # You can give a block to this method as in the case of ::to_html, but the parameter to the block is a tree of XhtmlElement objects
102
121
  #
103
- def self.to_xhtml(hiki_data, &block)
104
- format(hiki_data, :xhtml, options=nil, &block)
122
+ def self.to_xhtml(hiki_data, auto_linker=BlockParser.auto_linker, &block)
123
+ format(hiki_data, :xhtml, nil, auto_linker, &block)
105
124
  end
106
125
 
107
126
  # Converts <hiki_data> into HTML5
108
127
  #
109
128
  # You can give a block to this method as in the case of ::to_html, but the parameter to the block is a tree of Xhtml5Element objects
110
129
  #
111
- def self.to_html5(hiki_data, &block)
112
- format(hiki_data, :html5, options=nil, &block)
130
+ def self.to_html5(hiki_data, auto_linker=BlockParser.auto_linker, &block)
131
+ format(hiki_data, :html5, nil, auto_linker, &block)
113
132
  end
114
133
 
115
134
  # Converts <hiki_data> into plain texts without tags
116
135
  #
117
- def self.to_plain(hiki_data, &block)
118
- format(hiki_data, :plain, options=nil, &block)
136
+ def self.to_plain(hiki_data, auto_linker=BlockParser.auto_linker, &block)
137
+ format(hiki_data, :plain, nil, auto_linker, &block)
119
138
  end
120
139
 
121
140
  # Converts <hiki_data> into Markdown
122
141
  #
123
- def self.to_markdown(hiki_data, &block)
124
- format(hiki_data, :markdown, options=nil, &block)
142
+ def self.to_markdown(hiki_data, auto_linker=BlockParser.auto_linker, &block)
143
+ format(hiki_data, :markdown, nil, auto_linker, &block)
125
144
  end
126
145
 
127
146
  # Converts <hiki_data> into GitHub Flavored Markdown
128
147
  #
129
- def self.to_gfm(hiki_data, &block)
130
- format(hiki_data, :gfm, options=nil, &block)
148
+ def self.to_gfm(hiki_data, auto_linker=BlockParser.auto_linker, &block)
149
+ format(hiki_data, :gfm, nil, auto_linker, &block)
131
150
  end
132
151
  end
133
152
  end
153
+
154
+ require 'pseudohiki/sinatra_helpers' if defined? Sinatra
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+ require 'lib/pseudohiki/blockparser'
5
+ require 'lib/pseudohiki/htmlformat'
6
+ require 'lib/pseudohiki/autolink'
7
+
8
+ class TC_WikiName < MiniTest::Unit::TestCase
9
+ include PseudoHiki
10
+
11
+
12
+ def test_link_only_url
13
+ text = <<TEXT
14
+ a line with a url http://www.example.org/ and a WikiName.
15
+ TEXT
16
+
17
+ xhtml = <<HTML
18
+ <p>
19
+ a line with a url <a href="http://www.example.org/">http://www.example.org/</a> and a WikiName.
20
+ </p>
21
+ HTML
22
+ auto_linker = AutoLink::WikiName.new({:wiki_name => false})
23
+ tree = BlockParser.parse(text.lines.to_a, auto_linker)
24
+ assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
25
+ end
26
+
27
+ def test_link_wiki_name
28
+ text = <<TEXT
29
+ a line with a url http://www.example.org/ , an ^EscapedWikiName and a WikiName.
30
+ TEXT
31
+
32
+ xhtml = <<HTML
33
+ <p>
34
+ a line with a url <a href="http://www.example.org/">http://www.example.org/</a> , an EscapedWikiName and a <a href="WikiName">WikiName</a>.
35
+ </p>
36
+ HTML
37
+ auto_linker = AutoLink::WikiName.new
38
+ tree = BlockParser.parse(text.lines.to_a, auto_linker)
39
+ assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
40
+ end
41
+
42
+ def test_not_escape_wiki_name
43
+ text = <<TEXT
44
+ a line with a url http://www.example.org/ , an ^EscapedWikiName and a WikiName.
45
+ TEXT
46
+
47
+ xhtml = <<HTML
48
+ <p>
49
+ a line with a url <a href="http://www.example.org/">http://www.example.org/</a> , an ^<a href="EscapedWikiName">EscapedWikiName</a> and a <a href="WikiName">WikiName</a>.
50
+ </p>
51
+ HTML
52
+ auto_linker = AutoLink::WikiName.new({:wiki_name => true, :escape_wiki_name => false})
53
+ tree = BlockParser.parse(text.lines.to_a, auto_linker)
54
+ assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
55
+ end
56
+
57
+ def test_link_only_wiki_name
58
+ text = <<TEXT
59
+ a line with a url http://www.example.org/ , an ^EscapedWikiName and a WikiName.
60
+ TEXT
61
+
62
+ xhtml = <<HTML
63
+ <p>
64
+ a line with a url http://www.example.org/ , an EscapedWikiName and a <a href="WikiName">WikiName</a>.
65
+ </p>
66
+ HTML
67
+ auto_linker = AutoLink::WikiName.new({:url => false, :wiki_name => true, :escape_wiki_name => true})
68
+ tree = BlockParser.parse(text.lines.to_a, auto_linker)
69
+ assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
70
+ end
71
+
72
+ def test_link_wiki_name_in_quote
73
+ text = <<TEXT
74
+ ""a line with a url http://www.example.org/ , an ^EscapedWikiName and a WikiName.
75
+ TEXT
76
+
77
+ xhtml = <<HTML
78
+ <blockquote>
79
+ <p>
80
+ a line with a url <a href="http://www.example.org/">http://www.example.org/</a> , an EscapedWikiName and a <a href="WikiName">WikiName</a>.
81
+ </p>
82
+ </blockquote>
83
+ HTML
84
+
85
+ wikiname_off_xhtml = <<HTML
86
+ <blockquote>
87
+ <p>
88
+ a line with a url <a href="http://www.example.org/">http://www.example.org/</a> , an ^EscapedWikiName and a WikiName.
89
+ </p>
90
+ </blockquote>
91
+ HTML
92
+ auto_linker = AutoLink::WikiName.new({:wiki_name => true, :escape_wiki_name => true})
93
+ tree = BlockParser.parse(text.lines.to_a, auto_linker)
94
+ assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
95
+
96
+ BlockParser.auto_linker = AutoLink::WikiName.new({:wiki_name => true, :escape_wiki_name => true})
97
+ tree = BlockParser.parse(text.lines.to_a)
98
+ assert_equal(xhtml, XhtmlFormat.format(tree).to_s)
99
+
100
+ BlockParser.auto_linker = nil
101
+ tree = BlockParser.parse(text.lines.to_a)
102
+ assert_equal(wikiname_off_xhtml, XhtmlFormat.format(tree).to_s)
103
+ end
104
+ end
@@ -39,7 +39,7 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
39
39
  paragraph_line = "This is a paragraph."
40
40
  paragraph = parser.select_leaf_type(paragraph_line).create(paragraph_line)
41
41
  assert_equal([paragraph_line], paragraph)
42
- assert_equal(nil, paragraph.nominal_level)
42
+ assert_equal(nil, paragraph.level)
43
43
  end
44
44
 
45
45
  def test_nestedleaf_create
@@ -47,12 +47,12 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
47
47
  level1_heading_line = "!This is a level1 heading."
48
48
  heading1 = parser.select_leaf_type(level1_heading_line).create(level1_heading_line)
49
49
  assert_equal([["This is a level1 heading."]], heading1)
50
- assert_equal(1, heading1.nominal_level)
50
+ assert_equal(1, heading1.level)
51
51
 
52
52
  level2_heading_line = "!!This is a level2 heading."
53
53
  heading2 = parser.select_leaf_type(level2_heading_line).create(level2_heading_line)
54
54
  assert_equal([["This is a level2 heading."]], heading2)
55
- assert_equal(2, heading2.nominal_level)
55
+ assert_equal(2, heading2.level)
56
56
  end
57
57
 
58
58
  def test_select_leaf_type
@@ -85,7 +85,7 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
85
85
  stack.push create_leaf(paragraph_str)
86
86
  paragraph_tree = stack.tree
87
87
  assert_equal([[[paragraph_str]]],paragraph_tree)
88
- assert_equal(nil,paragraph_tree.first.nominal_level)
88
+ assert_equal(nil,paragraph_tree.first.level)
89
89
  another_paragraph = create_leaf(another_paragraph_str)
90
90
  stack.push another_paragraph
91
91
  assert_equal([[[paragraph_str,
@@ -96,7 +96,7 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
96
96
  stack.push create_leaf("!"+heading_str)
97
97
  heading_tree = stack.tree
98
98
  # heading_tree = push_leaf_on_stack("!"+heading_str).tree
99
- assert_equal(1,heading_tree.first.nominal_level)
99
+ assert_equal(1,heading_tree.first.level)
100
100
  assert_equal(HeadingNode, heading_tree.first.class)
101
101
  assert_equal(HeadingLeaf, heading_tree.first.first.class)
102
102
  stack.push create_leaf("!!"+heading_str)
@@ -107,7 +107,7 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
107
107
  stack.push create_leaf("!!"+heading_str)
108
108
  heading2_tree = stack.tree
109
109
  assert_equal([[[[heading_str]]]], heading2_tree)
110
- assert_equal(2,heading2_tree.first.nominal_level)
110
+ assert_equal(2,heading2_tree.first.level)
111
111
 
112
112
  stack = PseudoHiki::BlockParser.new.stack
113
113
  stack.push create_leaf("!"+heading_str)
@@ -180,11 +180,11 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
180
180
  parser.stack.push list2_leaf
181
181
  current_node_superclass = parser.stack.current_node.class.superclass
182
182
  leaf_superclass = list1_leaf.block.superclass
183
- assert_equal(2, parser.stack.current_node.nominal_level)
183
+ assert_equal(2, parser.stack.current_node.level)
184
184
  assert_equal(ListNode, list1_leaf.block)
185
- assert_equal(1, list1_leaf.nominal_level)
185
+ assert_equal(1, list1_leaf.level)
186
186
  assert_equal(ListNode, list2_leaf.block)
187
- assert_equal(2, list2_leaf.nominal_level)
187
+ assert_equal(2, list2_leaf.level)
188
188
  assert_equal(ListWrapNode, parser.stack.current_node.class)
189
189
  # assert_equal(true, parser.stack.current_node.class.kind_of?(PseudoHiki::BlockParser::ListTypeBlockNode))
190
190
  assert_equal(PseudoHiki::BlockParser::ListLeafNode, current_node_superclass)
@@ -192,8 +192,8 @@ class TC_BlockLeaf < MiniTest::Unit::TestCase
192
192
  assert_equal(false, current_node_superclass == leaf_superclass)
193
193
  assert_equal(true, PseudoHiki::BlockParser::ListTypeBlockNode == leaf_superclass)
194
194
  assert_equal(true, parser.breakable?(blocknode_end))
195
- assert_equal(false, parser.stack.current_node.nominal_level <= list1_leaf.nominal_level)
196
- assert_equal(true, parser.stack.current_node.nominal_level <= list2_leaf.nominal_level)
195
+ assert_equal(false, parser.stack.current_node.level <= list1_leaf.level)
196
+ assert_equal(true, parser.stack.current_node.level <= list2_leaf.level)
197
197
  assert_equal(true, parser.breakable?(list1_leaf))
198
198
  assert_equal(true, parser.breakable?(list2_leaf))
199
199
  parser.stack.pop
@@ -311,6 +311,73 @@ 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
+ def test_sectioning_node
344
+ text = <<TEXT
345
+ ! Main title
346
+
347
+ //@begin[header]
348
+ !! first title in header
349
+
350
+ paragraph
351
+
352
+ !! second title in header
353
+
354
+ paragraph2
355
+
356
+ //@end[header]
357
+
358
+ !! first subtitle in main part
359
+
360
+ paragraph3
361
+
362
+ TEXT
363
+
364
+ expected_tree = [[[[" Main title\n"]],
365
+ [
366
+ [[[" first title in header\n"]],
367
+ [[["paragraph\n"]]]],
368
+ [[[" second title in header\n"]],
369
+ [[["paragraph2\n"]]]]
370
+ ],
371
+ [[[" first subtitle in main part\n"]],
372
+ [[["paragraph3\n"]]]]]]
373
+
374
+
375
+ tree = PseudoHiki::BlockParser.parse(text)
376
+ assert_equal(expected_tree, tree)
377
+ assert_kind_of(PseudoHiki::BlockParser::BlockElement::SectioningNode, tree[0][1])
378
+ assert_equal("header", tree[0][1].node_id)
379
+ end
380
+
314
381
  def test_comment_out_followed_by_a_verbatim_block
315
382
  text = <<TEXT
316
383
  the first paragraph