Pages

Tuesday, December 27, 2011

Highlight code with Blogger's "Dynamic Views"

This post is about how I got my code snippets to be highlighted on Blogger's recent "Dynamic Views".

I was pointed to this post, but which required a fair amount of steps. Moreover, the resulting functionality only worked for Java and XML coloring, which was the intent of the authors but didn't provide detailed steps on how to get your own languages to work (Python, etc.)

And I wanted...


So I ended up getting it to work with this Javascript code prettifier library.

Short version (tl;dr)

At the end of each of your blog posts, include the following code using the HTML editor:

<script src="https://gist.github.com/aconrad/1522901/raw/e77a27e421b269974e56d1fffc3da23b00ae4b0c/highlight.js" type="text/javascript"></script>


Long version

As of now (Dec 2011), you can't change Blogger's Dynamic Views template to add a Javascript call, such as prettyPrint(). So the only way to do it is to include the call in each of your blog posts. Yes, this is ugly. But it works.

(function() {
    try {
        prettyPrint();
    } catch(e) {
        var scriptId = 'prettyPrinter';
        if (document.getElementById(scriptId) === null) {
            var elem = document.createElement('SCRIPT');
            elem.id = scriptId;
            elem.onload = function() {
                prettyPrint();
            }
            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";
            var theBody = document.getElementsByTagName('body')[0];
            theBody.appendChild(elem);
        }
    }
})();

This is mainly a tweaked rip-off from what the Crux Framework folks came up with. As you can see, the code tries to call prettyPrint() and if it fails (not yet loaded), it will download the prettify.js script and try again.

Once you have this working, you can personalize the CSS. I took the Desert style, pasted it in the Advanced section and use the CSS customization tool of Blogger to adapted it.

/* default scheme ported from vim to google prettify */
pre { display: block; background-color: #221122; padding: 1em; color: #FFFFFF }
pre .nocode { background-color: none; color: #000 }
pre .str { color: #C00000 } /* string */
pre .kwd { color: #C4A000 } /* keyword */
pre .com { color: #3465A4 } /* comment */
pre .typ { color: #06989A } /* type */
pre .lit { color: #C00000 } /* literal */
pre .pun { color: #FFFFFF } /* punctuation */
pre .pln { color: #FFFFFF } /* plaintext */
pre .tag { color: #C4A000 } /* html/xml tag */
pre .atn { color: #4E9A06 } /* attribute name */
pre .atv { color: #C00000 } /* attribute value */
pre .dec { color: #98fb98 } /* decimal */

/* Specify class=linenums on a pre to get line numbering */
ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE } /* IE indents via margin-left */
li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
/* Alternate shading for lines */
li.L1,li.L3,li.L5,li.L7,li.L9 { }

@media print {
  pre { background-color: none }
  pre .str, code .str { color: #060 }
  pre .kwd, code .kwd { color: #006; font-weight: bold }
  pre .com, code .com { color: #600; font-style: italic }
  pre .typ, code .typ { color: #404; font-weight: bold }
  pre .lit, code .lit { color: #044 }
  pre .pun, code .pun { color: #440 }
  pre .pln, code .pln { color: #000 }
  pre .tag, code .tag { color: #006; font-weight: bold }
  pre .atn, code .atn { color: #404 }
  pre .atv, code .atv { color: #060 }
}
Ironically, I have not taken the time to figure out how to colorize the above CSS properly, which requires this extra Javascript code to be loaded.

Enjoy!

10 comments:

  1. I'm using your solution! I decided to try it out last week to make some of my code posts more readable. I'm running into a problem, though. When I link to a specific post, http://technofart.blogspot.com/2012/02/rsync-controlled-by-python.html for example, my post width and prettifier width (on my computer, anyhow) are limited and some of my white code text cannot be seen for running into the white background.

    This is not the case with you and yours, so I was wondering if you had any thoughts as to why this is happening to mine. Note that when you view the blog in whole (not just singled to a specific post), this problem is not an issue.

    Many thanks!

    ReplyDelete
  2. To be fair, after my last comment, I noticed a part of this post where code droops outside the dark border just a little bit. That's just a word wrap feature issue, and can be remedied by attention to line length. But my entire post, except for the code portions, have line length more limited than should be.

    Thanks yet again!

    ReplyDelete
  3. Hi Brad,

    I haven't bothered looking into it because the code that currently spills out of my "pre" tag is actually colored, thus readable. I'm sure yours readers can select (mouse) the white-on-white code to discover it. You could also tweak the CSS to turn the white code look like a light gray.

    Cheers,
    Alex

    ReplyDelete
  4. Right, I've thought about changing the coloring. The biggest, weirdest issue to me is the truncation of line (and code block background) width while the post width remains correct.

    Thank you,

    BradG

    ReplyDelete
  5. You could also set "overflow: auto;" on your "pre" tag CSS definition. This should add horizontal scrolling when the code is wider than your pre block.

    ReplyDelete
  6. Hi alex. Thanks a lot for the cool info. I never thought javascript works within posts. Would you mind if I repost this to my blog? I added backlinks to this page though. Thanks again. http://jaygamay.blogspot.com/

    ReplyDelete
  7. Hi Jay, no problem. I am glad that it helped you out. Thanks for back-linking.

    ReplyDelete
  8. thanks! this work great. ;)

    btw, blogger just allow editing its dynamic template. but i still can't figure out how to make it auto-highlighting w/o paste <script> at the end of every post.

    ReplyDelete
  9. thanks for your job! it helps me to start using gists in blogger. But I think I'm going to migrate from Blogger to Jekyll in Github.

    Regards!

    ReplyDelete
  10. > At the end of each of your blog posts, include the following code...

    There has to be a way to register a callback to fire when the article content is loaded so that the function is run automatically instead of manually adding a snippet to every blog post. Unfortunately, the "Dynamic Views" theme seems to block propagation of click events in the sidebar, so you can't bind your own event (well, you can, but it won't get called).

    If anyone knows how to get a function to run automatically after content load, please share your secret!

    ReplyDelete