Code Presentation

b.gr's take on Code Presentaion in HTML, including syntax highlighting in JavaScript.

This entry was first published on August 06, 2004, 05:06 AM, CET and categorized as Code, Web.

So far, 4 comments have been added to this entry. You can add your thoughts to the discussion below.

After reading Redesign explained: tag transformations - and remembering CSS numbered code listings - I had to play with this, too. While c'log does not have many code samples by now, it is better to prepare for the future when you're bored enough :) Anyway, the HTML/CSS stuff is easy enough as Dunstan is giving out the code - I just made some changes to indent code after line breaks.

But I wanted syntax highlight, so I did some thinking: Processing the code on the server to do the syntax highlight was dropped soon because the client can do it equally good and it will save some bandwidth and processing time - not that I have any problems with these but doing it in JavaScript is just more fun :)

Enough introduction, off to the code:

  1. // This function will process an ol to syntax highlight
  2. // id - required: the ID of the ol
  3. // type - required: the language type (currently c, c#, js and php are supported)
  4. // noGetCode - optional: flag indicating whether or not to add the Get Code span
  5. function processCode(id, type, noGetCode);

The above code snippet is the prototype of the main function for the sytax highlighting. The following snippet shows how the above is done:

  1. <ol class="code" id="pcp">
  2. <li class="cmt"><code>// This function will process an ol to syntax highlight</code></li>
  3. <li class="cmt"><code>// id - required: the ID of the ol</code></li>
  4. <li class="cmt"><code>// type - required: the language type (currently c, c#, js and php are supported)</code></li>
  5. <li class="cmt"><code>// noGetCode - optional: flag indicating whether or not to add the <em>Get Code</em> span</code></li>
  6. <li><code>function processCode(id, type, noGetCode);</code></li>
  7. </ol>
  8. <script type="text/javascript">
  9. processCode("pcp", "js", true);
  10. </script>
  11. The HTML for the function prototype above (not really readable :])

Maintaing more than one file per entry ain't nice so I needed a way to let the user easily copy the presented code. The function below does this - in a highly imperfect way:

  1. function getCode(evt) {
  2. var e = xbGetRelativeByTag( xbGetEventElement(evt), "parentNode", "ol");
  3. if(!e) return;
  4. var getTabs = /t(\d)/;
  5. var tabs = "\t\t\t\t\t\t";
  6. var code = "";
  7. var lis = e.getElementsByTagName("li");
  8. for(var i = 0, l = lis.length; i < l; i++) {
  9. // Get the code element
  10. var ce = lis[i].childNodes[0];
  11. if(!ce) continue;
  12. // Retrieve the tab count
  13. var cn = lis[i].className;
  14. var t = cn && getTabs.test(cn) ? getTabs.exec(cn)[1] : 0;
  15. if(t) code += tabs.substr(0, t);
  16. // Strip the previously added syntax highlighting, open parameters removed
  17. code += ce.innerHTML.replace(/<\\?.+?>/g, "");
  18. code += "\n";
  19. }
  20. // Open a window with a textarea containing the pure, properly indented code
  21. var cw = window.open('about:blank', 'codeview', '...');
  22. if(cw) {
  23. var cd = cw.document;
  24. cd.open("text/html");
  25. // HTML writing stripped from sample
  26. cd.write(code);
  27. cd.close();
  28. cd.title = "Code View";
  29. }
  30. }
  31. Commented version of the function that extracts the code from the page to make copying easier

What the getCode function does is it iterates through the li of the given ol, stripping all HTML from the lis content and applies the right number of tabs before the code is concatenated. Then it opens a popup window whit a textarea containing the code.

The whole code can be found in code.js and is available under the Creative Commons Attribution License.

What is left is a plug-in for MT which is postponed to another time of boredom…

Final note: If you look at this entry in Mozilla or Firefox, chances are high that you see an unintended right or bottom padding on the code ol. This is due to a bug in Gecko…

Update

Due to popular demand (see comments) I added another link to show the code in a resizable window so the user can read the code unwrapped and syntax highlighted.

And I forgot to line out how the line wrap indentation is done… So, without any further bla here is the how: it is simple padding and negative margin voodoo:

  1. ol.code li
  2. {
  3. padding-left: 2em;
  4. }
  5. ol.code li.t1
  6. {
  7. padding-left: 4em;
  8. }
  9. /* and so on for .t3 to .t6, increasing padding-left by 2 */
  10. ol.code li code
  11. {
  12. color: #000;
  13. margin-left: -1.75em;
  14. }

This seems to work so far. And finally, here is the missing link (pun intended) to the CSS file used for the code formating.

Comments

Add your comment

  1. Scoutn, 5 days later

    I still think that the 'Get code' window should have syntax highlighting. I know you mentioned that for some reason it wasn't possible, but knowing you, you'll figure something out.

    The reason why I mention this; I prefer to look at code without line wraps, which is not currently possible with the syntax highlighting. Call me a stickler, but at least I am giving you something to do; something to add to your list of projects that helps you keep that list as long as mine.

    Don't say I never give you anything.

  2. b.gr, 1 week later

    I can add something to either let the reader disable the wrap or to open another, syntax highlighted window. As mentioned before: the current window will never be syntax highlighted :)

  3. Scoutn, 1 week later

    Hrm. Well, um, scrolling horizontally is always a bad thing in my opinion, so, I guess my preference would be a new window with syntax higlighting. :)

  4. b.gr, 1 week later

    And the horizontally scrolling was the inital reason for this thing :)