',
'Unordered list item',
'[list][*]item 1[*] item2[/list]',
:list],
'Ordered list (numerical)' => [
/\[list=1(:.*)?\](.+)\[\/list(:.)?\1?\]/mi,
'\2',
'Ordered list numerically',
'[list=1][*]item 1[*] item2[/list]',
:list],
'Ordered list (alphabetical)' => [
/\[list=a(:.*)?\](.+)\[\/list(:.)?\1?\]/mi,
'\2',
'Ordered list alphabetically',
'[list=a][*]item 1[*] item2[/list]',
:list],
'Definition List' => [
/\[dl\](.*?)\[\/dl\]/im,
'
\1
',
'List of terms/items and their definitions',
'[dl][dt]Fusion Reactor[/dt][dd]Chamber that provides power to your... nerd stuff[/dd][dt]Mass Cannon[/dt][dd]A gun of some sort[/dd][/dl]',
:definelist],
'Definition Term' => [
/\[dt\](.*?)\[\/dt\]/mi,
'
',
'Definition definitions',
'[dd]my definition[/dd',
:definition],
'Quote' => [
/\[quote(:.*)?=(?:")?(.*?)(?:")?\](.*?)\[\/quote\1?\]/mi,
'',
'Quote with citation',
'[quote=mike]Now is the time...[/quote]',
:quote],
'Quote (Sourceless)' => [
/\[quote(:.*)?\](.*?)\[\/quote\1?\]/mi,
'',
'Quote (sourceclass)',
'[quote]Now is the time...[/quote]',
:quote],
'Link' => [
/\[url=(?:")?(.*?)(?:")?\](.*?)\[\/url\]/mi,
'\2',
'Hyperlink to somewhere else',
'Maybe try looking on [url=http://google.com]Google[/url]?',
:link],
'Link (Implied)' => [
/\[url\](.*?)\[\/url\]/mi,
'\1',
'Hyperlink (implied)',
'Maybe try looking on [url]http://google.com[/url]',
:link],
'Link (Automatic)' => [
%r{(\A|\s)(https?://[^\s<\[]+)},
' \2',
'Hyperlink (automatic)',
'Maybe try looking on http://www.google.com',
:link],
'Link (Automatic without leading http(s))' => [
/(\A|\s)(www\.[^\s<\[]+)/,
' \2',
'Hyperlink (automatic without leading http(s))',
'Maybe try looking on www.google.com',
:link],
'Image (Resized)' => [
/\[img(:.+)? size=#{@@quote_matcher}(\d+)x(\d+)\2\](.*?)\[\/img\1?\]/im,
'',
'Display an image with a set width and height',
'[img size=96x96]http://www.google.com/intl/en_ALL/images/logo.gif[/img]',
:image],
'Image (Alternative)' => [
/\[img=([^\[\]].*?)\.(#{@@imageformats})\]/im,
'',
'Display an image (alternative format)',
'[img=http://myimage.com/logo.gif]',
:image],
'Image (Aligned)' => [
/\[img(:.+)? align=(left|right)\](.*?)\[\/img\1?\]/im,
'',
'Display an aligned image',
'[img align=right]http://catsweekly.com/crazycat.jpg[/img]',
:image],
'Image' => [
/\[img(:.+)?\]([^\[\]].*?)\.(#{@@imageformats})\[\/img\1?\]/im,
'',
'Display an image',
'Check out this crazy cat: [img]http://catsweekly.com/crazycat.jpg[/img]',
:image],
'YouTube' => [
/\[youtube\](.*?)\?v=([\w\d\-]+).*?\[\/youtube\]/im,
# '',
'',
'Display a video from YouTube.com',
'[youtube]http://youtube.com/watch?v=E4Fbk52Mk1w[/youtube]',
:video],
'YouTube (Alternative)' => [
/\[youtube\](.*?)\/v\/([\w\d\-]+)\[\/youtube\]/im,
# '',
'',
'Display a video from YouTube.com (alternative format)',
'[youtube]http://youtube.com/watch/v/E4Fbk52Mk1w[/youtube]',
:video],
'Vimeo' => [
/\[vimeo\](.*?)\/(\d+)\[\/vimeo\]/im,
'',
'Display a video from Vimeo',
'[vimeo]http://www.vimeo.com/3485239[/vimeo]',
:video],
'Google Video' => [
/\[gvideo\](.*?)\?docid=([-]{0,1}\d+).*\[\/gvideo\]/mi,
'',
'Display a video from Google Video',
'[gvideo]http://video.google.com/videoplay?docid=-2200109535941088987[/gvideo]',
:video],
'Email' => [
%r{\[email[^:=]?\](((?!\[/email\]).)*)\[/email\]}mi,
'\1',
'Link to email address',
'[email]wadus@wadus.com[/email]',
:email],
'Email (alternative)' => [
%r{\[email[:=]([^\]]+)\](((?!\[/email\]).)*)(\[/email\1?\])?}mi,
'\2',
'Link to email address',
'[email:wadus@wadus.com]Email Me[/email]',
:email],
'Align' => [
/\[align=(.*?)\](.*?)\[\/align\]/mi,
"\\2",
'Align this object using float',
'Here\'s a wrapped image: [align=right][img]image.png[/img][/align]',
:align],
'Left' => [
/\[left(:.+)?\](.*?)\[\/left\1?\]/mi,
"
\\2
",
'Aligns contents along the left side',
'[left]Left-aligned content[/left]',
:left],
'Center' => [
/\[center(:.+)?\](.*?)\[\/center\1?\]/mi,
"
\\2
",
'Aligns contents on the center',
'[center]Centered content[/center]',
:center],
'Right' => [
/\[right(:.+)?\](.*?)\[\/right\1?\]/mi,
"
\\2
",
'Aligns contents along the right side',
'[right]Right-aligned content[/right]',
:right],
'Line break' => [
/\[br\]/mi,
" ",
'Inserts line break tag',
'One[br]Two[br]Three lines!',
:br]
}
class << self
# Convert a string with BBCode markup into its corresponding HTML markup
#
# === Basic Usage
#
# The first parameter is the string off BBCode markup to be processed
#
# text = "[b]some bold text to markup[/b]"
# output = BBRuby.to_html(text)
# # output => "some bold text to markup"
#
# === Custom BBCode translations
#
# You can supply your own BBCode markup translations to create your own custom markup
# or override the default BBRuby translations (parameter is a hash of custom translations).
#
# The hash takes the following format: "name" => [regexp, replacement, description, example, enable_symbol]
#
# custom_blockquote = {
# 'Quote' => [
# /\[quote(:.*)?=(.*?)\](.*?)\[\/quote\1?\]/mi,
# '
\2
\3
',
# 'Quote with citation',
# '[quote=mike]please quote me[/quote]',
# :quote
# ]
# }
#
# === Enable and Disable specific tags
#
# BBRuby will allow you to only enable certain BBCode tags, or to explicitly disable certain tags.
# Pass in either :disable or :enable to set your method, followed by the comma-separated list of tags
# you wish to disable or enable
#
# BBRuby.to_html(text, {}, true, :enable, :image, :bold, :quote)
# BBRuby.to_html(text, {}, true, :disable, :image, :video, :color)
#
def to_html(text, tags_alternative_definition={}, escape_html=true, method=:disable, *tags)
text = process_tags(text, tags_alternative_definition, escape_html, method, *tags)
# parse spacing
text.gsub!( /\r\n?/, "\n" )
# return markup
text
end
# The same as BBRuby.to_html except the output is passed through simple_format first
#
# Returns text transformed into HTML using simple formatting rules. Two or more consecutive newlines(\n\n)
# are considered as a paragraph and wrapped in
tags. One newline (\n) is considered as a linebreak and
# a tag is appended. This method does not remove the newlines from the text.
#
def to_html_with_formatting(text, tags_alternative_definition={}, escape_html=true, method=:disable, *tags)
text = process_tags(text, tags_alternative_definition, escape_html, method, *tags)
# parse spacing
simple_format( text )
end
# Returns the list of tags processed by BBRuby in a Hash object
def tag_list
@@tags
end
private
def process_tags(text, tags_alternative_definition={}, escape_html=true, method=:disable, *tags)
text = text.dup
# escape "<, >, &" and quotes to remove any html
if escape_html
text.gsub!( '&', '&' )
text.gsub!( '<', '<' )
text.gsub!( '>', '>' )
text.gsub!( '"', '"' )
text.gsub!( "'", ''' )
end
tags_definition = @@tags.merge(tags_alternative_definition)
# parse bbcode tags
case method
when :enable
tags_definition.each_value do |t|
gsub!(text, t[0], t[1]) if tags.include?( t[4] )
end
when :disable
# this works nicely because the default is disable and the default set of tags is [] (so none disabled) :)
tags_definition.each_value do |t|
gsub!(text, t[0], t[1]) unless tags.include?( t[4] )
end
end
text
end
def gsub!(text, pattern, replacement)
if replacement.class == String
# just replace if replacement is String
while text.gsub!( pattern, replacement ); end
else
# call replacement
# It may be Proc or lambda with one argument
# Argument is MatchData. See 'Bold' tag name for example.
while text.gsub!( pattern ){ replacement.call($~) }; end
end
end
# extracted from Rails ActionPack
def simple_format( text )
start_tag = '
'
text = text.to_s.dup
text.gsub!(/\r\n?/, "\n") # \r\n and \r => \n
text.gsub!(/\n\n+/, "
\n\n#{start_tag}") # 2+ newline => paragraph
text.gsub!(/([^\n]\n)(?=[^\n])/, '\1 ') # 1 newline => br
text.insert 0, start_tag
text << ''
end
end # class << self
end
class String
# Convert a string with BBCode markup into its corresponding HTML markup
#
# === Basic Usage
#
# text = "[b]some bold text to markup[/b]"
# output = text.bbcode_to_html
# # output => "some bold text to markup"
#
# === Custom BBCode translations
#
# You can supply your own BBCode markup translations to create your own custom markup
# or override the default BBRuby translations (parameter is a hash of custom translations).
#
# The hash takes the following format: "name" => [regexp, replacement, description, example, enable_symbol]
#
# custom_blockquote = {
# 'Quote' => [
# /\[quote(:.*)?=(.*?)\](.*?)\[\/quote\1?\]/mi,
# '
\2
\3
',
# 'Quote with citation',
# '[quote=mike]please quote me[/quote]',
# :quote
# ]
# }
#
# output = text.bbcode_to_html(custom_blockquote)
#
# === Enable and Disable specific tags
#
# BBRuby will allow you to only enable certain BBCode tags, or to explicitly disable certain tags.
# Pass in either :disable or :enable to set your method, followed by the comma-separated list of tags
# you wish to disable or enable
#
# output = text.bbcode_to_html({}, true, :enable, :image, :bold, :quote)
# output = text.bbcode_to_html({}, true, :disable, :image, :video, :color)
#
# === HTML auto-escaping
#
# By default, BBRuby will auto-escape HTML. You can prevent this by passing in false as the second
# parameter
#
# output = text.bbcode_to_html({}, false)
#
def bbcode_to_html(tags_alternative_definition = {}, escape_html=true, method=:disable, *tags)
BBRuby.to_html(self, tags_alternative_definition, escape_html, method, *tags)
end
# Replace the string contents with the HTML-converted markup
def bbcode_to_html!(tags_alternative_definition = {}, escape_html=true, method=:disable, *tags)
self.replace(BBRuby.to_html(self, tags_alternative_definition, escape_html, method, *tags))
end
def bbcode_to_html_with_formatting(tags_alternative_definition = {}, escape_html=true, method=:disable, *tags)
BBRuby.to_html_with_formatting(self, tags_alternative_definition, escape_html, method, *tags)
end
# Replace the string contents with the HTML-converted markup using simple_format
def bbcode_to_html_with_formatting!(tags_alternative_definition = {}, escape_html=true, method=:disable, *tags)
self.replace(BBRuby.to_html_with_formatting(self, tags_alternative_definition, escape_html, method, *tags))
end
end