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.
@@ -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