Skip to content

Using Pygments in Redmine

12-Nov-08

The syntax highlighting engine in Redmine is CodeRay which is vastly underpowered to be used in software as useful as Redmine. The obvious choice (at least for me) for proper syntax highlighting is Pygments, a python library. To change the syntax highlighting engine a few modifications need to be made to both Redmine and to Pygments.

The method that is called for syntax highlighting is in the app/helpers/repositories_helper.rb file.

def syntax_highlight(name, content)
  type = CodeRay::FileType[name]
  type ? CodeRay.scan(content, type).html : h(content)
end

(Note: This is for version 0.7-stable as the location of this method has moved in the trunk of the repository to app/helpers/application_helper.rb)

I initially piped the contents to Pygments with the -g argument which tries to guess the language but the success rate was too low. While it can choose a lexer based on a filename it also attempts to read the code from the file which doesn’t physically exist on our filesystem. The only solution was to add the desired functionality to Pygments via a new command-line argument. The ticket along with patch can be viewed here. Hopefully the patch will be accepted and patching will no longer be necessary (see update at end of post). The new argument, -N, allows you to pass a filename to Pygments which will return the lexer which best represents the contents based solely on the filename.

After patching Pygments we need to call it in the syntax highlighting method instead of CodeRay.

  def syntax_highlight(name, content)
    f = IO.popen("pygmentize -N " + name, 'r')
    lexer = f.read[0...-1] # removes trailing newline
 
    f = IO.popen("pygmentize -f html -l " + lexer, 'w+')
    f.write(content)
    f.close_write
    return f.read[28...-13]# removes surrounding div and pre as well as trailing newline
  end

As this was my first endeavor with Ruby I doubt it’s as elegant as it could be but it gets the job done. For this to work as-is it is assumed that pygmentize is in your PATH variable. Since Pygments uses its own CSS styles we must generate them, embed them in the stylesheet, and change an HTML tag so the new CSS rules are being applied. To generate the CSS use the following command:

[redmine-0.7]$ pygmentize -f html -S colorful -a .Pygments >> public/stylesheets/scm.css

This will append the new rules onto the already existing ones in the scm.css file. We still need to add an additional custom rule though so open scm.css in your favorite text editor and append the following:

.Pygments pre { margin: 0px; }

Now all that needs to be done is editing the templates to change the table class from “CodeRay” to “Pygments” so our new CSS rules are used. Open app/views/repositories/entry.rhtml and change line 4 and app/views/repositories/diff.rhtml and change line 18 and 48 to read:

<table class="filecontent Pygments">

Also open app/views/repositories/annotate.rhtml and change line 6 to read:

<table class="filecontent annotate Pygments">

You should now be able to enjoy the Pygments highlighting engine in your Redmine repositories!

Update:
My patch to Pygments has been accepted and checked into the repository. The changeset can be viewed here. The 1.0 version, the first to include this feature, is slated to be released on December 1st, 2008.

iPhone MMS

04-Nov-08

To send an MMS to another phone from your iPhone use the number + provider suffix below as the email address.

Provider Email suffix
Alltel @message.alltel.com
AT&T/Cingular @mms.att.com
Sprint/Nextel @messaging.sprintpcs.com
T-Mobile @tmomail.net
Verizon @vzwpix.com

If you were to specify a custom field in each contact with their service provider an application could theoretically use that information and their mobile number to effectively send an MMS elegantly.

My New Programming Language

29-Oct-08

There’s a lot to take into consideration when a new programming language is being invented. Is there a demand for a new language, is there a specific niche that it will fill, etc. Out of curiosity in combining two things which I have a relatively natural talent for, programming and drumming, I am inventing a programming language.

My high school drum line had a warm-up titled “Morse Code” which, when translated, was essentially gibberish. I initially thought of writing my own cadence around popular phrases from books and movies into Morse code and dividing it among the instruments. While this is an intriguing idea and something I won’t soon forget it seemed rudimentary (no pun intended) and just was not unique enough. As I was taking a compiler class a few semesters back I began to think about how certain sequences are interpreted by a compiler. Initially I was going to use the Morse code interpretations for the ASCII into music. An implementation like this did not feel useful as it was only a different way of representing an already existing syntax. I decided to use my introductory knowledge of writing a compiler to create a programming language syntax which was based off of musical notation.

There are a surprising amount of control structures that we use in programming already built in to musical notation. The most obvious to me and one of the most useful for a language is the use of repeats as for loops. For the sake of maintaining playability as well as something that can be interpreted we have to take some liberties from both view points. An example is that function calls could be represent using codas that jump back to the previous section when finished. There is still a lot to conceptualize before I even begin writing any kind of formal specification. I don’t anticipate writing a musical operating system with this language but small, fun exercises would be interesting to be seen–and heard!

I haven’t yet thought of a name… PyDrum++ doesn’t exactly roll off the tongue. Stay tuned for more information as well as a full specification for the language. Eventually.