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