Org-Mode CSS May 13th, 2010
Patrick Stein

The color scheme here is a bit me-centric, but I am mostly posting it because I find the typography pleasing…. In my .emacs file, I have set up the org-export-headline-levels to two and the org-export-html-style to the following:

;;; .emacs.lisp
(setq org-export-html-style
      "<style type="text/css">#<:use "style.css"></style>")

# style.css
<<basic body style>>
<<header style>>
<<content style>>

The basic body has no margin and a pleasing (to me) khaki color.

# basic body style
body {
   background-color: #999966;
   margin: 0em;
}

The headers are carefully sized to try to take up a multiple of 1.4em with a consistent bottom margin.

# header style
h1 {
   font-size: 2.0em;
   margin-top: 1.9em;
   margin-bottom: 0.3em;
}
h2 {
   font-size: 1.5em;
   margin-top: 2.4em;
   margin-bottom: 0.3em;
}
h3 {
   font-size: 1.25em;
   margin-top: 1.25em;
   margin-bottom: 0.3em;
}

The main body is a pale yellow color with vertical borders. It’s got a decent font (the one that I have by default for my browser) with a slight tweak to the letter spacing and a big tweak to the leading. It keeps from getting too wide and stays centered. Oh, and I don’t skip space before lists.

# content style
div#content {
   background-color: #ffffcc;
   border-left: double #333300 3mm;
   border-right: double #333300 3mm;
   font-family: Times, serif;
   letter-spacing: 0.075em;
   line-height: 1.4;
   margin: 0em auto;
   padding: 2em;
   width: 45em;
}
ul {
   margin: 0;
}

Here is some sample output.

SLIME/noweb-mode/Lisp tip May 7th, 2010
Patrick Stein

Just a quick tip here if you use SLIME for Lisp and use Lisp as a noweb-code-mode…. Either change slime-auto-connect to 'ask or 'always or just remember to start slime before you wander into a Lisp code chunk. If you don’t, noweb-mode gets all confused and won’t code-highlight your Lisp or switch back to doc-mode when you leave that chunk.

I spent a long time just thinking noweb-mode was entirely broken if there were single quotes or less-than signs in any document chunk. Alas, it just needed SLIME to stop chucking a Not connected error.

Literate WordPress May 6th, 2010
Patrick Stein

I use WordPress along with the CodeColor plugin. This works fairly well for me. I find myself, however, breaking code up into sometimes awkward chunks to describe the code here or leaving things in very long segments.

Further, I often leave them ordered in my post in an order where they would compile if you just copied them into a file in the order presented. That’s not always the most useful order to present the code.

Literate programming seeks to tackle exactly these problems. So, I got to thinking: Why don’t I write some filters for noweb to output into WordPress+CodeColorer.

My Solution

My solution is in two parts, one filter of general use to all noweb users which simply inserts @language tags into the noweb stream and a noweave backend that outputs something you can just paste into the WordPress (HTML) input box.

Here is an example of how I used this to process the post.nw file that I used to compose this post.

# example.sh
noweave -n -filter langify-nw -backend wordpress-nw post.nw

  • langify-nw script
  • wordpress-nw script
  • tee-nw script useful for debugging noweb streams
  • post.nw literate source for this post (technically, I tweaked it a bit after proofreading without going back to the source combining the first two paragraphs and changing <h2>’s to <h3>’s and adding this parenthetical)

The langify-nw script guesses the language for each chunk based on the filename extension on the top-level chunk that incorporates that chunk. That’s why I used filename extensions on the top-level chunks in this post.

An Example

Several months back, I posted some code for rendering anti-aliased text in OpenGL. At the bottom of that post, I had an unwieldy 33-line function that you have to scroll to see with the way my blog is styled.

This would have been an excellent candidate for literate programming. Here is that same function broken up with noweb chunks with some descriptive text sprinkled between chunks.

At the heart of the algorithm, I need to take some point <px, py, pz>, run it backwards through all of the projection matrices so that I have it in pixel coordinates, and calculate the distance between that and the screen coordinates of the origin. So, I have this little function here to do that calculation given the object-local coordinates <px, py, pz> and the origin’s screen coordinates <ox, oy, oz>.

;;; dist-to-point-from-origin labels decl
(dist-to-point-from-origin (px py pz ox oy oz)
   (multiple-value-bind (nx ny nz)
       (glu:un-project px py pz
                       :modelview modelview
                       :projection projection
                       :viewport viewport)
     (dist nx ny nz ox oy oz)))

That, of course, also needs to determine the distance between two three-dimensional points. For my purposes, I don’t need the straight-line distance. I just need the maximum delta along any coordinate axis.

;;; dist labels decl
(dist (x1 y1 z1 x2 y2 z2)
   (max (abs (- x1 x2))
        (abs (- y1 y2))
        (abs (- z1 z2))))

Also, to do those reverse-projections, I need to retrieve the appropriate transformation matrices.

;;; collect projection matrices
(modelview (gl:get-double :modelview-matrix))
(projection (gl:get-double :projection-matrix))
(viewport (gl:get-integer :viewport))

Once I have those pieces, I am just going to collect those matrices, unproject the origin, then find half of the minimum unprojected distance of the points <1, 0, 0> and <0, 1, 0> from the origin.

;;; calculate-cutoff.lisp
(defun calculate-cutoff (font-loader size)
  (gl:with-pushed-matrix
    #<:use "scale based on font-size">
    (let (#<:use "collect projection matrices">)
      (labels (#<:use "dist labels decl">
               #<:use "dist-to-point-from-origin labels decl">)
        (multiple-value-bind (ox oy oz)
            (glu:un-project 0.0 0.0 0.0
                            :modelview modelview
                            :projection projection
                            :viewport viewport)
          (/ (min (dist-to-point-from-origin 1 0 0 ox oy oz)
                  (dist-to-point-from-origin 0 1 0 ox oy oz))
             2)))))))

Oh, and being the tricksy devil that I am, I scaled things based on my font size before doing any of that.

;;; scale based on font-size
(let ((ss (/ size (zpb-ttf:units/em font-loader))))
  (gl:scale ss ss ss)

Getting started with Clojure/Emacs/Slime May 4th, 2010
Patrick Stein

I spent some considerable time yesterday poring over the shelves in the programmer’s section of a local bookstore yesterday. Based on the available jobs at the moment, I was trying to decide whether it would be less painful to learn C#/.NET/AFW/blurpz or Hibernate/Springs/Struts/glorpka. My lambda, those things are fugly. When I open a book to find that my simple database example takes eight XML configuration files and twenty-five lines of calls to the same function (with a 25-character identifier (which, technically, should be namespace qualified, too)), I just don’t want to go there.

So, I walked away with Programming Clojure and a determination to think really hard about how to get paid to do something that’s not intensely painful.

Well, yesterday afternoon and late-night were intensely painful trying to get Clojure/Emacs/Slime all working together. Today, magickly, I messed something up in my .emacs file that convinced swank-clojure to download its own copies of the three JAR files it needs and zoom… I’m out of the gate.

Someday, I’d still like to be able to use my own JAR files for all of this, but in the meantime, I’m up and running.

Here’s what works

This is the relevant configuration from my .emacs file. It draws partly from these instructions by I’m not sure who, partly from this message by Constantine Vetoshev, partly from how my .emacs file was previously arranged, partly from sources now lost in the browser history sea, and partly from sheer luck.

First, some generic stuff up at the beginning:

(defun add-subdirs-to-load-path (dir)
  (let ((default-directory (concat dir "/")))
    (normal-top-level-add-subdirs-to-load-path)))

(add-to-list 'load-path "~/.emacs.d/site-lisp")
(add-subdirs-to-load-path "~/.emacs.d/site-lisp")

Then, prepping slime a bit:

(require 'slime-autoloads)
(add-to-list 'load-path "~/.emacs.d/site-lisp/slime/contrib")

(add-hook 'lisp-mode-hook (lambda () (slime-mode t)))
(add-hook 'inferior-lisp-mode-hook (lambda () (inferior-slime-mode t)))
(setq common-lisp-hyperspec-root
      "file:///Developer/Documentation/Lisp/clhs/HyperSpec/")

(slime-setup '(slime-repl))

(setq slime-net-coding-system 'utf-8-unix)

Then, setting up some general stuff for easy lisp implementations. (The –sbcl-nolineedit is something I personally use in my .sbclrc to decide whether to load linedit.)

(setq slime-lisp-implementations
      '((sbcl ("sbcl" "--sbcl-nolineedit"))
        (ccl ("ccl"))
        (ccl64 ("ccl64"))))

Some commands to simplify things so I don’t have to remember to M–– M-x slime:

(defmacro defslime-start (name mapping)
  `(defun ,name ()
     (interactive)
     (let ((slime-default-lisp ,mapping))
       (slime))))

(defslime-start ccl 'ccl)
(defslime-start ccl64 'ccl64)
(defslime-start clojure 'clojure)
(defslime-start sbcl 'sbcl)

Then, Clojure-specific SLIME stuff

(autoload 'clojure-mode "clojure-mode" "A major mode for Clojure" t)
(add-to-list 'auto-mode-alist '("\\.clj$" . clojure-mode))
(require 'swank-clojure)

(setq slime-lisp-implementations
      (append slime-lisp-implementations
              `((clojure ,(swank-clojure-cmd) :init swank-clojure-init))))

And, a touch more slime stuff to make things a little happier.

(add-hook 'slime-mode-hook
          (lambda ()
            (setq slime-truncate-lines nil)
            (slime-redirect-inferior-output)))

In my .emacs.d/site-lisp, I did the following:

% rm -rf slime swank-clojure clojure-mode
% git clone git://git.boinkor.net/slime.git
% git clone http://github.com/technomancy/swank-clojure.git
% git clone http://github.com/jochu/clojure-mode.git

What didn’t work

Before accidentally triggering swank-clojure to download its own JARs, I tried installing what I could with ELPA. I tried installing clojure, clojure-contrib, and swank-clojure with Lein. I tried installing them with Maven. I tried various combinations of versions of clojure and swank-clojure.

I have no idea how the JARs that swank-clojure built itself got built. I cannot reproduce it.

Edit: Ah, it appears that the Subversion repository for Clojure that I found is deprecated. But, I don’t have the energy to try the git repository myself at this point. Maybe next week.

XML Parser Generator March 16th, 2010
Patrick Stein

A few years back (for a very generous few), we needed to parse a wide variety of XML strings. It was quite tedious to go from the XML to the native-language representations of the data (even from a DOM version). Furthermore, we needed to parse this XML both in Java and in C++.

I wrote (in Java) an XML parser generator that took an XML description of how you’d like the native-language data structures to look and where in the XML it could find the values for those data structures. The Java code-base for this was ugly, ugly, ugly. I tried several times to clean it up into something publishable. I tried to clean it up several times so that it could actually generate the parser it used to read the XML description file. Alas, the meta-ness, combined with the clunky Java code, kept me from completing the circle.

Fast forward to last week. Suddenly, I have a reason to parse a wide variety of XML strings in Objective C. I certainly didn’t want to pull out the Java parser generator and try to beat it into generating Objective C, too. That’s fortunate, too, because I cannot find any of the copies (in various states of repair) that once lurked in ~/src.

What’s a man to do? Write it in Lisp, of course.

Example

Here’s an example to show how it works. Let’s take some simple XML that lists food items on a menu:

<menu>
        <food name="Belgian Waffles" price="$5.95" calories="650">
                <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
        </food>
        <!-- ... more food entries, omitted here for brevity ... -->
</menu>

We craft an XML description of how to go from the XML into a native representation:

<parser_generator root="menu" from="/menu">
  <struct name="food item">
    <field type="string" name="name" from="@name" />
    <field type="string" name="price" from="@price" />
    <field type="string" name="description" from="/description/." />
    <field type="integer" name="calories" from="@calories" />
  </struct>

  <struct name="menu">
    <field name="menu items">
      <array>
        <array_element type="food item" from="/food" />
      </array>
    </field>
  </struct>
</parser_generator>

Now, you run the parser generator on the above input file:

% sh parser-generator.sh --language=lisp \
                           --types-package menu \
                           --reader-package menu-reader \
                           --file menu.xml

This generates two files for you: types.lisp and reader.lisp. This is what types.lisp looks like:

(defpackage :menu
  (:use :common-lisp)
  (:export #:food-item
             #:name
             #:price
             #:description
             #:calories
           #:menu
             #:menu-items))

(in-package :menu)

(defclass food-item ()
  ((name :initarg :name :type string)
   (price :initarg :price :type string)
   (description :initarg :description :type string)
   (calories :initarg :calories :type integer)))

(defclass menu ()
  ((menu-items :initarg :menu-items :type list :initform nil)))

I will not bore you with all of reader.lisp as it’s 134 lines of code you never had to write. The only part you need to worry about is the parse function which takes a stream for or pathname to the XML and returns an instance of the menu class. Here is a small snippet though:

;;; =================================================================
;;; food-item struct
;;; =================================================================
(defmethod data progn ((handler sax-handler) (item food-item) path value)
  (with-slots (name price description calories) item
    (case path
      (:|@name| (setf name value))
      (:|@price| (setf price value))
      (:|/description/.| (setf description value))
      (:|@calories| (setf calories (parse-integer value))))))

Where it’s at

I currently have the parser generator generating its own parser (five times fast). I still have a little bit more that I’d like to add to include assertions for things like the minimum number of elements in an array or the minimum value of an integer. I also have a few kinks to work out so that you can return some type other than an instance of a class for cases like this where the menu class just wraps one item.

My next step though is to get it generating Objective C parsers.

Somewhere in there, I’ll post this to a public git repository.

Updates In Email

Email:

l