Journal format

A journal is a UTF-8 text file. Everything that starts in column 1 is a directive, a transaction header or a comment; everything indented belongs to the transaction above it.

; comment                          (also: a line starting with #)
include 2026/*.journal
option strict
commodity INR  format "₹1,00,000.00"
account Assets:Bank:HDFC   ; declared account
P 2026-01-05 USD 83.12 INR

2026-01-03 ! (REF-42) Grocery store | weekly shop  ; tag:food, trip:goa
    ; a note attached to the transaction
    Expenses:Food:Groceries   1,240.50 INR
    Assets:Bank:HDFC                          ; amount left out: auto-balances

Directives

Directive Meaning
include PATH Read another file. Relative to the including file; *, ? and [...] globs are expanded in sorted order. An include cycle is an error.
commodity NAME format "NUMBER" Declares how a commodity is displayed (see below).
account NAME Declares an account. Trailing ; comment allowed.
P DATE COMMODITY AMOUNT Market price: one unit of COMMODITY was worth AMOUNT on DATE.
option strict Same as passing --strict: every account used in a posting must be declared.
~ PERIOD DESCRIPTION Periodic transaction, see below.

Unknown directives are errors (not silently ignored) so typos surface immediately.

Commodity formats

commodity INR format "₹1,00,000.00" teaches ledgerline three things by example:

Commodities without a commodity directive are inferred from use: position and spacing of the first occurrence, the highest precision seen, and grouping if any amount used commas.

Commodity names are letters/symbols, optionally with digits after the first character when written after the number (10 NIFTY50). Anything else (spaces, a leading digit) must be quoted: 3 "ABC 1".

Accounts and strict mode

Account names are :-separated components (Assets:Bank:HDFC); empty components are an error. A name can contain single spaces (Assets:Cash In Hand); the account is separated from the amount by two or more spaces or a tab. If you forget, ledgerline tells you (account name 'Expenses:Food 80 INR' contains an amount-like part).

With option strict / --strict, an undeclared account is an error with a did-you-mean suggestion. Declaring Expenses:Food:Dining implicitly declares Expenses:Food and Expenses.

Reports classify accounts by their top-level name (case-insensitive): Assets, Liabilities, Equity, Income/Revenue, Expenses. Other top-level names show up in bal/reg but not in is/bs.

Transactions

DATE [STATUS] [(CODE)] [DESCRIPTION] [; COMMENT]
    [; note]
    ACCOUNT  [AMOUNT] [@ UNITCOST | @@ TOTALCOST] [= ASSERTION]  [; comment]

Amounts

1,240.50 INR      -1800.00 USD      ₹1,00,000.00      -$5      10 AAPL      3 "ABC 1"      0

A sign may come before the commodity or the number. An amount with no commodity is allowed (it is the empty commodity). Numbers are Decimal; there are no floats anywhere.

Costs

10 AAPL @ 180.00 USD states a per-unit price, 10 AAPL @@ 1800.00 USD a total price. For balancing, the posting is worth the cost, not the quantity. The cost must be positive and in a different commodity. Costs also feed the price database (see design.md).

Balancing

Balance assertions

Assets:Bank 0 INR = 48,759.50 INR asserts that after this posting the account holds exactly that amount of that commodity. The amount before = may be anything (zero is typical for a pure check). Only the account itself is checked, not its sub-accounts. Assertions are evaluated in date order (posting date, then file order), not in file order, so you can keep them anywhere. A failure shows expected, actual and the difference.

Periodic transactions

~ monthly from 2026-01-01 to 2026-12-31  Rent
    Expenses:Rent     25,000 INR
    Assets:Bank:HDFC

Period expression: daily, weekly, monthly, quarterly, yearly, or every N days|weeks|months|quarters|years, then optional from DATE and to DATE (exclusive). Periodic transactions do not affect balances; ledgerline budget uses their explicitly-amounted postings as budgets (the elided balancing posting is not a budget line).

Formatting

ledgerline fmt rewrites transactions canonically: 4-space posting indent, two spaces between account and amount, amounts right-aligned within a transaction, one blank line between transactions, amounts rendered with the commodity's declared format (never losing precision). Comments, directives and elided amounts are kept. The output is a fixed point: formatting twice changes nothing.