require "bb-ruby/version" module BBRuby # allowable image formats @@imageformats = 'png|bmp|jpg|gif|jpeg' @@quote_matcher = '("|'|)' # built-in BBCode tabs that will be processed @@tags = { # tag name => [regex, replace, description, example, enable/disable symbol] 'Bold' => [ /\[b(:.*)?\](.*?)\[\/b\1?\]/mi, '\2', 'Embolden text', 'Look [b]here[/b]', :bold], 'Italics' => [ /\[i(:.+)?\](.*?)\[\/i\1?\]/mi, '\2', 'Italicize or emphasize text', 'Even my [i]cat[/i] was chasing the mailman!', :italics], 'Underline' => [ /\[u(:.+)?\](.*?)\[\/u\1?\]/mi, '\2', 'Underline', 'Use it for [u]important[/u] things or something', :underline], 'Strikeout' => [ /\[s(:.+)?\](.*?)\[\/s\1?\]/mi, '\2', 'Strikeout', '[s]nevermind[/s]', :strikeout], 'Delete' => [ /\[del(:.+)?\](.*?)\[\/del\1?\]/mi, '\2', 'Deleted text', '[del]deleted text[/del]', :delete], 'Insert' => [ /\[ins(:.+)?\](.*?)\[\/ins\1?\]/mi, '\2', 'Inserted Text', '[ins]inserted text[/del]', :insert], 'Code' => [ /\[code(:.+)?\](.*?)\[\/code\1?\]/mi, '\2', 'Code Text', '[code]some code[/code]', :code], 'Size' => [ /\[size=#{@@quote_matcher}(.*?)\1\](.*?)\[\/size\]/im, '\3', 'Change text size', '[size=20]Here is some larger text[/size]', :size], 'Color' => [ /\[color=#{@@quote_matcher}(\w+|\#\w{6})\1(:.+)?\](.*?)\[\/color\3?\]/im, '\4', 'Change text color', '[color=red]This is red text[/color]', :color], 'Ordered List' => [ /\[ol\](.*?)\[\/ol\]/mi, '
    \1
', 'Ordered list', 'My favorite people (alphabetical order): [ol][li]Jenny[/li][li]Alex[/li][li]Beth[/li][/ol]', :orderedlist], 'Unordered List' => [ /\[ul\](.*?)\[\/ul\]/mi, '', 'Unordered list', 'My favorite people (order of importance): [ul][li]Jenny[/li][li]Alex[/li][li]Beth[/li][/ul]', :unorderedlist], 'List Item' => [ /\[li\](.*?)\[\/li\]/mi, '
  • \1
  • ', 'List item', 'See ol or ul', :listitem], 'List Item (alternative)' => [ /\[\*(:[^\[]+)?\]([^(\[|\<)]+)/mi, '
  • \2
  • ', 'List item (alternative)', '[*]list item', :listitem], 'Unordered list (alternative)' => [ /\[list(:.*)?\]((?:(?!\[list(:.*)?\]).)*)\[\/list(:.)?\1?\]/mi, '', '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, '
    \1
    ', 'List of definition terms', '[dt]definition term[/dt]', :defineterm], 'Definition Definition' => [ /\[dd\](.*?)\[\/dd\]/mi, '
    \1
    ', 'Definition definitions', '[dd]my definition[/dd', :definition], 'Quote' => [ /\[quote(:.*)?=(?:")?(.*?)(?:")?\](.*?)\[\/quote\1?\]/mi, '
    \2
    \3
    ', 'Quote with citation', "[quote=mike]Now is the time...[/quote]", :quote], 'Quote (Sourceless)' => [ /\[quote(:.*)?\](.*?)\[\/quote\1?\]/mi, '
    \2
    ', '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)' => [ /(\A|\s)((https?:\/\/|www\.)[^\s<]+)/, ' \2', 'Hyperlink (automatic)', 'Maybe try looking on http://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' => [ /\[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' => [ /\[email(:.+)?\](.+)\[\/email\1?\]/i, '\2', 'Link to email address', '[email]wadus@wadus.com[/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] } 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" ) text.gsub!( /\n/, "
    \n" ) text.gsub!(/\[quote\]/, '
    Quote:
    ') text.gsub!(/\[quote(:.*)?="?(.*?)"?\]/, '
    Quote: \2
    ') text.gsub!(/\[\/quote\]/, '
    ') # 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 { |t| text.gsub!(t[0], t[1]) if tags.include?(t[4]) } when :disable # this works nicely because the default is disable and the default set of tags is [] (so none disabled) :) tags_definition.each_value { |t| text.gsub!(t[0], t[1]) unless tags.include?(t[4]) } end text 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