The following mini-doc attempts to cover every syntactic corner of the
Ledger transaction syntax. If I've missed anything, please let me know.
Note that this is a subset of all the syntax allowed in a journal file. I
haven't covered directives here or file-level comments.
John
# Basic format
The most basic form of transaction is:
2012-03-10 KFC
Expenses:Food $20.00
Assets:Cash $-20.00
This transaction has a date, a payee or description, a target account (the
first posting), and a source account (the second posting). Each posting
specifies what action is taken related to that account.
## Multiple postings
A transaction can have any number of postings:
2012-03-10 KFC
Expenses:Food $20.00
Assets:Cash $-10.00
Liabilities:Credit $-10.00
# Eliding amounts
The first thing you can do to make things easier is elide amounts. That is,
if exactly one posting has no amount specified, Ledger will infer the inverse
of the other postings' amounts:
2012-03-10 KFC
Expenses:Food $20.00
Assets:Cash $-10.00
Liabilities:Credit ; same as specifying $-10
## Elision with multiple commodities
If the other postings use multiple commodities, Ledger will copy the empty
posting N times and fill in the negated values of the various commodities:
2012-03-10 KFC
Expenses:Food $20.00
Expenses:Tips $2.00
Assets:Cash EUR -10.00
Assets:Cash GBP -10.00
Liabilities:Credit
This transaction is identical to writing:
2012-03-10 KFC
Expenses:Food $20.00
Expenses:Tips $2.00
Assets:Cash EUR -10.00
Assets:Cash GBP -10.00
Liabilities:Credit $-22.00
Liabilities:Credit EUR 10.00
Liabilities:Credit GBP 10.00
# Auxiliary dates
You can associate a second date with a transaction by following the primary
date with an equals sign:
2012-03-10=2012-03-08 KFC
Expenses:Food $20.00
Assets:Cash $-20.00
What this auxiliary date means is entirely up to you. The only use Ledger has
for it is that if you specify --aux-date, then all reports and calculations
(including pricing) will use the aux date as if it were the primary date.
# Codes
A transaction can have a textual "code". This has no meaning and is only
displayed by the print command. Checking accounts often use codes like DEP,
XFER, etc., as well as check numbers. This is to give you a place to put
those codes:
2012-03-10 (#100) KFC
Expenses:Food $20.00
Assets:Checking
# Transaction state
A transaction can have a "state": cleared, pending, or uncleared. The default
is uncleared. To mark a transaction cleared, put a * before the payee, and
after date or code:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
To mark it pending, use a !:
2012-03-10 ! KFC
Expenses:Food $20.00
Assets:Cash
What these mean is entirely up to you. The --cleared option will limits to
reports to only cleared items, while --uncleared shows both uncleared and
pending items, and --pending shows only pending items.
I use cleared to mean that I've reconciled the transaction with my bank
statement, and pending to mean that I'm in the middle of a reconciliation.
## Posting state
When you clear a transaction, that's really just shorthand for clearing all of
postings. That is:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
Is the same as writing:
2012-03-10 KFC
* Expenses:Food $20.00
* Assets:Cash
You can mark individual postings as cleared or pending, in case one "side" of
the transaction has cleared, but the other hasn't yet:
2012-03-10 * KFC
Liabilities:Credit $100.00
* Assets:Checking
# Transaction notes
After the payee, and after at least one tab or two spaces (or a space and a
tab) [Ledger calls this a "hard separator"], you may introduce a note about
the transaction using the ; character:
2012-03-10 * KFC ; yum, chicken...
Expenses:Food $20.00
Assets:Cash
Notes can also appear on the next line, so long as that line begins with
whitespace:
2012-03-10 * KFC ; yum, chicken...
; and more notes...
Expenses:Food $20.00
Assets:Cash
2012-03-10 * KFC
; just these notes...
Expenses:Food $20.00
Assets:Cash
## Posting notes
A transaction notes is shared by all its postings. This becomes significant
when querying for metadata (see below). To specify that a note belongs only
to one posting, place it after a hard separator after the amount, or on its
own line preceded by whitespace:
2012-03-10 * KFC
Expenses:Food $20.00 ; posting #1 note
Assets:Cash
; posting #2 note, extra indentation is optional
# Metadata
One of Ledger's more powerful features is the ability to associate typed
metadata with postings and transactions (by which I mean all of a
transaction's postings). This metadata can be queried, displayed, and used in
calculations.
The are two forms of metadata: tags and tag/value pairs.
## Metadata tags
To tag an item, put any word not containing whitespace between two colons:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
; :TAG:
You can gang up multiple tags by sharing colons:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
; :TAG1:TAG2:TAG3:
## Metadata values
To associate a value with a tag, use the syntax "Key: Value", where the value
can be any string of characters. Whitespace is needed after the colon, and
cannot appear in the Key:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
; MyTag: This is just a bogus value for MyTag
### Typed metadata
If a metadata tag ends in ::, it's value will be parsed as a value expression
and stored internally as a value rather than as a string. For example,
although I can specify a date textually like so:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
; AuxDate: 2012/02/30
This date is just a string, and won't be parsed as a date unless its value is
used in a date-context (at which time the string is parsed into a date
automatically every time it is needed as a date). If on the other hand I
write this:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
; AuxDate:: [2012/02/30]
Then it is parsed as a date only once, and during parsing of the journal file,
which would let me know right away that it is an invalid date.
# Virtual postings
Ordinary, the amounts of all postings in a transaction must balance to zero.
This is non-negotiable. It's what double-entry accounting is all about! But
there are some tricks up Ledger's sleeve...
You can use virtual accounts to transfer amounts to an account on the sly,
bypassing the balancing requirement. The trick is that these postings are not
considered "real", and can be removed from all reports using --real.
To specify a virtual account, surround the account name with parentheses:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
(Budget:Food) $-20.00
If you want, you can state that virtual postings *should* balance against
one or more other virtual postings by using brackets (which look "harder")
rather than parentheses:
2012-03-10 * KFC
Expenses:Food $20.00
Assets:Cash
[Budget:Food] $-20.00
[Equity:Budgets] $20.00
# Expression amounts
An amount is usually a numerical figure with an (optional) commodity, but it
can also be any value expression. To indicate this, surround the amount
expression with parentheses:
2012-03-10 * KFC
Expenses:Food ($10.00 + $20.00) ; Ledger adds it up for you
Assets:Cash
# Balance verification
If at the end of a posting's amount (and after the cost too, if there is one)
there is an equals sign, then Ledger will verify that the total value for that
account as of that posting matches the amount specified.
There are two forms of this features: balance assertions, and balance
assignments.
## Balance assertions
A balance assertion has this general form:
2012-03-10 KFC
Expenses:Food $20.00
Assets:Cash $-20.00 = $500.00
This simply asserts that after subtracting $20.00 from Assets:Cash, that the
resulting total matches $500.00. If not, it is an error.
## Balance assignments
A balance assignment has this form:
2012-03-10 KFC
Expenses:Food $20.00
Assets:Cash = $500.00
This sets the amount of the second posting to whatever it would need to be for
the total in Assets:Cash to be $500.00 after the posting. If the resulting
amount is not $-20.00 in this case, it is an error.
## Tip: Resetting a balance
Say your book-keeping has gotten a bit out of date, and your Ledger balance no
longer matches your bank balance. You can create an adjustment transaction
using balance assignments:
2012-03-10 Adjustment
Assets:Cash = $500.00
Equity:Adjustments
Since the second posting is also null, it's value will become the inverse of
whatever amount is generated for the first posting.
This is the only time in ledger
...