Posts tagged with 'ruby':

Announcing Coloration, editor color scheme converter


Without further ado I'm introducing Coloration - editor/IDE color scheme converter. It is an evolution of tm2jed tool and at the moment it can convert Textmate color themes (in XML plist format) to Vim, JEdit and Kate/KWrite/KDevelop color schemes. So if you are Textmate->Vim convert or you just envy Textmate users for their good looking, dark themes now you have no excuse to not try out Coloration.

Here's how Vim with Sunburst theme looks like:

Vim with Sunburst color scheme

If you want to give Coloration a try you have two options. Either you can use online version at coloration.sickill.net or you can install ruby gem coloration:

gem install coloration

It will give you tm2vim, tm2jedit and tm2katepart commands. Note it requires ruby 1.9.

Let me know if you find it useful. Source code is available at github.com/sickill/coloration.

Enjoy!

View Comments

Thoughts on Ruby gem dependencies


The problem

Having gem bundler is great. First, you can forget about gem version collisions (damn you activation errors!). Second, you can forget about manually installing gems on all your machines. Third, you can use git repositories and local directories as gem sources which is neat and is invaluable when working on your own gems. But bundler is a workaround. Yes, it's a workaround for poor rubygems design. Let's look at few examples of the problems I've noticed.

I'll start with dm-paperclip gem. Recently I was porting my Merb app to Rails 3 and I've encountered few problems with this little sucker. The biggest headache I had with validations. Note it was fixed recently in dm-paperclip, but makes good example of problem that still exists in relation to other gems. dm-paperclip was doing this:

...
unless defined?(DataMapper::Validate).nil?
...

What's the problem here? Let's say you have following lines in your Gemfile:

gem "dm-validations"
gem "dm-paperclip"

Looks like everything should work. Wrong! Rails 3 requires all the gems from your Gemfile by calling Bundler.require Rails.env but Bundler.require doesn't use order of gems specified in Gemfile. For me it first required dm-paperclip and then dm-validations, so when dm-paperclip was being required DataMapper::Validate wasn't defined yet. I heard that it may change in future and Bundler will respect the order, to some degree of course. Does this problem lay in bundler or in dm-paperclip? In none of them. Bundler doesn't know about "optional" dependencies of dm-paperclip and dm-paperclip has no way to tell us/bundler it can benefit from some optional lib.

Anyway, this is good example why explicit requiring of gems seems better in this scenario. By adding require "this" and require "that" in places where you actually need it you're breaking DRY principle (you already have it in Gemfile) but you can have perfect control of the order. This way you can solve above dm-paperclip problem. And by using explicit requires you can move your app away from bundler (to i.e. rip or Isolate) if you want to and you don't need to add these requires because they're already in the app. But why would you need to think about gem require order in your Rails app? You shouldn't think about it. And you don't always know what are optional libraries for the gems you're using.

Let's look at second issue. Multiple markdown processing libraries. There's BlueCloth, Maruku, Kramdown, RDiscount, rpeg-markdown and some more. All of them are doing the same thing but the difference is mainly in performance. BlueCloth and Maruku are pure ruby libraries, RDiscount and rpeg-markdown are bindings to fast C libraries. But they all have the same interface:

BlueCloth.new(markdown_string).to_html          # bluecloth
Maruku.new(markdown_string).to_html             # maruku
Kramdown::Document.new(markdown_string).to_html # kramdown
RDiscount.new(markdown_string).to_html          # rdiscount
Markdown.new(markdown_string).to_html           # rpeg-markdown

Now, if gem A depends on Maruku and gem B depends on RDiscount I'll have two markdown libraries with identical interface required in my app. I know that RDiscount is faster because it's C and I'd like all of my app's functionalities to use it but gem A will use slower Maruku. Sad but true.

Third rubygems issue is something in the middle between dm-paperclip+bundler problem and markdown problem. Devise, "Flexible authentication solution for Rails with Warden" supports many ORMs (ActiveRecord, DataMapper, Mongoid). Now, all code related to integration with mentioned ORMs is included in devise itself. Devise checks which ORM is available at runtime (like in dm-paperclip example) and requires appropriate file choosing from many available alternatives (like in markdown example). It's far from being perfect. How this could be improved?

It'd be probably better to put integration code in separate gems. This way people involved in development of ORMs could work on integration without access to Devise repository. Yeah, I know, it's not a big deal on github, just fork and send pull request. But it worked really well for dm-rails. DataMapper guys were more interested in getting DM work under Rails 3 than Rails developers and they definitely knew more about DM specifics. They provide the gem and everyone is happy. But if there were many gems providing this functionality for Devise then user would be responsible for installing it. There's better solution on my mind though, read on.

Possible solutions

To solve first mentioned issue let's just add optional dependencies to rubygems. It could work in following way.

Gem author specifies list of optional dependencies:

Gem::Specification.new do |s|
  ...
  s.optional_dependency "nokogiri", "for tidying output"
  s.optional_dependency "bar", "for bar support"
end

You are installing the gem:

$ gem install foo
Installed foo.
Optional dependencies for foo:
- nokogiri (for tidying output)
- bar (for bar support)

Or you could install it with optional deps:

$ gem install foo --with-optional-deps
Installed nokogiri.
Installed bar.
Installed foo.

Benefits of having explicit optional deps would be:

  • user could see what are the optionals and decide if he wants them
  • automatic tools like bundler could be configured to install optional deps, either for all gems or for specific ones
  • bundler could require optional gems before the one which "optionally" depends on them, solving require order issues

To solve second and third issue we can add "provider gems". What's that? Decent Linux package managers like Archlinux's pacman allows you to specify that the package provides the same functionality and the same interface as the other one. In rubygems it could look like this:

Gem authors of all mentioned markdown processors could specify that their gem provides "markdown":

Gem::Specification.new do |s|
  ...
  s.provides "markdown"
  ...
end

Additionally they would need to provide unified interface, in this case simple Markdown = RDiscount should do the trick.

Now, you as gem user could use it like this:

require "markdown"
Markdown.new(markdown_string).to_html

This way gem A and B can depend on "markdown", and you decide which one you want to install. gem install A or bundle install in this case could show you this:

$ gem install A
Gem "A" depends on "markdown". Please select provider gem from following alternatives:
1. BlueCloth
2. Maruku
3. ....

Of course having two "markdown providers" with the same interface (note that require "markdown" is also part of the interface) would be impossible in the same gem environment but this can easily be solved by using Bundler, Isolate or awesome rvm's gemsets. Only problem I see here is when one gem depends on "maruku", not on "markdown", another gem depends on "rdiscount", and your app depends on both of these gems... yuck.

"Provider gems" can be easily applied to Devise's case:

Gem::Specification.new do |s|
  s.name "devise"
  s.dependency "devise-orm-proxy"
  ...
end

Gem::Specification.new do |s|
  s.name "devise-orm-mongoid"
  s.provides "devise-orm-proxy"
  ...
end

Gem::Specification.new do |s|
  s.name "devise-orm-dm"
  s.provides "devise-orm-proxy"
  ...
end

Another example why "provider gems" can be good idea is extlib / AS collision. For example dm-paperclip depends on extlib because it needs inflector. But you can't easily use it in Rails 3 app at the moment because AS+extlib = "UsersesController" :) dm-core used to use extlib for inflections and has been recently converted to AS for some reasons.

"Provider gems" can solve also this problem. Look at this:

Gem::Specification.new do |s|
  s.name "dm-core"
  s.dependency "inflector"
  ...
end

Gem::Specification.new do |s|
  s.name "dm-paperclip"
  s.dependency "inflector"
  ...
end

Gem::Specification.new do |s|
  s.name "extlib"
  s.provides "..."
  s.provides "inflector"
  s.provides "..."
end

Gem::Specification.new do |s|
  s.name "activesupport"
  s.provides "..."
  s.provides "inflector"
  s.provides "..."
end

Conclusion

I realize that these proposed solutions are not ideal and there are some edge cases which need some more thought but maybe it will become a good start for further discussion about the problem. Rubygems code is on github now so we can fork it and improve it!

View Comments

Quick and dirty hack for RSpec's before(:all)


RSpec is generally nice testing framework. It supports before and after hooks which can be invoked before/after each test case or all test cases. before(:all) is a little confusing though. It runs your "before" block before all "describes" and "contexts", also nested ones. Here's example:

describe User do
  before(:all) { puts "preparing for war" }
  it "should foo" do
    ...
  end
  context "active" do
    it "should bar" do
      ...
    end
  end
  context "inactive" do
    it "should baz" do
      ...
    end
  end
end

I would expect "preparing for war" to show up once. But before(:all) was called thrice. First, for top level "describe", then two times for "contexts". There were some suggestions to change this behaviour or to add and option to skip call for nested groups but nothing has changed recently. People are even trying some crazy hacks like this.

What I needed was to wipe database for every model spec and every request spec because factory generated records made my build unstable (due to uniqueness validations). After trying few things I ended up with using before(:all) with some condition. First, I've added before_top_level_group method to Spec::Runner::Configuration and saved it in spec/before_top_level_group.rb:

$_groups = []

class Spec::Runner::Configuration
  def before_top_level_group
    before(:all) do
      top_level_group = self.class.to_s[/^.+ExampleGroup::([^:]+)/, 1]
      unless $_groups.any? { |g| top_level_group == g }
        $_groups << top_level_group
        yield
      end
    end
  end
end

Then in spec_helper I used it like this:

require 'before_top_level_group'

Spec::Runner.configure do |config|
  config.before_top_level_group do
    # re-migrate db for each top-level group (it usually equals one *_spec.rb file)
    DataMapper.auto_migrate!
  end
end

Voila! I know it's a dirty hack but it works for me and I'll be using it until RSpec is patched or I switch my testing framework to something else (Bacon looks nice).

View Comments

More Rack::Shell goodies for all Rack worshippers


Rack::Shell got a lot of attention lately and I received some feature requests/ideas from great ruby hackers. Daniel Neighman, currently working on Pancake, pointed me towards Bryan Helmkamp's rack-test. This awesome piece of code is now used by racksh to simulate HTTP requests to your Rack application. Yay!

% racksh
Rack::Shell v0.9.4 started in development environment.
>> $rack.get "/"
=> #<Rack::MockResponse:0xb68fa7bc @body="<html>...", @headers={"Content-Type"=>"text/html", "Content-Length"=>"1812"}, @status=200, ...

Check out README for details. Here are just few examples what's possible:

$rack.get "/", {}, { 'REMOTE_ADDR' => '123.45.67.89' }
$rack.header "User-Agent", "Firefox"
$rack.post "/users", :user => { :name => "Jola", :email => "jola@misi.ak" }

Now you can build and test Sinatra apps in single racksh session like this.

Another nice thing in new version is support for session setup through config files. Rack::Shell supports configuration file .rackshrc which is loaded from two places during startup: user's home dir and application directory (in this order). You can put any ruby code in it, but it's purpose is to setup your session, ie. setting headers which will be used for all $rack.get/post/... requests.

For example to set user agent to Firefox and re-migrate db if loaded environment is test put following in .rackshrc:

# .rackshrc

$rack.header "User-Agent", "Firefox"
DataMapper.auto_migrate! if $rack.env == "test"

You can also make requests in config file:

# .rackshrc

$rack.put "/signin", :login => "jola", :password => "misiacz"

This will ensure you are always logged in when you start racksh :)

Full documentation and sources are on github, gems for all versions on gemcutter.org. Enjoy!

View Comments

Rails-like console for any Rack based ruby web app


I always miss script/console from Rails while developing my Sinatra apps, especially ones built with DataMapper where I need to auto-migrate my db. Sinatra doesn't come with any comparable solution as it's not a full framework, but rather library for creating simple web apps. Recently I tried Heroku platform and their "heroku console" command inspired me to create something similar - racksh aka Rack::Shell.

racksh is a console for Rack based ruby web applications. It's like Rails' script/console or Merb's merb -i, but for any app built on Rack. You can use it to load application environment for Rails, Merb, Sinatra, Camping, Ramaze or your own framework provided there is config.ru file in app's root directory.

It's purpose is to allow developer to introspect his application and/or make some initial setup, ie. running mentioned DataMapper.auto_migrate!. It's mainly aimed at apps that don't have similar facility (like Sinatra) but can be used without problems with Merb or Rails apps.

How it works? It loads whole application environment like Rack web server, but it doesn't run the app. Simply, methods like use or run which are normally invoked on Rack::Builder instance are being stubbed.

Instalation is as easy as:

gem install racksh -s http://gemcutter.org

Then to open console run following inside rack application directory (containing config.ru file):

racksh

To specify location of config.ru set CONFIG_RU env variable:

CONFIG_RU=~/projects/foobar/config.ru racksh

Executing ruby code inside application environment and printing results is also supported:

racksh Order.all
racksh "Order.first :created_at => Date.today"

Default Rack environment is set to development but it can be changed by setting RACK_ENV env variable:

RACK_ENV=production racksh

Now I don't need to create some kind of console.rb for my new Rack app, I just use racksh. Enjoy!

UPDATE: Read here for more info.

View Comments

Subdomain shared cookies in Merb's specs


I’m currently working on Merb app which makes use of subdomains for user accounts. In order to have user authenticated on both base domain and subdomains I set cookie domain like this in init.rb:

 Merb::Config.use do |c|
    c[:default_cookie_domain] = ".mydomain.com"
  end

Dot at the start of domain name specifies that the cookie will be set for “mydomain.com” and all its subdomains. This works perfectly in browser(s) but I’ve encountered a problem in my request specs. After authenticating at “mydomain.com” app redirects to “username.mydomain.com”. But next request to either “mydomain.com” or “username.mydomain.com” shows that session is no longer authenticated. After some reading through merb-core sources I’ve found that Merb::Test::Cookie can’t properly handle cookies with domain set to ‘.foo.com’ (with dot at the start).

This is because Merb::Test::Cookie#valid? makes some regexp check comparing current request domain with domain from cookie, which fails for cookie domain set to ‘.foo.com’. I’ve created a fix and spec for this scenario. Patch can be found in this commit.

Until it gets merged and released with new Merb version (I hope in 1.1) It was already merged into Merb master branch, but until the 1.1 release the simplest workaround is to monkey patch Merb::Test::Cookie class, ie. in spec_helper.rb like this:

class Merb::Test::Cookie
  def valid?(uri)
    domain_ = domain.start_with?('.') ? domain[1..-1] : domain
    uri_path = uri.path.blank? ? "/" : uri.path
    uri.host =~ Regexp.new("#{Regexp.escape(domain_)}$") &&
    uri_path =~ Regexp.new("^#{Regexp.escape(path)}")
  end
end
View Comments

Coderack, a Rack middleware contest launched


You’ve probably heard about Rack, right? Few months ago during the conversation with my teammate about potential and possibilities of Rack, and Rack middleware we’ve came up with an idea of creating some coding contest. We wanted to encourage Ruby developers to explore the power of Rack because we believe it’s the best thing since sliced bread. And what better way than to hold a contest? And now we can proudly say that it happened! We’ve just launched it and got really positive feedback about it so far.

But what is this CodeRack thingie all about? Like I’ve mentioned first goal is to show Rack’s power and encourage its use in Ruby web apps. The secondary goal of the contest is to generate a set of open source solutions that will solve real problems and inspire others. Every entry will be released under the MIT open source license.

Programmers are encouraged to submit contest entries that will be judged based on the cleverness of the application and the elegance of the code. Entries can be submitted at coderack.org until midnight CEST November 15th. Finalists are scheduled to be announced on the 1st of December and public voting will run for one month. The final winners will be announced on the 5th of January.

The first round of the contest will be judged by an elite panel of judges including Ben Bangert (Pylons framework), Chris Wanstrath and PJ Hyett of GitHub, Joshua Peek of 37Signals, Yehuda Katz of Engine Yard (also Rails core team member), Ryan Tomayko of Heroku, Core Rails team member Matt Aimonetti, and the Rails Envy team of Gregg Pollack and Jason Seifer. Once the finalists have been selected by the panel, the public will vote for the top prize winners.

Prizes have been donated by Bytemark Hosting, GitHub, Jetbrains, Mindmeister, Freelance Total, Heroku, Rackspace Hosting, Peepcode, BDDCasts, and Zenbe Shareflow. The top prize includes a dedicated quad core server package and is valued at over $3000. Every entrant will receive a credit from bddcasts.com and $30 credit from Heroku! All finalists will receive a package including Zenbe Shareflow subscriptions, a RubyMine license from JetBrains, and five credits from bddcasts.com. Details of all of the prize packages will soon be available on the contest website.

So, want to become a Rackstar? It’s easy, create some interesting code and submit it to the contest. We’ve already collected over 45 entries in just few days. Oh, and I’ve almost forgot, CodeRack site itself is using middlewares, one of them being Ryan Tomayko’s awesome Rack::Cache.

View Comments

LessCSS goodies


If you haven’t heard about LessCSS then check it out, really cool solution for writing css code in concise way. I’m planning to use it in some of my projects (and probably for this blog’s styles) and I’ve created two tools which could ease my work with LessCSS.

First tool, css2less, is CSS-to-LessCSS converter. Of course it can’t use all of LessCSS features because only programmer knows where to use variables and other stuff properly for specific project. However what it can do is to find all rules that can be nested and outputs them for given css file.

Grab it from github and use like that:

ruby css2less.rb my.css > my.less

You will get .less file with all styles from original .css file but with nested rules notation. It’s a good start for further tweaking, ie adding variables.

Second tool, rack-lesscss, is a Rack middleware which converts .less files into .css files on the fly during request. It’s main purpose is to ease development stage when you change your .less files frequently. With rack-lesscss middleware enabled you don’t need to compile .less files by hand after every change. LessCSS compiler has an option to watch for changes in .less file and automatically recompiles it but you need to remember to run compiler in watch mode for every stylesheet every time you start development session. There are also at least two Rails plugins which nicely integrates LessCSS into the app but this middleware can be used with Rails as well as with other ruby web frameworks like Merb or Sinatra.

Install gem:

sudo gem install --source http://gems.github.com sickill-rack-lesscss

or grab it from github.

Enable by adding following to your rackup file (config.ru, or config/rack.rb in Merb app):

require 'rack-lesscss'
use Rack::LessCss, :less_path => File.join(APP_ROOT, "public", "css"), :css_route => "/css"

Above code will enable on-the-fly .less files compilation for all requests matching /css/*.css.

It accepts two arguments:

  • :less_path – directory where source .less files are stored (required)
  • :css_route – route which this middleware will handle (optional, default is /stylesheets)

And don’t use it on production for obvious reason :) It’s meant to be used for development only.

View Comments

Archlinux + Nginx + Passenger


UPDATE: I’ve added this package to AUR. You can grab it here if you prefer to build it from AUR. Note: it automatically builds passenger’s nginx module so step 2. is not needed for it, you only need to have passenger gem installed.

If someone needs to setup Nginx web server with Passenger support quick on Archlinux here are few simple steps to get it running in minutes.

1. Make sure you have the latest Passenger gem installed:

sudo gem install passenger

2. Compile Passenger module for Nginx:

cd `passenger-config --root`; sudo rake nginx

3. Download this PKGBUILD (modified PKGBUILD of nginx-0.7.61-1 from community repository with passenger module added)

4. Unpack and build package (if running as non-root be sure you have fakeroot package installed):

tar xf archlinux-nginx-passenger.tgz
cd nginx
makepkg

5. Install package:

sudo pacman -U nginx-0.7.61-1-i686.pkg.tar.gz

6. Set Passenger’s root directory in /etc/nginx/conf/nginx.conf:

http {
  ...
  passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4;
  ...
}

7. Enable Passenger in your vhost:

server {
  listen 80;
  server_name foo.bar.net;
  root /var/www/foo.bar.net/public;
  passenger_enabled on;
}

Restart nginx and that’s it. Now your Arch can serve ruby apps under Passenger.

Kudos for Phusion guys for creating such simple and really good working solution for hassle-free deployment!

View Comments

Rack middleware showing git or svn revision


Rack is fun. Really, lots of fun. After creating middleware for showing markup errors and viewing several presentations related to Rack I was thinking about Rack’s potential. And it’s big. The result of my thinking (and a little coding) is another middleware.

When you deploy application to a demo server QA (or client) wants to know which revision is currently running. Of course you can handle it in a old-school way putting some helper into your layout(s) which will obtain revision number exec’ing “svnversion” or sth like this. It works but it’s not the most elegant solution. First, you are including code related only to demo/staging server in layouts/helpers (production server and your development box don’t need it at all). Second, you probably do this for every new project. But all ruby web frameworks now run on Rack so better solution would be to move revision-displaying code from the app itself to the middleware. So here comes RevisionInfo.

Install:

gem install sickill-rack_revision_info --source http://gems.github.com

Enable in Merb:

config/dependencies.rb:

dependency "sickill-rack_revision_info", :require_as => "rack_revision_info"

config/rack.rb (before line with run Merb::Rack::Application.new):

use Rack::RevisionInfo, :path => Merb.root

Enable in Rails:

config/environment.rb:

config.gem "sickill-rack_revision_info", :lib => "rack_revision_info", :source => "http://gems.github.com"
config.middleware.use "Rack::RevisionInfo", :path => RAILS_ROOT

Enabling this middleware for svn managed application you will get <!-- Revision 666 (2009-05-28 19:00:25 +00:00) --> appended to the end of resulting html. For git repository it will be <!-- Revision 31d0fa132584c7e9bf978443052b545c1aeca96b (2009-05-28 19:00:25 +00:00) -->. It’s commented out so in order to see it look into page source.

However if you prefer to see revision number somewhere on the page you can specify CSS selector of page element and method of injection like this:

use Rack::RevisionInfo, :path => Merb.root, :inner_html => ".footer li.revision"

Here are available injection methods:

  • :append => "div.footer" inserts revision info at the end of footer div content
    <div class="footer"><img...> Revision 666 (2009-05-28 19:00:25 +00:00)</div>
  • :prepend => "div.footer" inserts revision info at the begining of footer div
    <div class="footer">Revision 666 (2009-05-28 19:00:25 +00:00) <img...></div>
  • :after => "div.footer" inserts revision info after footer div
    <div class="footer"><img...></div>Revision 666 (2009-05-28 19:00:25 +00:00)
  • :before => "div.footer" inserts revision info before footer div
    Revision 666 (2009-05-28 19:00:25 +00:00)<div class="footer"><img...></div>
  • :inner_html => "div.footer" replaces footer div content with revision info
    <div class="footer">Revision 666 (2009-05-28 19:00:25 +00:00)</div>
  • :swap => "div.footer" replaces whole footer div with revision info
    Revision 666 (2009-05-28 19:00:25 +00:00)

If you enable injection using one of above methods you need to have Hpricot gem installed because HTML manipulation is done using it (if you don’t use injection – only comment appending – you don’t need hpricot). Specified CSS selector can be any selector supported by hpricot so you can freely use funky stuff like #main ul.footer li:last. You can also use XPath like //div/ul/li.

Sources (as usual) are available on github.com. Enjoy!

View Comments

Rainbow gem updated for Ruby 1.9.1


Thanks to Chad from Spicycode my rainbow gem now supports Ruby 1.9.1 (and it’s backwards compatible with Ruby 1.8.x). It doesn’t provide any new features so there is no need for upgrade for Ruby 1.8.x users. I’ve released new version 1.0.2 at rubyforge.

View Comments

Rack middleware using HTML Tidy


Did you waste some time trying to spot the problem in html markup in your ruby web app? Are you strict validation freak? If yes, then read on.

I had several situations when something disappeared from the page or layout broke and the problem was in some missing closing tags or invalid nesting of elements. As I recently do my web development in Merb and Sinatra (this blog actually runs on Sinatra) and both of them are built on top of Rack I thought that I could write a middleware which can show me the problems in my markup.

So here it is. It uses well known Tidy tool to check for markup errors in actions output. Following code snippet shows the middleware class and its use in the simplest Sinatra app.

After running this tiny webapp and opening root url in your browser you will get following output in terminal:

It prints any warning and error messages to the console so you can easily spot any minor and major problems in the markup.

View Comments

Improved ruby mode for JEdit


My post about Textmate to JEdit theme converter (tm2jed) included example screenshots of JEdit running with some converted themes. However I’m using a little tweaked ruby highlighting mode which recognizes method, class and module names. It shows those names using styling defined for FUNCTION type entities (not all JEdit themes include styling for it but themes converted with tm2jed use it).

If you want to have highlighting for method names in your ruby code put following xml code into first RULES block in your ruby.xml file:

<!-- method, class and modules names -->
<MARK_FOLLOWING TYPE="FUNCTION" MATCH_TYPE="KEYWORD1">def </MARK_FOLLOWING>
<MARK_FOLLOWING TYPE="FUNCTION" MATCH_TYPE="KEYWORD1">class </MARK_FOLLOWING>
<MARK_FOLLOWING TYPE="FUNCTION" MATCH_TYPE="KEYWORD1">module </MARK_FOLLOWING>

Or just get mine ruby.xml file, put it into your .jedit/modes directory and add this to .jedit/modes/catalog file:

<MODE NAME="ruby" FILE="ruby.xml" FILE_NAME_GLOB="*.rb" />
View Comments

Colorizing console output with Rainbow ruby gem


If you’re working on some cool ruby console-based application or just want to add a little style to your script here is a nice gem for you. It’s called Rainbow and it extends ruby String class adding methods to wrap the string with ANSI escape codes.

Look at example irb session and see example usage:

Rainbow adds following methods to String class:

  • foreground(color) (with color and colour aliases)
  • background(color)
  • reset
  • bright
  • italic (not well supported by terminal emulators).
  • underline
  • blink
  • inverse
  • hide.

Color can be one of following symbols: :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white and :default.

Each of those methods returns string wrapped with some ANSI codes so you can chain calls as in example above.

It also has Windows support (uses win32console gem if installed, otherwise strings are returned unaltered).

The gem is on rubyforge.org so install it by:

sudo gem install rainbow

and require it in your script.

The sources are on github, as usual.

Note: I know that there is similar gem on rubyforge called colored_. But, first, it adds too many methods to String class (the Rails way, method per color + method per background color + method per foregroundbackground color…). Second, as I had it already implemented creating a gem from this code was a snap, so why not do it?

View Comments

Textmate to JEdit Colour Theme Converter


JEdit was my favourite code editor for a long time and I was polishing its configuration constantly to make it perfect. It has lots of great plugins which make it rather feature complete for me. As I’m working with the code 8+ hours a day I also need some nice colour scheme for my code. EditorScheme plugin adds support for changing schemes in JEdit and it’s bundled with several schemes. Unfortunately I couldn’t find a scheme which suits me…

Fortunately I saw several nice themes for Textmate which looked really sexy ;) Converting themes by hand was too much hassle so I’ve created tm2jed to convert them automatically. It’s written in ruby and all it does is reading given Textmate theme and outputing it as JEdit’s theme.

Following screenshots show how JEdit look with Twilight, Glow, Plastic Code Wrap and Glitter Bomb themes:

jedit with twilight themejedit with glow themejedit with plastic-code-wrap themejedit with glitter-bomb theme

You can get tm2jed here (as zip archive). Alternatively you can get it from github.

Once you have it, run:

ruby tm2jed.rb some_textmate_theme.tmTheme

It will save converted theme as some_textmate_theme.jedit-scheme which you can put in schemes directory of your jedit settings folder. Then choose it in EditorScheme plugin inside JEdit and you have new shiny colour scheme!

Conversion is not perfect as JEdit and Textmate implement theming in different way but for most cases it works fine.

I’ve converted 16 Textmate themes so if you don’t want to mess with tm2jed you can grab them here in one zip file. It contains Cool Glow, Monokai, Starlight, Texari, idleFingers, Glitter Bomb, Plastic Code Wrap, Succulent, Twilight, Monoindustrial, Glow, RubyBlue, Sunburst, Vibrant Ink, IR_Black, Spectacular, Tango and Choco themes.

View Comments