UP | HOME

Support via Liberapay

Using Ledger for Accounting in Org-mode with Babel

1. Introduction

Ledger is a double entry accounting system which uses simple text files for recording all transactions. As such, it is fundamentally compatible with org mode in Emacs. Using Babel, it is possible to record financial transactions conveniently in an org file and subsequently generate the financial reports required.

1.1. Getting Started

With a recent version of org (7.01+), Ledger support is provided. To use it, enable Ledger support. Check the Babel documentation on Worg for instructions on how to achieve this but I currently do this directly as follows:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((R . t)
   (ditaa . t)
   (dot . t)
   (emacs-lisp . t)
   (gnuplot . t)
   (haskell . nil)
   (latex . t)
   (ledger . t)         ;this is the important one for this tutorial
   (ocaml . nil)
   (octave . t)
   (python . t)
   (ruby . t)
   (screen . nil)
   (sh . t)
   (sql . nil)
   (sqlite . t)))

Once Ledger support in Babel has been enabled, we can use proceed to include Ledger entries within an org file. There are three ways (at least) in which these can be included:

  1. place all Ledger entries within one source block and execute this block with different arguments to generate the appropriate reports;
  2. place Ledger entries in more than one source block and use the noweb literary programming approach, supported by babel, to combine these into one block elsewhere in the file for processing by Ledger; and,
  3. place Ledger entries in different source blocks and use tangling to generate a Ledger file which you can subsequently process using Ledger directly.

The first two are described in more detail in this short tutorial. This tutorial, however, only scratches the surface of what is possible in Ledger. For further information on Ledger, check out the project website.

2. Embedded Ledger example with single source block

The easiest, albeit possibly less useful, way in which to use Ledger within an org file is to use a single source block to record all Ledger entries. The following is an example source block:

#+name: allinone
#+begin_src ledger
2010/01/01 * Starting balance
  assets:bank:savings  £1300.00
  income:starting balances
2010/07/22 * Got paid
  assets:bank:chequing  £1000.00
  income:salary
2010/07/23 Rent
  expenses:rent  £500.00
  assets:bank:chequing
2010/07/24 Food
  expenses:food  £150.00
  assets:bank:chequing
2010/07/31 * Interest on bank savings
  assets:bank:savings  £3.53
  income:interest
2010/07/31 * Transfer savings
  assets:bank:savings  £250.00
  assets:bank:chequing
2010/08/01 got paid again
  assets:bank:chequing  £1000.00
  income:salary
#+end_src

In this example, we have combined both expenses and income into one set of Ledger entries. We can now generate register and balance reports (as well as many other types of reports) using babel to invoke Ledger with specific arguments. The arguments are passed to Ledger using the :cmdline header argument. In the code block above, there is no such argument so the system takes the default. For Ledger code blocks, the default :cmdline argument is bal and the result of evaluating this code block (C-c C-c) would be:

#+results: allinone()
:            £2653.53  assets
:             £650.00  expenses
:           £-3303.53  income

If, instead, you wished to generate a register of all the transactions, you would change the #+begin_src line for the code block to include the required command line option:

#+begin_src ledger :cmdline reg

Evaluating the code block again would generate a different report.

Having to change the actual directive on the code block and re-evaluate makes it difficult to have more than one view of your transactions and financial state. Eventually, babel will support passing arguments to #+call evaluations of code blocks but this support is missing currently. Instead, we can use the concepts of literary programming, as implemented by the noweb features of babel, to help us.

3. Multiple Ledger source blocks with noweb

The noweb feature of babel allows us to expand references to other code blocks within a code block. For Ledger, this can be used to group transactions according to type, say, and then bring various sets of transactions together to generate reports.

Using the same transactions used above, we could consider splitting these into expenses and income, as follows:

3.1. Income Entries

The first set of entries relates to income, either monthly pay or interest, all typically going into one of my bank accounts. Here, I have placed several entries, but we could have had each entry in a separate src block. Note that all code blocks you wish to refer to later must have the :noweb yes babel header argument specified.

#+name: income
#+begin_src ledger :noweb yes
2010/01/01 * Starting balance
  assets:bank:savings  £1300.00
  income:starting balances
2010/07/22 * Got paid
  assets:bank:chequing  £1000.00
  income:salary
2010/07/31 * Interest on bank savings
  assets:bank:savings  £3.53
  income:interest
2010/07/31 * Transfer savings
  assets:bank:savings  £250.00
  assets:bank:chequing
2010/08/01 got paid again
  assets:bank:chequing  £1000.00
  income:salary
#+end_src

3.2. Expenses

The following entries relate to personal expenses, such as rent and food. Again, these have all been placed in a single src block but could have been done individually.

#+name: expenses
#+begin_src ledger :noweb yes
2010/07/23 Rent
  expenses:rent  £500.00
  assets:bank:chequing
2010/07/24 Food
  expenses:food  £150.00
  assets:bank:chequing
#+end_src

3.3. Financial Summaries

Given the ledger entries defined above in the income and expenses code blocks, we can now refer to these using the noweb expansion directives, <<name>>. We can now define different code blocks to generate specific reports for those transactions. Below are two examples, one to generate a balance report and one to generate a register report of all transactions.

3.3.1. An overall balance summary

The overall balance of your account and expenditure with a breakdown according to category is specified by passing the :cmdline bal argument to Ledger. This code block can now be evaluated (C-c C-c) and the results generated by incorporating the transactions referred to by the <<income>> and <<expenses>>= lines.

#+name: balance
#+begin_src ledger :cmdline bal :noweb yes
<<income>>
<<expenses>>
#+end_src

#+results: balance
:            £2653.53  assets
:             £650.00  expenses
:           £-3303.53  income

If you want a more detailed breakdown of where your money is and where it has been spent, you can specify the -s flag (i.e. :cmdline -s bal) to tell Ledger to include sub-accounts in the report.

#+begin_src ledger :cmdline -s bal :noweb yes
<<income>>
<<expenses>>
#+end_src

#+results:
:           £2653.53  assets:bank
:           £1100.00    chequing
:           £1553.53    savings
:            £650.00  expenses
:            £150.00    food
:            £500.00    rent
:          £-3303.53  income
:             £-3.53    interest
:          £-2000.00    salary
:          £-1300.00    starting balances

3.3.2. Generating a monthly register

You can also generate a monthly register (the reg command) by executing the following src block. This presents a summary of transactions for each monthly period (the -M argument) with a running total in the final column (which should be 0 at the end if all the entries are correct).

#+name: monthlyregister
#+begin_src ledger :cmdline -M reg :noweb yes
<<income>>
<<expenses>>
#+end_src

#+results: monthlyregister
:2010/01/01 - 2010/01/31         assets:bank:savings       £1300.00    £1300.00
:                                in:starting balances     £-1300.00            0
:2010/07/01 - 2010/07/31         assets:bank:chequing       £100.00     £100.00
:                                assets:bank:savings        £253.53     £353.53
:                                expenses:food              £150.00     £503.53
:                                expenses:rent              £500.00    £1003.53
:                                income:interest             £-3.53    £1000.00
:                                income:salary            £-1000.00            0
:2010/08/01 - 2010/08/01         assets:bank:chequing      £1000.00    £1000.00
:                                income:salary            £-1000.00            0

We could also generate a monthly report on our assets showing how these are increasing (or decreasing!). In this case, the final column will be the running total of the assets in our ledger.

#+name: monthlyassetsregister
#+begin_src ledger :cmdline -M reg assets :noweb yes
<<income>>
<<expenses>>
#+end_src

#+results: monthlyassetsregister
: 2010/01/01 - 2010/01/31         assets:bank:savings       £1300.00    £1300.00
: 2010/07/01 - 2010/07/31         assets:bank:chequing       £100.00    £1400.00
:                                 assets:bank:savings        £253.53    £1653.53
: 2010/08/01 - 2010/08/01         assets:bank:chequing      £1000.00    £2653.53

4. Summary

This short tutorial shows how Ledger entries can be embedded in a org file and manipulated using Babel. However, only simple Ledger features have been illustrated; please refer to the Ledger documentation for examples of more complex integrations with a ledger.

Documentation from the orgmode.org/worg/ website (either in its HTML format or in its Org format) is licensed under the GNU Free Documentation License version 1.3 or later. The code examples and css stylesheets are licensed under the GNU General Public License v3 or later.