Although Ruby On Rails has support for various markup languages like textile and markdown via RedCloth and BlueCloth gems, often simple HTML is more preferable solution(like "Some HTML is OK" on Flickr). This article contains simple Ruby function ae_some_html which allows usage of basic HTML tags and converts everything else to entity-escaped HTML code.
This function ae_some_html converts all HTML special symbols to HTML entities:
Afterwards it parses escaped string with regular expressions replacing safe constructions with proper HTML code. Here is the source code of the function: source code: Ruby def ae_some_html(s) # converting newlines s.gsub!(/\r\n?/, "\n") # escaping HTML to entities s = s.to_s.gsub('&', '&').gsub('<', '<').gsub('>', '>') # blockquote tag support s.gsub!(/\n?<blockquote>\n*(.+?)\n*<\/blockquote>/im, "<blockquote>\\1</blockquote>") # other tags: b, i, em, strong, u %w(b i em strong u).each { |x| s.gsub!(Regexp.new('<(' + x + ')>(.+?)</('+x+')>', Regexp::MULTILINE|Regexp::IGNORECASE), "<\\1>\\2</\\1>") } # A tag support # href="" attribute auto-adds http:// s = s.gsub(/<a.+?href\s*=\s*['"](.+?)["'].*?>(.+?)<\/a>/im) { |x| '<a href="' + ($1.index('://') ? $1 : 'http://'+$1) + "\">" + $2 + "</a>" } # replacing newlines to <br> ans <p> tags # wrapping text into paragraph s = "<p>" + s.gsub(/\n\n+/, "</p>\n\n<p>"). gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') + "</p>" s end The function allows following HTML:
Any of unclosed or broken tags will not be converted to HTML. As you can see this function also replaces line breaks with <br />(single line break) and <p>(two or more line breaks) tags. Usage example: source code: Ruby s = "Test is a <b>test</b> <blockquote> >>><em>It Works!</em><<< </blockquote> <a href='anyexample.com'>Linking</a> works! <b>Broken HTML does not work: </i> " print ae_some_html(s) HTML result is: It is possible to put ae_some_html call in before_save function of your Model class. For example: source code: Ruby / Ruby On Rails class Comment < ActiveRecord::Base belongs_to :user validates_length_of :text, :minimum => 3 # copy-paste ae_come_html here # or to separate .rb file in lib folder (and 'require' it) def before_save # text_view field is for View # original text field saved for editing self.text_view = ae_some_html(self.text) # if you don't need to save original text # just do # self.text = ae_some_html(self.text) end end You can also add ae_some_html to app/helpers/application_helper.rb and call it directly from application templates. This approach usually requires caching techniques to avoid unnecessary ae_some_html calls.
|
|