As I went about figuring out how to get some syntax highlighting for my rails apps, I did not think it would turn out to be such a process. I’m not saying the available syntax highlighters are of inferior quality. I just ran into a few problems combining all the pieces I wanted to use.

When I started this out, I wasn’t ( still not really) sure of the best way to get syntax highlighting working with my rails apps. What follows is a quick overview of the hoops I went through to accomplish this and the solution ( or hack might be a better word) I finished with.

The Wordpress editor is a good example of what I wanted to end up with. Server side highlighting via GeSHi or Syntax could be nice, but using them with a text editor for a rails app seems a bit out of reach for me at this point. This left the available Javascript solutions as a better route.

SyntaxHighlighter appeared to be the early winner. With Worpress, its easy, you just press the code button, create the needed pre tags with name=”code” class=”xlang.” For my rails app, I installed the tiny_mce plugin and then realized that the code tab in Wordpress actually switches the editor to a quicktags editor. I set about creating the needed buttons and found the source of the switchEditor function here. After the better part of a day, I finally managed to get the button to work by specifying the exact text area as opposed to the generic textareas option within the uses_tiny_mce options hash in my controller.

Shortly after that, I realized the plugin was using TinyMCE 2.0.8 instead of the latest stable TinyMCE, 3.0.1 as of this writing. Consequently, I never finished with the 2.0 version and moved to running 3.0. Once running, I discovered, the functionality I wanted to implement was already there, albeit in a slightly different fashion. It came in the form of the html source code editor button. This brought about another issue.

SyntaxHighlighter hightlights pre tags based on the name attribute, and the name attribute is not a valid pre tag attribute. Since TinyMCE strips out invalid attributes, my code was not getting highlighted. Keeping everything valid is a priority, so SyntaxHighlighter wasn’t going to work in its current state.

After some investigative work into SyntaxHighlighter, I decided it was not worth the effort to change it to work without the name tag.

Chili steps into the equation for two reasons now, it was really easy to change it to highlight pre tags, and it is a jQuery plugin. All I did was change the ChiliBook.automaticSelector value to “pre” and it seems to do the trick. So far, I haven’t noticed any issues that could be caused by this.

I thought I would be done now, but I was wrong yet again. TinyMCE replaces the new line characters within pre tags with br tags. After Chili completes highlighting code with br tags, what results is one long line of highlighted code. Not exactly usable. The substitution seems to occur when the editor opens up a previously saved record. I did not determine exactly where this was occurring.

Upon consulting the TinyMCE wiki, there appeared to be several configuration options that would do the trick. After going through each of these options, I was still in the same state of displaying incorrectly formatted code. I looked at cleanup_on_startup, convert_newlines_to_brs, remove_linebreaks as well as others. With names like that, you would think one would stop the substitution of new lines to br tags. Eventually, the save_callback method appeared as a way to fix the problem. It did not actually stop the substitution, but it allowed my pages to correctly display code. My save_callback simply calls a replace(/<br\s\/>/g, “\n”) on the returned text. What this means is, my code will now format and display correctly to end users because the brs no longer conflict with Chili. After you have pasted a snippet of code, you never really need to edit the code through the html source code viewer anymore and the brs become an ignorable issue now. The TinyMCE init script end up as the one below.

<script language="javascript" type="text/javascript">
    function replace_brs_with_n(element_id, html, body) {
      html = html.replace(//g, “\n”);
      return html;
    }
    tinyMCE.init({
    	theme : “advanced”,
    	mode : “textareas”,
      save_callback : “replace_brs_with_n”,
      plugins : “visualchars,xhtmlxtras”,
	    // Theme options
    	theme_advanced_buttons1 : “bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect”,
    	theme_advanced_buttons2 : “bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,code,|,forecolor,backcolor,|,cite,del,ins,sub,sup”,
    	theme_advanced_buttons3 : “”,
    	theme_advanced_buttons4 : “”,
    	theme_advanced_toolbar_location : “top”,
    	theme_advanced_toolbar_align : “left”,
    	theme_advanced_statusbar_location : “bottom”,
    	theme_advanced_resizing : true,
    });
  </script>

With the resolution of that issue, the only thing left to do was create the recipes for Chili to highlight both ruby and rails code. My regex skills are lacking as of this point, but I managed to put together some regular expressions and they appear to be doing a decent job. The regular expressions were generated with the help of GeSHi and SyntaxHighlighter.

The way to get syntax highlighted code is to click the html button and manually type in <pre class=”supported language you want”></pre> and paste your code in between. If you save the record and come back later to edit and you use the html editor, you will notice the new lines have been replaced with br tags. Fortunately, most editing can be done from the main editor window just fine. As long as you have included the correct Javascript and css files, your code should be nice and highlighted when being displayed. Please leave any comments, ideas or suggestions below.

Tags: , , , , , ,