Htmlize your Erlang code buffer

Recently I’ve begun to make blog posts and now want to have highlighting of Erlang’s code(actually any code , be it Python, Lisp, etc) in my posts. I’m using The One True Editor and it goes without saying that i want to convert my erlang code into html from within emacs to have corresponding syntax coloring. Htmlize package to the rescue!

After you downloaded package and put

(add-to-list 'load-path "path_to_your_htmlize.el")
(require 'htmlize)

into your dot emacs – you are ready to use it.

M-x htmlize-buffer or M-x htmlize-region will convert whole buffer or selected region with associated decorations into HTML( See C-h a htmlize RET for more functions). By default htmlize will make HTML output in css mode which is not very suitable for inserting into blog post as output includes also style sheets. Excerpt from htmlize documentation:

;; htmlize supports three types of HTML output, selected by setting
;; `htmlize-output-type': `css', `inline-css', and `font'.  In `css'
;; mode, htmlize uses cascading style sheets to specify colors; it
;; generates classes that correspond to Emacs faces and uses <span
;; class=FACE>...</span> to color parts of text.  In this mode, the
;; produced HTML is valid under the 4.01 strict DTD, as confirmed by
;; the W3C validator.  `inline-css' is like `css', except the CSS is
;; put directly in the STYLE attribute of the SPAN element, making it
;; possible to paste the generated HTML to other documents.  In `font'
;; mode, htmlize uses <font color="...">...</font> to colorize HTML,
;; which is not standard-compliant, but works better in older
;; browsers.  `css' mode is the default.

inline-css is the type of output i want. This can be achieved by customizing htmlize-output-type variable with M-x customize htmlize RET or directly modifying dot emacs. Converting:

(add-to-list 'load-path "path_to_your_htmlize.el")
(require 'htmlize)

with htmlize-region and then applying nxml-mode to produced result gives:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<!-- Created by htmlize-1.34 in inline-css mode. -->
<html>
  <head>
    <title>.emacs</title>
  </head>
  <body style="color: #ffffff; background-color: #000000;">
    <pre>
(add-to-list 'load-path <span style="color: #ffa07a;">"path_to_your_htmlize.el"</span>)
(<span style="color: #00ffff;">require</span> '<span style="color: #7fffd4;">htmlize</span>)
</pre>
  </body>
</html>

As you see I need to cut contents between <pre> </pre> including
<pre> tags itself to insert that then directly into blog post. After that i need manually copy/paste styles from <body> tag into <pre> tag and also add font-size: 8pt to meet my taste. Being lazy i’ve implemented function my-htmlize-region in elisp to make that job for me every time i press F5 key:

(defun my-htmlize-region (beg end)
  "Htmlize region and put into <pre> tag style that is left in <body> tag
plus add font-size: 8pt"
  (interactive "r")
  (let* ((buffer-faces (htmlize-faces-in-buffer))
         (face-map (htmlize-make-face-map (adjoin 'default buffer-faces)))
         (pre-tag (format
                   "<pre style=\"%s font-size: 8pt\">"
                   (mapconcat #'identity (htmlize-css-specs
                                          (gethash 'default face-map)) " ")))
         (htmlized-reg (htmlize-region-for-paste beg end)))
    (switch-to-buffer-other-window "*htmlized output*")
    ; clear buffer
    (kill-region (point-min) (point-max))
    ; set mode to have syntax highlighting
    (nxml-mode)
    (save-excursion
      (insert htmlized-reg))
    (while (re-search-forward "<pre>" nil t)
      (replace-match pre-tag nil nil))
    (goto-char (point-min))))

(global-set-key [(f5)] (lambda (beg end)
                         (interactive "r") (my-htmlize-region beg end)))

So now selecting:

(add-to-list 'load-path "path_to_your_htmlize.el")
(require 'htmlize)

and pressing F5 i get this in another buffer:

<pre style="color: #ffffff; background-color: #000000; font-size: 8pt">
(add-to-list 'load-path <span style="color: #ffa07a;">"path_to_your_htmlize.el"</span>)
(<span style="color: #00ffff;">require</span> '<span style="color: #7fffd4;">htmlize</span>)
</pre>

As you see it’s just what i want:
<pre> tags with content and <pre> tag contains style from above mentioned <body> tag plus font-size is added too.

Factorial in Erlang with syntax coloring as i have it in my Emacs:

-module(factorial).
-export([factorial/1, factorial_rec/1]).

%% tail recursion
factorial(Num) ->
    factorial(Num, 1).

factorial(1, Acc) -> Acc;
factorial(Num, Acc) ->
    factorial(Num-1, Num * Acc).

%% recursion
factorial_rec(1) -> 1;
factorial_rec(Num) ->
    Num * factorial_rec(Num-1).

This is a joy of using Emacs.

8 Responses to “Htmlize your Erlang code buffer”

  1. Doug Hellmann Says:

    Thanks for the tip! Using htmlize is much easier than what I have been doing.

  2. ( ? , qUeStIoNMaRk ) :: Htmlize your * code buffer :: August :: 2007 Says:

    [...] attempted to use the htmlize package for Emacs as described in Htmlize your Erlang code buffer, but I managed to get the code syntax hilighted only in the preview window, once the post gets [...]

  3. Ruslan Spivak Says:

    I’m using WordPress blog engine + inline-css html output(i guess you do too) in Htmlize package and for me it works just fine, but your mileage may vary and i would take a look at html source code of your published page, maybe style attributes of your htmlized code were stripped off by your blog engine.

  4. Shane Celis Says:

    Very cool stuff. I was hoping that htmlize-region-for-paste might do exactly what your function does. Unfortunately, it doesn’t. So I’m very glad to have your function, but it’d be nice if the code went upstream into htmlize.el. Have you considered submitting a patch to it?

  5. Ruslan Spivak Says:

    Glad you liked the stuff, Shane and thanks for feedback. As for submitting a patch – no, i didn’t consider that (yet) as function contains some hardcoded stuff, like font-size and may not be well suited for including into htmlize.el in its current form.

  6. Htmlize bug or How I formatted my code from last post - M-x Kelsin Says:

    [...] Kelsin on Feb.23, 2009, under Emacs, Linux, Software I recently stubled across this post where Ruslan outlines a great custom Emacs function for slightly editing htmlize output for blog [...]

  7. Interesting Emacs Links - 2009 Week 9 « A Curious Programmer Says:

    [...] to html using htmlize. As htmlize uses css classes rather than inline styles it uses a snippet from Ruslan’s blog. htmlize-region-for-paste can also convert the css classes to inline styles although it isn’t [...]

  8. posting code on wordpress « IO BLOG Says:

    [...] worked but I couldn’t figure out how to change the default settings. I then came across this blog who’s author had the same issue with the htmlize default output, but who much better [...]

Leave a Reply