HAML – TextMate Command

I have been enamored with Ruby lately and one of the gems that has been stuck in the back of my mind for a very long time was HAML. HAML is a really slick way to write some html code with Ruby hooks. If you’re a Ruby on Rails user you can convert all your .rhtml files into .haml files and really reduce the file’s contents to its pure essence. To see what I mean:

!!!
%html
  %head
    %title Simple Page
  %body
    #header
    #sidebar
      %ul.menu
    #content
      %h1 HAML is awesome
      %p
        It even performs Ruby!
        = 50 * 10
    #footer
      %span{:style=>'text-align: center'} Joseph Pecoraro

Produces this super clean HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>Simple Page</title>
  </head>
  <body>
    <div id='header'>
    </div>
    <div id='sidebar'>
      <ul class='menu'>
      </ul>
    </div>
    <div id='content'>
      <h1>HAML is awesome</h1>
      <p>
        It even performs Ruby!
        500
      </p>
    </div>
    <div id='footer'>
      <span style='text-align: center'>Joseph Pecoraro</span>
    </div>
  </body>
</html>

Now here is the catch. I don’t currently use Ruby on Rails, but I really value the quick translation of the easy to type HAML to valid and nicely formatted XHTML. I didn’t see a HAML function for TextMate that I wanted so I wrote my own command.

TextMate Hamlize Command

Download the Hamlize Command Here

Feel free to download it and customize the usage to your own workflow. I personally bound the command to ⌃⇧H which will let me choose between the Tidy command or Hamlize. Also the command will work on the selected text, or if nothing is selected it will do the entire document. Now I can whip out a simple XHTML template page in even less time.

Make sure to get HAML first. Just download the gem and you’re all set.

$ sudo gem install haml

Here are some nice HAML references to help show you even more powerful options:
HAML Tutorial
HAML Documentation

rr – 1.1 – In Place Edits and Multiple Files

Less then 48 hours after rr becomes 1.0 it gets a few very handy improvements!

In place modification of files is activated via the –modify (or shorthand -m) option. This means that you can bypass any output redirection and just go straight to modifying the original file. This feature does use filename.tmp as a temp file which it later renames to the original filename. Again if no filenames are specified then input is expected to come from STDIN and therefore the new –modify option will be ignored in this special case.

Another original goal of mine was adding support for multiple filenames. Specifically so that useful shell tricks like *.txt file globbing would work nicely with rr. Well support has been added and it works great with the new –modify option.

The usage message has been cleaned up a bit but here is the very basic usage for all new people.

usage: rr [options] find replace [filenames]
       rr [options] s/find/replace/ [filenames]

I wanted to point out a rather hidden feature. The way I implemented the options is that the ARGV array is actually parsed first for all options and then removes the options before going on to parse the find, replace, and filename arguments. This means that your options can go anywhere on the command line so long as they start with a -.

This presents 1 problem, a workaround, and a question for users. Using the second form of usage, where the find and replace portions are separate argument if your regex or replacement text starts with a “-” the script will interpret it as an option. You can avoid this by using the s/find/replace/ usage (or putting the regex in /regex/ format, which is allowed). But really this boils down to deciding whether or not I am being too liberal with my command line arguments. Since this is a very big fringe condition with a workaround I am going to allow options to be placed anywhere, allowing you to bring up the last command in bash with the up arrow and adding an option to the end of your rr command (like the new -m) to repeat your last command with an option much easier.

rr is always free, Try It Out:
rr – Current Version Download
rr – changelog.txt – Click Here

$ gem install regex_replace

rr – 1.0 – Now a Pipe Friendly Filter

rr has reached the 1.0 milestone! The obvious improvement over the last version is that input is allowed from standard input. It seemed silly to always require a filename and the option of having standard input was always on my to do list. Usage is now:

usage: rr [options] find replace [filename]
       rr [options] s/find/replace/ [filename]

Now you can use rr as a filter and happily make find replace changes by piping input into it or out of it! I already have a script that runs a file through 4 rr commands to produce much nicer and cleaner output. Wrap that up in a shell/ruby/perl script and you have a useful tool.

Enjoy. Again its all free!
rr – Current Version Download
rr – changelog.txt – Click Here

$ gem install regex_replace

rr – Updated to 0.9.1

rr now has some improvements, including a new style of usage. Both this new style and the original style usage are available to you.

rr [options] s/find/replace/ filename

The new s/find/replace/ syntax is still weak with respect to the forward slash character in either the find or replace, but works for everything else so far. Of course if you want to include any whitespace then you should wrap the entire argument in quotes. Also, because the strings are coming from the command line, if you want to have literal backslashes then use single quotes around your string so the shell doesn’t escape them itself before sending it to Ruby.

Another highlight is that all escape sequences should now work. That means your typical \n, \t, and all the obscure even including \a (system bell). Check out this example, you will hear two system bells once this has been run:

$ echo "aba" > in.1; rr a "\a" in.1; rm in.1

Also I was considering renaming to fr for “Find/Replace” however I am keeping rr. rr can be interpreted as “Run Regex” with the s/find/replace/ syntax, or “Regex Replace” for the normal 3 argument usage. If you like fr you can easily make an alias like so: Want to know how to always load the alias?

$ alias fr="rr"

So have fun, of course everything is free and available right here:
rr – Current Version Download
rr – changelog.txt – Click Here

rr – Regex Replace on a File – SotD

I was frustrated with regular expression find/replace programs that only did line processing. This was because often I had find/replace needs that spanned multiple lines. Programs like grep, ack (which I recently found and is really, really very awesome for searching code), and sed were easy enough to use for basic needs. But again, when it came to multiple line pattern matching both fell short of my needs.

My solution was to write my own script to parse an entire file as a single string and do my find/replace bidding. The cons being liberal use of memory and a few hundredths of a second longer then the usual find/replace algorithms seemed insignificant to the pros of a multi-line capable find/replace using a regular expression with the capability of using back references (like \1) to incorporate captured groups from the regex into the replacement text.

So, without further ado I present rr.

I am hopeful for some public criticism to help me bring rr up from its current version of 0.9 to a landmark 1.0. The ruby script weighs in at 100 lines but really under 50 are code and the rest is comments, whitespace, or the usage string. Speaking of usage, here is what it currently [v0.9.0] looks like:

usage: rr [options] find replace filename
  find     - a regular expression to be run on the entire file as one string
  replace  - replacement text, \1-\9 and \n are allowed
  filename - name of the input file to be parsed

options:
  --line or -l    process line by line instead of all at once (not default)
  --case or -c    makes the regular expression case sensitive (not default)
  --global or -g  process all occurrences by default (this is already default)

negated options are done by adding 'not' or 'n' in switches like so:
  --notline or -nl

example usage:
  The following takes a file and doubles the last character on each line
  and turns the newlines into two newlines.
  rr "(.)\\n" "\\1\\1\\n\\n" file

More then likely this will undergo a lot of changes. A quick list of my current ideas include:

  1. If no filename is provided take input from STDIN. Multiple files can be handled by piping the `cat` of multiple files through rr.
  2. Better switch structure, although right now I don’t have any idea what that is

I’ll throw a test scenario at you. I had tabulated data in a file but each row was split across multiple lines. Now this wasn’t the only data in the file but I’ll present you with a simplier version here: [in.1]

Product A  12.99
           2001
----
Product B   1.99
           1997

Here you can see that I can’t just replace every other newline. What I want to actually do is replace newlines where there was a digit followed by a newline, some whitespace and another digit. I ran this through my script:

> rr "(\d)\n\s+(\d)" "\1  \2" in.1 > out.1

And I got the output I wanted: [out.1]

Product A  12.99  2001
----
Product B   1.99  1997

Even cleaner results can be seen by running a more advanced regex to remove the extra lines:

> rr "(\\d)\\n\\s+(\\d.*?\\n)(-+\\n)?" "\\1  \\2" in.1
Product A  12.99  2001
Product B   1.99  1997

So what are you waiting for? Download the script, add it to your bin directory, give it a test run, and tell me how you want it improved!

rr – Most Recent Version – Download

Thanks!

Ruby – “Oh No He Didn’t Just Do That”

I am sitting at my computer and I have an idea. I want to print out the square of each number from 1 to 200 because I think that it might be useful in solving a problem that I am facing. I happen to know Ruby, and while I was thinking it, I typing this in my terminal:

ruby -e "1.upto(200) { |i| puts i**2 }" > squares.txt

No wait… I typed this:

ruby -e "(1..200).each { |i| puts i*i }" > squares.txt

Perfect, the output went to a file named “squares.txt” where I can easily access it again and again. What were you doing? Was it something like this:

public class Squares {
  public static void main(String[] args) {
    for (int i = 0; i <= 200; i++) {
      System.out.println(i*i);
    }
  }
}

Not to mention the time to compile it... the output did not even go to a file for easy reading in the future. Your counter argument was that my Ruby solution didn't either? Let me do it again, only this time I won't do a terminal one liner (even though its not complex), but I'll write you a full ruby script:

File.open('squares.txt','w') do |f|
  1.upto(200) { |i| f.puts i**2 }
end

Can you imagine what writing to a file would look like in Java? I can't remember what to import, which writer I should wrap in a buffer, and oh my goodness lets not forget about the try catch block if you're too much of a gentleman to allow your main method to "throw Exception." Gasp!

The idea I am trying to get across is that Ruby is an exceptional tool for a programmer. Being an interpreted, purely object orientated, loosely typed programming language has huge benefits for writing short scripts like the one above. If you're unfamiliar with Ruby you were probably shocked to see what the simple script did. You might be a little shocked to see the classic "Hello World" written Ruby style:

5.times { puts 'Hello World' }

Thats right, the Ruby version prints out "Hello World" five times because its so happy! No, there is no mistake above, I did just call a method on the number 5... get used to it. You've heard it all before, "Ruby is Purely Object Oriented." Nearly everything is an object. Numbers and Strings especially! Here is a quickie, how characters are in this sentence?

'Here is a quickie, how characters are in this sentence?'.length

The above Ruby line of code spits out 55. What would you do? Please tell me you really didn't count each letter... Maybe you pasted it in Microsoft Word, went to Tools, clicked Word Count and checked the number of characters. I don't care how you do it, everyone has their favorite ways, my favorite is the fastest and most convenient way. Ruby is the answer. It has eclipsed my expectations when I started learning it and now I want it to blow your mind.

Heres something that might shock you. I'm going to put a method right into the String class and then I'm going to actually use it from a String:

class String
  def exclaim
    self + "!!!"
  end
end

puts "Ruby is fun".exclaim

The script, as expected, prints out:

Ruby is fun!!!

This is my first post about Ruby, and its meant to be harsh. I want you to be a little bit shocked, a little embarrassed, and most of all a wee bit interested. Because if you give Ruby a chance, you won't regret it. I will post more about Ruby soon, so if you don't already know Ruby then sit up straight and click on this link to learn Ruby in just 15 minutes:

Try Ruby - In Your Browser

If you try that link you will be presented with the interactive ruby prompt, the same prompt where I typed in my Ruby code and received instant feedback. The mastermind behind the above is also the author of the first tutorial listed below and a developer of Hackety Hack, a really neat Ruby starter kit. Its aimed at teens but I suggest that you download it because of these quick benefits:

  1. The same "Try Ruby Tutorial" is Built In
  2. A Great Ruby Cheat Sheet
  3. Extra Quick Tutorials
  4. File Organizer for your Ruby Scripts

After you get your feet wet from the above take a look at these Ruby tutorials which are themselves unlike any other tutorials you have ever read:

Why's Poignant Guide to Ruby - The most talked about Ruby Tutorial ever written. No description I can put here can describe it. Just know that reading this might change your life... well maybe not your life but at least your perspective on what a technical tutorial can be.

Ruby's Homepage - You were probably wondering when I might mention where you can actually download Ruby. Here is the home page for all things Ruby. Download it and start one of the tutorials from this website and in 30 minutes you will have a new favorite programming language.

Mr. Neighborly's Humble Little Ruby Guide - Another great tutorial that gets deep quickly. Not as loose as "Why's Guide" (but what else is?). Still this tutorial tops all the Java tutorials I have ever read.

There are so many links that I could throw at you but lets face it... if you take a chance with the 15 minute Ruby tutorial, then you will want to know more. These links give you everything you need to get started and days of joyful programing and hacking. Its your ambition that will take you further. Have a safe journey!

search