Htmlize your Erlang code buffer

August 18, 2007

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.


More about binary search in Erlang

August 17, 2007

In my previous post My Erlang binary search I’ve implemented binary search in Python and Erlang as small exercise for myself after reading Half-baked Ideas blog post. Good article pointing to specifics of implementation of that algorithm in Erlang was posted on Erlane’s blog which is in a nutshell: binary search in Erlang implemented on list data structure is less efficient than linear search.

So to grasp why linear search which is O(N) is faster in Erlang then binary search which is in theory O(logN) go and read that article.
In Python list data structure (I’m talking here about CPython) is implemented as mutable and extensible vector of references to objects(we might say array of pointers), here is the excerpt from listobject.h:

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     * list.sort() temporarily sets allocated to -1 to detect mutations.
     *
     * Items must normally not be NULL, except during construction when
     * the list is not yet visible outside the function that builds it.
     */
    Py_ssize_t allocated;
} PyListObject;

So Python version works as expected regarding efficiency. While my goal of implementing binary search algorithm in Erlang was learning Erlang and not particulary developing optimized version of that algorithm or using another one it’s always good to pick new tricks of the trade along the way and for me the issue with my implementation of binary search in Erlang just boils down to: your experience and know your tools (language, os, editor(emacs :), etc )

As Aldous Huxly said: “Experience is not what happens to you; it’s what you do with what happens to you.”. So make errors (not many :) in your programs, fix them and gain new experience with your new language.

Another post by Erlane team is good reading describing paradigm shifts when you are newbie and are on your own way to Erlang/OTP wizardry.



My Erlang binary search

August 15, 2007

I was lurking and watching Erlang quite some time during this year and finally decided give it a shot after Programming Erlang was released. I ordered book in pdf format to rest assured i’ll get it in fastest possible way. After i read book a bit i was hooked

Today i came across binary search in Erlang blog post and decided to implement quickly binary search myself. My first attempt was to do it in python as it’s my daily job’s programming language and it turned this way (no check for edge cases like empty sequence):

def binsearch(seq, key, start, end):
    if end < start:
        return -1
    mid = (start + end) / 2
    if key == seq[mid]:
        return mid
    if key < seq[mid]:
        return binsearch(seq, key, start, mid-1)
    if key > seq[mid]:
        return binsearch(seq, key, start+1, end)

After i looked at code a bit i was surprised i wrote it recursively, earlier i would do it like:

def binsearch(seq, key):
    start = 0
    end = len(seq) - 1

    while True:
        if end < start:
            return -1
        mid = (start + end) / 2
        if key == seq[mid]:
            return mid
        if key < seq[mid]:
            end = mid - 1
        else:
            start = mid + 1

Erlang obviously bends my mind :)

And my version in Erlang which was just exercise for myself and mainly looks like in original blog post:

-module(search).
-export([binsearch/2]).
-import(lists, [nth/2]).
-include_lib("eunit/include/eunit.hrl").

binsearch(List, Key) ->
    binsearch(List, Key, 1, length(List)).

binsearch(List, Key, LowerBound, UpperBound) ->
    if
        UpperBound < LowerBound -> -1;
        true ->
            Mid = (LowerBound + UpperBound) div 2,
            Item = nth(Mid, List),
            if
                Key < Item ->
                    binsearch(List, Key, LowerBound, Mid-1);
                Key > Item ->
                    binsearch(List, Key, Mid+1, UpperBound);
                true ->
                    Mid
            end
    end.

setup_test_() ->
    {setup,
     fun() -> [7, 11, 14, 40, 50] end,
     fun(L) ->
             [?_assertMatch(3, binsearch(L, 14)),
              ?_assertMatch(-1, binsearch(L, 70))]
     end
    }.

Running unit tests:

(em@localhost)1> search:test().
  All 2 tests successful.
ok