Prettify your Code
Most of us like to post some code samples from time to time, when writing about our favorite CMS.
That isn't a problem, but it would be nice also, if we could have our code samples syntax highlighted, just the same way as it appears in our Favorite Texteditor
Usually we would then either use a plugin or install the Geshi Syntax Highlighter and extend that also for our favorite Language, writing our own Language file, if Geshi wouldn't already have one.
I have been thinking about it, but then on the other hand, you have to run extra PHP stuff Server-side-wise and that also might slow page-load down.
When I saw the first themed pastie pastes, I thought whow, how did they do that.
I never managed to track this down to the point, until I stumbled over Aaron Quint's Blog
The Idea, is to do this right from within TM itself.
Most ideally, this should be converted into a plugin, so it could happen automatically for each pre wrapped code portion. However before even thinking about that, a nice workaround would have been a drag command. Keep your code snippets nicely organized in a Code Folder and drag along while the spans wrap automatically around the code.
I already used this concept for some other drag commands. For instance, I have a special set of articles, that I like to keep under TM control, with the TXP Bundle. These article have a too complex markup, to leave the HTML formating to Textile, and I author these article, rightaway in HTML, while I write along. When I want to cross-link another of these articles, there is for instance a drag command, that does insert this link automaticlly, if I drag that article inside the document window, where I want it.
The code, that is used for the create HTML from Selection/Document however does currently not work from within drag commands. Modifying the Ruby code to use the contents of the dropped file instead of $TM_SELECTED_TEXT doesn't output anything except the usual wrapper HTML tags.
But actually it is much better to first write the article and then do this stuff at at the end once you are finished, so you don't have to look at these huge blocks, which in my case is even worser, since the Folding Stop and Start Markers are only working on TXP Tags.
Nothing is however impossible with TextMate.
The Plan
-
We first create a drag command within the Language Bundle that we are working with, putting the following code inside and set the file-extension to code
echo "<pre class=\"code\">`cat "$TM_DROPPED_FILEPATH"`</pre>"
The only thing that this does is, that it will insert the code snippet and wrap it up with code classed pre tags.
Care for those instances of Shell code and such, escaping the necessary bits, or else TM will run the code instead, which isn't what we want.
That will also allow us, just to continue writing, without having to worry about where we are.
-
Next we need a command (The green smarties), but we want to omit the output of the CSS styles in this case, so instead of the default code of Create HTML from Current Document, we put this code inside:
#!/usr/bin/env ruby -rjcode -Ku require "#{ENV['TM_BUNDLE_SUPPORT']}/lib/doctohtml.rb" require "#{ENV['TM_SUPPORT_PATH']}/lib/progress.rb" unit = ENV.has_key?('TM_SELECTED_TEXT') ? 'selection' : 'document' TextMate.call_with_progress(:message => "Creating HTML version of #{unit}…") do print document_to_html( STDIN.read ) endSet Input to: Selected text or Nothing, and Output to: Replace selected Text
Give it a shortcut, so you can trigger it later, here I used ⌃ ⌘ |
Note, that this Command needs to be inside the TextMate Bundle, or else you probably have to source the scripts.
Next, we create a macro on some sample code snippets, that we have at hand.
We first select the TextMate Bundle in side the Bundle Editor, so the Macro records as a TextMate Macro.
Start Macro recording, and move caret to Beginning of document
Now call Find with Options, using the following Look-around RE, using PREVIOUS.
(?<=<pre class=\"code\">)(.*?)(?=(</pre>))
This will select everything which is inside the pre tags.
Now we do execute command with options, triggering the above command, that we have created.
Now we do a find and replace using NEXT, but we use these expressions instead:
find string: (<pre class=\"code\">)(.*?)(</pre>) replace string: $2</pre></pre>This puts the contents of the pre tags in Capture Register 2 and strips off the pre classed code tags, that we don't need any more.
Move the caret to the right using →
Move to the End of the line, and stop macro recording. Give it a Trigger, here I used ⌃ ⌘ ⇧ C which looks convenient.
Create another Macro using the same sample document as previously
Start Macro recording again and ensure, that you have selceted the TextMate Bundle in the Bundle Editor. Move to the Beginning of the Document.
-
Now we do a Find with Options again using this RE Expression:
(<pre class=\"code\">)(.*?)(</pre>)
Move the caret to the right again
Play the previous Macro, that we created about ten times (Should be enough for about what we want to write about code on a Blog)
Next in case, the code examples are lesser than ten and to get rid of the slack I run a Find with options about 9 times, using this RE:
<pre class=\"textmate-source\"><span class=\"([\w+_\s]+)\"></span></pre>
Finally we do move to the End of the Document and stop Macro Recording and save this Macro as well giving it the same shortcut as previously.
I named this Macro Prettify Code/Document and kept the previous one also as a one-liner named: Prettify Code/Selection
To use the Macros, we don't need to make a selection, in fact the macros wont' work if we do.Just leave the caret where it is just behind the pre closing tag, before triggering the macro.
Below is an example, how that looks like with TXP tags
This is how your comment will appear when submitted. said, #
What next ?
Ok, the hard work is done, now we actually have to test it, and see if it works as expected.
Get a sample file, with code snippets, that where dragged inside with your drag command
Once you triggered the Macro head over to the kitchen to grab a cup of coffee, since it'll take some time to run.
One caveat: I didn't think about the new-lines, when I threw together the regular expressions,so it only works if the code snippets are one-liners each time.
That doesn't make a lot of sense, especially if we want to show bash code, like in this example here
Before I forget it: Can we edit a Macro, once it was recorded?
Oh yes we can: Just drag it out from the Bundle Editor to your Desktop or a Finder window.
Then right click, and open with another Editor. I usually use Skedit for that, but you can also change the key/value pairs with the plist Editor, and once done save, close and open again with Textmate and confirm the Update Bundle Item Dialog. In case you want to keep your previous Macro, then just Duplicate it beforehand in the Bundle Editor.