Aru’s Information Management System (AIMS)

Arumoy Shome

2022-02-28 Mon 03:27

AIMS or Aru’s Information Management System is a collection of shellscripts to manage information in plaintext. It is inspired by org-mode, and tries to replicate a subset of its functionalities which I frequently use. AIMS is completely tuned towards my workflow as a researcher and how I manage my digital notes.

Although org-mode is great, the primary motivation behind AIMs is because I was feeling a lot of resistance when trying to tune it to my workflow, primarily because of Elisp.

You can find the latest version of the script on my dotfiles repo, below is the script as it stands on [2022-02-28 Mon 03:33].

#!/usr/bin/env bash

# aims: Aru's Information Management System

# A set of unix shellscripts to manage information. This is tuned
# specifically for my workflow as a researcher.

[[ ! -e "$INBOX" ]] && touch "$INBOX"

__capture() {
  # Capture incoming info quickly. All items are appended to INBOX
  # which defaults to `' in NOTESDIR. Optionally a template
  # can be specified using the --template| -t flag.
  local TEMPLATE="$TEMPLATESDIR/default"

  while [[ "$1" =~ ^-+.* && ! "$1" == "--" ]]; do
    case "$1" in
      --template | -t)
        echo "Error: unknown option $1."
        return 1
    esac; shift

  local ITEM=$(mktemp)
  if [[ -e "$TEMPLATE" && -x "$TEMPLATE" ]]; then
    eval "$TEMPLATE $ITEM"

  if eval "$EDITOR -c 'set ft=markdown' $ITEM"; then
    [[ "$1" && -e "$NOTESDIR/$1" ]] && INBOX="$NOTESDIR/$1"
    cat "$ITEM" >> "$INBOX"
    echo "Info: captured in $INBOX."

  echo "Info: cleaning up $(rm -v "$ITEM")"

__capture "$@"

For the time being, it only provides the capture functionality. What I find really neat is the templating system. An arbitrary name for a template can be passed to aims using the --template (or -t for short) flag. aims looks for a shellscript with the same name in the $XDG_DATA_HOME/aims directory and executes it if it exists. The beauty of this design is in its simplicity. Since templates are shellscripts, it gives us the full expressiveness of the shell. This is best demonstrated with some examples. Here is my default template as of [2022-02-28 Mon 03:40] which is used when no template is specified.

#!/usr/bin/env bash

[[ -z "$1" ]] && return 1

echo >> "$1"
echo "# [$(date +'%Y-%m-%d %a %H:%M')]" >> $1

It simply adds a level 1 markdown header followed by a timestamp. Here is another for capturing research papers.

#!/usr/bin/env bash

[[ -z "$1" ]] && return 1

echo >> "$1"

BIBKEY=$(pbpaste | grep '^@.*' | sed 's/^@.*{\(.*\),/\1/')
if [[ -n "$BIBKEY" ]]; then
  echo "# [$(date +'%Y-%m-%d %a %H:%M')] $BIBKEY" >> $1
  echo "# [$(date +'%Y-%m-%d %a %H:%M')]" >> $1

echo >> "$1"
echo '+ **Problem Statement:**' >> "$1"
echo '+ **Solution**' >> "$1"
echo '+ **Results**' >> "$1"
echo '+ **Limitations**' >> "$1"
echo '+ **Remarks**' >> "$1"
echo >> "$1"
echo '```bibtex' >> "$1"

if [[ -n "$BIBKEY" ]]; then
  pbpaste | sed '/^$/d' >> "$1" # remove empty lines
  pbcopy <(echo "$BIBKEY")

echo '```' >> "$1"

This one is a bit more involved but highlights the power of using shellscripts for templating. Given that a bibentry is copied in the clipboard, this template adds a level 1 markdown header with a timestamp and the bibkey. It adds some prompts for later when I write my notes and sticks the bibentry at the bottom.

A temporary file is used to compose the text first. Upon successful completion, the contents of the temporary file are appended to the default INBOX file if no other files are specified.