diff --git a/bristlecode.rb b/bristlecode.rb
index 935cdee..1a5b02a 100644
--- a/bristlecode.rb
+++ b/bristlecode.rb
@@ -27,12 +27,21 @@ module Bristlecode
rule(:url_close) { str('[/url]') | eof }
rule(:simple_href) { (url_close.absent? >> any).repeat }
rule(:simple_url) { url_open >> simple_href.as(:href) >> url_close }
- rule(:url) { simple_url.as(:url) }
+ rule(:url_title_open) { str('[url=') }
+ rule(:url_title_href) { (match(']').absent? >> any).repeat }
+ rule(:url_with_title) {
+ url_title_open >>
+ url_title_href.as(:href) >>
+ match(']') >>
+ children.as(:title) >>
+ url_close
+ }
+ rule(:url) { (simple_url | url_with_title).as(:url) }
rule(:eof) { any.absent? }
rule(:tag) { bold | italic | url | linebreak }
rule(:elem) { text.as(:text) | tag }
- rule(:tag_open) { bold_open | italic_open | url_open }
+ rule(:tag_open) { bold_open | italic_open | url_open | url_title_open }
rule(:tag_close) { bold_close | italic_close | url_close }
rule(:tag_delim) { tag_open | tag_close | linebreak }
@@ -70,6 +79,15 @@ module Bristlecode
def initialize(text)
self.text = text.to_str.strip
+ clean
+ end
+
+ def clean
+ text.gsub!('&', '&')
+ text.gsub!('<', '<')
+ text.gsub!('>', '>')
+ text.gsub!('"', '"')
+ text.gsub!("'", ''')
end
def to_html
@@ -80,16 +98,12 @@ module Bristlecode
class Bold
attr_accessor :children
- def initialize(children)
- self.children = children
+ def initialize(children)
+ self.children = Doc.new(children)
end
def to_html
- s = StringIO.new
- s << ""
- children.each{|child| s << child.to_html }
- s << ""
- s.string
+ "#{children.to_html}"
end
end
@@ -97,15 +111,11 @@ module Bristlecode
attr_accessor :children
def initialize(children)
- self.children = children
+ self.children = Doc.new(children)
end
def to_html
- s = StringIO.new
- s << ""
- children.each{|child| s << child.to_html }
- s << ""
- s.string
+ "#{children.to_html}"
end
end
@@ -114,11 +124,15 @@ module Bristlecode
def initialize(args)
self.href = args[:href].to_str.strip
- self.title = args[:title] || href
+ if args.has_key? :title
+ self.title = Doc.new(args[:title])
+ else
+ self.title = Text.new(href)
+ end
end
def to_html
- "#{title}"
+ "#{title.to_html}"
end
end
diff --git a/spec/bristlecode/parser_spec.rb b/spec/bristlecode/parser_spec.rb
index 1f45cc0..e948f62 100644
--- a/spec/bristlecode/parser_spec.rb
+++ b/spec/bristlecode/parser_spec.rb
@@ -17,6 +17,14 @@ module Bristlecode
expect(to_html(" \t \n \n \t")).to eq("")
end
+ it 'handles special chars' do
+ expect(to_html('&')).to eq('&')
+ expect(to_html('>')).to eq('>')
+ expect(to_html('<')).to eq('<')
+ expect(to_html("'")).to eq(''')
+ expect(to_html('"')).to eq('"')
+ end
+
it 'handles plain text just fine' do
expect(to_html("plaintext")).to eq("plaintext")
end
@@ -62,6 +70,12 @@ module Bristlecode
expect(to_html(input)).to eq(output)
end
+ it 'handles urls with titles' do
+ input = '[url=google.com]the google[/url]'
+ output = 'the google'
+ expect(to_html(input)).to eq(output)
+ end
+
it 'renders a linebreak' do
expect(to_html('[br]')).to eq('
')
end
@@ -157,6 +171,11 @@ module Bristlecode
describe '#url' do
it 'can parse correct urls' do
expect(parser.url).to parse('[url]google.com[/url]')
+ expect(parser.url).to parse('[url=google.com]google[/url]')
+ end
+
+ it 'can parse title subtrees' do
+ expect(parser.url).to parse('[url=google.com]this is [b]google[/b] yo[/url]')
end
it "doesn't die on elements nested in simple urls" do