rbbcode 0.1.6 → 0.1.7

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.
@@ -19,12 +19,12 @@ module RbbCode
19
19
 
20
20
  def make_html(node)
21
21
  output = ''
22
- case node.class.to_s
23
- when 'RbbCode::RootNode'
22
+ case node
23
+ when RbbCode::RootNode
24
24
  node.children.each do |child|
25
25
  output << make_html(child)
26
26
  end
27
- when 'RbbCode::TagNode'
27
+ when RbbCode::TagNode
28
28
  custom_tag_method = "html_from_#{node.tag_name}_tag"
29
29
  if respond_to?(custom_tag_method)
30
30
  output << send(custom_tag_method, node)
@@ -33,9 +33,14 @@ module RbbCode
33
33
  node.children.each do |child|
34
34
  inner_html << make_html(child)
35
35
  end
36
- output << content_tag(map_tag_name(node.tag_name), inner_html)
36
+ to_append = content_tag(map_tag_name(node.tag_name), inner_html)
37
+ if node.preformatted?
38
+ to_append = content_tag('pre', to_append)
39
+ end
40
+ output << to_append
41
+ #puts output
37
42
  end
38
- when 'RbbCode::TextNode'
43
+ when RbbCode::TextNode
39
44
  output << node.text
40
45
  else
41
46
  raise "Don't know how to make HTML from #{node.class}"
@@ -50,6 +50,16 @@ module RbbCode
50
50
  @name = name
51
51
  end
52
52
 
53
+ def is_not_preformatted
54
+ @schema.unmark_as_preformatted(@name)
55
+ self
56
+ end
57
+
58
+ def is_preformatted
59
+ @schema.mark_as_preformatted(@name)
60
+ self
61
+ end
62
+
53
63
  def may_be_nested
54
64
  @schema.allow_descent(@name, @name)
55
65
  self
@@ -154,6 +164,7 @@ module RbbCode
154
164
  @required_parents = {}
155
165
  @no_text = []
156
166
  @twin_closers = []
167
+ @preformatted = []
157
168
  end
158
169
 
159
170
  def close_twins(tag_name)
@@ -199,6 +210,7 @@ module RbbCode
199
210
  @never_empty = []
200
211
  @no_text = []
201
212
  @twin_closers = []
213
+ @preformatted = []
202
214
  use_defaults
203
215
  end
204
216
 
@@ -206,10 +218,18 @@ module RbbCode
206
218
  'br'
207
219
  end
208
220
 
221
+ def mark_as_preformatted(tag_name)
222
+ @preformatted << tag_name.to_s unless @preformatted.include?(tag_name.to_s)
223
+ end
224
+
209
225
  def paragraph_tag_name
210
226
  'p'
211
227
  end
212
228
 
229
+ def preformatted?(tag_name)
230
+ @preformatted.include?(tag_name.to_s)
231
+ end
232
+
213
233
  def require_parents(parents, child) #:nodoc:
214
234
  @required_parents[child.to_s] = parents.collect { |p| p.to_s }
215
235
  parents.each do |parent|
@@ -254,6 +274,10 @@ module RbbCode
254
274
  return true
255
275
  end
256
276
 
277
+ def unmark_as_preformatted(tag_name)
278
+ @preformatted.delete(tag_name.to_s)
279
+ end
280
+
257
281
  def unrequire_parent(parent, child)
258
282
  @required_parents.delete(child.to_s)
259
283
  end
@@ -270,6 +294,7 @@ module RbbCode
270
294
  tag('url').may_not_be_nested
271
295
  tag('img').may_not_be_nested
272
296
  tag('code').may_not_be_nested
297
+ tag('code').is_preformatted
273
298
  tag('p').may_not_be_nested
274
299
  tag('*').must_be_child_of('list')
275
300
  tag('*').closes_twins
@@ -70,6 +70,7 @@ module RbbCode
70
70
  super(parent)
71
71
  @tag_name = tag_name
72
72
  @value = value
73
+ @preformatted = false
73
74
  end
74
75
 
75
76
  def inner_bb_code
@@ -78,6 +79,14 @@ module RbbCode
78
79
  end
79
80
  end
80
81
 
82
+ def preformat!
83
+ @preformatted = true
84
+ end
85
+
86
+ def preformatted?
87
+ @preformatted
88
+ end
89
+
81
90
  def to_bb_code
82
91
  if @value.nil?
83
92
  output = "[#{@tag_name}]"
@@ -262,7 +271,7 @@ module RbbCode
262
271
  case char
263
272
  when '['
264
273
  current_parent << TextNode.new(current_parent, '[')
265
- # No need to reset current_token or current_token_type
274
+ # No need to reset current_token or current_token_type, because now we're in a new possible tag
266
275
  when '/'
267
276
  current_token_type = :closing_tag
268
277
  current_token << '/'
@@ -302,7 +311,12 @@ module RbbCode
302
311
  current_parent << tag_node
303
312
  current_parent = tag_node
304
313
  end # else, don't do anything--the tag is invalid and will be ignored
305
- current_token_type = :unknown
314
+ if @schema.preformatted?(current_parent.tag_name)
315
+ current_token_type = :preformatted
316
+ current_parent.preformat!
317
+ else
318
+ current_token_type = :unknown
319
+ end
306
320
  current_token = ''
307
321
  elsif char == "\r" or char == "\n"
308
322
  current_parent << TextNode.new(current_parent, current_token)
@@ -339,6 +353,27 @@ module RbbCode
339
353
  current_token_type = :text
340
354
  current_token << char
341
355
  end
356
+ when :preformatted
357
+ if char == '['
358
+ current_parent << TextNode.new(current_parent, current_token)
359
+ current_token_type = :possible_preformatted_end
360
+ current_token = '['
361
+ else
362
+ current_token << char
363
+ end
364
+ when :possible_preformatted_end
365
+ current_token << char
366
+ if current_token == "[/#{current_parent.tag_name}]" # Did we just see the closing tag for this preformatted element?
367
+ current_parent = current_parent.parent
368
+ current_token_type = :unknown
369
+ current_token = ''
370
+ elsif char == ']' # We're at the end of this opening/closing tag, and it's not the closing tag for the preformatted element
371
+ current_parent << TextNode.new(current_parent, current_token)
372
+ current_token_type = :preformatted
373
+ current_token = ''
374
+ end
375
+ else
376
+ raise "Unknown token type in state machine: #{current_token_type}"
342
377
  end
343
378
  end
344
379
  # Handle whatever's left in the current token
@@ -76,5 +76,15 @@ describe RbbCode::HtmlMaker do
76
76
  end
77
77
  end
78
78
  end
79
- end
79
+
80
+ it 'wraps preformatted tags in <pre>' do
81
+ expect_html('<p><pre><code>Some code</code></pre></p>') do
82
+ tag('p') do
83
+ tag('code', nil, true) do
84
+ text 'Some code'
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
80
90
  end
@@ -78,8 +78,9 @@ class NodeBuilder
78
78
  self << TextNode.new(@current_parent, contents)
79
79
  end
80
80
 
81
- def tag(tag_name, value = nil, &block)
81
+ def tag(tag_name, value = nil, preformatted = false, &block)
82
82
  tag_node = TagNode.new(@current_parent, tag_name, value)
83
+ tag_node.preformat! if preformatted
83
84
  self << tag_node
84
85
  original_parent = @current_parent
85
86
  @current_parent = tag_node
data/spec/parser_spec.rb CHANGED
@@ -39,10 +39,6 @@ describe RbbCode::Parser do
39
39
  @parser.parse('[img]http://example.com/image.jpg[/img]').should == '<p><img src="http://example.com/image.jpg" alt=""/></p>'
40
40
  end
41
41
 
42
- it 'should turn [code] to <code>' do
43
- @parser.parse('Too bad [code]method_missing[/code] is rarely useful').should == '<p>Too bad <code>method_missing</code> is rarely useful</p>'
44
- end
45
-
46
42
  it 'should parse nested tags' do
47
43
  @parser.parse('[b][i]This is bold-italic[/i][/b]').should == '<p><strong><em>This is bold-italic</em></strong></p>'
48
44
  end
@@ -101,5 +97,21 @@ describe RbbCode::Parser do
101
97
  @parser.parse("[list]\n[*]one\n[*]two\n[/list]"
102
98
  ).should == '<ul><li>one</li><li>two</li></ul>'
103
99
  end
100
+
101
+ context 'parsing [code] tags' do
102
+ # Thanks to fatalerrorx for finding these
103
+ it 'wraps the <code> tags in <pre> tags' do
104
+ @parser.parse('The [code]some code[/code] should be preformatted').should == '<p>The <pre><code>some code</code></pre> should be preformatted</p>'
105
+ end
106
+
107
+ it 'leaves line breaks inside untouched' do
108
+ @parser.parse("Two lines of code:\n\n[code]line 1\n\nline 2[/code]\n\nAnd some more text.").should ==
109
+ "<p>Two lines of code:</p><p><pre><code>line 1\n\nline 2</code></pre></p><p>And some more text.</p>"
110
+ end
111
+
112
+ it 'treats tags other than the closing tag as literals' do
113
+ @parser.parse('[code]This is [b]bold[/b] text[/code]').should == '<p><pre><code>This is [b]bold[/b] text</code></pre></p>'
114
+ end
115
+ end
104
116
  end
105
117
  end
data/spec/spec_helper.rb CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'spec'
4
4
 
5
- def puts(foo)
6
- raise 'puts called'
7
- end
5
+ #def puts(foo)
6
+ # raise 'puts called'
7
+ #end
8
8
 
9
9
  require File.expand_path(File.dirname(__FILE__) + '/../lib/rbbcode')
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 6
9
- version: 0.1.6
8
+ - 7
9
+ version: 0.1.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jarrett Colby
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-07 00:00:00 -06:00
17
+ date: 2010-03-17 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency