Extending RedCloth

I wanted to put emoticons into Textile for
Beast, but to do it, I needed to use very
few lines of code since there is a 500LOC limit on Beast. After a long time
debugging, here’s what I came up with:

First, I made a new method in the RedCloth namespace.


class RedCloth
  def refs_smiley(text)
    text.gsub!(/(\s)~(:P|:D|:O|:o|:S|:\||;\)|:'\(|:\)|:\()/) do |m|
      bef,ma = $~[1..2]
      filename = ActionController::AbstractRequest.relative_url_root+"/images/emoticons/"+(ma.split(//).collect{|l|l[0]}.join('_'))+".png"
      "#{bef}<img src='#{filename}' title='#{ma}' class='smiley' />"
    end
  end
end

All I’m doing here is some nifty gsubbing with a block. The resultant
replacement expression is the last thing returned by the block. This RegExp
will match any of the possible emoticons I specified as long as they are
preceeded by a ~. This prevents things like :Person from being converted
into :Person. Here is
the post about it with all the emotes I allow. Try it out. While I was at
it, I re-activated tables for Textile in Beast. This was totally necessary. ;)

Then I changed the text format helper in Beast to reflect my new method:


  def format_text(text)
    RedCloth.new(auto_link(text.to_s)).to_html(:textile,:refs_smiley)
  end

The key part here is the options passed to to_html. This allows you to
pick any rules you want for your code generation. I found that when I named
the method smiley, it wouldn’t be called. That’s because there is a
RegExp match that happens when the rule methods are called that matches on
methods that begin with refs_. I think you could get around that
somehow, but I just went with it. The default options that are implicit on a
call of to_html are :markdown,:textile, and as you can see, I left out
markdown. Also, I realized that white_list was causing my generated
tables to be ruined, so I took that out. This might be a little dangerous,
but I’m not too worried at this point. I might have to submit a patch (or
make a modification) to the white_list plugin. The possibilities here are
endless, thanks to _why.



Comments

  1. evan

    September 13, 2006 at 6:52 PM

    Hey, I saw this blog entry in the making. :)
    Thanks for documenting it; eventually I will probably need it.


  2. evan

    September 13, 2006 at 6:52 PM

    And in a burst of irony, my smiley face between "making" and the "." was swallowed by typo somehow.


  3. Hank

    September 13, 2006 at 6:52 PM

    I think I have smilies turned off on comments for Typo. :P


  4. Joey

    September 13, 2006 at 6:52 PM

    I was, I believe, a partner in crime with Hank in this certain occasion.


  5. Hans

    September 13, 2006 at 6:52 PM

    Lately I’ve been thinking about extending RedCloth with some of the screen scraping functions of Hpricot.

    Am I crazy? Probably.

    Anyway thanks for writing this article and giving me a place to start.

    It looks like your code snippet is now the [official example](http://github.com/jgarber/redcloth/tree/master/test/test_extensions.rb) in the Redcloth test cases.