From 6d1995a0c3c8f9ed9f1570e2663cbef96d286077 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Fri, 6 Nov 2015 08:04:59 -0500 Subject: [PATCH] return original text on parse failure --- bristlecode.rb | 64 +++++++++++++++++++++++++-------- spec/bristlecode/parser_spec.rb | 10 ++++++ 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/bristlecode.rb b/bristlecode.rb index 9536c54..48ab082 100644 --- a/bristlecode.rb +++ b/bristlecode.rb @@ -18,14 +18,18 @@ module Bristlecode ) def Bristlecode.to_html(text) - parser = Bristlecode::Parser.new - parse_tree = parser.parse(text) - tree = Bristlecode::Transform.new.apply(parse_tree) - html = tree.to_html + begin + parser = Bristlecode::Parser.new + parse_tree = parser.parse(text) + tree = Bristlecode::Transform.new.apply(parse_tree) + html = tree.to_html + rescue Parslet::ParseFailed => parse_error + html = text + end Sanitize.fragment(html, Bristlecode::Config) end - def Bristlecode.clean(text) + def Bristlecode.clean!(text) text.gsub!('&', '&') text.gsub!('<', '<') text.gsub!('>', '>') @@ -50,7 +54,7 @@ module Bristlecode rule(:simple_href) { (url_close.absent? >> any).repeat } rule(:simple_url) { url_open >> simple_href.as(:href) >> url_close } rule(:url_title_open) { str('[url=') } - rule(:url_title_href) { (match(']').absent? >> any).repeat } + rule(:url_title_href) { (match(']').absent? >> any).repeat(1) } rule(:url_with_title) { url_title_open >> url_title_href.as(:href) >> @@ -100,6 +104,12 @@ module Bristlecode children.each{|child| s << child.to_html } s.string end + + def to_text + s = StringIO.new + children.each{|child| s << child.to_text } + s.string + end end class Text @@ -107,12 +117,16 @@ module Bristlecode def initialize(text) self.text = text.to_str - Bristlecode.clean(self.text) + Bristlecode.clean!(self.text) end def to_html text end + + def to_text + text + end end class Bold @@ -125,6 +139,10 @@ module Bristlecode def to_html "#{children.to_html}" end + + def to_text + "[b]#{children.to_text}[/b]" + end end class Italic @@ -137,6 +155,10 @@ module Bristlecode def to_html "#{children.to_html}" end + + def to_text + "[i]#{children.to_text}[/i]" + end end class Url @@ -149,27 +171,29 @@ module Bristlecode self.title = Doc.new(args[:title]) else self.title_supplied = false - self.title = Text.new(self.href) + self.title = Text.new(args[:href].to_str.strip) end end def href_ok? - href =~ /^https?:/ + href =~ /^(\/|https?:\/\/)/ end def to_html if href_ok? "#{title.to_html}" else - reject + to_text end end - def reject + def to_text if title_supplied - "[url=#{href}]#{title.to_html}[/url]" + "[url=#{href}]#{title.to_text}[/url]" else - Text.new("[url]#{href}[/url]").to_html + text = "[url]#{href}[/url]" + Bristlecode.clean!(text) + text end end end @@ -178,6 +202,10 @@ module Bristlecode def to_html "
" end + + def to_text + "[br]" + end end class Img @@ -188,15 +216,21 @@ module Bristlecode end def src_ok? - src =~ /^(\/[^\/]|https?:\/\/)/ + src =~ /^(\/|https?:\/\/)/ end def to_html if src_ok? "" else - Text.new("[img]#{src}[/img]").to_html + to_text end end + + def to_text + text = "[img]#{src}[/img]" + Bristlecode.clean!(text) + text + end end end diff --git a/spec/bristlecode/parser_spec.rb b/spec/bristlecode/parser_spec.rb index 6233490..17c7aa6 100644 --- a/spec/bristlecode/parser_spec.rb +++ b/spec/bristlecode/parser_spec.rb @@ -57,7 +57,9 @@ module Bristlecode input = '[url]http://example.com[/url]' output = 'http://example.com' expect(to_html(input)).to eq(output) + end + it 'trims whitespace around urls' do input = '[url] http://example.com [/url]' output = 'http://example.com' expect(to_html(input)).to eq(output) @@ -113,6 +115,14 @@ module Bristlecode input = '[img]ftp://example.com/cat.gif[/img]' expect(to_html(input)).to eq(input) end + + it 'returns the original text on parse failure' do + input = '[img]http://example.com/dog.gif[img]http://example.com/cat.gif[/img][/img]' + expect(to_html(input)).to eq(input) + + input = '[url][url]x[/url][/url]' + expect(to_html(input)).to eq(input) + end end describe Parser do