Blogging with Style
October 18th, 2005Since I’m a little obsessed with AppleScript, I end up pasting AppleScript code into my blog. I recently decided it was a real shame that I couldn’t easily replicate the way AppleScript code looks in Script Editor, in my blog. I thought about this situation for a while, and then did some experimenting.
If I copy the contents of a Script Editor window, and paste it into TextEdit, it looks great! Just like Script Editor! Why can’t I get that in HTML? I decided to try saving as HTML from TextEdit. Sure enough, that yields an HTML look-alike, but it depends on a rather elaborate set of CSS definitions in the <head> block of the document. I’m not ambitious enough to figure out whether I can include non-inlined CSS styles in random locations like the content of my blog post. Besides, I’d like to be able to “grab some styled text” and run with it.
It occurred to me that maybe AppleScript itself could help me get the formatting I needed. After a little tinkering, Sure enough, with TextEdit and the Text Suite, I can parse a chunk of styled text and spit out reasonably similar-looking HTML!
In this blog entry, I submit to you a script that will turn the text from the front-most document in TextEdit into a self-contained, inline styled chunk of HTML. It’s not pretty, but it works! As a proof-of-concept, the following code was copied from Script Editor, pasted into TextEdit, and then run from Script Editor. Because of some WordPress funkiness I had to change a few minor details in the source for this page, but I think you’ll find that the script works as expected in most contexts.:
tell application "Script Editor"
-- Since we are probably capturing newlines, tabs, etc.,
-- Let’s tag the content as "pre-formatted".
set myHTML to "<pre>"
--
Prefetch lists from the runs for performance during loopset {myFonts} to {font} of attribute runs of document 1
set {myColors} to {color} of attribute runs of document 1
set {mySizes} to {size} of attribute runs of document 1
set {myTexts} to {characters} of attribute runs of document 1
--
Build an independent HTML span for every attribute runrepeat with attrIndex from 1 to count of attribute runs of document 1
-- Figure the color
set thisColor to (item attrIndex of myColors)
set redComp to (my RGBColorNumToHex(item 1 of thisColor) as string)
set blueComp to (my RGBColorNumToHex(item 2 of thisColor) as string)
set greenComp to (my RGBColorNumToHex(item 3 of thisColor) as string)
set thisHexString to "#" & redComp & blueComp & greenComp
--
Font name and sizeset thisFont to (item attrIndex of myFonts as string)
set thisFontSize to (item attrIndex of mySizes as string)
--
Get the textset thisTextRun to (item attrIndex of myTexts as string)
--
Put it all togetherset thisHTMLRun to "<span style=\"color:" & thisHexString & "; font-family:’" & thisFont & "’; font-size:" & thisFontSize & "pt;\">" & thisTextRun & "</span>"
set myHTML to myHTML & thisHTMLRun end repeat
set myHTML to myHTML & "</pre>"
set the clipboard to myHTML
end tell
--
Based on Num32ToHex by Walter Ian Kaye-- http://www.natural-innovations.com/as/snippets.html
on RGBColorNumToHex(num)
-- We want smaller numbers
set num to num / 256
set out to ""
repeat with idx from 1 to 0 by -1
set bas to (16 ^ idx) as integer
if num ≥ bas then
set mult to ((num – (num mod bas)) / bas) as integer
set out to out & character mult of "123456789ABCDEF"
set num to (num – bas * mult)
else
set out to out & "0"
end if
end repeat
return out
end RGBColorNumToHex
Wow, that looks quite a bit more Script-Editor-like than your average web posting! It’s shamefully inefficent (take a look at the HTML it generates), but it gets the job done! I am happy to have this new tool at my disposal, but aside from producing rotten HTML code, the script is also dog slow. Also, when I copy the script above and paste it into Script Editor, it comes out double-spaced. Anybody out there have any tips for achieving this goal in a slightly more gallant manner?
Update: The script above has been updated since the original post. I discovered a few prefetching tricks that dramatically improve performance of the script. How dramatically? Thanks to Shark I can tell you! The test case for both scripts is converting the styled script text above from TextEdit to inline HTML. The old script? 58 seconds! 40% of which was spent in TextEdit itself. The optimized version above, which prefetches the pertinent styled text data from TextEdit? 4.5 seconds, with only 5.4% of the processor taken up by TextEdit. More than 10-times faster! Just imagine how fast it will be when a good scripter rewrites it!
