Tables of files with Org mode
Literate programming is a superb way of encoding knowledge in a collaboration with a machine, and Org mode is one of the best environments for interacting with text and images out there.
As part of my work to maintain my TIL streak, I’m creating MDX files with dates that determine when a page should go live. This allows me to queue up TILs so I can get away for a few days when a friend is getting married.
While I’ve yet to fully automate the drafting process, I did want a quick way to see what’s queued up and which days are taken care of. Something, Org-mode is brilliantly equipped to help me with this.
We start with a little ripgrep
to find files with a date: (.*)
pattern in
the relevant content directory.
The output from ripgrep
needs some massaging as we want the date first and
don’t want the leading date:
string included in our output, so we make use of
--replace
like so:
rg '^date: (.*)' --replace '$1' .
The directory is specified using the :dir
header argument to the source block
so there’s no need to cd
around in our snippet.
With ripgrep
returning the right search results, we move on to formatting the
output. As we’re going to produce a table, we provide the column names, too,
using :colnames
and a quoted list.
#+begin_src sh :dir src/content/tils :colnames '("Date" "File")
rg '^date: (.*)' --replace '$1' . | awk -F: '{ print $2 "\t" $1 }' | sort
#+end_src
With awk
, we can split our results on colons, reverse the fields, and inject
a tab, which Org mode helpfully recognises as a column delimiter.
Putting it all together, we execute the source block, and Org-mode drops the following output below our source block.
#+results:
| Date | File |
|------------+---------------------------------------------------|
| 2024-01-02 | ./installing-aspell-dicts-with-nix.mdx |
| 2024-01-03 | ./removing-backticks-from-tailwind-typography.mdx |
| 2024-01-04 | ./scheduling-a-vercel-deployment.mdx |
| 2024-01-05 | ./blocking-a-domain-with-adguard.mdx |
| 2024-01-06 | ./stable-scrollbars.mdx |
| 2024-01-07 | ./finding-project-files-in-emacs.mdx |
| 2024-01-08 | ./flake-parts-and-unfree-packages.mdx |
| 2024-01-09 | ./system-appearance-in-emacs-on-macos.mdx |
| 2024-01-10 | ./creating-clis-with-sub.mdx |
| 2024-01-11 | ./silencing-the-message-of-the-day.mdx |
| 2024-01-12 | ./when-pkg-wont-update.mdx |
| 2024-01-13 | ./rip-statistical-mechanics.mdx |
| 2024-01-14 | ./lite-system-configuration.mdx |
Note, that while I was working this out, I was using Org mode to execute my source block so I could interrogate the machine and learn by doing. This is what I think of when I hear test-driven development these days. To me, it’s about tightening feedback loops rather than dogmatic adherence to prescriptive processes.