return original text on parse failure

master
Jordan Orelli 9 years ago
parent 219b2f13c8
commit 6d1995a0c3

@ -18,14 +18,18 @@ module Bristlecode
) )
def Bristlecode.to_html(text) def Bristlecode.to_html(text)
begin
parser = Bristlecode::Parser.new parser = Bristlecode::Parser.new
parse_tree = parser.parse(text) parse_tree = parser.parse(text)
tree = Bristlecode::Transform.new.apply(parse_tree) tree = Bristlecode::Transform.new.apply(parse_tree)
html = tree.to_html html = tree.to_html
rescue Parslet::ParseFailed => parse_error
html = text
end
Sanitize.fragment(html, Bristlecode::Config) Sanitize.fragment(html, Bristlecode::Config)
end end
def Bristlecode.clean(text) def Bristlecode.clean!(text)
text.gsub!('&', '&') text.gsub!('&', '&')
text.gsub!('<', '&lt;') text.gsub!('<', '&lt;')
text.gsub!('>', '&gt;') text.gsub!('>', '&gt;')
@ -50,7 +54,7 @@ module Bristlecode
rule(:simple_href) { (url_close.absent? >> any).repeat } rule(:simple_href) { (url_close.absent? >> any).repeat }
rule(:simple_url) { url_open >> simple_href.as(:href) >> url_close } rule(:simple_url) { url_open >> simple_href.as(:href) >> url_close }
rule(:url_title_open) { str('[url=') } 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) { rule(:url_with_title) {
url_title_open >> url_title_open >>
url_title_href.as(:href) >> url_title_href.as(:href) >>
@ -100,6 +104,12 @@ module Bristlecode
children.each{|child| s << child.to_html } children.each{|child| s << child.to_html }
s.string s.string
end end
def to_text
s = StringIO.new
children.each{|child| s << child.to_text }
s.string
end
end end
class Text class Text
@ -107,12 +117,16 @@ module Bristlecode
def initialize(text) def initialize(text)
self.text = text.to_str self.text = text.to_str
Bristlecode.clean(self.text) Bristlecode.clean!(self.text)
end end
def to_html def to_html
text text
end end
def to_text
text
end
end end
class Bold class Bold
@ -125,6 +139,10 @@ module Bristlecode
def to_html def to_html
"<b>#{children.to_html}</b>" "<b>#{children.to_html}</b>"
end end
def to_text
"[b]#{children.to_text}[/b]"
end
end end
class Italic class Italic
@ -137,6 +155,10 @@ module Bristlecode
def to_html def to_html
"<i>#{children.to_html}</i>" "<i>#{children.to_html}</i>"
end end
def to_text
"[i]#{children.to_text}[/i]"
end
end end
class Url class Url
@ -149,27 +171,29 @@ module Bristlecode
self.title = Doc.new(args[:title]) self.title = Doc.new(args[:title])
else else
self.title_supplied = false self.title_supplied = false
self.title = Text.new(self.href) self.title = Text.new(args[:href].to_str.strip)
end end
end end
def href_ok? def href_ok?
href =~ /^https?:/ href =~ /^(\/|https?:\/\/)/
end end
def to_html def to_html
if href_ok? if href_ok?
"<a href=\"#{href}\">#{title.to_html}</a>" "<a href=\"#{href}\">#{title.to_html}</a>"
else else
reject to_text
end end
end end
def reject def to_text
if title_supplied if title_supplied
"[url=#{href}]#{title.to_html}[/url]" "[url=#{href}]#{title.to_text}[/url]"
else else
Text.new("[url]#{href}[/url]").to_html text = "[url]#{href}[/url]"
Bristlecode.clean!(text)
text
end end
end end
end end
@ -178,6 +202,10 @@ module Bristlecode
def to_html def to_html
"<br>" "<br>"
end end
def to_text
"[br]"
end
end end
class Img class Img
@ -188,15 +216,21 @@ module Bristlecode
end end
def src_ok? def src_ok?
src =~ /^(\/[^\/]|https?:\/\/)/ src =~ /^(\/|https?:\/\/)/
end end
def to_html def to_html
if src_ok? if src_ok?
"<img src=\"#{src}\">" "<img src=\"#{src}\">"
else else
Text.new("[img]#{src}[/img]").to_html to_text
end
end end
def to_text
text = "[img]#{src}[/img]"
Bristlecode.clean!(text)
text
end end
end end
end end

@ -57,7 +57,9 @@ module Bristlecode
input = '[url]http://example.com[/url]' input = '[url]http://example.com[/url]'
output = '<a href="http://example.com" rel="nofollow">http://example.com</a>' output = '<a href="http://example.com" rel="nofollow">http://example.com</a>'
expect(to_html(input)).to eq(output) expect(to_html(input)).to eq(output)
end
it 'trims whitespace around urls' do
input = '[url] http://example.com [/url]' input = '[url] http://example.com [/url]'
output = '<a href="http://example.com" rel="nofollow">http://example.com</a>' output = '<a href="http://example.com" rel="nofollow">http://example.com</a>'
expect(to_html(input)).to eq(output) expect(to_html(input)).to eq(output)
@ -113,6 +115,14 @@ module Bristlecode
input = '[img]ftp://example.com/cat.gif[/img]' input = '[img]ftp://example.com/cat.gif[/img]'
expect(to_html(input)).to eq(input) expect(to_html(input)).to eq(input)
end 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 end
describe Parser do describe Parser do

Loading…
Cancel
Save