Discourse.BBCode =
QUOTE_REGEXP: /\[quote=([^\]]*)\]([\s\S]*?)\[\/quote\]/im
# Define our replacers
replacers:
base:
withoutArgs:
"ol": (_, content) -> "
#{content}
"
"li": (_, content) -> "#{content}"
"ul": (_, content) -> ""
"code": (_, content) -> "#{content}"
"url": (_, url) -> "#{url}"
"email": (_, address) -> "#{address}"
"img": (_, src) -> "
"
withArgs:
"url": (_, href, title) -> "#{title}"
"email": (_, address, title) -> "#{title}"
"color": (_, color, content) ->
return content unless /^(\#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?)|(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)$/.test(color)
"#{content}"
# For HTML emails
email:
withoutArgs:
"b": (_, content) -> "#{content}"
"i": (_, content) -> "#{content}"
"u": (_, content) -> "#{content}"
"s": (_, content) -> "#{content}"
"spoiler": (_, content) -> "#{content}"
withArgs:
"size": (_, size, content) -> "#{content}"
# For sane environments that support CSS
default:
withoutArgs:
"b": (_, content) -> "#{content}"
"i": (_, content) -> "#{content}"
"u": (_, content) -> "#{content}"
"s": (_, content) -> "#{content}"
"spoiler": (_, content) -> "#{content}"
withArgs:
"size": (_, size, content) -> "#{content}"
# Apply a particular set of replacers
apply: (text, environment) ->
replacer = Discourse.BBCode.parsedReplacers()[environment]
replacer.forEach (r) -> text = text.replace r.regexp, r.fn
text
parsedReplacers: ->
return @parsed if @parsed
result = {}
Object.keys Discourse.BBCode.replacers, (name, rules) ->
parsed = result[name] = []
Object.keys Object.merge(Discourse.BBCode.replacers.base.withoutArgs, rules.withoutArgs), (tag, val) ->
parsed.push(regexp: RegExp("\\[#{tag}\\]([\\s\\S]*?)\\[\\/#{tag}\\]", "igm"), fn: val)
Object.keys Object.merge(Discourse.BBCode.replacers.base.withArgs, rules.withArgs), (tag, val) ->
parsed.push(regexp: RegExp("\\[#{tag}=?(.+?)\\\]([\\s\\S]*?)\\[\\/#{tag}\\]", "igm"), fn: val)
@parsed = result
@parsed
buildQuoteBBCode: (post, contents="") ->
sansQuotes = contents.replace(@QUOTE_REGEXP, '').trim()
return "" if sansQuotes.length == 0
# Strip the HTML from cooked
tmp = document.createElement('div')
tmp.innerHTML = post.get('cooked')
stripped = tmp.textContent||tmp.innerText
# Let's remove any non alphanumeric characters as a kind of hash. Yes it's
# not accurate but it should work almost every time we need it to. It would be unlikely
# that the user would quote another post that matches in exactly this way.
stripped_hashed = stripped.replace(/[^a-zA-Z0-9]/g, '')
contents_hashed = contents.replace(/[^a-zA-Z0-9]/g, '')
result = "[quote=\"#{post.get('username')}, post:#{post.get('post_number')}, topic:#{post.get('topic_id')}"
# If the quote is the full message, attribute it as such
if stripped_hashed == contents_hashed
result += ", full:true"
result += "\"]\n#{sansQuotes}\n[/quote]\n\n"
formatQuote: (text, opts) ->
# Replace quotes with appropriate markup
while matches = @QUOTE_REGEXP.exec(text)
paramsString = matches[1]
paramsString = paramsString.replace(/\"/g, '')
paramsSplit = paramsString.split(/\, */)
params=[]
paramsSplit.each (p, i) ->
if i > 0
assignment = p.split(':')
if assignment[0] and assignment[1]
params.push(key: assignment[0], value: assignment[1].trim())
username = paramsSplit[0]
# Arguments for formatting
args =
username: username
params: params
quote: matches[2].trim()
avatarImg: opts.lookupAvatar(username) if opts.lookupAvatar
templateName = 'quote'
templateName = "quote_#{opts.environment}" if opts?.environment
text = text.replace(matches[0], "" + HANDLEBARS_TEMPLATES[templateName](args) + "")
text
format: (text, opts) ->
text = Discourse.BBCode.apply(text, opts?.environment || 'default')
# Add quotes
text = Discourse.BBCode.formatQuote(text, opts)
text