Introducing Quesadilla

Posted on

I've been thinking about making this Ruby gem for awhile. It was originally called "cheddar-text", but I decided something that sounded more fun would be better. Awhile back, I was trying to rewrite this library in C and named the repo Quesadilla. It turns out, writing a C extensions that manipulates strings is really hard, so now the Ruby version is named Quesadilla.

Quesadilla is an entity-style text parser. Quesadilla was extracted from Cheddar. It's what powers all of Cheddar's text parsing. It was inspired a bit by Twitter's tweet entity.

Since Cheddar works on iOS and Mac (as well as the web), I needed something that could give me ranges for special things in the text. iOS and Mac convert this to an NSAttributedString using the indices included in each entity. Here's the source for how Cheddar for iOS does it in Objective-C.

We also use Quesadilla in Seesaw (my day job). It works really well for us there too.

Quesadilla supports extracting the following:

  • Markdown (italic, bold, bold italic, strikethrough, code, and links)
  • Links
  • Named Emoji
  • Hashtags
  • User Mentions

Here's a little example of what a hashtag looks like:

Quesadilla.extract('Some #awesome text')
# => {
#   display_text: "Some #awesome text",
#   display_html: "Some <a href=\"#hashtag-awesome\" class=\"tag\">#awesome</a> text",
#   entities: [
#     {
#       type: "hashtag",
#       text: "#awesome",
#       display_text: "#awesome",
#       indices: [5, 13],
#       hashtag: "awesome",
#       display_indices: [5, 13]
#     }
#   ]
# }

You can even provide a custom user validator:

validator = lambda do |username|
  # User.where('LOWER(username) = ?', username.downcase).first.try(:id)
  username == 'soffes'

extraction = Quesadilla.extract('Real @soffes and fake @nobody', users: true, user_validator: validator)
# An entity for `soffes` will be added, but not for `nobody`

Anyway, Quesadilla does a lot of stuff. Checkout the readme for more or read the documentation. It's tested on Ruby 1.9.2, Ruby 1.9.3, Ruby 2.0.0, JRuby 1.7.2 (1.9 mode), and Rubinius 2.0.0 (1.9 mode), so it should work for you.

Hit my up on Twitter if you find this useful. Enjoy!