9

I wrote this post in Emacs. In order to make the tables look nice, I decided to adjust the spacing so that decimals line up neatly. The original format from the database looked like this:

emacs                11505 227          3.6       3.3         1.9         68.9          93.5        68         
vi                   1087  289          11.1      6.9         2.9         71.7          96.2        9          
wolfram-mathematica  2993  360          4         2.2         1.9         66.7          92.5        51         

That's pretty close, but I want the columns right justified and all the ones digits lined up. The fourth column should look like:

 3.6
11.1
 4

I played around with the align commands and could not find a way to automatically align the table on the (optional) decimal point. For some reason, these instructions fail to align anything at all:

Figures can also be lined up with respect to the decimal point, using M-- M-x align.

1 Answers1

8

First, you need to be sure that the buffer is in Text mode:

M-x text-mode

Once in text mode, C-- M-x align (which invokes the text-dollar-figure alignment rule) will align the first decimal vertically. But it fails to align the second decimal column. Plus it fails to align numbers that don't have an explicit decimal point (such as wolfram-mathematica's average score of 4). To fix that, you'll want to adjust the value of the rule in the align-rules-list:

(text-dollar-figure
  (regexp . "\\$?\\(\\s-+[0-9]+\\)\\.?")
  (modes . align-text-modes)
  (repeat . t)
  (spacing . 2)
  (justify . t)
  (run-if lambda nil
      (eq '- current-prefix-arg)))

That does a few things:

  • The regexp now allows for the an optional trailing period.
  • By turning on repeat, each instance of a number is aligned.
  • I added 2 spaces instead of just one for readability.

The result:

emacs                11505  227   3.6  3.3  1.9  68.9  93.5   68         
vi                    1087  289  11.1  6.9  2.9  71.7  96.2    9          
wolfram-mathematica   2993  360   4    2.2  1.9  66.7  92.5   51         

A more or less equivalent method is to define a function that calls align-regexp:

(defun align-decimal (start end)
    "Align a table of numbers on (optional) decimal points."
    (interactive "r")
    (align-regexp start end "\\(\\s-*\\)\\$?\\(\\s-+[0-9]+\\)\\.?"
                  -2 0 t))

In this case, I set the groups parameter to a negative number to turn on right justification and spacing to 0 in order to preserve the original spacing as much as possible.