Smiley Parser

Hi,

Does anyone know of smiley parser - that can parse for standard smileys { :), :frowning: etc } and replace with images?

I also wanted URL parser that can automagically give hyperlinks to URLs.

Any inputs?

PS:

http://www.rubyonrails.ch/doku.php/wiki:syntax#smileys

This seemed interesting, but didnt really knw how to use it.

Regards, Sandeep G

Hi,

Does anyone know of smiley parser - that can parse for standard
smileys { :), :frowning: etc } and replace with images?

I also wanted URL parser that can automagically give hyperlinks to
URLs.

auto_link ?

I don't know of one, but this shouldn't be hard, just a bunch of gsubs
really.

Fred

Sandeep,

I recently had to do this for an app... spent lots of time searching. Here, this will save you some time:

reg = /(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(: [0-9]{1,5})?(\/[^\s]*)/ix line.gsub(reg,%q[<a href='\0'>\0</a>])

Do some console tests with that just to be sure it matches what you want, but it's the best regexp I've found for URL matching... i.e. the most complete. Note, you can grab various parts using \1, \2, etc. \0 just grabs the whole match.

As for the smilies, I have no idea... that would be a much more complex matching algorithm. It sounds like an ideal candidate for a plugin... i.e. "acts_as_smiley". :slight_smile:

-Dan

Of course, as Fred mentioned, auto_link as a helper will do all that anyway: http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M001058

Hehe.

-Dan

Hi,

Thank you all for inputs.

Is there a more efficient way of doing GSUB, instead of doing gsub on entire text for each smiley? As the list of Smileys grows big, gsub in loop will be a overhead.

Regards, Sandeep G

Nathan Esquenazi wrote:

Hi,

Thank you all for inputs.

Is there a more efficient way of doing GSUB, instead of doing gsub on entire text for each smiley? As the list of Smileys grows big, gsub in loop will be a overhead.

well first of all, i'd worry about that when that became a problem rather than assuming it might. Secondly you could probably use something like

smileys = {'smiley1' => 'xxx', 'smiley2' => 'yyy', 'smiley1' => 'zzz' text.gsub /(smiley1)|(smiley2)|(smiley3)/ do |match|    smileys[match] end

Frederick Cheung wrote:

smileys = {'smiley1' => 'xxx', 'smiley2' => 'yyy', 'smiley1' => 'zzz' text.gsub /(smiley1)|(smiley2)|(smiley3)/ do |match|   smileys[match] end

That duplicates smileys 1 2 and 3. Can we DRY it?

And could .gsub be .scan instead?

Frederick Cheung wrote:

smileys = {'smiley1' => 'xxx', 'smiley2' => 'yyy', 'smiley1' => 'zzz' text.gsub /(smiley1)|(smiley2)|(smiley3)/ do |match| smileys[match] end

That duplicates smileys 1 2 and 3. Can we DRY it?

sure, was just trying to be explicit. You could build the regexp from
the smileys array. There's probably a limit on how long a regexp can
be though.

And could .gsub be .scan instead?

doesn't gsub make more sense if the goal is to replace stuff in the
source text with something else?

Fred

Hi Fred,

def smileyize(text)

        smileys = {   "8-)" => 'icon_cool.gif' ,   "8-O" => 'icon_eek.gif',   "8-o" => 'icon_eek.gif',   ':-(' => 'icon_sad.gif',   ':-)' => 'icon_smile.gif',    }   text.gsub /("8-o")/ do |match|      image_path(smileys[match])         end return text end

I tried something like this, but didnt work. It sends back the same text.Can you help me on this?

I even tried to simplify things and test with this: <%= "XX".gsub /("XX")/ do |match| "YY" end%> This displays XX itself :frowning:

Frederick Cheung wrote:

Sandeep.

Try it without the quotes:

"XX".gsub /(XX)/ do |match| "YY" end

=> "YY"

or even just: "XX".gsub /XX/, "YY"

:sunglasses: ... er... icon_cool.gif

-Danimal

Thank you all! That was nice of you!

Posting my final func:

def smileyize(text) smileys = { "8-O" => 'icon_eek.gif', "8-o" => 'icon_eek.gif',":-(" => 'icon_sad.gif', ":-)" => 'icon_smile.gif', ":-/" => 'icon_doubt.gif' , ":-\\" => 'icon_doubt2.gif', ":-\?" =>'icon_confused.gif',":-D" => 'icon_biggrin.gif', ":-P" =>'icon_razz.gif',":-o" => 'icon_surprised.gif',":-O" =>'icon_surprised.gif',":-x"=>'icon_silenced.gif',":-X" => 'icon_silenced.gif',":-|" => 'icon_neutral.gif',";-)" =>'icon_wink.gif',"^_^" => 'icon_fun.gif',":?:" => 'icon_question.gif',":!:" => 'icon_exclaim.gif',"LOL" =>'icon_lol.gif' }

text = (text).gsub /(8-O)|(:-\))|(:-\()|(:-\/)|(:-\\)|(:-\?)|(:-D)|(:-P)|(:-o)|(:-O)|(:-X)|(:-x)|(:-\|)|(;-\))|(\^_\^)|(:\?:)|(:!:)|(LOL)/ do |match| image_tag(image_path("smileys"+"/"+smileys[match])) end

  return text end

Regards, Sandeep G

It occurs to me that YAML could be a real boon here. I.e. define your mappings via YAML (or XML but who does that anymore? *grin*). Probably define it as something simple like:

mappings:   icon_eek.gif: 8-O   icon_sad.gif: :frowning:

etc.

then read it into a very similar hash table to what you have, maybe reversing the keys if need be.

I think it would be cool to have an "acts_as_smiley" plugin. Maybe something where you could do:

class Post < ActiveRecord::Base   acts_as_smiley :body, :icons => "myicons" # (this would be a subdir of "images" in public) end

Then, "underneath the covers", it redefines the body accessor so that it returns the smiley-parsed value of :body.

I could even imagine some other hooks like defining additional accessors, like :body_nosmiley or :body_smiley that skips or runs the parser.

Just a thought. Anyway, glad you got it working!

-Danimal 8-O

That regexp is scary. If you think of adding more smileys:

regexp = Regexp.new("("+ smileys.keys.map{|k| Regexp.escape(k)}.join("|") +")")

with the added benefit that you need to add more smileys in just one place.