{
"$type": "site.standard.document",
"content": "---\ntitle: \"Mapping over table rows in org-mode\"\ndescription: \"How to apply elisp functions to org-mode table rows using named tables and\n code blocks, with practical caveats and a Pride and Prejudice example.\"\ntags:\n - dev\n---\n\nI'm an [Emacs](https://www.gnu.org/software/emacs/) guy, and so if I've got some\nsimple tabular data I'd _much_ rather keep it in an\n[org-mode](https://orgmode.org) table than have to fire up Excel.\n\nHere's an example:\n\n<!-- note: the language specifiers for the code blocks in this post are wrong, but they're the \"best fit\" -->\n\n```ruby\n#+NAME: pap-table\n| first name | last name | yearly-income |\n|-------------|-----------|---------------|\n| Mr | Bennett | 2000 |\n| Fitzwilliam | Darcy | 10000 |\n| Charles | Bingley | 5000 |\n```\n\nIf the prospect of having to keep all those `|` characters manually aligned is\nfreaking you out, don't worry---`orgtbl-mode` does it all for you automatically.\n\nNow, I often want to get my functional programming on and apply a function to\nall the rows of the table. Org-mode does have some special syntax with bunch of\ncool features for doing arithmetic on the cells (just like Excel formulas) but\nI'm usually happier just writing regular elisp to get the job done.\n\nThe nicest[^nicer] way I've found to do this is to give the table a **name** (in\nthe example above the table name is `pap-table`---can you guess why?). Then, you\ncan tell an elisp\n[code block](https://orgmode.org/manual/Structure-of-code-blocks.html) about the\ndata in that table like so (note the `:var table=pap-table` at the start):\n\n[^nicer]: if there's a nicer way, please let me know!\n\n```scheme\n#+BEGIN_SRC emacs-lisp :var table=pap-table\n (-map\n (lambda (row)\n (cl-destructuring-bind (first last income) row\n (list\n (format \"Mr. %s is a man of %s fortune; %s a year.\"\n last\n (if (< income 2500) \"small\" \"large\")\n income))))\n table)\n#+END_SRC\n```\n\nThen, when you evaluate the code block with `C-c C-c` (or just `, ,` in\nSpacemacs) it'll return the \"result\":\n\n```ruby\n#+RESULTS:\n| Mr. Bennett is a man of small fortune; 2000 a year. |\n| Mr. Darcy is a man of large fortune; 10000 a year. |\n| Mr. Bingley is a man of large fortune; 5000 a year. |\n```\n\nThis is really handy, as you can imagine. I use it for all sorts of things,\nincluding sending \"mail merge\" emails with template values (since I also use\n[Emacs as my mail client](https://www.djcbsoftware.nl/code/mu/mu4e.html)---sending\nan email is just an elisp function call away).\n\n## Caveats\n\nThere are a few \"tricks\" in the above process which took me a while to figure\nout, so hopefully by listing them here I can save others a bunch of time &\nhassle.\n\n- The elisp doesn't actually know about the column names from the table---I had\n to re-bind them in the code block using `cl-destructuring-bind`. Make sure you\n change the bindings if you change the names/order of the columns in the table!\n\n- Org-mode tables don't have a way of specifying the column \"type\", so while\n it'll try it's best with the basics (e.g. detecting strings vs numbers)\n sometimes it gets confused. It's probably worth putting an explicit e.g.\n `string-to-number` in if you want to be sure.\n\n- In the example above my elisp block returns a value (a list, since I'm using\n `-map` from the excellent\n [`dash.el` library](https://github.com/magnars/dash.el)) and that's why the\n results get nicely formatted in the results block. If your code is\n side-effectful but doesn't return a value then you see the results in that\n place, you'll have to look elsewhere (e.g. if you call `message` you'll need\n to look in the `*Messages*` buffer as usual).\n\n- Further to the previous caveat, you'll notice that I'm actually wrapping the\n result of the inner `lambda` in another `list`, so the output of the code\n block is actually a list of lists. I could have just returned a list of the\n strings, but then it would be interpreted as an _1×n_ table, rather than the\n (nicer looking on the page) _n×1_ table shown above.\n",
"createdAt": "2026-05-13T23:14:59.824Z",
"description": "How to apply elisp functions to org-mode table rows using named tables and code blocks, with practical caveats and a Pride and Prejudice example.",
"path": "/blog/2019/03/09/mapping-over-table-rows-in-org-mode",
"publishedAt": "2019-03-09T00:00:00.000Z",
"site": "at://did:plc:tevykrhi4kibtsipzci76d76/site.standard.publication/self",
"tags": [
"dev"
],
"textContent": "How to apply elisp functions to org-mode table rows using named tables and code blocks, with practical caveats and a Pride and Prejudice example.",
"title": "Mapping over table rows in org-mode"
}