From ff3a05f89175ef590dffc2ba027ee79df1b911b6 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Thu, 24 Dec 2020 10:20:19 -0800 Subject: [PATCH] ;update manuals --- hledger/hledger.1 | 3732 +++++++++++++++++++++++++++++++++++- hledger/hledger.info | 4322 ++++++++++++++++++++++++++++++++++++++---- hledger/hledger.txt | 2739 +++++++++++++++++++++++++- 3 files changed, 10310 insertions(+), 483 deletions(-) diff --git a/hledger/hledger.1 b/hledger/hledger.1 index 17f68ad98..7161264b4 100644 --- a/hledger/hledger.1 +++ b/hledger/hledger.1 @@ -474,6 +474,40 @@ Eg to search for amounts with the dollar sign in hledger-web, write On the command line, some metacharacters like \f[C]$\f[R] have a special meaning to the shell and so must be escaped at least once more. See Special characters. +.SH ENVIRONMENT +.PP +\f[B]LEDGER_FILE\f[R] The journal file path when not specified with +\f[C]-f\f[R]. +Default: \f[C]\[ti]/.hledger.journal\f[R] (on windows, perhaps +\f[C]C:/Users/USER/.hledger.journal\f[R]). +.PP +A typical value is \f[C]\[ti]/DIR/YYYY.journal\f[R], where DIR is a +version-controlled finance directory and YYYY is the current year. +Or \f[C]\[ti]/DIR/current.journal\f[R], where current.journal is a +symbolic link to YYYY.journal. +.PP +On Mac computers, you can set this and other environment variables in a +more thorough way that also affects applications started from the GUI +(say, an Emacs dock icon). +Eg on MacOS Catalina I have a \f[C]\[ti]/.MacOSX/environment.plist\f[R] +file containing +.IP +.nf +\f[C] +{ + \[dq]LEDGER_FILE\[dq] : \[dq]\[ti]/finance/current.journal\[dq] +} +\f[R] +.fi +.PP +To see the effect you may need to \f[C]killall Dock\f[R], or reboot. +.PP +\f[B]COLUMNS\f[R] The screen width used by the register command. +Default: the full terminal width. +.PP +\f[B]NO_COLOR\f[R] If this variable exists with any value, hledger will +not use ANSI color codes in terminal output. +This overrides the --color/--colour option. .SH DATA FILES .PP hledger reads transactions from one or more data files. @@ -551,6 +585,8 @@ T}@T{ T} .TE .PP +These formats are described in their own sections, below. +.PP hledger detects the format automatically based on the file extensions shown above. If it can\[aq]t recognise the file extension, it assumes @@ -2091,12 +2127,12 @@ roi - show return on investments .PP \f[B]Miscellaneous reports:\f[R] .IP \[bu] 2 -accounts (a) - show account names +accounts - show account names .IP \[bu] 2 activity - show postings-per-interval bar charts .IP \[bu] 2 -\f[B]balance (b, bal)\f[R] - show balance changes/end balances/budgets -in any accounts +\f[B]balance (bal)\f[R] - show balance changes/end balances/budgets in +any accounts .IP \[bu] 2 codes - show transaction codes .IP \[bu] 2 @@ -2114,11 +2150,11 @@ payees - show unique payee segments of transaction descriptions .IP \[bu] 2 prices - show market price records .IP \[bu] 2 -\f[B]print (p, txns)\f[R] - show transactions (journal entries) +\f[B]print\f[R] - show transactions (journal entries) .IP \[bu] 2 print-unique - show only transactions with unique descriptions .IP \[bu] 2 -\f[B]register (r, reg)\f[R] - show postings in one or more accounts & +\f[B]register (reg)\f[R] - show postings in one or more accounts & running total .IP \[bu] 2 register-match - show a recent posting that best matches a description @@ -3569,7 +3605,7 @@ Examples: \f[C] $ hledger help Please choose a manual by typing \[dq]hledger help MANUAL\[dq] (a substring is ok). -Manuals: hledger hledger-ui hledger-web journal csv timeclock timedot +Manuals: hledger hledger-ui hledger-web \f[R] .fi .IP @@ -4711,6 +4747,3656 @@ add-on program directly, eg: $ hledger-web --serve \f[R] .fi +.SH JOURNAL FORMAT +.PP +hledger\[aq]s default file format, representing a General Journal. +.PP +hledger\[aq]s usual data source is a plain text file containing journal +entries in hledger journal format. +This file represents a standard accounting general journal. +I use file names ending in \f[C].journal\f[R], but that\[aq]s not +required. +The journal file contains a number of transaction entries, each +describing a transfer of money (or any commodity) between two or more +named accounts, in a simple format readable by both hledger and humans. +.PP +hledger\[aq]s journal format is a compatible subset, mostly, of +ledger\[aq]s journal format, so hledger can work with compatible ledger +journal files as well. +It\[aq]s safe, and encouraged, to run both hledger and ledger on the +same journal file, eg to validate the results you\[aq]re getting. +.PP +You can use hledger without learning any more about this file; just use +the add or web or import commands to create and update it. +.PP +Many users, though, edit the journal file with a text editor, and track +changes with a version control system such as git. +Editor addons such as ledger-mode or hledger-mode for Emacs, vim-ledger +for Vim, and hledger-vscode for Visual Studio Code, make this easier, +adding colour, formatting, tab completion, and useful commands. +See Editor configuration at hledger.org for the full list. +.PP +Here\[aq]s a description of each part of the file format (and +hledger\[aq]s data model). +These are mostly in the order you\[aq]ll use them, but in some cases +related concepts have been grouped together for easy reference, or +linked before they are introduced, so feel free to skip over anything +that looks unnecessary right now. +.SS Transactions +.PP +Transactions are the main unit of information in a journal file. +They represent events, typically a movement of some quantity of +commodities between two or more named accounts. +.PP +Each transaction is recorded as a journal entry, beginning with a simple +date in column 0. +This can be followed by any of the following optional fields, separated +by spaces: +.IP \[bu] 2 +a status character (empty, \f[C]!\f[R], or \f[C]*\f[R]) +.IP \[bu] 2 +a code (any short number or text, enclosed in parentheses) +.IP \[bu] 2 +a description (any remaining text until end of line or a semicolon) +.IP \[bu] 2 +a comment (any remaining text following a semicolon until end of line, +and any following indented lines beginning with a semicolon) +.IP \[bu] 2 +0 or more indented \f[I]posting\f[R] lines, describing what was +transferred and the accounts involved (indented comment lines are also +allowed, but not blank lines or non-indented lines). +.PP +Here\[aq]s a simple journal file containing one transaction: +.IP +.nf +\f[C] +2008/01/01 income + assets:bank:checking $1 + income:salary $-1 +\f[R] +.fi +.SS Dates +.SS Simple dates +.PP +Dates in the journal file use \f[I]simple dates\f[R] format: +\f[C]YYYY-MM-DD\f[R] or \f[C]YYYY/MM/DD\f[R] or \f[C]YYYY.MM.DD\f[R], +with leading zeros optional. +The year may be omitted, in which case it will be inferred from the +context: the current transaction, the default year set with a default +year directive, or the current date when the command is run. +Some examples: \f[C]2010-01-31\f[R], \f[C]2010/01/31\f[R], +\f[C]2010.1.31\f[R], \f[C]1/31\f[R]. +.PP +(The UI also accepts simple dates, as well as the more flexible smart +dates documented in the hledger manual.) +.SS Secondary dates +.PP +Real-life transactions sometimes involve more than one date - eg the +date you write a cheque, and the date it clears in your bank. +When you want to model this, for more accurate daily balances, you can +specify individual posting dates. +.PP +Or, you can use the older \f[I]secondary date\f[R] feature (Ledger calls +it auxiliary date or effective date). +Note: we support this for compatibility, but I usually recommend +avoiding this feature; posting dates are almost always clearer and +simpler. +.PP +A secondary date is written after the primary date, following an equals +sign. +If the year is omitted, the primary date\[aq]s year is assumed. +When running reports, the primary (left) date is used by default, but +with the \f[C]--date2\f[R] flag (or \f[C]--aux-date\f[R] or +\f[C]--effective\f[R]), the secondary (right) date will be used instead. +.PP +The meaning of secondary dates is up to you, but it\[aq]s best to follow +a consistent rule. +Eg \[dq]primary = the bank\[aq]s clearing date, secondary = date the +transaction was initiated, if different\[dq], as shown here: +.IP +.nf +\f[C] +2010/2/23=2/19 movie ticket + expenses:cinema $10 + assets:checking +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger register checking +2010-02-23 movie ticket assets:checking $-10 $-10 +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger register checking --date2 +2010-02-19 movie ticket assets:checking $-10 $-10 +\f[R] +.fi +.SS Posting dates +.PP +You can give individual postings a different date from their parent +transaction, by adding a posting comment containing a tag (see below) +like \f[C]date:DATE\f[R]. +This is probably the best way to control posting dates precisely. +Eg in this example the expense should appear in May reports, and the +deduction from checking should be reported on 6/1 for easy bank +reconciliation: +.IP +.nf +\f[C] +2015/5/30 + expenses:food $10 ; food purchased on saturday 5/30 + assets:checking ; bank cleared it on monday, date:6/1 +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f t.j register food +2015-05-30 expenses:food $10 $10 +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f t.j register checking +2015-06-01 assets:checking $-10 $-10 +\f[R] +.fi +.PP +DATE should be a simple date; if the year is not specified it will use +the year of the transaction\[aq]s date. +You can set the secondary date similarly, with \f[C]date2:DATE2\f[R]. +The \f[C]date:\f[R] or \f[C]date2:\f[R] tags must have a valid simple +date value if they are present, eg a \f[C]date:\f[R] tag with no value +is not allowed. +.PP +Ledger\[aq]s earlier, more compact bracketed date syntax is also +supported: \f[C][DATE]\f[R], \f[C][DATE=DATE2]\f[R] or +\f[C][=DATE2]\f[R]. +hledger will attempt to parse any square-bracketed sequence of the +\f[C]0123456789/-.=\f[R] characters in this way. +With this syntax, DATE infers its year from the transaction and DATE2 +infers its year from DATE. +.SS Status +.PP +Transactions, or individual postings within a transaction, can have a +status mark, which is a single character before the transaction +description or posting account name, separated from it by a space, +indicating one of three statuses: +.PP +.TS +tab(@); +l l. +T{ +mark \ +T}@T{ +status +T} +_ +T{ +\ +T}@T{ +unmarked +T} +T{ +\f[C]!\f[R] +T}@T{ +pending +T} +T{ +\f[C]*\f[R] +T}@T{ +cleared +T} +.TE +.PP +When reporting, you can filter by status with the +\f[C]-U/--unmarked\f[R], \f[C]-P/--pending\f[R], and +\f[C]-C/--cleared\f[R] flags; or the \f[C]status:\f[R], +\f[C]status:!\f[R], and \f[C]status:*\f[R] queries; or the U, P, C keys +in hledger-ui. +.PP +Note, in Ledger and in older versions of hledger, the \[dq]unmarked\[dq] +state is called \[dq]uncleared\[dq]. +As of hledger 1.3 we have renamed it to unmarked for clarity. +.PP +To replicate Ledger and old hledger\[aq]s behaviour of also matching +pending, combine -U and -P. +.PP +Status marks are optional, but can be helpful eg for reconciling with +real-world accounts. +Some editor modes provide highlighting and shortcuts for working with +status. +Eg in Emacs ledger-mode, you can toggle transaction status with C-c C-e, +or posting status with C-c C-c. +.PP +What \[dq]uncleared\[dq], \[dq]pending\[dq], and \[dq]cleared\[dq] +actually mean is up to you. +Here\[aq]s one suggestion: +.PP +.TS +tab(@); +lw(9.7n) lw(60.3n). +T{ +status +T}@T{ +meaning +T} +_ +T{ +uncleared +T}@T{ +recorded but not yet reconciled; needs review +T} +T{ +pending +T}@T{ +tentatively reconciled (if needed, eg during a big reconciliation) +T} +T{ +cleared +T}@T{ +complete, reconciled as far as possible, and considered correct +T} +.TE +.PP +With this scheme, you would use \f[C]-PC\f[R] to see the current balance +at your bank, \f[C]-U\f[R] to see things which will probably hit your +bank soon (like uncashed checks), and no flags to see the most +up-to-date state of your finances. +.SS Description +.PP +A transaction\[aq]s description is the rest of the line following the +date and status mark (or until a comment begins). +Sometimes called the \[dq]narration\[dq] in traditional bookkeeping, it +can be used for whatever you wish, or left blank. +Transaction descriptions can be queried, unlike comments. +.SS Payee and note +.PP +You can optionally include a \f[C]|\f[R] (pipe) character in +descriptions to subdivide the description into separate fields for +payee/payer name on the left (up to the first \f[C]|\f[R]) and an +additional note field on the right (after the first \f[C]|\f[R]). +This may be worthwhile if you need to do more precise querying and +pivoting by payee or by note. +.SS Comments +.PP +Lines in the journal beginning with a semicolon (\f[C];\f[R]) or hash +(\f[C]#\f[R]) or star (\f[C]*\f[R]) are comments, and will be ignored. +(Star comments cause org-mode nodes to be ignored, allowing emacs users +to fold and navigate their journals with org-mode or orgstruct-mode.) +.PP +You can attach comments to a transaction by writing them after the +description and/or indented on the following lines (before the +postings). +Similarly, you can attach comments to an individual posting by writing +them after the amount and/or indented on the following lines. +Transaction and posting comments must begin with a semicolon +(\f[C];\f[R]). +.PP +Some examples: +.IP +.nf +\f[C] +# a file comment +; another file comment +* also a file comment, useful in org/orgstruct mode + +comment +A multiline file comment, which continues +until a line containing just \[dq]end comment\[dq] +(or end of file). +end comment + +2012/5/14 something ; a transaction comment + ; the transaction comment, continued + posting1 1 ; a comment for posting 1 + posting2 + ; a comment for posting 2 + ; another comment line for posting 2 +; a file comment (because not indented) +\f[R] +.fi +.PP +You can also comment larger regions of a file using \f[C]comment\f[R] +and \f[C]end comment\f[R] directives. +.SS Tags +.PP +Tags are a way to add extra labels or labelled data to postings and +transactions, which you can then search or pivot on. +.PP +A simple tag is a word (which may contain hyphens) followed by a full +colon, written inside a transaction or posting comment line: +.IP +.nf +\f[C] +2017/1/16 bought groceries ; sometag: +\f[R] +.fi +.PP +Tags can have a value, which is the text after the colon, up to the next +comma or end of line, with leading/trailing whitespace removed: +.IP +.nf +\f[C] + expenses:food $10 ; a-posting-tag: the tag value +\f[R] +.fi +.PP +Note this means hledger\[aq]s tag values can not contain commas or +newlines. +Ending at commas means you can write multiple short tags on one line, +comma separated: +.IP +.nf +\f[C] + assets:checking ; a comment containing tag1:, tag2: some value ... +\f[R] +.fi +.PP +Here, +.IP \[bu] 2 +\[dq]\f[C]a comment containing\f[R]\[dq] is just comment text, not a tag +.IP \[bu] 2 +\[dq]\f[C]tag1\f[R]\[dq] is a tag with no value +.IP \[bu] 2 +\[dq]\f[C]tag2\f[R]\[dq] is another tag, whose value is +\[dq]\f[C]some value ...\f[R]\[dq] +.PP +Tags in a transaction comment affect the transaction and all of its +postings, while tags in a posting comment affect only that posting. +For example, the following transaction has three tags (\f[C]A\f[R], +\f[C]TAG2\f[R], \f[C]third-tag\f[R]) and the posting has four (those +plus \f[C]posting-tag\f[R]): +.IP +.nf +\f[C] +1/1 a transaction ; A:, TAG2: + ; third-tag: a third transaction tag, <- with a value + (a) $1 ; posting-tag: +\f[R] +.fi +.PP +Tags are like Ledger\[aq]s metadata feature, except hledger\[aq]s tag +values are simple strings. +.SS Postings +.PP +A posting is an addition of some amount to, or removal of some amount +from, an account. +Each posting line begins with at least one space or tab (2 or 4 spaces +is common), followed by: +.IP \[bu] 2 +(optional) a status character (empty, \f[C]!\f[R], or \f[C]*\f[R]), +followed by a space +.IP \[bu] 2 +(required) an account name (any text, optionally containing \f[B]single +spaces\f[R], until end of line or a double space) +.IP \[bu] 2 +(optional) \f[B]two or more spaces\f[R] or tabs followed by an amount. +.PP +Positive amounts are being added to the account, negative amounts are +being removed. +.PP +The amounts within a transaction must always sum up to zero. +As a convenience, one amount may be left blank; it will be inferred so +as to balance the transaction. +.PP +Be sure to note the unusual two-space delimiter between account name and +amount. +This makes it easy to write account names containing spaces. +But if you accidentally leave only one space (or tab) before the amount, +the amount will be considered part of the account name. +.SS Virtual postings +.PP +A posting with a parenthesised account name is called a \f[I]virtual +posting\f[R] or \f[I]unbalanced posting\f[R], which means it is exempt +from the usual rule that a transaction\[aq]s postings must balance add +up to zero. +.PP +This is not part of double entry accounting, so you might choose to +avoid this feature. +Or you can use it sparingly for certain special cases where it can be +convenient. +Eg, you could set opening balances without using a balancing equity +account: +.IP +.nf +\f[C] +1/1 opening balances + (assets:checking) $1000 + (assets:savings) $2000 +\f[R] +.fi +.PP +A posting with a bracketed account name is called a \f[I]balanced +virtual posting\f[R]. +The balanced virtual postings in a transaction must add up to zero +(separately from other postings). +Eg: +.IP +.nf +\f[C] +1/1 buy food with cash, update budget envelope subaccounts, & something else + assets:cash $-10 ; <- these balance + expenses:food $7 ; <- + expenses:food $3 ; <- + [assets:checking:budget:food] $-10 ; <- and these balance + [assets:checking:available] $10 ; <- + (something:else) $5 ; <- not required to balance +\f[R] +.fi +.PP +Ordinary non-parenthesised, non-bracketed postings are called \f[I]real +postings\f[R]. +You can exclude virtual postings from reports with the +\f[C]-R/--real\f[R] flag or \f[C]real:1\f[R] query. +.SS Account names +.PP +Account names typically have several parts separated by a full colon, +from which hledger derives a hierarchical chart of accounts. +They can be anything you like, but in finance there are traditionally +five top-level accounts: \f[C]assets\f[R], \f[C]liabilities\f[R], +\f[C]income\f[R], \f[C]expenses\f[R], and \f[C]equity\f[R]. +.PP +Account names may contain single spaces, eg: +\f[C]assets:accounts receivable\f[R]. +Because of this, they must always be followed by \f[B]two or more +spaces\f[R] (or newline). +.PP +Account names can be aliased. +.SS Amounts +.PP +After the account name, there is usually an amount. +(Important: between account name and amount, there must be \f[B]two or +more spaces\f[R].) +.PP +hledger\[aq]s amount format is flexible, supporting several +international formats. +Here are some examples. +Amounts have a number (the \[dq]quantity\[dq]): +.IP +.nf +\f[C] +1 +\f[R] +.fi +.PP +\&..and usually a currency or commodity name (the \[dq]commodity\[dq]). +This is a symbol, word, or phrase, to the left or right of the quantity, +with or without a separating space: +.IP +.nf +\f[C] +$1 +4000 AAPL +\f[R] +.fi +.PP +If the commodity name contains spaces, numbers, or punctuation, it must +be enclosed in double quotes: +.IP +.nf +\f[C] +3 \[dq]no. 42 green apples\[dq] +\f[R] +.fi +.PP +Amounts can be preceded by a minus sign (or a plus sign, though plus is +the default), The sign can be written before or after a left-side +commodity symbol: +.IP +.nf +\f[C] +-$1 +$-1 +\f[R] +.fi +.PP +One or more spaces between the sign and the number are acceptable when +parsing (but they won\[aq]t be displayed in output): +.IP +.nf +\f[C] ++ $1 +$- 1 +\f[R] +.fi +.PP +Scientific E notation is allowed: +.IP +.nf +\f[C] +1E-6 +EUR 1E3 +\f[R] +.fi +.PP +A decimal mark can be written as a period or a comma: +.IP +.nf +\f[C] +1.23 +1,23456780000009 +\f[R] +.fi +.SS Digit group marks +.PP +In the integer part of the quantity (left of the decimal mark), groups +of digits can optionally be separated by a \[dq]digit group mark\[dq] - +a space, comma, or period (different from the decimal mark): +.IP +.nf +\f[C] + $1,000,000.00 + EUR 2.000.000,00 +INR 9,99,99,999.00 + 1 000 000.9455 +\f[R] +.fi +.PP +Note, a number containing a single group mark and no decimal mark is +ambiguous. +Are these group marks or decimal marks ? +.IP +.nf +\f[C] +1,000 +1.000 +\f[R] +.fi +.PP +hledger will treat them both as decimal marks by default (cf #793). +If you use digit group marks, to prevent confusion and undetected typos +we recommend you write commodity directives at the top of the file to +explicitly declare the decimal mark (and optionally a digit group mark). +Note, these formats (\[dq]amount styles\[dq]) are specific to each +commodity, so if your data uses multiple formats, hledger can handle it: +.IP +.nf +\f[C] +commodity $1,000.00 +commodity EUR 1.000,00 +commodity INR 9,99,99,999.00 +commodity 1 000 000.9455 +\f[R] +.fi +.PP +.SS Commodity display style +.PP +For the amounts in each commodity, hledger chooses a consistent display +style. +(Excluding price amounts, which are always displayed as written). +The display style is chosen as follows: +.IP \[bu] 2 +If there is a commodity directive (or default commodity directive) for +the commodity, its style is used (see examples above). +.IP \[bu] 2 +Otherwise the style is inferred from the amounts in that commodity seen +in the journal. +.IP \[bu] 2 +Or if there are no such amounts in the journal, a default style is used +(like \f[C]$1000.00\f[R]). +.PP +A style is inferred from the journal amounts in a commodity as follows: +.IP \[bu] 2 +Use the general style (decimal mark, symbol placement) of the first +amount +.IP \[bu] 2 +Use the first-seen digit group style (digit group mark, digit group +sizes), if any +.IP \[bu] 2 +Use the maximum number of decimal places of all. +.PP +Transaction price amounts don\[aq]t affect the commodity display style +directly, but occasionally they can do so indirectly (eg when a +posting\[aq]s amount is inferred using a transaction price). +If you find this causing problems, use a commodity directive to fix the +display style. +.PP +In summary, each commodity\[aq]s amounts will be normalised to +.IP \[bu] 2 +the style declared by a \f[C]commodity\f[R] directive +.IP \[bu] 2 +or, the style of the first posting amount in the journal, with the +first-seen digit group style and the maximum-seen number of decimal +places. +.PP +So if your reports are showing amounts in a way you don\[aq]t like, eg +with too many decimal places, use a commodity directive to set the +commodity\[aq]s display style. +For example: +.IP +.nf +\f[C] +# declare euro, dollar and bitcoin commodities and set their display styles: +commodity EUR 1.000, +commodity $1000.00 +commodity 1000.00000000 BTC +\f[R] +.fi +.SS Rounding +.PP +Amounts are stored internally as decimal numbers with up to 255 decimal +places, and displayed with the number of decimal places specified by the +commodity display style. +Note, hledger uses banker\[aq]s rounding: it rounds to the nearest even +number, eg 0.5 displayed with zero decimal places is \[dq]0\[dq]). +(Guaranteed since hledger 1.17.1; in older versions this could vary if +hledger was built with Decimal < 0.5.1.) +.SS Transaction prices +.PP +Within a transaction, you can note an amount\[aq]s price in another +commodity. +This can be used to document the cost (in a purchase) or selling price +(in a sale). +For example, transaction prices are useful to record purchases of a +foreign currency. +Note transaction prices are fixed at the time of the transaction, and do +not change over time. +See also market prices, which represent prevailing exchange rates on a +certain date. +.PP +There are several ways to record a transaction price: +.IP "1." 3 +Write the price per unit, as \f[C]\[at] UNITPRICE\f[R] after the amount: +.RS 4 +.IP +.nf +\f[C] +2009/1/1 + assets:euros \[Eu]100 \[at] $1.35 ; one hundred euros purchased at $1.35 each + assets:dollars ; balancing amount is -$135.00 +\f[R] +.fi +.RE +.IP "2." 3 +Write the total price, as \f[C]\[at]\[at] TOTALPRICE\f[R] after the +amount: +.RS 4 +.IP +.nf +\f[C] +2009/1/1 + assets:euros \[Eu]100 \[at]\[at] $135 ; one hundred euros purchased at $135 for the lot + assets:dollars +\f[R] +.fi +.RE +.IP "3." 3 +Specify amounts for all postings, using exactly two commodities, and let +hledger infer the price that balances the transaction: +.RS 4 +.IP +.nf +\f[C] +2009/1/1 + assets:euros \[Eu]100 ; one hundred euros purchased + assets:dollars $-135 ; for $135 +\f[R] +.fi +.RE +.IP "4." 3 +Like 1, but the \f[C]\[at]\f[R] is parenthesised, i.e. +\f[C](\[at])\f[R]; this is for compatibility with Ledger journals +(Virtual posting costs), and is equivalent to 1 in hledger. +.IP "5." 3 +Like 2, but as in 4 the \f[C]\[at]\[at]\f[R] is parenthesised, i.e. +\f[C](\[at]\[at])\f[R]; in hledger, this is equivalent to 2. +.PP +Use the \f[C]-B/--cost\f[R] flag to convert amounts to their transaction +price\[aq]s commodity, if any. +(mnemonic: \[dq]B\[dq] is from \[dq]cost Basis\[dq], as in Ledger). +Eg here is how -B affects the balance report for the example above: +.IP +.nf +\f[C] +$ hledger bal -N --flat + $-135 assets:dollars + \[Eu]100 assets:euros +$ hledger bal -N --flat -B + $-135 assets:dollars + $135 assets:euros # <- the euros\[aq] cost +\f[R] +.fi +.PP +Note -B is sensitive to the order of postings when a transaction price +is inferred: the inferred price will be in the commodity of the last +amount. +So if example 3\[aq]s postings are reversed, while the transaction is +equivalent, -B shows something different: +.IP +.nf +\f[C] +2009/1/1 + assets:dollars $-135 ; 135 dollars sold + assets:euros \[Eu]100 ; for 100 euros +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger bal -N --flat -B + \[Eu]-100 assets:dollars # <- the dollars\[aq] selling price + \[Eu]100 assets:euros +\f[R] +.fi +.SS Lot prices, lot dates +.PP +Ledger allows another kind of price, lot price (four variants: +\f[C]{UNITPRICE}\f[R], \f[C]{{TOTALPRICE}}\f[R], +\f[C]{=FIXEDUNITPRICE}\f[R], \f[C]{{=FIXEDTOTALPRICE}}\f[R]), and/or a +lot date (\f[C][DATE]\f[R]) to be specified. +These are normally used to select a lot when selling investments. +hledger will parse these, for compatibility with Ledger journals, but +currently ignores them. +A transaction price, lot price and/or lot date may appear in any order, +after the posting amount and before the balance assertion if any. +.SS Balance assertions +.PP +hledger supports Ledger-style balance assertions in journal files. +These look like, for example, \f[C]= EXPECTEDBALANCE\f[R] following a +posting\[aq]s amount. +Eg here we assert the expected dollar balance in accounts a and b after +each posting: +.IP +.nf +\f[C] +2013/1/1 + a $1 =$1 + b =$-1 + +2013/1/2 + a $1 =$2 + b $-1 =$-2 +\f[R] +.fi +.PP +After reading a journal file, hledger will check all balance assertions +and report an error if any of them fail. +Balance assertions can protect you from, eg, inadvertently disrupting +reconciled balances while cleaning up old entries. +You can disable them temporarily with the +\f[C]-I/--ignore-assertions\f[R] flag, which can be useful for +troubleshooting or for reading Ledger files. +(Note: this flag currently does not disable balance assignments, below). +.SS Assertions and ordering +.PP +hledger sorts an account\[aq]s postings and assertions first by date and +then (for postings on the same day) by parse order. +Note this is different from Ledger, which sorts assertions only by parse +order. +(Also, Ledger assertions do not see the accumulated effect of repeated +postings to the same account within a transaction.) +.PP +So, hledger balance assertions keep working if you reorder +differently-dated transactions within the journal. +But if you reorder same-dated transactions or postings, assertions might +break and require updating. +This order dependence does bring an advantage: precise control over the +order of postings and assertions within a day, so you can assert +intra-day balances. +.SS Assertions and included files +.PP +With included files, things are a little more complicated. +Including preserves the ordering of postings and assertions. +If you have multiple postings to an account on the same day, split +across different files, and you also want to assert the account\[aq]s +balance on the same day, you\[aq]ll have to put the assertion in the +right file. +.SS Assertions and multiple -f options +.PP +Balance assertions don\[aq]t work well across files specified with +multiple -f options. +Use include or concatenate the files instead. +.SS Assertions and commodities +.PP +The asserted balance must be a simple single-commodity amount, and in +fact the assertion checks only this commodity\[aq]s balance within the +(possibly multi-commodity) account balance. +This is how assertions work in Ledger also. +We could call this a \[dq]partial\[dq] balance assertion. +.PP +To assert the balance of more than one commodity in an account, you can +write multiple postings, each asserting one commodity\[aq]s balance. +.PP +You can make a stronger \[dq]total\[dq] balance assertion by writing a +double equals sign (\f[C]== EXPECTEDBALANCE\f[R]). +This asserts that there are no other unasserted commodities in the +account (or, that their balance is 0). +.IP +.nf +\f[C] +2013/1/1 + a $1 + a 1\[Eu] + b $-1 + c -1\[Eu] + +2013/1/2 ; These assertions succeed + a 0 = $1 + a 0 = 1\[Eu] + b 0 == $-1 + c 0 == -1\[Eu] + +2013/1/3 ; This assertion fails as \[aq]a\[aq] also contains 1\[Eu] + a 0 == $1 +\f[R] +.fi +.PP +It\[aq]s not yet possible to make a complete assertion about a balance +that has multiple commodities. +One workaround is to isolate each commodity into its own subaccount: +.IP +.nf +\f[C] +2013/1/1 + a:usd $1 + a:euro 1\[Eu] + b + +2013/1/2 + a 0 == 0 + a:usd 0 == $1 + a:euro 0 == 1\[Eu] +\f[R] +.fi +.SS Assertions and prices +.PP +Balance assertions ignore transaction prices, and should normally be +written without one: +.IP +.nf +\f[C] +2019/1/1 + (a) $1 \[at] \[Eu]1 = $1 +\f[R] +.fi +.PP +We do allow prices to be written there, however, and print shows them, +even though they don\[aq]t affect whether the assertion passes or fails. +This is for backward compatibility (hledger\[aq]s close command used to +generate balance assertions with prices), and because balance +\f[I]assignments\f[R] do use them (see below). +.SS Assertions and subaccounts +.PP +The balance assertions above (\f[C]=\f[R] and \f[C]==\f[R]) do not count +the balance from subaccounts; they check the account\[aq]s exclusive +balance only. +You can assert the balance including subaccounts by writing \f[C]=*\f[R] +or \f[C]==*\f[R], eg: +.IP +.nf +\f[C] +2019/1/1 + equity:opening balances + checking:a 5 + checking:b 5 + checking 1 ==* 11 +\f[R] +.fi +.SS Assertions and virtual postings +.PP +Balance assertions are checked against all postings, both real and +virtual. +They are not affected by the \f[C]--real/-R\f[R] flag or \f[C]real:\f[R] +query. +.SS Assertions and precision +.PP +Balance assertions compare the exactly calculated amounts, which are not +always what is shown by reports. +Eg a commodity directive may limit the display precision, but this will +not affect balance assertions. +Balance assertion failure messages show exact amounts. +.SS Balance assignments +.PP +Ledger-style balance assignments are also supported. +These are like balance assertions, but with no posting amount on the +left side of the equals sign; instead it is calculated automatically so +as to satisfy the assertion. +This can be a convenience during data entry, eg when setting opening +balances: +.IP +.nf +\f[C] +; starting a new journal, set asset account balances +2016/1/1 opening balances + assets:checking = $409.32 + assets:savings = $735.24 + assets:cash = $42 + equity:opening balances +\f[R] +.fi +.PP +or when adjusting a balance to reality: +.IP +.nf +\f[C] +; no cash left; update balance, record any untracked spending as a generic expense +2016/1/15 + assets:cash = $0 + expenses:misc +\f[R] +.fi +.PP +The calculated amount depends on the account\[aq]s balance in the +commodity at that point (which depends on the previously-dated postings +of the commodity to that account since the last balance assertion or +assignment). +Note that using balance assignments makes your journal a little less +explicit; to know the exact amount posted, you have to run hledger or do +the calculations yourself, instead of just reading it. +.SS Balance assignments and prices +.PP +A transaction price in a balance assignment will cause the calculated +amount to have that price attached: +.IP +.nf +\f[C] +2019/1/1 + (a) = $1 \[at] \[Eu]2 +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger print --explicit +2019-01-01 + (a) $1 \[at] \[Eu]2 = $1 \[at] \[Eu]2 +\f[R] +.fi +.SS Directives +.PP +A directive is a line in the journal beginning with a special keyword, +that influences how the journal is processed. +hledger\[aq]s directives are based on a subset of Ledger\[aq]s, but +there are many differences (and also some differences between hledger +versions). +.PP +Directives\[aq] behaviour and interactions can get a little bit complex, +so here is a table summarising the directives and their effects, with +links to more detailed docs. +Note part of this table is hidden when viewed in a web browser - scroll +it sideways to see more. +.PP +.TS +tab(@); +lw(7.8n) lw(8.6n) lw(7.0n) lw(27.8n) lw(18.8n). +T{ +directive +T}@T{ +end directive +T}@T{ +subdirectives +T}@T{ +purpose +T}@T{ +can affect (as of 2018/06) +T} +_ +T{ +\f[C]account\f[R] +T}@T{ +T}@T{ +any text +T}@T{ +document account names, declare account types & display order +T}@T{ +all entries in all files, before or after +T} +T{ +\f[C]alias\f[R] +T}@T{ +\f[C]end aliases\f[R] +T}@T{ +T}@T{ +rewrite account names +T}@T{ +following entries until end of current file or end directive +T} +T{ +\f[C]apply account\f[R] +T}@T{ +\f[C]end apply account\f[R] +T}@T{ +T}@T{ +prepend a common parent to account names +T}@T{ +following entries until end of current file or end directive +T} +T{ +\f[C]comment\f[R] +T}@T{ +\f[C]end comment\f[R] +T}@T{ +T}@T{ +ignore part of journal +T}@T{ +following entries until end of current file or end directive +T} +T{ +\f[C]commodity\f[R] +T}@T{ +T}@T{ +\f[C]format\f[R] +T}@T{ +declare a commodity and its number notation & display style +T}@T{ +number notation: following entries in that commodity in all files ; +display style: amounts of that commodity in reports +T} +T{ +\f[C]D\f[R] +T}@T{ +T}@T{ +T}@T{ +declare a commodity to be used for commodityless amounts, and its number +notation & display style +T}@T{ +default commodity: following commodityless entries until end of current +file; number notation: following entries in that commodity until end of +current file; display style: amounts of that commodity in reports +T} +T{ +\f[C]include\f[R] +T}@T{ +T}@T{ +T}@T{ +include entries/directives from another file +T}@T{ +what the included directives affect +T} +T{ +\f[C]P\f[R] +T}@T{ +T}@T{ +T}@T{ +declare a market price for a commodity +T}@T{ +amounts of that commodity in reports, when -V is used +T} +T{ +\f[C]Y\f[R] +T}@T{ +T}@T{ +T}@T{ +declare a year for yearless dates +T}@T{ +following entries until end of current file +T} +T{ +\f[C]=\f[R] +T}@T{ +T}@T{ +T}@T{ +declare an auto posting rule, adding postings to other transactions +T}@T{ +all entries in parent/current/child files (but not sibling files, see +#1212) +T} +.TE +.PP +And some definitions: +.PP +.TS +tab(@); +lw(6.0n) lw(64.0n). +T{ +subdirective +T}@T{ +optional indented directive line immediately following a parent +directive +T} +T{ +number notation +T}@T{ +how to interpret numbers when parsing journal entries (the identity of +the decimal separator character). +(Currently each commodity can have its own notation, even in the same +file.) +T} +T{ +display style +T}@T{ +how to display amounts of a commodity in reports (symbol side and +spacing, digit groups, decimal separator, decimal places) +T} +T{ +directive scope +T}@T{ +which entries and (when there are multiple files) which files are +affected by a directive +T} +.TE +.PP +As you can see, directives vary in which journal entries and files they +affect, and whether they are focussed on input (parsing) or output +(reports). +Some directives have multiple effects. +.SS Directives and multiple files +.PP +If you use multiple \f[C]-f\f[R]/\f[C]--file\f[R] options, or the +\f[C]include\f[R] directive, hledger will process multiple input files. +But note that directives which affect input (see above) typically last +only until the end of the file in which they occur. +.PP +This may seem inconvenient, but it\[aq]s intentional; it makes reports +stable and deterministic, independent of the order of input. +Otherwise you could see different numbers if you happened to write -f +options in a different order, or if you moved includes around while +cleaning up your files. +.PP +It can be surprising though; for example, it means that \f[C]alias\f[R] +directives do not affect parent or sibling files (see below). +.SS Comment blocks +.PP +A line containing just \f[C]comment\f[R] starts a commented region of +the file, and a line containing just \f[C]end comment\f[R] (or the end +of the current file) ends it. +See also comments. +.SS Including other files +.PP +You can pull in the content of additional files by writing an include +directive, like this: +.IP +.nf +\f[C] +include FILEPATH +\f[R] +.fi +.PP +Only journal files can include, and only journal, timeclock or timedot +files can be included (not CSV files, currently). +.PP +If the file path does not begin with a slash, it is relative to the +current file\[aq]s folder. +.PP +A tilde means home directory, eg: \f[C]include \[ti]/main.journal\f[R]. +.PP +The path may contain glob patterns to match multiple files, eg: +\f[C]include *.journal\f[R]. +.PP +There is limited support for recursive wildcards: \f[C]**/\f[R] (the +slash is required) matches 0 or more subdirectories. +It\[aq]s not super convenient since you have to avoid include cycles and +including directories, but this can be done, eg: +\f[C]include */**/*.journal\f[R]. +.PP +The path may also be prefixed to force a specific file format, +overriding the file extension (as described in hledger.1 -> Input +files): \f[C]include timedot:\[ti]/notes/2020*.md\f[R]. +.SS Default year +.PP +You can set a default year to be used for subsequent dates which +don\[aq]t specify a year. +This is a line beginning with \f[C]Y\f[R] followed by the year. +Eg: +.IP +.nf +\f[C] +Y2009 ; set default year to 2009 + +12/15 ; equivalent to 2009/12/15 + expenses 1 + assets + +Y2010 ; change default year to 2010 + +2009/1/30 ; specifies the year, not affected + expenses 1 + assets + +1/31 ; equivalent to 2010/1/31 + expenses 1 + assets +\f[R] +.fi +.SS Declaring commodities +.PP +The \f[C]commodity\f[R] directive has several functions: +.IP "1." 3 +It declares commodities which may be used in the journal. +This is currently not enforced, but can serve as documentation. +.IP "2." 3 +It declares what decimal mark character (period or comma) to expect when +parsing input - useful to disambiguate international number formats in +your data. +(Without this, hledger will parse both \f[C]1,000\f[R] and +\f[C]1.000\f[R] as 1). +.IP "3." 3 +It declares a commodity\[aq]s display style in output - decimal and +digit group marks, number of decimal places, symbol placement etc. +.PP +You are likely to run into one of the problems solved by commodity +directives, sooner or later, so it\[aq]s a good idea to just always use +them to declare your commodities. +.PP +A commodity directive is just the word \f[C]commodity\f[R] followed by +an amount. +It may be written on a single line, like this: +.IP +.nf +\f[C] +; commodity EXAMPLEAMOUNT + +; display AAAA amounts with the symbol on the right, space-separated, +; using period as decimal point, with four decimal places, and +; separating thousands with comma. +commodity 1,000.0000 AAAA +\f[R] +.fi +.PP +or on multiple lines, using the \[dq]format\[dq] subdirective. +(In this case the commodity symbol appears twice and should be the same +in both places.): +.IP +.nf +\f[C] +; commodity SYMBOL +; format EXAMPLEAMOUNT + +; display indian rupees with currency name on the left, +; thousands, lakhs and crores comma-separated, +; period as decimal point, and two decimal places. +commodity INR + format INR 1,00,00,000.00 +\f[R] +.fi +.PP +The quantity of the amount does not matter; only the format is +significant. +The number must include a decimal mark: either a period or a comma, +followed by 0 or more decimal digits. +.PP +Note hledger normally uses banker\[aq]s rounding, so 0.5 displayed with +zero decimal digits is \[dq]0\[dq]. +(More at Commodity display style.) +.SS Commodity error checking +.PP +In strict mode, enabled with the \f[C]-s\f[R]/\f[C]--strict\f[R] flag, +hledger will report an error if a commodity symbol is used that has not +been declared by a \f[C]commodity\f[R] directive. +This works similarly to account error checking, see the notes there for +more details. +.SS Default commodity +.PP +The \f[C]D\f[R] directive sets a default commodity, to be used for +amounts without a commodity symbol (ie, plain numbers). +This commodity will be applied to all subsequent commodity-less amounts, +or until the next \f[C]D\f[R] directive. +(Note, this is different from Ledger\[aq]s \f[C]D\f[R].) +.PP +For compatibility/historical reasons, \f[C]D\f[R] also acts like a +\f[C]commodity\f[R] directive, setting the commodity\[aq]s display style +(for output) and decimal mark (for parsing input). +As with \f[C]commodity\f[R], the amount must always be written with a +decimal mark (period or comma). +If both directives are used, \f[C]commodity\f[R]\[aq]s style takes +precedence. +.PP +The syntax is \f[C]D AMOUNT\f[R]. +Eg: +.IP +.nf +\f[C] +; commodity-less amounts should be treated as dollars +; (and displayed with the dollar sign on the left, thousands separators and two decimal places) +D $1,000.00 + +1/1 + a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00 + b +\f[R] +.fi +.SS Declaring market prices +.PP +The \f[C]P\f[R] directive declares a market price, which is an exchange +rate between two commodities on a certain date. +(In Ledger, they are called \[dq]historical prices\[dq].) These are +often obtained from a stock exchange, cryptocurrency exchange, or the +foreign exchange market. +.PP +Here is the format: +.IP +.nf +\f[C] +P DATE COMMODITYA COMMODITYBAMOUNT +\f[R] +.fi +.IP \[bu] 2 +DATE is a simple date +.IP \[bu] 2 +COMMODITYA is the symbol of the commodity being priced +.IP \[bu] 2 +COMMODITYBAMOUNT is an amount (symbol and quantity) in a second +commodity, giving the price in commodity B of one unit of commodity A. +.PP +These two market price directives say that one euro was worth 1.35 US +dollars during 2009, and $1.40 from 2010 onward: +.IP +.nf +\f[C] +P 2009/1/1 \[Eu] $1.35 +P 2010/1/1 \[Eu] $1.40 +\f[R] +.fi +.PP +The \f[C]-V\f[R], \f[C]-X\f[R] and \f[C]--value\f[R] flags use these +market prices to show amount values in another commodity. +See Valuation. +.SS Declaring accounts +.PP +\f[C]account\f[R] directives can be used to declare accounts (ie, the +places that amounts are transferred from and to). +Though not required, these declarations can provide several benefits: +.IP \[bu] 2 +They can document your intended chart of accounts, providing a +reference. +.IP \[bu] 2 +They can help hledger know your accounts\[aq] types (asset, liability, +equity, revenue, expense), useful for reports like balancesheet and +incomestatement. +.IP \[bu] 2 +They control account display order in reports, allowing non-alphabetic +sorting (eg Revenues to appear above Expenses). +.IP \[bu] 2 +They can store extra information about accounts (account numbers, notes, +etc.) +.IP \[bu] 2 +They help with account name completion in the add command, hledger-iadd, +hledger-web, ledger-mode etc. +.IP \[bu] 2 +In strict mode, they restrict which accounts may be posted to by +transactions, which helps detect typos. +.PP +The simplest form is just the word \f[C]account\f[R] followed by a +hledger-style account name, eg this account directive declares the +\f[C]assets:bank:checking\f[R] account: +.IP +.nf +\f[C] +account assets:bank:checking +\f[R] +.fi +.SS Account error checking +.PP +By default, accounts come into existence when a transaction references +them by name. +This is convenient, but it means hledger can\[aq]t warn you when you +mis-spell an account name in the journal. +Usually you\[aq]ll find the error later, as an extra account in balance +reports, or an incorrect balance when reconciling. +.PP +In strict mode, enabled with the \f[C]-s\f[R]/\f[C]--strict\f[R] flag, +hledger will report an error if any transaction uses an account name +that has not been declared by an account directive. +Some notes: +.IP \[bu] 2 +The declaration is case-sensitive; transactions must use the correct +account name capitalisation. +.IP \[bu] 2 +The account directive\[aq]s scope is \[dq]whole file and below\[dq] (see +directives). +This means it affects all of the current file, and any files it +includes, but not parent or sibling files. +The position of account directives within the file does not matter, +though it\[aq]s usual to put them at the top. +.IP \[bu] 2 +Accounts can only be declared in \f[C]journal\f[R] files (but will +affect included files in other formats). +.IP \[bu] 2 +It\[aq]s currently not possible to declare \[dq]all possible +subaccounts\[dq] with a wildcard; every account posted to must be +declared. +.SS Account comments +.PP +Comments, beginning with a semicolon, can be added: +.IP \[bu] 2 +on the same line, \f[B]after two or more spaces\f[R] (because ; is +allowed in account names) +.IP \[bu] 2 +on the next lines, indented +.PP +An example of both: +.IP +.nf +\f[C] +account assets:bank:checking ; same-line comment, note 2+ spaces before ; + ; next-line comment + ; another with tag, acctno:12345 (not used yet) +\f[R] +.fi +.PP +Same-line comments are not supported by Ledger, or hledger <1.13. +.SS Account subdirectives +.PP +We also allow (and ignore) Ledger-style indented subdirectives, just for +compatibility.: +.IP +.nf +\f[C] +account assets:bank:checking + format blah blah ; <- subdirective, ignored +\f[R] +.fi +.PP +Here is the full syntax of account directives: +.IP +.nf +\f[C] +account ACCTNAME [ACCTTYPE] [;COMMENT] + [;COMMENTS] + [LEDGER-STYLE SUBDIRECTIVES, IGNORED] +\f[R] +.fi +.SS Account types +.PP +hledger recognises five main types of account, corresponding to the +account classes in the accounting equation: +.PP +\f[C]Asset\f[R], \f[C]Liability\f[R], \f[C]Equity\f[R], +\f[C]Revenue\f[R], \f[C]Expense\f[R]. +.PP +These account types are important for controlling which accounts appear +in the balancesheet, balancesheetequity, incomestatement reports (and +probably for other things in future). +.PP +Additionally, we recognise the \f[C]Cash\f[R] type, which is also an +\f[C]Asset\f[R], and which causes accounts to appear in the cashflow +report. +(\[dq]Cash\[dq] here means liquid assets, eg bank balances but typically +not investments or receivables.) +.SS Declaring account types +.PP +Generally, to make these reports work you should declare your top-level +accounts and their types, using account directives with \f[C]type:\f[R] +tags. +.PP +The tag\[aq]s value should be one of: \f[C]Asset\f[R], +\f[C]Liability\f[R], \f[C]Equity\f[R], \f[C]Revenue\f[R], +\f[C]Expense\f[R], \f[C]Cash\f[R], \f[C]A\f[R], \f[C]L\f[R], +\f[C]E\f[R], \f[C]R\f[R], \f[C]X\f[R], \f[C]C\f[R] (all case +insensitive). +The type is inherited by all subaccounts except where they override it. +Here\[aq]s a complete example: +.IP +.nf +\f[C] +account assets ; type: Asset +account assets:bank ; type: Cash +account assets:cash ; type: Cash +account liabilities ; type: Liability +account equity ; type: Equity +account revenues ; type: Revenue +account expenses ; type: Expense +\f[R] +.fi +.SS Auto-detected account types +.PP +If you happen to use common english top-level account names, you may not +need to declare account types, as they will be detected automatically +using the following rules: +.PP +.TS +tab(@); +l l. +T{ +If name matches regular expression: +T}@T{ +account type is: +T} +_ +T{ +\f[C]\[ha]assets?(:|$)\f[R] +T}@T{ +\f[C]Asset\f[R] +T} +T{ +\f[C]\[ha](debts?|liabilit(y|ies))(:|$)\f[R] +T}@T{ +\f[C]Liability\f[R] +T} +T{ +\f[C]\[ha]equity(:|$)\f[R] +T}@T{ +\f[C]Equity\f[R] +T} +T{ +\f[C]\[ha](income|revenue)s?(:|$)\f[R] +T}@T{ +\f[C]Revenue\f[R] +T} +T{ +\f[C]\[ha]expenses?(:|$)\f[R] +T}@T{ +\f[C]Expense\f[R] +T} +.TE +.PP +.TS +tab(@); +lw(56.9n) lw(13.1n). +T{ +If account type is \f[C]Asset\f[R] and name does not contain regular +expression: +T}@T{ +account type is: +T} +_ +T{ +\f[C](investment|receivable|:A/R|:fixed)\f[R] +T}@T{ +\f[C]Cash\f[R] +T} +.TE +.PP +Even so, explicit declarations may be a good idea, for clarity and +predictability. +.SS Interference from auto-detected account types +.PP +If you assign any account type, it\[aq]s a good idea to assign all of +them, to prevent any confusion from mixing declared and auto-detected +types. +Although it\[aq]s unlikely to happen in real life, here\[aq]s an +example: with the following journal, \f[C]balancesheetequity\f[R] shows +\[dq]liabilities\[dq] in both Liabilities and Equity sections. +Declaring another account as \f[C]type:Liability\f[R] would fix it: +.IP +.nf +\f[C] +account liabilities ; type:Equity + +2020-01-01 + assets 1 + liabilities 1 + equity -2 +\f[R] +.fi +.SS Old account type syntax +.PP +In some hledger journals you might instead see this old syntax (the +letters ALERX, separated from the account name by two or more spaces); +this is deprecated and may be removed soon: +.IP +.nf +\f[C] +account assets A +account liabilities L +account equity E +account revenues R +account expenses X +\f[R] +.fi +.SS Account display order +.PP +Account directives also set the order in which accounts are displayed, +eg in reports, the hledger-ui accounts screen, and the hledger-web +sidebar. +By default accounts are listed in alphabetical order. +But if you have these account directives in the journal: +.IP +.nf +\f[C] +account assets +account liabilities +account equity +account revenues +account expenses +\f[R] +.fi +.PP +you\[aq]ll see those accounts displayed in declaration order, not +alphabetically: +.IP +.nf +\f[C] +$ hledger accounts -1 +assets +liabilities +equity +revenues +expenses +\f[R] +.fi +.PP +Undeclared accounts, if any, are displayed last, in alphabetical order. +.PP +Note that sorting is done at each level of the account tree (within each +group of sibling accounts under the same parent). +And currently, this directive: +.IP +.nf +\f[C] +account other:zoo +\f[R] +.fi +.PP +would influence the position of \f[C]zoo\f[R] among +\f[C]other\f[R]\[aq]s subaccounts, but not the position of +\f[C]other\f[R] among the top-level accounts. +This means: +.IP \[bu] 2 +you will sometimes declare parent accounts (eg \f[C]account other\f[R] +above) that you don\[aq]t intend to post to, just to customize their +display order +.IP \[bu] 2 +sibling accounts stay together (you couldn\[aq]t display \f[C]x:y\f[R] +in between \f[C]a:b\f[R] and \f[C]a:c\f[R]). +.SS Rewriting accounts +.PP +You can define account alias rules which rewrite your account names, or +parts of them, before generating reports. +This can be useful for: +.IP \[bu] 2 +expanding shorthand account names to their full form, allowing easier +data entry and a less verbose journal +.IP \[bu] 2 +adapting old journals to your current chart of accounts +.IP \[bu] 2 +experimenting with new account organisations, like a new hierarchy or +combining two accounts into one +.IP \[bu] 2 +customising reports +.PP +Account aliases also rewrite account names in account directives. +They do not affect account names being entered via hledger add or +hledger-web. +.PP +See also Rewrite account names. +.SS Basic aliases +.PP +To set an account alias, use the \f[C]alias\f[R] directive in your +journal file. +This affects all subsequent journal entries in the current file or its +included files. +The spaces around the = are optional: +.IP +.nf +\f[C] +alias OLD = NEW +\f[R] +.fi +.PP +Or, you can use the \f[C]--alias \[aq]OLD=NEW\[aq]\f[R] option on the +command line. +This affects all entries. +It\[aq]s useful for trying out aliases interactively. +.PP +OLD and NEW are case sensitive full account names. +hledger will replace any occurrence of the old account name with the new +one. +Subaccounts are also affected. +Eg: +.IP +.nf +\f[C] +alias checking = assets:bank:wells fargo:checking +; rewrites \[dq]checking\[dq] to \[dq]assets:bank:wells fargo:checking\[dq], or \[dq]checking:a\[dq] to \[dq]assets:bank:wells fargo:checking:a\[dq] +\f[R] +.fi +.SS Regex aliases +.PP +There is also a more powerful variant that uses a regular expression, +indicated by the forward slashes: +.IP +.nf +\f[C] +alias /REGEX/ = REPLACEMENT +\f[R] +.fi +.PP +or \f[C]--alias \[aq]/REGEX/=REPLACEMENT\[aq]\f[R]. +.PP +REGEX is a case-insensitive regular expression. +Anywhere it matches inside an account name, the matched part will be +replaced by REPLACEMENT. +If REGEX contains parenthesised match groups, these can be referenced by +the usual numeric backreferences in REPLACEMENT. +Eg: +.IP +.nf +\f[C] +alias /\[ha](.+):bank:([\[ha]:]+):(.*)/ = \[rs]1:\[rs]2 \[rs]3 +; rewrites \[dq]assets:bank:wells fargo:checking\[dq] to \[dq]assets:wells fargo checking\[dq] +\f[R] +.fi +.PP +Also note that REPLACEMENT continues to the end of line (or on command +line, to end of option argument), so it can contain trailing whitespace. +.SS Combining aliases +.PP +You can define as many aliases as you like, using journal directives +and/or command line options. +.PP +Recursive aliases - where an account name is rewritten by one alias, +then by another alias, and so on - are allowed. +Each alias sees the effect of previously applied aliases. +.PP +In such cases it can be important to understand which aliases will be +applied and in which order. +For (each account name in) each journal entry, we apply: +.IP "1." 3 +\f[C]alias\f[R] directives preceding the journal entry, most recently +parsed first (ie, reading upward from the journal entry, bottom to top) +.IP "2." 3 +\f[C]--alias\f[R] options, in the order they appeared on the command +line (left to right). +.PP +In other words, for (an account name in) a given journal entry: +.IP \[bu] 2 +the nearest alias declaration before/above the entry is applied first +.IP \[bu] 2 +the next alias before/above that will be be applied next, and so on +.IP \[bu] 2 +aliases defined after/below the entry do not affect it. +.PP +This gives nearby aliases precedence over distant ones, and helps +provide semantic stability - aliases will keep working the same way +independent of which files are being read and in which order. +.PP +In case of trouble, adding \f[C]--debug=6\f[R] to the command line will +show which aliases are being applied when. +.SS Aliases and multiple files +.PP +As explained at Directives and multiple files, \f[C]alias\f[R] +directives do not affect parent or sibling files. +Eg in this command, +.IP +.nf +\f[C] +hledger -f a.aliases -f b.journal +\f[R] +.fi +.PP +account aliases defined in a.aliases will not affect b.journal. +Including the aliases doesn\[aq]t work either: +.IP +.nf +\f[C] +include a.aliases + +2020-01-01 ; not affected by a.aliases + foo 1 + bar +\f[R] +.fi +.PP +This means that account aliases should usually be declared at the start +of your top-most file, like this: +.IP +.nf +\f[C] +alias foo=Foo +alias bar=Bar + +2020-01-01 ; affected by aliases above + foo 1 + bar + +include c.journal ; also affected +\f[R] +.fi +.SS \f[C]end aliases\f[R] +.PP +You can clear (forget) all currently defined aliases with the +\f[C]end aliases\f[R] directive: +.IP +.nf +\f[C] +end aliases +\f[R] +.fi +.SS Default parent account +.PP +You can specify a parent account which will be prepended to all accounts +within a section of the journal. +Use the \f[C]apply account\f[R] and \f[C]end apply account\f[R] +directives like so: +.IP +.nf +\f[C] +apply account home + +2010/1/1 + food $10 + cash + +end apply account +\f[R] +.fi +.PP +which is equivalent to: +.IP +.nf +\f[C] +2010/01/01 + home:food $10 + home:cash $-10 +\f[R] +.fi +.PP +If \f[C]end apply account\f[R] is omitted, the effect lasts to the end +of the file. +Included files are also affected, eg: +.IP +.nf +\f[C] +apply account business +include biz.journal +end apply account +apply account personal +include personal.journal +\f[R] +.fi +.PP +Prior to hledger 1.0, legacy \f[C]account\f[R] and \f[C]end\f[R] +spellings were also supported. +.PP +A default parent account also affects account directives. +It does not affect account names being entered via hledger add or +hledger-web. +If account aliases are present, they are applied after the default +parent account. +.SS Periodic transactions +.PP +Periodic transaction rules describe transactions that recur. +They allow hledger to generate temporary future transactions to help +with forecasting, so you don\[aq]t have to write out each one in the +journal, and it\[aq]s easy to try out different forecasts. +.PP +Periodic transactions can be a little tricky, so before you use them, +read this whole section - or at least these tips: +.IP "1." 3 +Two spaces accidentally added or omitted will cause you trouble - read +about this below. +.IP "2." 3 +For troubleshooting, show the generated transactions with +\f[C]hledger print --forecast tag:generated\f[R] or +\f[C]hledger register --forecast tag:generated\f[R]. +.IP "3." 3 +Forecasted transactions will begin only after the last non-forecasted +transaction\[aq]s date. +.IP "4." 3 +Forecasted transactions will end 6 months from today, by default. +See below for the exact start/end rules. +.IP "5." 3 +period expressions can be tricky. +Their documentation needs improvement, but is worth studying. +.IP "6." 3 +Some period expressions with a repeating interval must begin on a +natural boundary of that interval. +Eg in \f[C]weekly from DATE\f[R], DATE must be a monday. +\f[C]\[ti] weekly from 2019/10/1\f[R] (a tuesday) will give an error. +.IP "7." 3 +Other period expressions with an interval are automatically expanded to +cover a whole number of that interval. +(This is done to improve reports, but it also affects periodic +transactions. +Yes, it\[aq]s a bit inconsistent with the above.) Eg: +\f[C]\[ti] every 10th day of month from 2020/01\f[R], which is +equivalent to \f[C]\[ti] every 10th day of month from 2020/01/01\f[R], +will be adjusted to start on 2019/12/10. +.PP +Periodic transaction rules also have a second meaning: they are used to +define budget goals, shown in budget reports. +.SS Periodic rule syntax +.PP +A periodic transaction rule looks like a normal journal entry, with the +date replaced by a tilde (\f[C]\[ti]\f[R]) followed by a period +expression (mnemonic: \f[C]\[ti]\f[R] looks like a recurring sine +wave.): +.IP +.nf +\f[C] +\[ti] monthly + expenses:rent $2000 + assets:bank:checking +\f[R] +.fi +.PP +There is an additional constraint on the period expression: the start +date must fall on a natural boundary of the interval. +Eg \f[C]monthly from 2018/1/1\f[R] is valid, but +\f[C]monthly from 2018/1/15\f[R] is not. +.PP +Partial or relative dates (M/D, D, tomorrow, last week) in the period +expression can work (useful or not). +They will be relative to today\[aq]s date, unless a Y default year +directive is in effect, in which case they will be relative to Y/1/1. +.SS Two spaces between period expression and description! +.PP +If the period expression is followed by a transaction description, these +must be separated by \f[B]two or more spaces\f[R]. +This helps hledger know where the period expression ends, so that +descriptions can not accidentally alter their meaning, as in this +example: +.IP +.nf +\f[C] +; 2 or more spaces needed here, so the period is not understood as \[dq]every 2 months in 2020\[dq] +; || +; vv +\[ti] every 2 months in 2020, we will review + assets:bank:checking $1500 + income:acme inc +\f[R] +.fi +.PP +So, +.IP \[bu] 2 +Do write two spaces between your period expression and your transaction +description, if any. +.IP \[bu] 2 +Don\[aq]t accidentally write two spaces in the middle of your period +expression. +.SS Forecasting with periodic transactions +.PP +The \f[C]--forecast\f[R] flag activates any periodic transaction rules +in the journal. +They will generate temporary recurring transactions, which are not saved +in the journal, but will appear in all reports (eg print). +This can be useful for estimating balances into the future, or +experimenting with different scenarios. +Or, it can be used as a data entry aid: describe recurring transactions, +and every so often copy the output of \f[C]print --forecast\f[R] into +the journal. +.PP +These transactions will have an extra tag indicating which periodic rule +generated them: \f[C]generated-transaction:\[ti] PERIODICEXPR\f[R]. +And a similar, hidden tag (beginning with an underscore) which, because +it\[aq]s never displayed by print, can be used to match transactions +generated \[dq]just now\[dq]: +\f[C]_generated-transaction:\[ti] PERIODICEXPR\f[R]. +.PP +Periodic transactions are generated within some forecast period. +By default, this +.IP \[bu] 2 +begins on the later of +.RS 2 +.IP \[bu] 2 +the report start date if specified with -b/-p/date: +.IP \[bu] 2 +the day after the latest normal (non-periodic) transaction in the +journal, or today if there are no normal transactions. +.RE +.IP \[bu] 2 +ends on the report end date if specified with -e/-p/date:, or 6 months +(180 days) from today. +.PP +This means that periodic transactions will begin only after the latest +recorded transaction. +And a recorded transaction dated in the future can prevent generation of +periodic transactions. +(You can avoid that by writing the future transaction as a one-time +periodic rule instead - put tilde before the date, eg +\f[C]\[ti] YYYY-MM-DD ...\f[R]). +.PP +Or, you can set your own arbitrary \[dq]forecast period\[dq], which can +overlap recorded transactions, and need not be in the future, by +providing an option argument, like \f[C]--forecast=PERIODEXPR\f[R]. +Note the equals sign is required, a space won\[aq]t work. +PERIODEXPR is a period expression, which can specify the start date, end +date, or both, like in a \f[C]date:\f[R] query. +(See also hledger.1 -> Report start & end date). +Some examples: \f[C]--forecast=202001-202004\f[R], +\f[C]--forecast=jan-\f[R], \f[C]--forecast=2020\f[R]. +.SS Budgeting with periodic transactions +.PP +With the \f[C]--budget\f[R] flag, currently supported by the balance +command, each periodic transaction rule declares recurring budget goals +for the specified accounts. +Eg the first example above declares a goal of spending $2000 on rent +(and also, a goal of depositing $2000 into checking) every month. +Goals and actual performance can then be compared in budget reports. +.PP +See also: Budgeting and Forecasting. +.PP +.SS Auto postings +.PP +\[dq]Automated postings\[dq] or \[dq]auto postings\[dq] are extra +postings which get added automatically to transactions which match +certain queries, defined by \[dq]auto posting rules\[dq], when you use +the \f[C]--auto\f[R] flag. +.PP +An auto posting rule looks a bit like a transaction: +.IP +.nf +\f[C] += QUERY + ACCOUNT AMOUNT + ... + ACCOUNT [AMOUNT] +\f[R] +.fi +.PP +except the first line is an equals sign (mnemonic: \f[C]=\f[R] suggests +matching), followed by a query (which matches existing postings), and +each \[dq]posting\[dq] line describes a posting to be generated, and the +posting amounts can be: +.IP \[bu] 2 +a normal amount with a commodity symbol, eg \f[C]$2\f[R]. +This will be used as-is. +.IP \[bu] 2 +a number, eg \f[C]2\f[R]. +The commodity symbol (if any) from the matched posting will be added to +this. +.IP \[bu] 2 +a numeric multiplier, eg \f[C]*2\f[R] (a star followed by a number N). +The matched posting\[aq]s amount (and total price, if any) will be +multiplied by N. +.IP \[bu] 2 +a multiplier with a commodity symbol, eg \f[C]*$2\f[R] (a star, number +N, and symbol S). +The matched posting\[aq]s amount will be multiplied by N, and its +commodity symbol will be replaced with S. +.PP +Any query term containing spaces must be enclosed in single or double +quotes, as on the command line. +Eg, note the quotes around the second query term below: +.IP +.nf +\f[C] += expenses:groceries \[aq]expenses:dining out\[aq] + (budget:funds:dining out) *-1 +\f[R] +.fi +.PP +Some examples: +.IP +.nf +\f[C] +; every time I buy food, schedule a dollar donation += expenses:food + (liabilities:charity) $-1 + +; when I buy a gift, also deduct that amount from a budget envelope subaccount += expenses:gifts + assets:checking:gifts *-1 + assets:checking *1 + +2017/12/1 + expenses:food $10 + assets:checking + +2017/12/14 + expenses:gifts $20 + assets:checking +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger print --auto +2017-12-01 + expenses:food $10 + assets:checking + (liabilities:charity) $-1 + +2017-12-14 + expenses:gifts $20 + assets:checking + assets:checking:gifts -$20 + assets:checking $20 +\f[R] +.fi +.SS Auto postings and multiple files +.PP +An auto posting rule can affect any transaction in the current file, or +in any parent file or child file. +Note, currently it will not affect sibling files (when multiple +\f[C]-f\f[R]/\f[C]--file\f[R] are used - see #1212). +.SS Auto postings and dates +.PP +A posting date (or secondary date) in the matched posting, or (taking +precedence) a posting date in the auto posting rule itself, will also be +used in the generated posting. +.SS Auto postings and transaction balancing / inferred amounts / balance assertions +.PP +Currently, auto postings are added: +.IP \[bu] 2 +after missing amounts are inferred, and transactions are checked for +balancedness, +.IP \[bu] 2 +but before balance assertions are checked. +.PP +Note this means that journal entries must be balanced both before and +after auto postings are added. +This changed in hledger 1.12+; see #893 for background. +.SS Auto posting tags +.PP +Automated postings will have some extra tags: +.IP \[bu] 2 +\f[C]generated-posting:= QUERY\f[R] - shows this was generated by an +auto posting rule, and the query +.IP \[bu] 2 +\f[C]_generated-posting:= QUERY\f[R] - a hidden tag, which does not +appear in hledger\[aq]s output. +This can be used to match postings generated \[dq]just now\[dq], rather +than generated in the past and saved to the journal. +.PP +Also, any transaction that has been changed by auto posting rules will +have these tags added: +.IP \[bu] 2 +\f[C]modified:\f[R] - this transaction was modified +.IP \[bu] 2 +\f[C]_modified:\f[R] - a hidden tag not appearing in the comment; this +transaction was modified \[dq]just now\[dq]. +.SH CSV FORMAT +.PP +How hledger reads CSV data, and the CSV rules file format. +.PP +hledger can read CSV files (Character Separated Value - usually comma, +semicolon, or tab) containing dated records as if they were journal +files, automatically converting each CSV record into a transaction. +.PP +(To learn about \f[I]writing\f[R] CSV, see CSV output.) +.PP +We describe each CSV file\[aq]s format with a corresponding \f[I]rules +file\f[R]. +By default this is named like the CSV file with a \f[C].rules\f[R] +extension added. +Eg when reading \f[C]FILE.csv\f[R], hledger also looks for +\f[C]FILE.csv.rules\f[R] in the same directory as \f[C]FILE.csv\f[R]. +You can specify a different rules file with the \f[C]--rules-file\f[R] +option. +If a rules file is not found, hledger will create a sample rules file, +which you\[aq]ll need to adjust. +.PP +This file contains rules describing the CSV data (header line, fields +layout, date format etc.), and how to construct hledger journal entries +(transactions) from it. +Often there will also be a list of conditional rules for categorising +transactions based on their descriptions. +Here\[aq]s an overview of the CSV rules; these are described more fully +below, after the examples: +.PP +.TS +tab(@); +lw(30.1n) lw(39.9n). +T{ +\f[B]\f[CB]skip\f[B]\f[R] +T}@T{ +skip one or more header lines or matched CSV records +T} +T{ +\f[B]\f[CB]fields\f[B]\f[R] +T}@T{ +name CSV fields, assign them to hledger fields +T} +T{ +\f[B]field assignment\f[R] +T}@T{ +assign a value to one hledger field, with interpolation +T} +T{ +\f[B]\f[CB]separator\f[B]\f[R] +T}@T{ +a custom field separator +T} +T{ +\f[B]\f[CB]if\f[B] block\f[R] +T}@T{ +apply some rules to CSV records matched by patterns +T} +T{ +\f[B]\f[CB]if\f[B] table\f[R] +T}@T{ +apply some rules to CSV records matched by patterns, alternate syntax +T} +T{ +\f[B]\f[CB]end\f[B]\f[R] +T}@T{ +skip the remaining CSV records +T} +T{ +\f[B]\f[CB]date-format\f[B]\f[R] +T}@T{ +how to parse dates in CSV records +T} +T{ +\f[B]\f[CB]decimal-mark\f[B]\f[R] +T}@T{ +the decimal mark used in CSV amounts, if ambiguous +T} +T{ +\f[B]\f[CB]newest-first\f[B]\f[R] +T}@T{ +disambiguate record order when there\[aq]s only one date +T} +T{ +\f[B]\f[CB]include\f[B]\f[R] +T}@T{ +inline another CSV rules file +T} +T{ +\f[B]\f[CB]balance-type\f[B]\f[R] +T}@T{ +choose which type of balance assignments to use +T} +.TE +.PP +Note, for best error messages when reading CSV files, use a +\f[C].csv\f[R], \f[C].tsv\f[R] or \f[C].ssv\f[R] file extension or file +prefix - see File Extension below. +.PP +There\[aq]s an introductory Convert CSV files tutorial on hledger.org. +.SS Examples +.PP +Here are some sample hledger CSV rules files. +See also the full collection at: +.PD 0 +.P +.PD +https://github.com/simonmichael/hledger/tree/master/examples/csv +.SS Basic +.PP +At minimum, the rules file must identify the date and amount fields, and +often it also specifies the date format and how many header lines there +are. +Here\[aq]s a simple CSV file and a rules file for it: +.IP +.nf +\f[C] +Date, Description, Id, Amount +12/11/2019, Foo, 123, 10.23 +\f[R] +.fi +.IP +.nf +\f[C] +# basic.csv.rules +skip 1 +fields date, description, _, amount +date-format %d/%m/%Y +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger print -f basic.csv +2019-11-12 Foo + expenses:unknown 10.23 + income:unknown -10.23 +\f[R] +.fi +.PP +Default account names are chosen, since we didn\[aq]t set them. +.SS Bank of Ireland +.PP +Here\[aq]s a CSV with two amount fields (Debit and Credit), and a +balance field, which we can use to add balance assertions, which is not +necessary but provides extra error checking: +.IP +.nf +\f[C] +Date,Details,Debit,Credit,Balance +07/12/2012,LODGMENT 529898,,10.0,131.21 +07/12/2012,PAYMENT,5,,126 +\f[R] +.fi +.IP +.nf +\f[C] +# bankofireland-checking.csv.rules + +# skip the header line +skip + +# name the csv fields, and assign some of them as journal entry fields +fields date, description, amount-out, amount-in, balance + +# We generate balance assertions by assigning to \[dq]balance\[dq] +# above, but you may sometimes need to remove these because: +# +# - the CSV balance differs from the true balance, +# by up to 0.0000000000005 in my experience +# +# - it is sometimes calculated based on non-chronological ordering, +# eg when multiple transactions clear on the same day + +# date is in UK/Ireland format +date-format %d/%m/%Y + +# set the currency +currency EUR + +# set the base account for all txns +account1 assets:bank:boi:checking +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f bankofireland-checking.csv print +2012-12-07 LODGMENT 529898 + assets:bank:boi:checking EUR10.0 = EUR131.2 + income:unknown EUR-10.0 + +2012-12-07 PAYMENT + assets:bank:boi:checking EUR-5.0 = EUR126.0 + expenses:unknown EUR5.0 +\f[R] +.fi +.PP +The balance assertions don\[aq]t raise an error above, because we\[aq]re +reading directly from CSV, but they will be checked if these entries are +imported into a journal file. +.SS Amazon +.PP +Here we convert amazon.com order history, and use an if block to +generate a third posting if there\[aq]s a fee. +(In practice you\[aq]d probably get this data from your bank instead, +but it\[aq]s an example.) +.IP +.nf +\f[C] +\[dq]Date\[dq],\[dq]Type\[dq],\[dq]To/From\[dq],\[dq]Name\[dq],\[dq]Status\[dq],\[dq]Amount\[dq],\[dq]Fees\[dq],\[dq]Transaction ID\[dq] +\[dq]Jul 29, 2012\[dq],\[dq]Payment\[dq],\[dq]To\[dq],\[dq]Foo.\[dq],\[dq]Completed\[dq],\[dq]$20.00\[dq],\[dq]$0.00\[dq],\[dq]16000000000000DGLNJPI1P9B8DKPVHL\[dq] +\[dq]Jul 30, 2012\[dq],\[dq]Payment\[dq],\[dq]To\[dq],\[dq]Adapteva, Inc.\[dq],\[dq]Completed\[dq],\[dq]$25.00\[dq],\[dq]$1.00\[dq],\[dq]17LA58JSKRD4HDGLNJPI1P9B8DKPVHL\[dq] +\f[R] +.fi +.IP +.nf +\f[C] +# amazon-orders.csv.rules + +# skip one header line +skip 1 + +# name the csv fields, and assign the transaction\[aq]s date, amount and code. +# Avoided the \[dq]status\[dq] and \[dq]amount\[dq] hledger field names to prevent confusion. +fields date, _, toorfrom, name, amzstatus, amzamount, fees, code + +# how to parse the date +date-format %b %-d, %Y + +# combine two fields to make the description +description %toorfrom %name + +# save the status as a tag +comment status:%amzstatus + +# set the base account for all transactions +account1 assets:amazon +# leave amount1 blank so it can balance the other(s). +# I\[aq]m assuming amzamount excludes the fees, don\[aq]t remember + +# set a generic account2 +account2 expenses:misc +amount2 %amzamount +# and maybe refine it further: +#include categorisation.rules + +# add a third posting for fees, but only if they are non-zero. +if %fees [1-9] + account3 expenses:fees + amount3 %fees +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f amazon-orders.csv print +2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed + assets:amazon + expenses:misc $20.00 + +2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed + assets:amazon + expenses:misc $25.00 + expenses:fees $1.00 +\f[R] +.fi +.SS Paypal +.PP +Here\[aq]s a real-world rules file for (customised) Paypal CSV, with +some Paypal-specific rules, and a second rules file included: +.IP +.nf +\f[C] +\[dq]Date\[dq],\[dq]Time\[dq],\[dq]TimeZone\[dq],\[dq]Name\[dq],\[dq]Type\[dq],\[dq]Status\[dq],\[dq]Currency\[dq],\[dq]Gross\[dq],\[dq]Fee\[dq],\[dq]Net\[dq],\[dq]From Email Address\[dq],\[dq]To Email Address\[dq],\[dq]Transaction ID\[dq],\[dq]Item Title\[dq],\[dq]Item ID\[dq],\[dq]Reference Txn ID\[dq],\[dq]Receipt ID\[dq],\[dq]Balance\[dq],\[dq]Note\[dq] +\[dq]10/01/2019\[dq],\[dq]03:46:20\[dq],\[dq]PDT\[dq],\[dq]Calm Radio\[dq],\[dq]Subscription Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]-6.99\[dq],\[dq]0.00\[dq],\[dq]-6.99\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]memberships\[at]calmradio.com\[dq],\[dq]60P57143A8206782E\[dq],\[dq]MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month\[dq],\[dq]\[dq],\[dq]I-R8YLY094FJYR\[dq],\[dq]\[dq],\[dq]-6.99\[dq],\[dq]\[dq] +\[dq]10/01/2019\[dq],\[dq]03:46:20\[dq],\[dq]PDT\[dq],\[dq]\[dq],\[dq]Bank Deposit to PP Account \[dq],\[dq]Pending\[dq],\[dq]USD\[dq],\[dq]6.99\[dq],\[dq]0.00\[dq],\[dq]6.99\[dq],\[dq]\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]0TU1544T080463733\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]60P57143A8206782E\[dq],\[dq]\[dq],\[dq]0.00\[dq],\[dq]\[dq] +\[dq]10/01/2019\[dq],\[dq]08:57:01\[dq],\[dq]PDT\[dq],\[dq]Patreon\[dq],\[dq]PreApproved Payment Bill User Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]-7.00\[dq],\[dq]0.00\[dq],\[dq]-7.00\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]support\[at]patreon.com\[dq],\[dq]2722394R5F586712G\[dq],\[dq]Patreon* Membership\[dq],\[dq]\[dq],\[dq]B-0PG93074E7M86381M\[dq],\[dq]\[dq],\[dq]-7.00\[dq],\[dq]\[dq] +\[dq]10/01/2019\[dq],\[dq]08:57:01\[dq],\[dq]PDT\[dq],\[dq]\[dq],\[dq]Bank Deposit to PP Account \[dq],\[dq]Pending\[dq],\[dq]USD\[dq],\[dq]7.00\[dq],\[dq]0.00\[dq],\[dq]7.00\[dq],\[dq]\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]71854087RG994194F\[dq],\[dq]Patreon* Membership\[dq],\[dq]\[dq],\[dq]2722394R5F586712G\[dq],\[dq]\[dq],\[dq]0.00\[dq],\[dq]\[dq] +\[dq]10/19/2019\[dq],\[dq]03:02:12\[dq],\[dq]PDT\[dq],\[dq]Wikimedia Foundation, Inc.\[dq],\[dq]Subscription Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]-2.00\[dq],\[dq]0.00\[dq],\[dq]-2.00\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]tle\[at]wikimedia.org\[dq],\[dq]K9U43044RY432050M\[dq],\[dq]Monthly donation to the Wikimedia Foundation\[dq],\[dq]\[dq],\[dq]I-R5C3YUS3285L\[dq],\[dq]\[dq],\[dq]-2.00\[dq],\[dq]\[dq] +\[dq]10/19/2019\[dq],\[dq]03:02:12\[dq],\[dq]PDT\[dq],\[dq]\[dq],\[dq]Bank Deposit to PP Account \[dq],\[dq]Pending\[dq],\[dq]USD\[dq],\[dq]2.00\[dq],\[dq]0.00\[dq],\[dq]2.00\[dq],\[dq]\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]3XJ107139A851061F\[dq],\[dq]\[dq],\[dq]\[dq],\[dq]K9U43044RY432050M\[dq],\[dq]\[dq],\[dq]0.00\[dq],\[dq]\[dq] +\[dq]10/22/2019\[dq],\[dq]05:07:06\[dq],\[dq]PDT\[dq],\[dq]Noble Benefactor\[dq],\[dq]Subscription Payment\[dq],\[dq]Completed\[dq],\[dq]USD\[dq],\[dq]10.00\[dq],\[dq]-0.59\[dq],\[dq]9.41\[dq],\[dq]noble\[at]bene.fac.tor\[dq],\[dq]simon\[at]joyful.com\[dq],\[dq]6L8L1662YP1334033\[dq],\[dq]Joyful Systems\[dq],\[dq]\[dq],\[dq]I-KC9VBGY2GWDB\[dq],\[dq]\[dq],\[dq]9.41\[dq],\[dq]\[dq] +\f[R] +.fi +.IP +.nf +\f[C] +# paypal-custom.csv.rules + +# Tips: +# Export from Activity -> Statements -> Custom -> Activity download +# Suggested transaction type: \[dq]Balance affecting\[dq] +# Paypal\[aq]s default fields in 2018 were: +# \[dq]Date\[dq],\[dq]Time\[dq],\[dq]TimeZone\[dq],\[dq]Name\[dq],\[dq]Type\[dq],\[dq]Status\[dq],\[dq]Currency\[dq],\[dq]Gross\[dq],\[dq]Fee\[dq],\[dq]Net\[dq],\[dq]From Email Address\[dq],\[dq]To Email Address\[dq],\[dq]Transaction ID\[dq],\[dq]Shipping Address\[dq],\[dq]Address Status\[dq],\[dq]Item Title\[dq],\[dq]Item ID\[dq],\[dq]Shipping and Handling Amount\[dq],\[dq]Insurance Amount\[dq],\[dq]Sales Tax\[dq],\[dq]Option 1 Name\[dq],\[dq]Option 1 Value\[dq],\[dq]Option 2 Name\[dq],\[dq]Option 2 Value\[dq],\[dq]Reference Txn ID\[dq],\[dq]Invoice Number\[dq],\[dq]Custom Number\[dq],\[dq]Quantity\[dq],\[dq]Receipt ID\[dq],\[dq]Balance\[dq],\[dq]Address Line 1\[dq],\[dq]Address Line 2/District/Neighborhood\[dq],\[dq]Town/City\[dq],\[dq]State/Province/Region/County/Territory/Prefecture/Republic\[dq],\[dq]Zip/Postal Code\[dq],\[dq]Country\[dq],\[dq]Contact Phone Number\[dq],\[dq]Subject\[dq],\[dq]Note\[dq],\[dq]Country Code\[dq],\[dq]Balance Impact\[dq] +# This rules file assumes the following more detailed fields, configured in \[dq]Customize report fields\[dq]: +# \[dq]Date\[dq],\[dq]Time\[dq],\[dq]TimeZone\[dq],\[dq]Name\[dq],\[dq]Type\[dq],\[dq]Status\[dq],\[dq]Currency\[dq],\[dq]Gross\[dq],\[dq]Fee\[dq],\[dq]Net\[dq],\[dq]From Email Address\[dq],\[dq]To Email Address\[dq],\[dq]Transaction ID\[dq],\[dq]Item Title\[dq],\[dq]Item ID\[dq],\[dq]Reference Txn ID\[dq],\[dq]Receipt ID\[dq],\[dq]Balance\[dq],\[dq]Note\[dq] + +fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note + +skip 1 + +date-format %-m/%-d/%Y + +# ignore some paypal events +if +In Progress +Temporary Hold +Update to + skip + +# add more fields to the description +description %description_ %itemtitle + +# save some other fields as tags +comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_ + +# convert to short currency symbols +if %currency USD + currency $ +if %currency EUR + currency E +if %currency GBP + currency P + +# generate postings + +# the first posting will be the money leaving/entering my paypal account +# (negative means leaving my account, in all amount fields) +account1 assets:online:paypal +amount1 %netamount + +# the second posting will be money sent to/received from other party +# (account2 is set below) +amount2 -%grossamount + +# if there\[aq]s a fee, add a third posting for the money taken by paypal. +if %feeamount [1-9] + account3 expenses:banking:paypal + amount3 -%feeamount + comment3 business: + +# choose an account for the second posting + +# override the default account names: +# if the amount is positive, it\[aq]s income (a debit) +if %grossamount \[ha][\[ha]-] + account2 income:unknown +# if negative, it\[aq]s an expense (a credit) +if %grossamount \[ha]- + account2 expenses:unknown + +# apply common rules for setting account2 & other tweaks +include common.rules + +# apply some overrides specific to this csv + +# Transfers from/to bank. These are usually marked Pending, +# which can be disregarded in this case. +if +Bank Account +Bank Deposit to PP Account + description %type for %referencetxnid %itemtitle + account2 assets:bank:wf:pchecking + account1 assets:online:paypal + +# Currency conversions +if Currency Conversion + account2 equity:currency conversion +\f[R] +.fi +.IP +.nf +\f[C] +# common.rules + +if +darcs +noble benefactor + account2 revenues:foss donations:darcshub + comment2 business: + +if +Calm Radio + account2 expenses:online:apps + +if +electronic frontier foundation +Patreon +wikimedia +Advent of Code + account2 expenses:dues + +if Google + account2 expenses:online:apps + description google | music +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f paypal-custom.csv print +2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon\[at]joyful.com, toemail:memberships\[at]calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed + assets:online:paypal $-6.99 = $-6.99 + expenses:online:apps $6.99 + +2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon\[at]joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $6.99 = $0.00 + assets:bank:wf:pchecking $-6.99 + +2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon\[at]joyful.com, toemail:support\[at]patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed + assets:online:paypal $-7.00 = $-7.00 + expenses:dues $7.00 + +2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon\[at]joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $7.00 = $0.00 + assets:bank:wf:pchecking $-7.00 + +2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon\[at]joyful.com, toemail:tle\[at]wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed + assets:online:paypal $-2.00 = $-2.00 + expenses:dues $2.00 + expenses:banking:paypal ; business: + +2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon\[at]joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $2.00 = $0.00 + assets:bank:wf:pchecking $-2.00 + +2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble\[at]bene.fac.tor, toemail:simon\[at]joyful.com, time:05:07:06, type:Subscription Payment, status:Completed + assets:online:paypal $9.41 = $9.41 + revenues:foss donations:darcshub $-10.00 ; business: + expenses:banking:paypal $0.59 ; business: +\f[R] +.fi +.SS CSV rules +.PP +The following kinds of rule can appear in the rules file, in any order. +Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are +ignored. +.SS \f[C]skip\f[R] +.IP +.nf +\f[C] +skip N +\f[R] +.fi +.PP +The word \[dq]skip\[dq] followed by a number (or no number, meaning 1) +tells hledger to ignore this many non-empty lines preceding the CSV +data. +(Empty/blank lines are skipped automatically.) You\[aq]ll need this +whenever your CSV data contains header lines. +.PP +It also has a second purpose: it can be used inside if blocks to ignore +certain CSV records (described below). +.SS \f[C]fields\f[R] +.IP +.nf +\f[C] +fields FIELDNAME1, FIELDNAME2, ... +\f[R] +.fi +.PP +A fields list (the word \[dq]fields\[dq] followed by comma-separated +field names) is the quick way to assign CSV field values to hledger +fields. +It does two things: +.IP "1." 3 +it names the CSV fields. +This is optional, but can be convenient later for interpolating them. +.IP "2." 3 +when you use a standard hledger field name, it assigns the CSV value to +that part of the hledger transaction. +.PP +Here\[aq]s an example that says \[dq]use the 1st, 2nd and 4th fields as +the transaction\[aq]s date, description and amount; name the last two +fields for later reference; and ignore the others\[dq]: +.IP +.nf +\f[C] +fields date, description, , amount, , , somefield, anotherfield +\f[R] +.fi +.PP +Field names may not contain whitespace. +Fields you don\[aq]t care about can be left unnamed. +Currently there must be least two items (there must be at least one +comma). +.PP +Note, always use comma in the fields list, even if your CSV uses another +separator character. +.PP +Here are the standard hledger field/pseudo-field names. +For more about the transaction parts they refer to, see the manual for +hledger\[aq]s journal format. +.SS Transaction field names +.PP +\f[C]date\f[R], \f[C]date2\f[R], \f[C]status\f[R], \f[C]code\f[R], +\f[C]description\f[R], \f[C]comment\f[R] can be used to form the +transaction\[aq]s first line. +.SS Posting field names +.SS account +.PP +\f[C]accountN\f[R], where N is 1 to 99, causes a posting to be +generated, with that account name. +.PP +Most often there are two postings, so you\[aq]ll want to set +\f[C]account1\f[R] and \f[C]account2\f[R]. +Typically \f[C]account1\f[R] is associated with the CSV file, and is set +once with a top-level assignment, while \f[C]account2\f[R] is set based +on each transaction\[aq]s description, and in conditional blocks. +.PP +If a posting\[aq]s account name is left unset but its amount is set (see +below), a default account name will be chosen (like +\[dq]expenses:unknown\[dq] or \[dq]income:unknown\[dq]). +.SS amount +.PP +\f[C]amountN\f[R] sets posting N\[aq]s amount. +If the CSV uses separate fields for inflows and outflows, you can use +\f[C]amountN-in\f[R] and \f[C]amountN-out\f[R] instead. +By assigning to \f[C]amount1\f[R], \f[C]amount2\f[R], ... +etc. +you can generate anywhere from 0 to 99 postings. +.PP +There is also an older, unnumbered form of these names, suitable for +2-posting transactions, which sets both posting 1\[aq]s and (negated) +posting 2\[aq]s amount: \f[C]amount\f[R], or \f[C]amount-in\f[R] and +\f[C]amount-out\f[R]. +This is still supported because it keeps pre-hledger-1.17 csv rules +files working, and because it can be more succinct, and because it +converts posting 2\[aq]s amount to cost if there\[aq]s a transaction +price, which can be useful. +.PP +If you have an existing rules file using the unnumbered form, you might +want to use the numbered form in certain conditional blocks, without +having to update and retest all the old rules. +To facilitate this, posting 1 ignores +\f[C]amount\f[R]/\f[C]amount-in\f[R]/\f[C]amount-out\f[R] if any of +\f[C]amount1\f[R]/\f[C]amount1-in\f[R]/\f[C]amount1-out\f[R] are +assigned, and posting 2 ignores them if any of +\f[C]amount2\f[R]/\f[C]amount2-in\f[R]/\f[C]amount2-out\f[R] are +assigned, avoiding conflicts. +.SS currency +.PP +If the CSV has the currency symbol in a separate field (ie, not part of +the amount field), you can use \f[C]currencyN\f[R] to prepend it to +posting N\[aq]s amount. +Or, \f[C]currency\f[R] with no number affects all postings. +.SS balance +.PP +\f[C]balanceN\f[R] sets a balance assertion amount (or if the posting +amount is left empty, a balance assignment) on posting N. +.PP +Also, for compatibility with hledger <1.17: \f[C]balance\f[R] with no +number is equivalent to \f[C]balance1\f[R]. +.PP +You can adjust the type of assertion/assignment with the +\f[C]balance-type\f[R] rule (see below). +.SS comment +.PP +Finally, \f[C]commentN\f[R] sets a comment on the Nth posting. +Comments can also contain tags, as usual. +.PP +See TIPS below for more about setting amounts and currency. +.SS field assignment +.IP +.nf +\f[C] +HLEDGERFIELDNAME FIELDVALUE +\f[R] +.fi +.PP +Instead of or in addition to a fields list, you can use a \[dq]field +assignment\[dq] rule to set the value of a single hledger field, by +writing its name (any of the standard hledger field names above) +followed by a text value. +The value may contain interpolated CSV fields, referenced by their +1-based position in the CSV record (\f[C]%N\f[R]), or by the name they +were given in the fields list (\f[C]%CSVFIELDNAME\f[R]). +Some examples: +.IP +.nf +\f[C] +# set the amount to the 4th CSV field, with \[dq] USD\[dq] appended +amount %4 USD + +# combine three fields to make a comment, containing note: and date: tags +comment note: %somefield - %anotherfield, date: %1 +\f[R] +.fi +.PP +Interpolation strips outer whitespace (so a CSV value like +\f[C]\[dq] 1 \[dq]\f[R] becomes \f[C]1\f[R] when interpolated) (#1051). +See TIPS below for more about referencing other fields. +.SS \f[C]separator\f[R] +.PP +You can use the \f[C]separator\f[R] rule to read other kinds of +character-separated data. +The argument is any single separator character, or the words +\f[C]tab\f[R] or \f[C]space\f[R] (case insensitive). +Eg, for comma-separated values (CSV): +.IP +.nf +\f[C] +separator , +\f[R] +.fi +.PP +or for semicolon-separated values (SSV): +.IP +.nf +\f[C] +separator ; +\f[R] +.fi +.PP +or for tab-separated values (TSV): +.IP +.nf +\f[C] +separator TAB +\f[R] +.fi +.PP +If the input file has a \f[C].csv\f[R], \f[C].ssv\f[R] or \f[C].tsv\f[R] +file extension (or a \f[C]csv:\f[R], \f[C]ssv:\f[R], \f[C]tsv:\f[R] +prefix), the appropriate separator will be inferred automatically, and +you won\[aq]t need this rule. +.SS \f[C]if\f[R] block +.IP +.nf +\f[C] +if MATCHER + RULE + +if +MATCHER +MATCHER +MATCHER + RULE + RULE +\f[R] +.fi +.PP +Conditional blocks (\[dq]if blocks\[dq]) are a block of rules that are +applied only to CSV records which match certain patterns. +They are often used for customising account names based on transaction +descriptions. +.SS Matching the whole record +.PP +Each MATCHER can be a record matcher, which looks like this: +.IP +.nf +\f[C] +REGEX +\f[R] +.fi +.PP +REGEX is a case-insensitive regular expression which tries to match +anywhere within the CSV record. +It is a POSIX ERE (extended regular expression) that also supports GNU +word boundaries (\f[C]\[rs]b\f[R], \f[C]\[rs]B\f[R], \f[C]\[rs]<\f[R], +\f[C]\[rs]>\f[R]), and nothing else. +If you have trouble, be sure to check our +https://hledger.org/hledger.html#regular-expressions doc. +.PP +Important note: the record that is matched is not the original record, +but a synthetic one, with any enclosing double quotes (but not enclosing +whitespace) removed, and always comma-separated (which means that a +field containing a comma will appear like two fields). +Eg, if the original record is +\f[C]2020-01-01; \[dq]Acme, Inc.\[dq]; 1,000\f[R], the REGEX will +actually see \f[C]2020-01-01,Acme, Inc., 1,000\f[R]). +.SS Matching individual fields +.PP +Or, MATCHER can be a field matcher, like this: +.IP +.nf +\f[C] +%CSVFIELD REGEX +\f[R] +.fi +.PP +which matches just the content of a particular CSV field. +CSVFIELD is a percent sign followed by the field\[aq]s name or column +number, like \f[C]%date\f[R] or \f[C]%1\f[R]. +.SS Combining matchers +.PP +A single matcher can be written on the same line as the \[dq]if\[dq]; or +multiple matchers can be written on the following lines, non-indented. +Multiple matchers are OR\[aq]d (any one of them can match), unless one +begins with an \f[C]&\f[R] symbol, in which case it is AND\[aq]ed with +the previous matcher. +.IP +.nf +\f[C] +if +MATCHER +& MATCHER + RULE +\f[R] +.fi +.SS Rules applied on successful match +.PP +After the patterns there should be one or more rules to apply, all +indented by at least one space. +Three kinds of rule are allowed in conditional blocks: +.IP \[bu] 2 +field assignments (to set a hledger field) +.IP \[bu] 2 +skip (to skip the matched CSV record) +.IP \[bu] 2 +end (to skip all remaining CSV records). +.PP +Examples: +.IP +.nf +\f[C] +# if the CSV record contains \[dq]groceries\[dq], set account2 to \[dq]expenses:groceries\[dq] +if groceries + account2 expenses:groceries +\f[R] +.fi +.IP +.nf +\f[C] +# if the CSV record contains any of these patterns, set account2 and comment as shown +if +monthly service fee +atm transaction fee +banking thru software + account2 expenses:business:banking + comment XXX deductible ? check it +\f[R] +.fi +.SS \f[C]if\f[R] table +.IP +.nf +\f[C] +if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn +MATCHER1,VALUE11,VALUE12,...,VALUE1n +MATCHER2,VALUE21,VALUE22,...,VALUE2n +MATCHER3,VALUE31,VALUE32,...,VALUE3n + +\f[R] +.fi +.PP +Conditional tables (\[dq]if tables\[dq]) are a different syntax to +specify field assignments that will be applied only to CSV records which +match certain patterns. +.PP +MATCHER could be either field or record matcher, as described above. +When MATCHER matches, values from that row would be assigned to the CSV +fields named on the \f[C]if\f[R] line, in the same order. +.PP +Therefore \f[C]if\f[R] table is exactly equivalent to a sequence of of +\f[C]if\f[R] blocks: +.IP +.nf +\f[C] +if MATCHER1 + CSVFIELDNAME1 VALUE11 + CSVFIELDNAME2 VALUE12 + ... + CSVFIELDNAMEn VALUE1n + +if MATCHER2 + CSVFIELDNAME1 VALUE21 + CSVFIELDNAME2 VALUE22 + ... + CSVFIELDNAMEn VALUE2n + +if MATCHER3 + CSVFIELDNAME1 VALUE31 + CSVFIELDNAME2 VALUE32 + ... + CSVFIELDNAMEn VALUE3n +\f[R] +.fi +.PP +Each line starting with MATCHER should contain enough (possibly empty) +values for all the listed fields. +.PP +Rules would be checked and applied in the order they are listed in the +table and, like with \f[C]if\f[R] blocks, later rules (in the same or +another table) or \f[C]if\f[R] blocks could override the effect of any +rule. +.PP +Instead of \[aq],\[aq] you can use a variety of other non-alphanumeric +characters as a separator. +First character after \f[C]if\f[R] is taken to be the separator for the +rest of the table. +It is the responsibility of the user to ensure that separator does not +occur inside MATCHERs and values - there is no way to escape separator. +.PP +Example: +.IP +.nf +\f[C] +if,account2,comment +atm transaction fee,expenses:business:banking,deductible? check it +%description groceries,expenses:groceries, +2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out +\f[R] +.fi +.SS \f[C]end\f[R] +.PP +This rule can be used inside if blocks (only), to make hledger stop +reading this CSV file and move on to the next input file, or to command +execution. +Eg: +.IP +.nf +\f[C] +# ignore everything following the first empty record +if ,,,, + end +\f[R] +.fi +.SS \f[C]date-format\f[R] +.IP +.nf +\f[C] +date-format DATEFMT +\f[R] +.fi +.PP +This is a helper for the \f[C]date\f[R] (and \f[C]date2\f[R]) fields. +If your CSV dates are not formatted like \f[C]YYYY-MM-DD\f[R], +\f[C]YYYY/MM/DD\f[R] or \f[C]YYYY.MM.DD\f[R], you\[aq]ll need to add a +date-format rule describing them with a strptime date parsing pattern, +which must parse the CSV date value completely. +Some examples: +.IP +.nf +\f[C] +# MM/DD/YY +date-format %m/%d/%y +\f[R] +.fi +.IP +.nf +\f[C] +# D/M/YYYY +# The - makes leading zeros optional. +date-format %-d/%-m/%Y +\f[R] +.fi +.IP +.nf +\f[C] +# YYYY-Mmm-DD +date-format %Y-%h-%d +\f[R] +.fi +.IP +.nf +\f[C] +# M/D/YYYY HH:MM AM some other junk +# Note the time and junk must be fully parsed, though only the date is used. +date-format %-m/%-d/%Y %l:%M %p some other junk +\f[R] +.fi +.PP +For the supported strptime syntax, see: +.PD 0 +.P +.PD +https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime +.SS \f[C]decimal-mark\f[R] +.IP +.nf +\f[C] +decimal-mark . +\f[R] +.fi +.PP +or: +.IP +.nf +\f[C] +decimal-mark , +\f[R] +.fi +.PP +hledger automatically accepts either period or comma as a decimal mark +when parsing numbers (cf Amounts). +However if any numbers in the CSV contain digit group marks, such as +thousand-separating commas, you should declare the decimal mark +explicitly with this rule, to avoid misparsed numbers. +.SS \f[C]newest-first\f[R] +.PP +hledger always sorts the generated transactions by date. +Transactions on the same date should appear in the same order as their +CSV records, as hledger can usually auto-detect whether the CSV\[aq]s +normal order is oldest first or newest first. +But if all of the following are true: +.IP \[bu] 2 +the CSV might sometimes contain just one day of data (all records having +the same date) +.IP \[bu] 2 +the CSV records are normally in reverse chronological order (newest at +the top) +.IP \[bu] 2 +and you care about preserving the order of same-day transactions +.PP +then, you should add the \f[C]newest-first\f[R] rule as a hint. +Eg: +.IP +.nf +\f[C] +# tell hledger explicitly that the CSV is normally newest first +newest-first +\f[R] +.fi +.SS \f[C]include\f[R] +.IP +.nf +\f[C] +include RULESFILE +\f[R] +.fi +.PP +This includes the contents of another CSV rules file at this point. +\f[C]RULESFILE\f[R] is an absolute file path or a path relative to the +current file\[aq]s directory. +This can be useful for sharing common rules between several rules files, +eg: +.IP +.nf +\f[C] +# someaccount.csv.rules + +## someaccount-specific rules +fields date,description,amount +account1 assets:someaccount +account2 expenses:misc + +## common rules +include categorisation.rules +\f[R] +.fi +.SS \f[C]balance-type\f[R] +.PP +Balance assertions generated by assigning to balanceN are of the simple +\f[C]=\f[R] type by default, which is a single-commodity, +subaccount-excluding assertion. +You may find the subaccount-including variants more useful, eg if you +have created some virtual subaccounts of checking to help with +budgeting. +You can select a different type of assertion with the +\f[C]balance-type\f[R] rule: +.IP +.nf +\f[C] +# balance assertions will consider all commodities and all subaccounts +balance-type ==* +\f[R] +.fi +.PP +Here are the balance assertion types for quick reference: +.IP +.nf +\f[C] += single commodity, exclude subaccounts +=* single commodity, include subaccounts +== multi commodity, exclude subaccounts +==* multi commodity, include subaccounts +\f[R] +.fi +.SS Tips +.SS Rapid feedback +.PP +It\[aq]s a good idea to get rapid feedback while +creating/troubleshooting CSV rules. +Here\[aq]s a good way, using entr from http://eradman.com/entrproject : +.IP +.nf +\f[C] +$ ls foo.csv* | entr bash -c \[aq]echo ----; hledger -f foo.csv print desc:SOMEDESC\[aq] +\f[R] +.fi +.PP +A desc: query (eg) is used to select just one, or a few, transactions of +interest. +\[dq]bash -c\[dq] is used to run multiple commands, so we can echo a +separator each time the command re-runs, making it easier to read the +output. +.SS Valid CSV +.PP +hledger accepts CSV conforming to RFC 4180. +When CSV values are enclosed in quotes, note: +.IP \[bu] 2 +they must be double quotes (not single quotes) +.IP \[bu] 2 +spaces outside the quotes are not allowed +.SS File Extension +.PP +To help hledger identify the format and show the right error messages, +CSV/SSV/TSV files should normally be named with a \f[C].csv\f[R], +\f[C].ssv\f[R] or \f[C].tsv\f[R] filename extension. +Or, the file path should be prefixed with \f[C]csv:\f[R], \f[C]ssv:\f[R] +or \f[C]tsv:\f[R]. +Eg: +.IP +.nf +\f[C] +$ hledger -f foo.ssv print +\f[R] +.fi +.PP +or: +.IP +.nf +\f[C] +$ cat foo | hledger -f ssv:- foo +\f[R] +.fi +.PP +You can override the file extension with a separator rule if needed. +See also: Input files in the hledger manual. +.SS Reading multiple CSV files +.PP +If you use multiple \f[C]-f\f[R] options to read multiple CSV files at +once, hledger will look for a correspondingly-named rules file for each +CSV file. +But if you use the \f[C]--rules-file\f[R] option, that rules file will +be used for all the CSV files. +.SS Valid transactions +.PP +After reading a CSV file, hledger post-processes and validates the +generated journal entries as it would for a journal file - balancing +them, applying balance assignments, and canonicalising amount styles. +Any errors at this stage will be reported in the usual way, displaying +the problem entry. +.PP +There is one exception: balance assertions, if you have generated them, +will not be checked, since normally these will work only when the CSV +data is part of the main journal. +If you do need to check balance assertions generated from CSV right +away, pipe into another hledger: +.IP +.nf +\f[C] +$ hledger -f file.csv print | hledger -f- print +\f[R] +.fi +.SS Deduplicating, importing +.PP +When you download a CSV file periodically, eg to get your latest bank +transactions, the new file may overlap with the old one, containing some +of the same records. +.PP +The import command will (a) detect the new transactions, and (b) append +just those transactions to your main journal. +It is idempotent, so you don\[aq]t have to remember how many times you +ran it or with which version of the CSV. +(It keeps state in a hidden \f[C].latest.FILE.csv\f[R] file.) This is +the easiest way to import CSV data. +Eg: +.IP +.nf +\f[C] +# download the latest CSV files, then run this command. +# Note, no -f flags needed here. +$ hledger import *.csv [--dry] +\f[R] +.fi +.PP +This method works for most CSV files. +(Where records have a stable chronological order, and new records appear +only at the new end.) +.PP +A number of other tools and workflows, hledger-specific and otherwise, +exist for converting, deduplicating, classifying and managing CSV data. +See: +.IP \[bu] 2 +https://hledger.org -> sidebar -> real world setups +.IP \[bu] 2 +https://plaintextaccounting.org -> data import/conversion +.SS Setting amounts +.PP +A posting amount can be set in one of these ways: +.IP \[bu] 2 +by assigning (with a fields list or field assignment) to +\f[C]amountN\f[R] (posting N\[aq]s amount) or \f[C]amount\f[R] (posting +1\[aq]s amount) +.IP \[bu] 2 +by assigning to \f[C]amountN-in\f[R] and \f[C]amountN-out\f[R] (or +\f[C]amount-in\f[R] and \f[C]amount-out\f[R]). +For each CSV record, whichever of these has a non-zero value will be +used, with appropriate sign. +If both contain a non-zero value, this may not work. +.IP \[bu] 2 +by assigning to \f[C]balanceN\f[R] (or \f[C]balance\f[R]) instead of the +above, setting the amount indirectly via a balance assignment. +If you do this the default account name may be wrong, so you should set +that explicitly. +.PP +There is some special handling for an amount\[aq]s sign: +.IP \[bu] 2 +If an amount value is parenthesised, it will be de-parenthesised and +sign-flipped. +.IP \[bu] 2 +If an amount value begins with a double minus sign, those cancel out and +are removed. +.IP \[bu] 2 +If an amount value begins with a plus sign, that will be removed +.SS Setting currency/commodity +.PP +If the currency/commodity symbol is included in the CSV\[aq]s amount +field(s): +.IP +.nf +\f[C] +2020-01-01,foo,$123.00 +\f[R] +.fi +.PP +you don\[aq]t have to do anything special for the commodity symbol, it +will be assigned as part of the amount. +Eg: +.IP +.nf +\f[C] +fields date,description,amount +\f[R] +.fi +.IP +.nf +\f[C] +2020-01-01 foo + expenses:unknown $123.00 + income:unknown $-123.00 +\f[R] +.fi +.PP +If the currency is provided as a separate CSV field: +.IP +.nf +\f[C] +2020-01-01,foo,USD,123.00 +\f[R] +.fi +.PP +You can assign that to the \f[C]currency\f[R] pseudo-field, which has +the special effect of prepending itself to every amount in the +transaction (on the left, with no separating space): +.IP +.nf +\f[C] +fields date,description,currency,amount +\f[R] +.fi +.IP +.nf +\f[C] +2020-01-01 foo + expenses:unknown USD123.00 + income:unknown USD-123.00 +\f[R] +.fi +.PP +Or, you can use a field assignment to construct the amount yourself, +with more control. +Eg to put the symbol on the right, and separated by a space: +.IP +.nf +\f[C] +fields date,description,cur,amt +amount %amt %cur +\f[R] +.fi +.IP +.nf +\f[C] +2020-01-01 foo + expenses:unknown 123.00 USD + income:unknown -123.00 USD +\f[R] +.fi +.PP +Note we used a temporary field name (\f[C]cur\f[R]) that is not +\f[C]currency\f[R] - that would trigger the prepending effect, which we +don\[aq]t want here. +.SS Referencing other fields +.PP +In field assignments, you can interpolate only CSV fields, not hledger +fields. +In the example below, there\[aq]s both a CSV field and a hledger field +named amount1, but %amount1 always means the CSV field, not the hledger +field: +.IP +.nf +\f[C] +# Name the third CSV field \[dq]amount1\[dq] +fields date,description,amount1 + +# Set hledger\[aq]s amount1 to the CSV amount1 field followed by USD +amount1 %amount1 USD + +# Set comment to the CSV amount1 (not the amount1 assigned above) +comment %amount1 +\f[R] +.fi +.PP +Here, since there\[aq]s no CSV amount1 field, %amount1 will produce a +literal \[dq]amount1\[dq]: +.IP +.nf +\f[C] +fields date,description,csvamount +amount1 %csvamount USD +# Can\[aq]t interpolate amount1 here +comment %amount1 +\f[R] +.fi +.PP +When there are multiple field assignments to the same hledger field, +only the last one takes effect. +Here, comment\[aq]s value will be be B, or C if \[dq]something\[dq] is +matched, but never A: +.IP +.nf +\f[C] +comment A +comment B +if something + comment C +\f[R] +.fi +.SS How CSV rules are evaluated +.PP +Here\[aq]s how to think of CSV rules being evaluated (if you really need +to). +First, +.IP \[bu] 2 +\f[C]include\f[R] - all includes are inlined, from top to bottom, depth +first. +(At each include point the file is inlined and scanned for further +includes, recursively, before proceeding.) +.PP +Then \[dq]global\[dq] rules are evaluated, top to bottom. +If a rule is repeated, the last one wins: +.IP \[bu] 2 +\f[C]skip\f[R] (at top level) +.IP \[bu] 2 +\f[C]date-format\f[R] +.IP \[bu] 2 +\f[C]newest-first\f[R] +.IP \[bu] 2 +\f[C]fields\f[R] - names the CSV fields, optionally sets up initial +assignments to hledger fields +.PP +Then for each CSV record in turn: +.IP \[bu] 2 +test all \f[C]if\f[R] blocks. +If any of them contain a \f[C]end\f[R] rule, skip all remaining CSV +records. +Otherwise if any of them contain a \f[C]skip\f[R] rule, skip that many +CSV records. +If there are multiple matched \f[C]skip\f[R] rules, the first one wins. +.IP \[bu] 2 +collect all field assignments at top level and in matched \f[C]if\f[R] +blocks. +When there are multiple assignments for a field, keep only the last one. +.IP \[bu] 2 +compute a value for each hledger field - either the one that was +assigned to it (and interpolate the %CSVFIELDNAME references), or a +default +.IP \[bu] 2 +generate a synthetic hledger transaction from these values. +.PP +This is all part of the CSV reader, one of several readers hledger can +use to parse input files. +When all files have been read successfully, the transactions are passed +as input to whichever hledger command the user specified. +.SH TIMECLOCK FORMAT +.PP +The time logging format of timeclock.el, as read by hledger. +.PP +hledger can read time logs in timeclock format. +As with Ledger, these are (a subset of) timeclock.el\[aq]s format, +containing clock-in and clock-out entries as in the example below. +The date is a simple date. +The time format is HH:MM[:SS][+-ZZZZ]. +Seconds and timezone are optional. +The timezone, if present, must be four digits and is ignored (currently +the time is always interpreted as a local time). +.IP +.nf +\f[C] +i 2015/03/30 09:00:00 some:account name optional description after two spaces +o 2015/03/30 09:20:00 +i 2015/03/31 22:21:45 another account +o 2015/04/01 02:00:34 +\f[R] +.fi +.PP +hledger treats each clock-in/clock-out pair as a transaction posting +some number of hours to an account. +Or if the session spans more than one day, it is split into several +transactions, one for each day. +For the above time log, \f[C]hledger print\f[R] generates these journal +entries: +.IP +.nf +\f[C] +$ hledger -f t.timeclock print +2015-03-30 * optional description after two spaces + (some:account name) 0.33h + +2015-03-31 * 22:21-23:59 + (another account) 1.64h + +2015-04-01 * 00:00-02:00 + (another account) 2.01h +\f[R] +.fi +.PP +Here is a sample.timeclock to download and some queries to try: +.IP +.nf +\f[C] +$ hledger -f sample.timeclock balance # current time balances +$ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009 +$ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week +\f[R] +.fi +.PP +To generate time logs, ie to clock in and clock out, you could: +.IP \[bu] 2 +use emacs and the built-in timeclock.el, or the extended timeclock-x.el +and perhaps the extras in ledgerutils.el +.IP \[bu] 2 +at the command line, use these bash aliases: +\f[C]shell alias ti=\[dq]echo i \[ga]date \[aq]+%Y-%m-%d %H:%M:%S\[aq]\[ga] \[rs]$* >>$TIMELOG\[dq] alias to=\[dq]echo o \[ga]date \[aq]+%Y-%m-%d %H:%M:%S\[aq]\[ga] >>$TIMELOG\[dq]\f[R] +.IP \[bu] 2 +or use the old \f[C]ti\f[R] and \f[C]to\f[R] scripts in the ledger 2.x +repository. +These rely on a \[dq]timeclock\[dq] executable which I think is just the +ledger 2 executable renamed. +.SH TIMEDOT FORMAT +.PP +hledger\[aq]s human-friendly time logging format. +.PP +Timedot is a plain text format for logging dated, categorised quantities +(of time, usually), supported by hledger. +It is convenient for approximate and retroactive time logging, eg when +the real-time clock-in/out required with a timeclock file is too precise +or too interruptive. +It can be formatted like a bar chart, making clear at a glance where +time was spent. +.PP +Though called \[dq]timedot\[dq], this format is read by hledger as +commodityless quantities, so it could be used to represent dated +quantities other than time. +In the docs below we\[aq]ll assume it\[aq]s time. +.PP +A timedot file contains a series of day entries. +A day entry begins with a non-indented hledger-style simple date (Y-M-D, +Y/M/D, Y.M.D..) Any additional text on the same line is used as a +transaction description for this day. +.PP +This is followed by optionally-indented timelog items for that day, one +per line. +Each timelog item is a note, usually a hledger:style:account:name +representing a time category, followed by two or more spaces, and a +quantity. +Each timelog item generates a hledger transaction. +.PP +Quantities can be written as: +.IP \[bu] 2 +dots: a sequence of dots (.) representing quarter hours. +Spaces may optionally be used for grouping. +Eg: .... +\&.. +.IP \[bu] 2 +an integral or decimal number, representing hours. +Eg: 1.5 +.IP \[bu] 2 +an integral or decimal number immediately followed by a unit symbol +\f[C]s\f[R], \f[C]m\f[R], \f[C]h\f[R], \f[C]d\f[R], \f[C]w\f[R], +\f[C]mo\f[R], or \f[C]y\f[R], representing seconds, minutes, hours, days +weeks, months or years respectively. +Eg: 90m. +The following equivalencies are assumed, currently: 1m = 60s, 1h = 60m, +1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d. +.PP +There is some flexibility allowing notes and todo lists to be kept right +in the time log, if needed: +.IP \[bu] 2 +Blank lines and lines beginning with \f[C]#\f[R] or \f[C];\f[R] are +ignored. +.IP \[bu] 2 +Lines not ending with a double-space and quantity are parsed as items +taking no time, which will not appear in balance reports by default. +(Add -E to see them.) +.IP \[bu] 2 +Org mode headlines (lines beginning with one or more \f[C]*\f[R] +followed by a space) can be used as date lines or timelog items (the +stars are ignored). +Also all org headlines before the first date line are ignored. +This means org users can manage their timelog as an org outline (eg +using org-mode/orgstruct-mode in Emacs), for organisation, faster +navigation, controlling visibility etc. +.PP +Examples: +.IP +.nf +\f[C] +# on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc. +2016/2/1 +inc:client1 .... .... .... .... .... .... +fos:haskell .... .. +biz:research . + +2016/2/2 +inc:client1 .... .... +biz:research . +\f[R] +.fi +.IP +.nf +\f[C] +2016/2/3 +inc:client1 4 +fos:hledger 3 +biz:research 1 +\f[R] +.fi +.IP +.nf +\f[C] +* Time log +** 2020-01-01 +*** adm:time . +*** adm:finance . +\f[R] +.fi +.IP +.nf +\f[C] +* 2020 Work Diary +** Q1 +*** 2020-02-29 +**** DONE +0700 yoga +**** UNPLANNED +**** BEGUN +hom:chores + cleaning ... + water plants + outdoor - one full watering can + indoor - light watering +**** TODO +adm:planning: trip +*** LATER +\f[R] +.fi +.PP +Reporting: +.IP +.nf +\f[C] +$ hledger -f t.timedot print date:2016/2/2 +2016-02-02 * + (inc:client1) 2.00 + +2016-02-02 * + (biz:research) 0.25 +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f t.timedot bal --daily --tree +Balance changes in 2016-02-01-2016-02-03: + + || 2016-02-01d 2016-02-02d 2016-02-03d +============++======================================== + biz || 0.25 0.25 1.00 + research || 0.25 0.25 1.00 + fos || 1.50 0 3.00 + haskell || 1.50 0 0 + hledger || 0 0 3.00 + inc || 6.00 2.00 4.00 + client1 || 6.00 2.00 4.00 +------------++---------------------------------------- + || 7.75 2.25 8.00 +\f[R] +.fi +.PP +I prefer to use period for separating account components. +We can make this work with an account alias: +.IP +.nf +\f[C] +2016/2/4 +fos.hledger.timedot 4 +fos.ledger .. +\f[R] +.fi +.IP +.nf +\f[C] +$ hledger -f t.timedot --alias /\[rs]\[rs]./=: bal date:2016/2/4 --tree + 4.50 fos + 4.00 hledger:timedot + 0.50 ledger +-------------------- + 4.50 +\f[R] +.fi +.PP +Here is a sample.timedot. .SH COMMON TASKS .PP Here are some quick examples of how to do some basic tasks with hledger. @@ -5167,40 +8853,6 @@ See the close command. .PP If using version control, don\[aq]t forget to \f[C]git add\f[R] the new file. -.SH ENVIRONMENT -.PP -\f[B]LEDGER_FILE\f[R] The journal file path when not specified with -\f[C]-f\f[R]. -Default: \f[C]\[ti]/.hledger.journal\f[R] (on windows, perhaps -\f[C]C:/Users/USER/.hledger.journal\f[R]). -.PP -A typical value is \f[C]\[ti]/DIR/YYYY.journal\f[R], where DIR is a -version-controlled finance directory and YYYY is the current year. -Or \f[C]\[ti]/DIR/current.journal\f[R], where current.journal is a -symbolic link to YYYY.journal. -.PP -On Mac computers, you can set this and other environment variables in a -more thorough way that also affects applications started from the GUI -(say, an Emacs dock icon). -Eg on MacOS Catalina I have a \f[C]\[ti]/.MacOSX/environment.plist\f[R] -file containing -.IP -.nf -\f[C] -{ - \[dq]LEDGER_FILE\[dq] : \[dq]\[ti]/finance/current.journal\[dq] -} -\f[R] -.fi -.PP -To see the effect you may need to \f[C]killall Dock\f[R], or reboot. -.PP -\f[B]COLUMNS\f[R] The screen width used by the register command. -Default: the full terminal width. -.PP -\f[B]NO_COLOR\f[R] If this variable exists with any value, hledger will -not use ANSI color codes in terminal output. -This overrides the --color/--colour option. .SH LIMITATIONS .PP The need to precede add-on command options with \f[C]--\f[R] when diff --git a/hledger/hledger.info b/hledger/hledger.info index e7a4299c3..814818eca 100644 --- a/hledger/hledger.info +++ b/hledger/hledger.info @@ -58,6 +58,7 @@ try some commands like 'hledger print' or 'hledger balance'. Run * Menu: * OPTIONS:: +* ENVIRONMENT:: * DATA FILES:: * TIME PERIODS:: * DEPTH:: @@ -66,13 +67,16 @@ try some commands like 'hledger print' or 'hledger balance'. Run * PIVOTING:: * OUTPUT:: * COMMANDS:: +* JOURNAL FORMAT:: +* CSV FORMAT:: +* TIMECLOCK FORMAT:: +* TIMEDOT FORMAT:: * COMMON TASKS:: -* ENVIRONMENT:: * LIMITATIONS:: * TROUBLESHOOTING::  -File: hledger.info, Node: OPTIONS, Next: DATA FILES, Prev: Top, Up: Top +File: hledger.info, Node: OPTIONS, Next: ENVIRONMENT, Prev: Top, Up: Top 1 OPTIONS ********* @@ -462,9 +466,42 @@ they support: See Special characters.  -File: hledger.info, Node: DATA FILES, Next: TIME PERIODS, Prev: OPTIONS, Up: Top +File: hledger.info, Node: ENVIRONMENT, Next: DATA FILES, Prev: OPTIONS, Up: Top -2 DATA FILES +2 ENVIRONMENT +************* + +*LEDGER_FILE* The journal file path when not specified with '-f'. +Default: '~/.hledger.journal' (on windows, perhaps +'C:/Users/USER/.hledger.journal'). + + A typical value is '~/DIR/YYYY.journal', where DIR is a +version-controlled finance directory and YYYY is the current year. Or +'~/DIR/current.journal', where current.journal is a symbolic link to +YYYY.journal. + + On Mac computers, you can set this and other environment variables in +a more thorough way that also affects applications started from the GUI +(say, an Emacs dock icon). Eg on MacOS Catalina I have a +'~/.MacOSX/environment.plist' file containing + +{ + "LEDGER_FILE" : "~/finance/current.journal" +} + + To see the effect you may need to 'killall Dock', or reboot. + + *COLUMNS* The screen width used by the register command. Default: +the full terminal width. + + *NO_COLOR* If this variable exists with any value, hledger will not +use ANSI color codes in terminal output. This overrides the +-color/-colour option. + + +File: hledger.info, Node: DATA FILES, Next: TIME PERIODS, Prev: ENVIRONMENT, Up: Top + +3 DATA FILES ************ hledger reads transactions from one or more data files. The default @@ -493,7 +530,7 @@ $ cat some.journal | hledger -f-  File: hledger.info, Node: Data formats, Next: Multiple files, Up: DATA FILES -2.1 Data formats +3.1 Data formats ================ Usually the data file is in hledger's journal format, but it can be in @@ -511,6 +548,8 @@ Reader: Reads: Used for file 'csv' comma/semicolon/tab/other-separated '.csv' '.ssv' '.tsv' values, for data import + These formats are described in their own sections, below. + hledger detects the format automatically based on the file extensions shown above. If it can't recognise the file extension, it assumes 'journal' format. So for non-journal files, it's important to use a @@ -526,7 +565,7 @@ $ echo 'i 2009/13/1 08:00:00' | hledger print -ftimeclock:-  File: hledger.info, Node: Multiple files, Next: Strict mode, Prev: Data formats, Up: DATA FILES -2.2 Multiple files +3.2 Multiple files ================== You can specify multiple '-f' options, to read multiple files as one big @@ -545,7 +584,7 @@ journal. There are some limitations with this:  File: hledger.info, Node: Strict mode, Prev: Multiple files, Up: DATA FILES -2.3 Strict mode +3.3 Strict mode =============== hledger checks input files for valid data. By default, the most @@ -570,7 +609,7 @@ without a lot of declarations:  File: hledger.info, Node: TIME PERIODS, Next: DEPTH, Prev: DATA FILES, Up: Top -3 TIME PERIODS +4 TIME PERIODS ************** * Menu: @@ -583,7 +622,7 @@ File: hledger.info, Node: TIME PERIODS, Next: DEPTH, Prev: DATA FILES, Up: T  File: hledger.info, Node: Smart dates, Next: Report start & end date, Up: TIME PERIODS -3.1 Smart dates +4.1 Smart dates =============== hledger's user interfaces accept a flexible "smart date" syntax. Smart @@ -621,7 +660,7 @@ results:  File: hledger.info, Node: Report start & end date, Next: Report intervals, Prev: Smart dates, Up: TIME PERIODS -3.2 Report start & end date +4.2 Report start & end date =========================== By default, most hledger reports will show the full span of time @@ -664,7 +703,7 @@ thismonth'  File: hledger.info, Node: Report intervals, Next: Period expressions, Prev: Report start & end date, Up: TIME PERIODS -3.3 Report intervals +4.3 Report intervals ==================== A report interval can be specified so that commands like register, @@ -677,7 +716,7 @@ intervals can not be specified with a query.  File: hledger.info, Node: Period expressions, Prev: Report intervals, Up: TIME PERIODS -3.4 Period expressions +4.4 Period expressions ====================== The '-p/--period' option accepts period expressions, a shorthand way of @@ -806,7 +845,7 @@ start date and exclusive end date):  File: hledger.info, Node: DEPTH, Next: QUERIES, Prev: TIME PERIODS, Up: Top -4 DEPTH +5 DEPTH ******* With the '--depth N' option (short form: '-N'), commands like account, @@ -818,7 +857,7 @@ less detail. This flag has the same effect as a 'depth:' query argument  File: hledger.info, Node: QUERIES, Next: VALUATION, Prev: DEPTH, Up: Top -5 QUERIES +6 QUERIES ********* One of hledger's strengths is being able to quickly report on precise @@ -927,7 +966,7 @@ and query arguments, and the resulting query will be their intersection  File: hledger.info, Node: VALUATION, Next: PIVOTING, Prev: QUERIES, Up: Top -6 VALUATION +7 VALUATION *********** Instead of reporting amounts in their original commodity, hledger can @@ -954,7 +993,7 @@ usually one of those is all you need.  File: hledger.info, Node: -B Cost, Next: -V Value, Up: VALUATION -6.1 -B: Cost +7.1 -B: Cost ============ The '-B/--cost' flag converts amounts to their cost or sale amount at @@ -963,7 +1002,7 @@ transaction time, if they have a transaction price specified.  File: hledger.info, Node: -V Value, Next: -X Value in specified commodity, Prev: -B Cost, Up: VALUATION -6.2 -V: Value +7.2 -V: Value ============= The '-V/--market' flag converts amounts to market value in their default @@ -973,7 +1012,7 @@ _valuation date(s)_, if any. More on these in a minute.  File: hledger.info, Node: -X Value in specified commodity, Next: Valuation date, Prev: -V Value, Up: VALUATION -6.3 -X: Value in specified commodity +7.3 -X: Value in specified commodity ==================================== The '-X/--exchange=COMM' option is like '-V', except you tell it which @@ -983,7 +1022,7 @@ that.  File: hledger.info, Node: Valuation date, Next: Market prices, Prev: -X Value in specified commodity, Up: VALUATION -6.4 Valuation date +7.4 Valuation date ================== Since market prices can change from day to day, market value reports @@ -1000,7 +1039,7 @@ of the period, by default.  File: hledger.info, Node: Market prices, Next: --infer-value market prices from transactions, Prev: Valuation date, Up: VALUATION -6.5 Market prices +7.5 Market prices ================= To convert a commodity A to its market value in another commodity B, @@ -1029,7 +1068,7 @@ converted.  File: hledger.info, Node: --infer-value market prices from transactions, Next: Valuation commodity, Prev: Market prices, Up: VALUATION -6.6 -infer-value: market prices from transactions +7.6 -infer-value: market prices from transactions ================================================= Normally, market value in hledger is fully controlled by, and requires, @@ -1062,7 +1101,7 @@ you, read all of this Valuation section carefully, and try adding  File: hledger.info, Node: Valuation commodity, Next: Simple valuation examples, Prev: --infer-value market prices from transactions, Up: VALUATION -6.7 Valuation commodity +7.7 Valuation commodity ======================= *When you specify a valuation commodity ('-X COMM' or '--value @@ -1100,7 +1139,7 @@ converted.  File: hledger.info, Node: Simple valuation examples, Next: --value Flexible valuation, Prev: Valuation commodity, Up: VALUATION -6.8 Simple valuation examples +7.8 Simple valuation examples ============================= Here are some quick examples of '-V': @@ -1135,7 +1174,7 @@ $ hledger -f t.j bal -N euros -V  File: hledger.info, Node: --value Flexible valuation, Next: More valuation examples, Prev: Simple valuation examples, Up: VALUATION -6.9 -value: Flexible valuation +7.9 -value: Flexible valuation ============================== '-B', '-V' and '-X' are special cases of the more general '--value' @@ -1183,7 +1222,7 @@ this commodity, deducing market prices as described above.  File: hledger.info, Node: More valuation examples, Next: Effect of valuation on reports, Prev: --value Flexible valuation, Up: VALUATION -6.10 More valuation examples +7.10 More valuation examples ============================ Here are some examples showing the effect of '--value', as seen with @@ -1297,7 +1336,7 @@ $ hledger print -X A  File: hledger.info, Node: Effect of valuation on reports, Prev: More valuation examples, Up: VALUATION -6.11 Effect of valuation on reports +7.11 Effect of valuation on reports =================================== Here is a reference for how valuation is supposed to affect each part of @@ -1433,7 +1472,7 @@ _report interval_  File: hledger.info, Node: PIVOTING, Next: OUTPUT, Prev: VALUATION, Up: Top -7 PIVOTING +8 PIVOTING ********** Normally hledger sums amounts, and organizes them in a hierarchy, based @@ -1490,7 +1529,7 @@ $ hledger balance --pivot member acct:.  File: hledger.info, Node: OUTPUT, Next: COMMANDS, Prev: PIVOTING, Up: Top -8 OUTPUT +9 OUTPUT ******** * Menu: @@ -1501,7 +1540,7 @@ File: hledger.info, Node: OUTPUT, Next: COMMANDS, Prev: PIVOTING, Up: Top  File: hledger.info, Node: Output destination, Next: Output format, Up: OUTPUT -8.1 Output destination +9.1 Output destination ====================== hledger commands send their output to the terminal by default. You can @@ -1519,7 +1558,7 @@ $ hledger print -o - # write to stdout (the default)  File: hledger.info, Node: Output format, Prev: Output destination, Up: OUTPUT -8.2 Output format +9.2 Output format ================= Some commands (print, register, the balance commands) offer a choice of @@ -1571,10 +1610,10 @@ $ hledger balancesheet -o foo.txt -O html # write HTML to foo.txt postings will be duped.  -File: hledger.info, Node: COMMANDS, Next: COMMON TASKS, Prev: OUTPUT, Up: Top +File: hledger.info, Node: COMMANDS, Next: JOURNAL FORMAT, Prev: OUTPUT, Up: Top -9 COMMANDS -********** +10 COMMANDS +*********** hledger provides a number of commands for producing reports and managing your data. Run 'hledger' with no arguments to list the commands @@ -1610,10 +1649,10 @@ journal file. *Miscellaneous reports:* - * accounts (a) - show account names + * accounts - show account names * activity - show postings-per-interval bar charts - * *balance (b, bal)* - show balance changes/end balances/budgets in - any accounts + * *balance (bal)* - show balance changes/end balances/budgets in any + accounts * codes - show transaction codes * commodities - show commodity/currency symbols * descriptions - show unique transaction descriptions @@ -1622,10 +1661,10 @@ journal file. * notes - show unique note segments of transaction descriptions * payees - show unique payee segments of transaction descriptions * prices - show market price records - * *print (p, txns)* - show transactions (journal entries) + * *print* - show transactions (journal entries) * print-unique - show only transactions with unique descriptions - * *register (r, reg)* - show postings in one or more accounts & - running total + * *register (reg)* - show postings in one or more accounts & running + total * register-match - show a recent posting that best matches a description * stats - show journal statistics @@ -1688,8 +1727,8 @@ these are maintained and released with hledger:  File: hledger.info, Node: accounts, Next: activity, Up: COMMANDS -9.1 accounts -============ +10.1 accounts +============= accounts, a Show account names. @@ -1718,8 +1757,8 @@ liabilities:debts  File: hledger.info, Node: activity, Next: add, Prev: accounts, Up: COMMANDS -9.2 activity -============ +10.2 activity +============= activity Show an ascii barchart of posting counts per interval. @@ -1739,8 +1778,8 @@ $ hledger activity --quarterly  File: hledger.info, Node: add, Next: aregister, Prev: activity, Up: COMMANDS -9.3 add -======= +10.3 add +======== add Prompt for transactions and add them to the journal. Any arguments will @@ -1810,8 +1849,8 @@ file path ends with a period, as that would cause problems (#1056).  File: hledger.info, Node: aregister, Next: balance, Prev: add, Up: COMMANDS -9.4 aregister -============= +10.4 aregister +============== aregister, areg Show transactions affecting a particular account, and the account's @@ -1854,8 +1893,8 @@ options The output formats supported are 'txt', 'csv', and 'json'.  File: hledger.info, Node: aregister and custom posting dates, Up: aregister -9.4.1 aregister and custom posting dates ----------------------------------------- +10.4.1 aregister and custom posting dates +----------------------------------------- Transactions whose date is outside the report period can still be shown, if they have a posting to this account dated inside the report period. @@ -1882,8 +1921,8 @@ $ hledger areg assets date:jul  File: hledger.info, Node: balance, Next: balancesheet, Prev: aregister, Up: COMMANDS -9.5 balance -=========== +10.5 balance +============ balance, bal, b Show accounts and their balances. @@ -1929,8 +1968,8 @@ options The output formats supported are (in most modes): 'txt', 'csv',  File: hledger.info, Node: Classic balance report, Next: Customising the classic balance report, Up: balance -9.5.1 Classic balance report ----------------------------- +10.5.1 Classic balance report +----------------------------- This is the original balance report, as found in Ledger. It usually looks like this: @@ -1975,8 +2014,8 @@ $ hledger balance -p 2008/6 expenses --no-total  File: hledger.info, Node: Customising the classic balance report, Next: Colour support, Prev: Classic balance report, Up: balance -9.5.2 Customising the classic balance report --------------------------------------------- +10.5.2 Customising the classic balance report +--------------------------------------------- You can customise the layout of classic balance reports with '--format FMT': @@ -2037,8 +2076,8 @@ may be needed to get pleasing results.  File: hledger.info, Node: Colour support, Next: Flat mode, Prev: Customising the classic balance report, Up: balance -9.5.3 Colour support --------------------- +10.5.3 Colour support +--------------------- In terminal output, when colour is enabled, the balance command shows negative amounts in red. @@ -2046,8 +2085,8 @@ negative amounts in red.  File: hledger.info, Node: Flat mode, Next: Depth limited balance reports, Prev: Colour support, Up: balance -9.5.4 Flat mode ---------------- +10.5.4 Flat mode +---------------- To see a flat list instead of the default hierarchical display, use '--flat'. In this mode, accounts (unless depth-clipped) show their full @@ -2062,8 +2101,8 @@ $ hledger balance -p 2008/6 expenses -N --flat --drop 1  File: hledger.info, Node: Depth limited balance reports, Next: Percentages, Prev: Flat mode, Up: balance -9.5.5 Depth limited balance reports ------------------------------------ +10.5.5 Depth limited balance reports +------------------------------------ With '--depth N' or 'depth:N' or just '-N', balance reports show accounts only to the specified numeric depth. This is very useful to @@ -2081,8 +2120,8 @@ show inclusive balances at the depth limit.  File: hledger.info, Node: Percentages, Next: Sorting by amount, Prev: Depth limited balance reports, Up: balance -9.5.6 Percentages ------------------ +10.5.6 Percentages +------------------ With '-%' or '--percent', balance reports show each account's value expressed as a percentage of the column's total. This is useful to get @@ -2113,8 +2152,8 @@ to use '-V' or '-B' to coerce the report into using a single commodity.  File: hledger.info, Node: Sorting by amount, Next: Multicolumn balance report, Prev: Percentages, Up: balance -9.5.7 Sorting by amount ------------------------ +10.5.7 Sorting by amount +------------------------ With '-S'/'--sort-amount', accounts with the largest (most positive) balances are shown first. For example, 'hledger bal expenses -MAS' @@ -2129,8 +2168,8 @@ like 'balancesheet' or 'incomestatement', which also support '-S'. Eg:  File: hledger.info, Node: Multicolumn balance report, Next: Budget report, Prev: Sorting by amount, Up: balance -9.5.8 Multicolumn balance report --------------------------------- +10.5.8 Multicolumn balance report +--------------------------------- Multicolumn or tabular balance reports are a very useful hledger feature, and usually the preferred style. They share many of the above @@ -2250,8 +2289,8 @@ bal -D --color=yes | less -RS'.  File: hledger.info, Node: Budget report, Prev: Multicolumn balance report, Up: balance -9.5.9 Budget report -------------------- +10.5.9 Budget report +-------------------- With '--budget', extra columns are displayed showing budget goals for each account and period, if any. Budget goals are defined by periodic @@ -2374,8 +2413,8 @@ Budget performance in 2017/11/01-2017/12/31:  File: hledger.info, Node: Budget report start date, Next: Nested budgets, Up: Budget report -9.5.9.1 Budget report start date -................................ +10.5.9.1 Budget report start date +................................. This might be a bug, but for now: when making budget reports, it's a good idea to explicitly set the report's start date to the first day of @@ -2418,8 +2457,8 @@ Budget performance in 2020-01-01..2020-01-15:  File: hledger.info, Node: Nested budgets, Prev: Budget report start date, Up: Budget report -9.5.9.2 Nested budgets -...................... +10.5.9.2 Nested budgets +....................... You can add budgets to any account in your account hierarchy. If you have budgets on both parent account and some of its children, then @@ -2506,8 +2545,8 @@ Budget performance in 2019/01:  File: hledger.info, Node: balancesheet, Next: balancesheetequity, Prev: balance, Up: COMMANDS -9.6 balancesheet -================ +10.6 balancesheet +================= balancesheet, bs This command displays a balance sheet, showing historical ending @@ -2560,8 +2599,8 @@ options The output formats supported are 'txt', 'csv', 'html', and  File: hledger.info, Node: balancesheetequity, Next: cashflow, Prev: balancesheet, Up: COMMANDS -9.7 balancesheetequity -====================== +10.7 balancesheetequity +======================= balancesheetequity, bse This command displays a balance sheet, showing historical ending @@ -2609,8 +2648,8 @@ options The output formats supported are 'txt', 'csv', 'html', and  File: hledger.info, Node: cashflow, Next: check, Prev: balancesheetequity, Up: COMMANDS -9.8 cashflow -============ +10.8 cashflow +============= cashflow, cf This command displays a cashflow statement, showing the inflows and @@ -2654,8 +2693,8 @@ options The output formats supported are 'txt', 'csv', 'html', and  File: hledger.info, Node: check, Next: close, Prev: cashflow, Up: COMMANDS -9.9 check -========= +10.9 check +========== check Check for various kinds of errors in your data. _experimental_ @@ -2681,8 +2720,8 @@ hledger check ordereddates uniqueleafnames # basic + specified checks  File: hledger.info, Node: Basic checks, Next: Strict checks, Up: check -9.9.1 Basic checks ------------------- +10.9.1 Basic checks +------------------- These are always run by this command and other commands: @@ -2699,8 +2738,8 @@ These are always run by this command and other commands:  File: hledger.info, Node: Strict checks, Next: Other checks, Prev: Basic checks, Up: check -9.9.2 Strict checks -------------------- +10.9.2 Strict checks +-------------------- These are always run by this and other commands when '-s'/'--strict' is used (strict mode): @@ -2713,8 +2752,8 @@ used (strict mode):  File: hledger.info, Node: Other checks, Next: Add-on checks, Prev: Strict checks, Up: check -9.9.3 Other checks ------------------- +10.9.3 Other checks +------------------- These checks can be run by specifying their names as arguments to the check command: @@ -2728,8 +2767,8 @@ check command:  File: hledger.info, Node: Add-on checks, Prev: Other checks, Up: check -9.9.4 Add-on checks -------------------- +10.9.4 Add-on checks +-------------------- Some checks are not yet integrated with this command, but are available as add-on commands in @@ -2747,8 +2786,8 @@ Cookbook -> Scripting may be helpful.  File: hledger.info, Node: close, Next: codes, Prev: check, Up: COMMANDS -9.10 close -========== +10.10 close +=========== close, equity Prints a "closing balances" transaction and an "opening balances" @@ -2787,8 +2826,8 @@ you have many foreign currency or investment transactions.  File: hledger.info, Node: close usage, Up: close -9.10.1 close usage ------------------- +10.10.1 close usage +------------------- If you split your journal files by time (eg yearly), you will typically run this command at the end of the year, and save the closing @@ -2858,8 +2897,8 @@ breaking balance assertions:  File: hledger.info, Node: codes, Next: commodities, Prev: close, Up: COMMANDS -9.11 codes -========== +10.11 codes +=========== codes List the codes seen in transactions, in the order parsed. @@ -2904,8 +2943,8 @@ $ hledger codes -E  File: hledger.info, Node: commodities, Next: descriptions, Prev: codes, Up: COMMANDS -9.12 commodities -================ +10.12 commodities +================= commodities List all commodity/currency symbols used or declared in the journal. @@ -2913,8 +2952,8 @@ List all commodity/currency symbols used or declared in the journal.  File: hledger.info, Node: descriptions, Next: diff, Prev: commodities, Up: COMMANDS -9.13 descriptions -================= +10.13 descriptions +================== descriptions List the unique descriptions that appear in transactions. @@ -2933,8 +2972,8 @@ Person A  File: hledger.info, Node: diff, Next: files, Prev: descriptions, Up: COMMANDS -9.14 diff -========= +10.14 diff +========== diff Compares a particular account's transactions in two input files. It @@ -2968,8 +3007,8 @@ These transactions are in the second file only:  File: hledger.info, Node: files, Next: help, Prev: diff, Up: COMMANDS -9.15 files -========== +10.15 files +=========== files List all files included in the journal. With a REGEX argument, only @@ -2978,8 +3017,8 @@ file names matching the regular expression (case sensitive) are shown.  File: hledger.info, Node: help, Next: import, Prev: files, Up: COMMANDS -9.16 help -========= +10.16 help +========== help Show any of the hledger manuals. @@ -2997,7 +3036,7 @@ particular viewer with the '--info', '--man', '--pager', '--cat' flags. $ hledger help Please choose a manual by typing "hledger help MANUAL" (a substring is ok). -Manuals: hledger hledger-ui hledger-web journal csv timeclock timedot +Manuals: hledger hledger-ui hledger-web $ hledger help h --man @@ -3018,8 +3057,8 @@ DESCRIPTION  File: hledger.info, Node: import, Next: incomestatement, Prev: help, Up: COMMANDS -9.17 import -=========== +10.17 import +============ import Read new transactions added to each FILE since last run, and add them to @@ -3048,8 +3087,8 @@ $ hledger import --dry ... | hledger -f- print unknown --ignore-assertions  File: hledger.info, Node: Importing balance assignments, Next: Commodity display styles, Up: import -9.17.1 Importing balance assignments ------------------------------------- +10.17.1 Importing balance assignments +------------------------------------- Entries added by import will have their posting amounts made explicit (like 'hledger print -x'). This means that any balance assignments in @@ -3067,8 +3106,8 @@ please test it and send a pull request.)  File: hledger.info, Node: Commodity display styles, Prev: Importing balance assignments, Up: import -9.17.2 Commodity display styles -------------------------------- +10.17.2 Commodity display styles +-------------------------------- Imported amounts will be formatted according to the canonical commodity styles (declared or inferred) in the main journal file. @@ -3076,8 +3115,8 @@ styles (declared or inferred) in the main journal file.  File: hledger.info, Node: incomestatement, Next: notes, Prev: import, Up: COMMANDS -9.18 incomestatement -==================== +10.18 incomestatement +===================== incomestatement, is @@ -3129,8 +3168,8 @@ options The output formats supported are 'txt', 'csv', 'html', and  File: hledger.info, Node: notes, Next: payees, Prev: incomestatement, Up: COMMANDS -9.19 notes -========== +10.19 notes +=========== notes List the unique notes that appear in transactions. @@ -3149,8 +3188,8 @@ Snacks  File: hledger.info, Node: payees, Next: prices, Prev: notes, Up: COMMANDS -9.20 payees -=========== +10.20 payees +============ payees List the unique payee/payer names that appear in transactions. @@ -3171,8 +3210,8 @@ Person A  File: hledger.info, Node: prices, Next: print, Prev: payees, Up: COMMANDS -9.21 prices -=========== +10.21 prices +============ prices Print market price directives from the journal. With -costs, also print @@ -3184,8 +3223,8 @@ Price amounts are always displayed with their full precision.  File: hledger.info, Node: print, Next: print-unique, Prev: prices, Up: COMMANDS -9.22 print -========== +10.22 print +=========== print, txns, p Show transaction journal entries, sorted by date. @@ -3293,8 +3332,8 @@ $ hledger print -Ocsv  File: hledger.info, Node: print-unique, Next: register, Prev: print, Up: COMMANDS -9.23 print-unique -================= +10.23 print-unique +================== print-unique Print transactions which do not reuse an already-seen description. @@ -3314,8 +3353,8 @@ $ LEDGER_FILE=unique.journal hledger print-unique  File: hledger.info, Node: register, Next: register-match, Prev: print-unique, Up: COMMANDS -9.24 register -============= +10.24 register +============== register, reg, r Show postings and their running total. @@ -3412,8 +3451,8 @@ length and comparable to the others in the report.  File: hledger.info, Node: Custom register output, Up: register -9.24.1 Custom register output ------------------------------ +10.24.1 Custom register output +------------------------------ register uses the full terminal width by default, except on windows. You can override this by setting the 'COLUMNS' environment variable (not @@ -3444,8 +3483,8 @@ options The output formats supported are 'txt', 'csv', and  File: hledger.info, Node: register-match, Next: rewrite, Prev: register, Up: COMMANDS -9.25 register-match -=================== +10.25 register-match +==================== register-match Print the one posting whose transaction description is closest to DESC, @@ -3457,8 +3496,8 @@ ledger-autosync detect already-seen transactions when importing.  File: hledger.info, Node: rewrite, Next: roi, Prev: register-match, Up: COMMANDS -9.26 rewrite -============ +10.26 rewrite +============= rewrite Print all transactions, rewriting the postings of matched transactions. @@ -3511,8 +3550,8 @@ commodity.  File: hledger.info, Node: Re-write rules in a file, Next: Diff output format, Up: rewrite -9.26.1 Re-write rules in a file -------------------------------- +10.26.1 Re-write rules in a file +-------------------------------- During the run this tool will execute so called "Automated Transactions" found in any journal it process. I.e instead of specifying this @@ -3549,8 +3588,8 @@ postings.  File: hledger.info, Node: Diff output format, Next: rewrite vs print --auto, Prev: Re-write rules in a file, Up: rewrite -9.26.2 Diff output format -------------------------- +10.26.2 Diff output format +-------------------------- To use this tool for batch modification of your journal files you may find useful output in form of unified diff. @@ -3590,8 +3629,8 @@ output from 'hledger print'.  File: hledger.info, Node: rewrite vs print --auto, Prev: Diff output format, Up: rewrite -9.26.3 rewrite vs. print -auto ------------------------------- +10.26.3 rewrite vs. print -auto +------------------------------- This command predates print -auto, and currently does much the same thing, but with these differences: @@ -3610,8 +3649,8 @@ thing, but with these differences:  File: hledger.info, Node: roi, Next: stats, Prev: rewrite, Up: COMMANDS -9.27 roi -======== +10.27 roi +========= roi Shows the time-weighted (TWR) and money-weighted (IRR) rate of return on @@ -3866,8 +3905,8 @@ $ hledger roi -Y --inv investment --pnl "unrealized"  File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: COMMANDS -9.28 stats -========== +10.28 stats +=========== stats Show some journal statistics. @@ -3897,8 +3936,8 @@ selection.  File: hledger.info, Node: tags, Next: test, Prev: stats, Up: COMMANDS -9.29 tags -========= +10.29 tags +========== tags List the unique tag names used in the journal. With a TAGREGEX @@ -3917,8 +3956,8 @@ they are omitted.  File: hledger.info, Node: test, Next: About add-on commands, Prev: tags, Up: COMMANDS -9.30 test -========= +10.30 test +========== test Run built-in unit tests. @@ -3944,8 +3983,8 @@ $ hledger test -- -pData.Amount --color=never  File: hledger.info, Node: About add-on commands, Prev: test, Up: COMMANDS -9.31 About add-on commands -========================== +10.31 About add-on commands +=========================== Add-on commands are programs or scripts in your PATH @@ -3983,9 +4022,3307 @@ add-on program directly, eg: $ hledger-web --serve  -File: hledger.info, Node: COMMON TASKS, Next: ENVIRONMENT, Prev: COMMANDS, Up: Top +File: hledger.info, Node: JOURNAL FORMAT, Next: CSV FORMAT, Prev: COMMANDS, Up: Top -10 COMMON TASKS +11 JOURNAL FORMAT +***************** + +hledger's default file format, representing a General Journal. + + hledger's usual data source is a plain text file containing journal +entries in hledger journal format. This file represents a standard +accounting general journal. I use file names ending in '.journal', but +that's not required. The journal file contains a number of transaction +entries, each describing a transfer of money (or any commodity) between +two or more named accounts, in a simple format readable by both hledger +and humans. + + hledger's journal format is a compatible subset, mostly, of ledger's +journal format, so hledger can work with compatible ledger journal files +as well. It's safe, and encouraged, to run both hledger and ledger on +the same journal file, eg to validate the results you're getting. + + You can use hledger without learning any more about this file; just +use the add or web or import commands to create and update it. + + Many users, though, edit the journal file with a text editor, and +track changes with a version control system such as git. Editor addons +such as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and +hledger-vscode for Visual Studio Code, make this easier, adding colour, +formatting, tab completion, and useful commands. See Editor +configuration at hledger.org for the full list. + + Here's a description of each part of the file format (and hledger's +data model). These are mostly in the order you'll use them, but in some +cases related concepts have been grouped together for easy reference, or +linked before they are introduced, so feel free to skip over anything +that looks unnecessary right now. + +* Menu: + +* Transactions:: +* Dates:: +* Status:: +* Description:: +* Comments:: +* Tags:: +* Postings:: +* Account names:: +* Amounts:: +* Transaction prices:: +* Lot prices lot dates:: +* Balance assertions:: +* Balance assignments:: +* Directives:: +* Directives and multiple files:: +* Comment blocks:: +* Including other files:: +* Default year:: +* Declaring commodities:: +* Default commodity:: +* Declaring market prices:: +* Declaring accounts:: +* Rewriting accounts:: +* Default parent account:: +* Periodic transactions:: +* Auto postings:: + + +File: hledger.info, Node: Transactions, Next: Dates, Up: JOURNAL FORMAT + +11.1 Transactions +================= + +Transactions are the main unit of information in a journal file. They +represent events, typically a movement of some quantity of commodities +between two or more named accounts. + + Each transaction is recorded as a journal entry, beginning with a +simple date in column 0. This can be followed by any of the following +optional fields, separated by spaces: + + * a status character (empty, '!', or '*') + * a code (any short number or text, enclosed in parentheses) + * a description (any remaining text until end of line or a semicolon) + * a comment (any remaining text following a semicolon until end of + line, and any following indented lines beginning with a semicolon) + * 0 or more indented _posting_ lines, describing what was transferred + and the accounts involved (indented comment lines are also allowed, + but not blank lines or non-indented lines). + + Here's a simple journal file containing one transaction: + +2008/01/01 income + assets:bank:checking $1 + income:salary $-1 + + +File: hledger.info, Node: Dates, Next: Status, Prev: Transactions, Up: JOURNAL FORMAT + +11.2 Dates +========== + +* Menu: + +* Simple dates:: +* Secondary dates:: +* Posting dates:: + + +File: hledger.info, Node: Simple dates, Next: Secondary dates, Up: Dates + +11.2.1 Simple dates +------------------- + +Dates in the journal file use _simple dates_ format: 'YYYY-MM-DD' or +'YYYY/MM/DD' or 'YYYY.MM.DD', with leading zeros optional. The year may +be omitted, in which case it will be inferred from the context: the +current transaction, the default year set with a default year directive, +or the current date when the command is run. Some examples: +'2010-01-31', '2010/01/31', '2010.1.31', '1/31'. + + (The UI also accepts simple dates, as well as the more flexible smart +dates documented in the hledger manual.) + + +File: hledger.info, Node: Secondary dates, Next: Posting dates, Prev: Simple dates, Up: Dates + +11.2.2 Secondary dates +---------------------- + +Real-life transactions sometimes involve more than one date - eg the +date you write a cheque, and the date it clears in your bank. When you +want to model this, for more accurate daily balances, you can specify +individual posting dates. + + Or, you can use the older _secondary date_ feature (Ledger calls it +auxiliary date or effective date). Note: we support this for +compatibility, but I usually recommend avoiding this feature; posting +dates are almost always clearer and simpler. + + A secondary date is written after the primary date, following an +equals sign. If the year is omitted, the primary date's year is +assumed. When running reports, the primary (left) date is used by +default, but with the '--date2' flag (or '--aux-date' or '--effective'), +the secondary (right) date will be used instead. + + The meaning of secondary dates is up to you, but it's best to follow +a consistent rule. Eg "primary = the bank's clearing date, secondary = +date the transaction was initiated, if different", as shown here: + +2010/2/23=2/19 movie ticket + expenses:cinema $10 + assets:checking + +$ hledger register checking +2010-02-23 movie ticket assets:checking $-10 $-10 + +$ hledger register checking --date2 +2010-02-19 movie ticket assets:checking $-10 $-10 + + +File: hledger.info, Node: Posting dates, Prev: Secondary dates, Up: Dates + +11.2.3 Posting dates +-------------------- + +You can give individual postings a different date from their parent +transaction, by adding a posting comment containing a tag (see below) +like 'date:DATE'. This is probably the best way to control posting +dates precisely. Eg in this example the expense should appear in May +reports, and the deduction from checking should be reported on 6/1 for +easy bank reconciliation: + +2015/5/30 + expenses:food $10 ; food purchased on saturday 5/30 + assets:checking ; bank cleared it on monday, date:6/1 + +$ hledger -f t.j register food +2015-05-30 expenses:food $10 $10 + +$ hledger -f t.j register checking +2015-06-01 assets:checking $-10 $-10 + + DATE should be a simple date; if the year is not specified it will +use the year of the transaction's date. You can set the secondary date +similarly, with 'date2:DATE2'. The 'date:' or 'date2:' tags must have a +valid simple date value if they are present, eg a 'date:' tag with no +value is not allowed. + + Ledger's earlier, more compact bracketed date syntax is also +supported: '[DATE]', '[DATE=DATE2]' or '[=DATE2]'. hledger will attempt +to parse any square-bracketed sequence of the '0123456789/-.=' +characters in this way. With this syntax, DATE infers its year from the +transaction and DATE2 infers its year from DATE. + + +File: hledger.info, Node: Status, Next: Description, Prev: Dates, Up: JOURNAL FORMAT + +11.3 Status +=========== + +Transactions, or individual postings within a transaction, can have a +status mark, which is a single character before the transaction +description or posting account name, separated from it by a space, +indicating one of three statuses: + +mark status + +----------------- + unmarked +'!' pending +'*' cleared + + When reporting, you can filter by status with the '-U/--unmarked', +'-P/--pending', and '-C/--cleared' flags; or the 'status:', 'status:!', +and 'status:*' queries; or the U, P, C keys in hledger-ui. + + Note, in Ledger and in older versions of hledger, the "unmarked" +state is called "uncleared". As of hledger 1.3 we have renamed it to +unmarked for clarity. + + To replicate Ledger and old hledger's behaviour of also matching +pending, combine -U and -P. + + Status marks are optional, but can be helpful eg for reconciling with +real-world accounts. Some editor modes provide highlighting and +shortcuts for working with status. Eg in Emacs ledger-mode, you can +toggle transaction status with C-c C-e, or posting status with C-c C-c. + + What "uncleared", "pending", and "cleared" actually mean is up to +you. Here's one suggestion: + +status meaning +-------------------------------------------------------------------------- +uncleared recorded but not yet reconciled; needs review +pending tentatively reconciled (if needed, eg during a big + reconciliation) +cleared complete, reconciled as far as possible, and considered + correct + + With this scheme, you would use '-PC' to see the current balance at +your bank, '-U' to see things which will probably hit your bank soon +(like uncashed checks), and no flags to see the most up-to-date state of +your finances. + + +File: hledger.info, Node: Description, Next: Comments, Prev: Status, Up: JOURNAL FORMAT + +11.4 Description +================ + +A transaction's description is the rest of the line following the date +and status mark (or until a comment begins). Sometimes called the +"narration" in traditional bookkeeping, it can be used for whatever you +wish, or left blank. Transaction descriptions can be queried, unlike +comments. + +* Menu: + +* Payee and note:: + + +File: hledger.info, Node: Payee and note, Up: Description + +11.4.1 Payee and note +--------------------- + +You can optionally include a '|' (pipe) character in descriptions to +subdivide the description into separate fields for payee/payer name on +the left (up to the first '|') and an additional note field on the right +(after the first '|'). This may be worthwhile if you need to do more +precise querying and pivoting by payee or by note. + + +File: hledger.info, Node: Comments, Next: Tags, Prev: Description, Up: JOURNAL FORMAT + +11.5 Comments +============= + +Lines in the journal beginning with a semicolon (';') or hash ('#') or +star ('*') are comments, and will be ignored. (Star comments cause +org-mode nodes to be ignored, allowing emacs users to fold and navigate +their journals with org-mode or orgstruct-mode.) + + You can attach comments to a transaction by writing them after the +description and/or indented on the following lines (before the +postings). Similarly, you can attach comments to an individual posting +by writing them after the amount and/or indented on the following lines. +Transaction and posting comments must begin with a semicolon (';'). + + Some examples: + +# a file comment +; another file comment +* also a file comment, useful in org/orgstruct mode + +comment +A multiline file comment, which continues +until a line containing just "end comment" +(or end of file). +end comment + +2012/5/14 something ; a transaction comment + ; the transaction comment, continued + posting1 1 ; a comment for posting 1 + posting2 + ; a comment for posting 2 + ; another comment line for posting 2 +; a file comment (because not indented) + + You can also comment larger regions of a file using 'comment' and +'end comment' directives. + + +File: hledger.info, Node: Tags, Next: Postings, Prev: Comments, Up: JOURNAL FORMAT + +11.6 Tags +========= + +Tags are a way to add extra labels or labelled data to postings and +transactions, which you can then search or pivot on. + + A simple tag is a word (which may contain hyphens) followed by a full +colon, written inside a transaction or posting comment line: + +2017/1/16 bought groceries ; sometag: + + Tags can have a value, which is the text after the colon, up to the +next comma or end of line, with leading/trailing whitespace removed: + + expenses:food $10 ; a-posting-tag: the tag value + + Note this means hledger's tag values can not contain commas or +newlines. Ending at commas means you can write multiple short tags on +one line, comma separated: + + assets:checking ; a comment containing tag1:, tag2: some value ... + + Here, + + * "'a comment containing'" is just comment text, not a tag + * "'tag1'" is a tag with no value + * "'tag2'" is another tag, whose value is "'some value ...'" + + Tags in a transaction comment affect the transaction and all of its +postings, while tags in a posting comment affect only that posting. For +example, the following transaction has three tags ('A', 'TAG2', +'third-tag') and the posting has four (those plus 'posting-tag'): + +1/1 a transaction ; A:, TAG2: + ; third-tag: a third transaction tag, <- with a value + (a) $1 ; posting-tag: + + Tags are like Ledger's metadata feature, except hledger's tag values +are simple strings. + + +File: hledger.info, Node: Postings, Next: Account names, Prev: Tags, Up: JOURNAL FORMAT + +11.7 Postings +============= + +A posting is an addition of some amount to, or removal of some amount +from, an account. Each posting line begins with at least one space or +tab (2 or 4 spaces is common), followed by: + + * (optional) a status character (empty, '!', or '*'), followed by a + space + * (required) an account name (any text, optionally containing *single + spaces*, until end of line or a double space) + * (optional) *two or more spaces* or tabs followed by an amount. + + Positive amounts are being added to the account, negative amounts are +being removed. + + The amounts within a transaction must always sum up to zero. As a +convenience, one amount may be left blank; it will be inferred so as to +balance the transaction. + + Be sure to note the unusual two-space delimiter between account name +and amount. This makes it easy to write account names containing +spaces. But if you accidentally leave only one space (or tab) before +the amount, the amount will be considered part of the account name. + +* Menu: + +* Virtual postings:: + + +File: hledger.info, Node: Virtual postings, Up: Postings + +11.7.1 Virtual postings +----------------------- + +A posting with a parenthesised account name is called a _virtual +posting_ or _unbalanced posting_, which means it is exempt from the +usual rule that a transaction's postings must balance add up to zero. + + This is not part of double entry accounting, so you might choose to +avoid this feature. Or you can use it sparingly for certain special +cases where it can be convenient. Eg, you could set opening balances +without using a balancing equity account: + +1/1 opening balances + (assets:checking) $1000 + (assets:savings) $2000 + + A posting with a bracketed account name is called a _balanced virtual +posting_. The balanced virtual postings in a transaction must add up to +zero (separately from other postings). Eg: + +1/1 buy food with cash, update budget envelope subaccounts, & something else + assets:cash $-10 ; <- these balance + expenses:food $7 ; <- + expenses:food $3 ; <- + [assets:checking:budget:food] $-10 ; <- and these balance + [assets:checking:available] $10 ; <- + (something:else) $5 ; <- not required to balance + + Ordinary non-parenthesised, non-bracketed postings are called _real +postings_. You can exclude virtual postings from reports with the +'-R/--real' flag or 'real:1' query. + + +File: hledger.info, Node: Account names, Next: Amounts, Prev: Postings, Up: JOURNAL FORMAT + +11.8 Account names +================== + +Account names typically have several parts separated by a full colon, +from which hledger derives a hierarchical chart of accounts. They can +be anything you like, but in finance there are traditionally five +top-level accounts: 'assets', 'liabilities', 'income', 'expenses', and +'equity'. + + Account names may contain single spaces, eg: 'assets:accounts +receivable'. Because of this, they must always be followed by *two or +more spaces* (or newline). + + Account names can be aliased. + + +File: hledger.info, Node: Amounts, Next: Transaction prices, Prev: Account names, Up: JOURNAL FORMAT + +11.9 Amounts +============ + +After the account name, there is usually an amount. (Important: between +account name and amount, there must be *two or more spaces*.) + + hledger's amount format is flexible, supporting several international +formats. Here are some examples. Amounts have a number (the +"quantity"): + +1 + + ..and usually a currency or commodity name (the "commodity"). This +is a symbol, word, or phrase, to the left or right of the quantity, with +or without a separating space: + +$1 +4000 AAPL + + If the commodity name contains spaces, numbers, or punctuation, it +must be enclosed in double quotes: + +3 "no. 42 green apples" + + Amounts can be preceded by a minus sign (or a plus sign, though plus +is the default), The sign can be written before or after a left-side +commodity symbol: + +-$1 +$-1 + + One or more spaces between the sign and the number are acceptable +when parsing (but they won't be displayed in output): + ++ $1 +$- 1 + + Scientific E notation is allowed: + +1E-6 +EUR 1E3 + + A decimal mark can be written as a period or a comma: + +1.23 +1,23456780000009 + +* Menu: + +* Digit group marks:: +* Commodity display style:: +* Rounding:: + + +File: hledger.info, Node: Digit group marks, Next: Commodity display style, Up: Amounts + +11.9.1 Digit group marks +------------------------ + +In the integer part of the quantity (left of the decimal mark), groups +of digits can optionally be separated by a "digit group mark" - a space, +comma, or period (different from the decimal mark): + + $1,000,000.00 + EUR 2.000.000,00 +INR 9,99,99,999.00 + 1 000 000.9455 + + Note, a number containing a single group mark and no decimal mark is +ambiguous. Are these group marks or decimal marks ? + +1,000 +1.000 + + hledger will treat them both as decimal marks by default (cf #793). +If you use digit group marks, to prevent confusion and undetected typos +we recommend you write commodity directives at the top of the file to +explicitly declare the decimal mark (and optionally a digit group mark). +Note, these formats ("amount styles") are specific to each commodity, so +if your data uses multiple formats, hledger can handle it: + +commodity $1,000.00 +commodity EUR 1.000,00 +commodity INR 9,99,99,999.00 +commodity 1 000 000.9455 + + +File: hledger.info, Node: Commodity display style, Next: Rounding, Prev: Digit group marks, Up: Amounts + +11.9.2 Commodity display style +------------------------------ + +For the amounts in each commodity, hledger chooses a consistent display +style. (Excluding price amounts, which are always displayed as +written). The display style is chosen as follows: + + * If there is a commodity directive (or default commodity directive) + for the commodity, its style is used (see examples above). + + * Otherwise the style is inferred from the amounts in that commodity + seen in the journal. + + * Or if there are no such amounts in the journal, a default style is + used (like '$1000.00'). + + A style is inferred from the journal amounts in a commodity as +follows: + + * Use the general style (decimal mark, symbol placement) of the first + amount + * Use the first-seen digit group style (digit group mark, digit group + sizes), if any + * Use the maximum number of decimal places of all. + + Transaction price amounts don't affect the commodity display style +directly, but occasionally they can do so indirectly (eg when a +posting's amount is inferred using a transaction price). If you find +this causing problems, use a commodity directive to fix the display +style. + + In summary, each commodity's amounts will be normalised to + + * the style declared by a 'commodity' directive + * or, the style of the first posting amount in the journal, with the + first-seen digit group style and the maximum-seen number of decimal + places. + + So if your reports are showing amounts in a way you don't like, eg +with too many decimal places, use a commodity directive to set the +commodity's display style. For example: + +# declare euro, dollar and bitcoin commodities and set their display styles: +commodity EUR 1.000, +commodity $1000.00 +commodity 1000.00000000 BTC + + +File: hledger.info, Node: Rounding, Prev: Commodity display style, Up: Amounts + +11.9.3 Rounding +--------------- + +Amounts are stored internally as decimal numbers with up to 255 decimal +places, and displayed with the number of decimal places specified by the +commodity display style. Note, hledger uses banker's rounding: it +rounds to the nearest even number, eg 0.5 displayed with zero decimal +places is "0"). (Guaranteed since hledger 1.17.1; in older versions +this could vary if hledger was built with Decimal < 0.5.1.) + + +File: hledger.info, Node: Transaction prices, Next: Lot prices lot dates, Prev: Amounts, Up: JOURNAL FORMAT + +11.10 Transaction prices +======================== + +Within a transaction, you can note an amount's price in another +commodity. This can be used to document the cost (in a purchase) or +selling price (in a sale). For example, transaction prices are useful +to record purchases of a foreign currency. Note transaction prices are +fixed at the time of the transaction, and do not change over time. See +also market prices, which represent prevailing exchange rates on a +certain date. + + There are several ways to record a transaction price: + + 1. Write the price per unit, as '@ UNITPRICE' after the amount: + + 2009/1/1 + assets:euros €100 @ $1.35 ; one hundred euros purchased at $1.35 each + assets:dollars ; balancing amount is -$135.00 + + 2. Write the total price, as '@@ TOTALPRICE' after the amount: + + 2009/1/1 + assets:euros €100 @@ $135 ; one hundred euros purchased at $135 for the lot + assets:dollars + + 3. Specify amounts for all postings, using exactly two commodities, + and let hledger infer the price that balances the transaction: + + 2009/1/1 + assets:euros €100 ; one hundred euros purchased + assets:dollars $-135 ; for $135 + + 4. Like 1, but the '@' is parenthesised, i.e. '(@)'; this is for + compatibility with Ledger journals (Virtual posting costs), and is + equivalent to 1 in hledger. + + 5. Like 2, but as in 4 the '@@' is parenthesised, i.e. '(@@)'; in + hledger, this is equivalent to 2. + + Use the '-B/--cost' flag to convert amounts to their transaction +price's commodity, if any. (mnemonic: "B" is from "cost Basis", as in +Ledger). Eg here is how -B affects the balance report for the example +above: + +$ hledger bal -N --flat + $-135 assets:dollars + €100 assets:euros +$ hledger bal -N --flat -B + $-135 assets:dollars + $135 assets:euros # <- the euros' cost + + Note -B is sensitive to the order of postings when a transaction +price is inferred: the inferred price will be in the commodity of the +last amount. So if example 3's postings are reversed, while the +transaction is equivalent, -B shows something different: + +2009/1/1 + assets:dollars $-135 ; 135 dollars sold + assets:euros €100 ; for 100 euros + +$ hledger bal -N --flat -B + €-100 assets:dollars # <- the dollars' selling price + €100 assets:euros + + +File: hledger.info, Node: Lot prices lot dates, Next: Balance assertions, Prev: Transaction prices, Up: JOURNAL FORMAT + +11.11 Lot prices, lot dates +=========================== + +Ledger allows another kind of price, lot price (four variants: +'{UNITPRICE}', '{{TOTALPRICE}}', '{=FIXEDUNITPRICE}', +'{{=FIXEDTOTALPRICE}}'), and/or a lot date ('[DATE]') to be specified. +These are normally used to select a lot when selling investments. +hledger will parse these, for compatibility with Ledger journals, but +currently ignores them. A transaction price, lot price and/or lot date +may appear in any order, after the posting amount and before the balance +assertion if any. + + +File: hledger.info, Node: Balance assertions, Next: Balance assignments, Prev: Lot prices lot dates, Up: JOURNAL FORMAT + +11.12 Balance assertions +======================== + +hledger supports Ledger-style balance assertions in journal files. +These look like, for example, '= EXPECTEDBALANCE' following a posting's +amount. Eg here we assert the expected dollar balance in accounts a and +b after each posting: + +2013/1/1 + a $1 =$1 + b =$-1 + +2013/1/2 + a $1 =$2 + b $-1 =$-2 + + After reading a journal file, hledger will check all balance +assertions and report an error if any of them fail. Balance assertions +can protect you from, eg, inadvertently disrupting reconciled balances +while cleaning up old entries. You can disable them temporarily with +the '-I/--ignore-assertions' flag, which can be useful for +troubleshooting or for reading Ledger files. (Note: this flag currently +does not disable balance assignments, below). + +* Menu: + +* Assertions and ordering:: +* Assertions and included files:: +* Assertions and multiple -f options:: +* Assertions and commodities:: +* Assertions and prices:: +* Assertions and subaccounts:: +* Assertions and virtual postings:: +* Assertions and precision:: + + +File: hledger.info, Node: Assertions and ordering, Next: Assertions and included files, Up: Balance assertions + +11.12.1 Assertions and ordering +------------------------------- + +hledger sorts an account's postings and assertions first by date and +then (for postings on the same day) by parse order. Note this is +different from Ledger, which sorts assertions only by parse order. +(Also, Ledger assertions do not see the accumulated effect of repeated +postings to the same account within a transaction.) + + So, hledger balance assertions keep working if you reorder +differently-dated transactions within the journal. But if you reorder +same-dated transactions or postings, assertions might break and require +updating. This order dependence does bring an advantage: precise +control over the order of postings and assertions within a day, so you +can assert intra-day balances. + + +File: hledger.info, Node: Assertions and included files, Next: Assertions and multiple -f options, Prev: Assertions and ordering, Up: Balance assertions + +11.12.2 Assertions and included files +------------------------------------- + +With included files, things are a little more complicated. Including +preserves the ordering of postings and assertions. If you have multiple +postings to an account on the same day, split across different files, +and you also want to assert the account's balance on the same day, +you'll have to put the assertion in the right file. + + +File: hledger.info, Node: Assertions and multiple -f options, Next: Assertions and commodities, Prev: Assertions and included files, Up: Balance assertions + +11.12.3 Assertions and multiple -f options +------------------------------------------ + +Balance assertions don't work well across files specified with multiple +-f options. Use include or concatenate the files instead. + + +File: hledger.info, Node: Assertions and commodities, Next: Assertions and prices, Prev: Assertions and multiple -f options, Up: Balance assertions + +11.12.4 Assertions and commodities +---------------------------------- + +The asserted balance must be a simple single-commodity amount, and in +fact the assertion checks only this commodity's balance within the +(possibly multi-commodity) account balance. This is how assertions work +in Ledger also. We could call this a "partial" balance assertion. + + To assert the balance of more than one commodity in an account, you +can write multiple postings, each asserting one commodity's balance. + + You can make a stronger "total" balance assertion by writing a double +equals sign ('== EXPECTEDBALANCE'). This asserts that there are no +other unasserted commodities in the account (or, that their balance is +0). + +2013/1/1 + a $1 + a 1€ + b $-1 + c -1€ + +2013/1/2 ; These assertions succeed + a 0 = $1 + a 0 = 1€ + b 0 == $-1 + c 0 == -1€ + +2013/1/3 ; This assertion fails as 'a' also contains 1€ + a 0 == $1 + + It's not yet possible to make a complete assertion about a balance +that has multiple commodities. One workaround is to isolate each +commodity into its own subaccount: + +2013/1/1 + a:usd $1 + a:euro 1€ + b + +2013/1/2 + a 0 == 0 + a:usd 0 == $1 + a:euro 0 == 1€ + + +File: hledger.info, Node: Assertions and prices, Next: Assertions and subaccounts, Prev: Assertions and commodities, Up: Balance assertions + +11.12.5 Assertions and prices +----------------------------- + +Balance assertions ignore transaction prices, and should normally be +written without one: + +2019/1/1 + (a) $1 @ €1 = $1 + + We do allow prices to be written there, however, and print shows +them, even though they don't affect whether the assertion passes or +fails. This is for backward compatibility (hledger's close command used +to generate balance assertions with prices), and because balance +_assignments_ do use them (see below). + + +File: hledger.info, Node: Assertions and subaccounts, Next: Assertions and virtual postings, Prev: Assertions and prices, Up: Balance assertions + +11.12.6 Assertions and subaccounts +---------------------------------- + +The balance assertions above ('=' and '==') do not count the balance +from subaccounts; they check the account's exclusive balance only. You +can assert the balance including subaccounts by writing '=*' or '==*', +eg: + +2019/1/1 + equity:opening balances + checking:a 5 + checking:b 5 + checking 1 ==* 11 + + +File: hledger.info, Node: Assertions and virtual postings, Next: Assertions and precision, Prev: Assertions and subaccounts, Up: Balance assertions + +11.12.7 Assertions and virtual postings +--------------------------------------- + +Balance assertions are checked against all postings, both real and +virtual. They are not affected by the '--real/-R' flag or 'real:' +query. + + +File: hledger.info, Node: Assertions and precision, Prev: Assertions and virtual postings, Up: Balance assertions + +11.12.8 Assertions and precision +-------------------------------- + +Balance assertions compare the exactly calculated amounts, which are not +always what is shown by reports. Eg a commodity directive may limit the +display precision, but this will not affect balance assertions. Balance +assertion failure messages show exact amounts. + + +File: hledger.info, Node: Balance assignments, Next: Directives, Prev: Balance assertions, Up: JOURNAL FORMAT + +11.13 Balance assignments +========================= + +Ledger-style balance assignments are also supported. These are like +balance assertions, but with no posting amount on the left side of the +equals sign; instead it is calculated automatically so as to satisfy the +assertion. This can be a convenience during data entry, eg when setting +opening balances: + +; starting a new journal, set asset account balances +2016/1/1 opening balances + assets:checking = $409.32 + assets:savings = $735.24 + assets:cash = $42 + equity:opening balances + + or when adjusting a balance to reality: + +; no cash left; update balance, record any untracked spending as a generic expense +2016/1/15 + assets:cash = $0 + expenses:misc + + The calculated amount depends on the account's balance in the +commodity at that point (which depends on the previously-dated postings +of the commodity to that account since the last balance assertion or +assignment). Note that using balance assignments makes your journal a +little less explicit; to know the exact amount posted, you have to run +hledger or do the calculations yourself, instead of just reading it. + +* Menu: + +* Balance assignments and prices:: + + +File: hledger.info, Node: Balance assignments and prices, Up: Balance assignments + +11.13.1 Balance assignments and prices +-------------------------------------- + +A transaction price in a balance assignment will cause the calculated +amount to have that price attached: + +2019/1/1 + (a) = $1 @ €2 + +$ hledger print --explicit +2019-01-01 + (a) $1 @ €2 = $1 @ €2 + + +File: hledger.info, Node: Directives, Next: Directives and multiple files, Prev: Balance assignments, Up: JOURNAL FORMAT + +11.14 Directives +================ + +A directive is a line in the journal beginning with a special keyword, +that influences how the journal is processed. hledger's directives are +based on a subset of Ledger's, but there are many differences (and also +some differences between hledger versions). + + Directives' behaviour and interactions can get a little bit complex, +so here is a table summarising the directives and their effects, with +links to more detailed docs. Note part of this table is hidden when +viewed in a web browser - scroll it sideways to see more. + +directiveend subdirectivespurpose can affect (as of + directive 2018/06) +----------------------------------------------------------------------------- +'account' any document account names, all entries in + text declare account types & all files, before + display order or after +'alias' 'end rewrite account names following entries + aliases' until end of + current file or + end directive +'apply 'end prepend a common parent to following entries +account' apply account names until end of + account' current file or + end directive +'comment''end ignore part of journal following entries + comment' until end of + current file or + end directive +'commodity' 'format'declare a commodity and its number notation: + number notation & display following entries + style in that commodity + in all files ; + display style: + amounts of that + commodity in + reports +'D' declare a commodity to be default + used for commodityless commodity: + amounts, and its number following + notation & display style commodityless + entries until end + of current file; + number notation: + following entries + in that commodity + until end of + current file; + display style: + amounts of that + commodity in + reports +'include' include entries/directives what the included + from another file directives affect +'P' declare a market price for amounts of that + a commodity commodity in + reports, when -V + is used +'Y' declare a year for yearless following entries + dates until end of + current file +'=' declare an auto posting all entries in + rule, adding postings to parent/current/child + other transactions files (but not + sibling files, + see #1212) + + And some definitions: + +subdirectiveoptional indented directive line immediately following a parent + directive +number how to interpret numbers when parsing journal entries (the +notationidentity of the decimal separator character). (Currently each + commodity can have its own notation, even in the same file.) +displayhow to display amounts of a commodity in reports (symbol side +style and spacing, digit groups, decimal separator, decimal places) +directivewhich entries and (when there are multiple files) which files +scope are affected by a directive + + As you can see, directives vary in which journal entries and files +they affect, and whether they are focussed on input (parsing) or output +(reports). Some directives have multiple effects. + + +File: hledger.info, Node: Directives and multiple files, Next: Comment blocks, Prev: Directives, Up: JOURNAL FORMAT + +11.15 Directives and multiple files +=================================== + +If you use multiple '-f'/'--file' options, or the 'include' directive, +hledger will process multiple input files. But note that directives +which affect input (see above) typically last only until the end of the +file in which they occur. + + This may seem inconvenient, but it's intentional; it makes reports +stable and deterministic, independent of the order of input. Otherwise +you could see different numbers if you happened to write -f options in a +different order, or if you moved includes around while cleaning up your +files. + + It can be surprising though; for example, it means that 'alias' +directives do not affect parent or sibling files (see below). + + +File: hledger.info, Node: Comment blocks, Next: Including other files, Prev: Directives and multiple files, Up: JOURNAL FORMAT + +11.16 Comment blocks +==================== + +A line containing just 'comment' starts a commented region of the file, +and a line containing just 'end comment' (or the end of the current +file) ends it. See also comments. + + +File: hledger.info, Node: Including other files, Next: Default year, Prev: Comment blocks, Up: JOURNAL FORMAT + +11.17 Including other files +=========================== + +You can pull in the content of additional files by writing an include +directive, like this: + +include FILEPATH + + Only journal files can include, and only journal, timeclock or +timedot files can be included (not CSV files, currently). + + If the file path does not begin with a slash, it is relative to the +current file's folder. + + A tilde means home directory, eg: 'include ~/main.journal'. + + The path may contain glob patterns to match multiple files, eg: +'include *.journal'. + + There is limited support for recursive wildcards: '**/' (the slash is +required) matches 0 or more subdirectories. It's not super convenient +since you have to avoid include cycles and including directories, but +this can be done, eg: 'include */**/*.journal'. + + The path may also be prefixed to force a specific file format, +overriding the file extension (as described in hledger.1 -> Input +files): 'include timedot:~/notes/2020*.md'. + + +File: hledger.info, Node: Default year, Next: Declaring commodities, Prev: Including other files, Up: JOURNAL FORMAT + +11.18 Default year +================== + +You can set a default year to be used for subsequent dates which don't +specify a year. This is a line beginning with 'Y' followed by the year. +Eg: + +Y2009 ; set default year to 2009 + +12/15 ; equivalent to 2009/12/15 + expenses 1 + assets + +Y2010 ; change default year to 2010 + +2009/1/30 ; specifies the year, not affected + expenses 1 + assets + +1/31 ; equivalent to 2010/1/31 + expenses 1 + assets + + +File: hledger.info, Node: Declaring commodities, Next: Default commodity, Prev: Default year, Up: JOURNAL FORMAT + +11.19 Declaring commodities +=========================== + +The 'commodity' directive has several functions: + + 1. It declares commodities which may be used in the journal. This is + currently not enforced, but can serve as documentation. + + 2. It declares what decimal mark character (period or comma) to expect + when parsing input - useful to disambiguate international number + formats in your data. (Without this, hledger will parse both + '1,000' and '1.000' as 1). + + 3. It declares a commodity's display style in output - decimal and + digit group marks, number of decimal places, symbol placement etc. + + You are likely to run into one of the problems solved by commodity +directives, sooner or later, so it's a good idea to just always use them +to declare your commodities. + + A commodity directive is just the word 'commodity' followed by an +amount. It may be written on a single line, like this: + +; commodity EXAMPLEAMOUNT + +; display AAAA amounts with the symbol on the right, space-separated, +; using period as decimal point, with four decimal places, and +; separating thousands with comma. +commodity 1,000.0000 AAAA + + or on multiple lines, using the "format" subdirective. (In this case +the commodity symbol appears twice and should be the same in both +places.): + +; commodity SYMBOL +; format EXAMPLEAMOUNT + +; display indian rupees with currency name on the left, +; thousands, lakhs and crores comma-separated, +; period as decimal point, and two decimal places. +commodity INR + format INR 1,00,00,000.00 + + The quantity of the amount does not matter; only the format is +significant. The number must include a decimal mark: either a period or +a comma, followed by 0 or more decimal digits. + + Note hledger normally uses banker's rounding, so 0.5 displayed with +zero decimal digits is "0". (More at Commodity display style.) + +* Menu: + +* Commodity error checking:: + + +File: hledger.info, Node: Commodity error checking, Up: Declaring commodities + +11.19.1 Commodity error checking +-------------------------------- + +In strict mode, enabled with the '-s'/'--strict' flag, hledger will +report an error if a commodity symbol is used that has not been declared +by a 'commodity' directive. This works similarly to account error +checking, see the notes there for more details. + + +File: hledger.info, Node: Default commodity, Next: Declaring market prices, Prev: Declaring commodities, Up: JOURNAL FORMAT + +11.20 Default commodity +======================= + +The 'D' directive sets a default commodity, to be used for amounts +without a commodity symbol (ie, plain numbers). This commodity will be +applied to all subsequent commodity-less amounts, or until the next 'D' +directive. (Note, this is different from Ledger's 'D'.) + + For compatibility/historical reasons, 'D' also acts like a +'commodity' directive, setting the commodity's display style (for +output) and decimal mark (for parsing input). As with 'commodity', the +amount must always be written with a decimal mark (period or comma). If +both directives are used, 'commodity''s style takes precedence. + + The syntax is 'D AMOUNT'. Eg: + +; commodity-less amounts should be treated as dollars +; (and displayed with the dollar sign on the left, thousands separators and two decimal places) +D $1,000.00 + +1/1 + a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00 + b + + +File: hledger.info, Node: Declaring market prices, Next: Declaring accounts, Prev: Default commodity, Up: JOURNAL FORMAT + +11.21 Declaring market prices +============================= + +The 'P' directive declares a market price, which is an exchange rate +between two commodities on a certain date. (In Ledger, they are called +"historical prices".) These are often obtained from a stock exchange, +cryptocurrency exchange, or the foreign exchange market. + + Here is the format: + +P DATE COMMODITYA COMMODITYBAMOUNT + + * DATE is a simple date + * COMMODITYA is the symbol of the commodity being priced + * COMMODITYBAMOUNT is an amount (symbol and quantity) in a second + commodity, giving the price in commodity B of one unit of commodity + A. + + These two market price directives say that one euro was worth 1.35 US +dollars during 2009, and $1.40 from 2010 onward: + +P 2009/1/1 € $1.35 +P 2010/1/1 € $1.40 + + The '-V', '-X' and '--value' flags use these market prices to show +amount values in another commodity. See Valuation. + + +File: hledger.info, Node: Declaring accounts, Next: Rewriting accounts, Prev: Declaring market prices, Up: JOURNAL FORMAT + +11.22 Declaring accounts +======================== + +'account' directives can be used to declare accounts (ie, the places +that amounts are transferred from and to). Though not required, these +declarations can provide several benefits: + + * They can document your intended chart of accounts, providing a + reference. + * They can help hledger know your accounts' types (asset, liability, + equity, revenue, expense), useful for reports like balancesheet and + incomestatement. + * They control account display order in reports, allowing + non-alphabetic sorting (eg Revenues to appear above Expenses). + * They can store extra information about accounts (account numbers, + notes, etc.) + * They help with account name completion in the add command, + hledger-iadd, hledger-web, ledger-mode etc. + * In strict mode, they restrict which accounts may be posted to by + transactions, which helps detect typos. + + The simplest form is just the word 'account' followed by a +hledger-style account name, eg this account directive declares the +'assets:bank:checking' account: + +account assets:bank:checking + +* Menu: + +* Account error checking:: +* Account comments:: +* Account subdirectives:: +* Account types:: +* Account display order:: + + +File: hledger.info, Node: Account error checking, Next: Account comments, Up: Declaring accounts + +11.22.1 Account error checking +------------------------------ + +By default, accounts come into existence when a transaction references +them by name. This is convenient, but it means hledger can't warn you +when you mis-spell an account name in the journal. Usually you'll find +the error later, as an extra account in balance reports, or an incorrect +balance when reconciling. + + In strict mode, enabled with the '-s'/'--strict' flag, hledger will +report an error if any transaction uses an account name that has not +been declared by an account directive. Some notes: + + * The declaration is case-sensitive; transactions must use the + correct account name capitalisation. + * The account directive's scope is "whole file and below" (see + directives). This means it affects all of the current file, and + any files it includes, but not parent or sibling files. The + position of account directives within the file does not matter, + though it's usual to put them at the top. + * Accounts can only be declared in 'journal' files (but will affect + included files in other formats). + * It's currently not possible to declare "all possible subaccounts" + with a wildcard; every account posted to must be declared. + + +File: hledger.info, Node: Account comments, Next: Account subdirectives, Prev: Account error checking, Up: Declaring accounts + +11.22.2 Account comments +------------------------ + +Comments, beginning with a semicolon, can be added: + + * on the same line, *after two or more spaces* (because ; is allowed + in account names) + * on the next lines, indented + + An example of both: + +account assets:bank:checking ; same-line comment, note 2+ spaces before ; + ; next-line comment + ; another with tag, acctno:12345 (not used yet) + + Same-line comments are not supported by Ledger, or hledger <1.13. + + +File: hledger.info, Node: Account subdirectives, Next: Account types, Prev: Account comments, Up: Declaring accounts + +11.22.3 Account subdirectives +----------------------------- + +We also allow (and ignore) Ledger-style indented subdirectives, just for +compatibility.: + +account assets:bank:checking + format blah blah ; <- subdirective, ignored + + Here is the full syntax of account directives: + +account ACCTNAME [ACCTTYPE] [;COMMENT] + [;COMMENTS] + [LEDGER-STYLE SUBDIRECTIVES, IGNORED] + + +File: hledger.info, Node: Account types, Next: Account display order, Prev: Account subdirectives, Up: Declaring accounts + +11.22.4 Account types +--------------------- + +hledger recognises five main types of account, corresponding to the +account classes in the accounting equation: + + 'Asset', 'Liability', 'Equity', 'Revenue', 'Expense'. + + These account types are important for controlling which accounts +appear in the balancesheet, balancesheetequity, incomestatement reports +(and probably for other things in future). + + Additionally, we recognise the 'Cash' type, which is also an 'Asset', +and which causes accounts to appear in the cashflow report. ("Cash" +here means liquid assets, eg bank balances but typically not investments +or receivables.) + +* Menu: + +* Declaring account types:: +* Auto-detected account types:: +* Interference from auto-detected account types:: +* Old account type syntax:: + + +File: hledger.info, Node: Declaring account types, Next: Auto-detected account types, Up: Account types + +11.22.4.1 Declaring account types +................................. + +Generally, to make these reports work you should declare your top-level +accounts and their types, using account directives with 'type:' tags. + + The tag's value should be one of: 'Asset', 'Liability', 'Equity', +'Revenue', 'Expense', 'Cash', 'A', 'L', 'E', 'R', 'X', 'C' (all case +insensitive). The type is inherited by all subaccounts except where +they override it. Here's a complete example: + +account assets ; type: Asset +account assets:bank ; type: Cash +account assets:cash ; type: Cash +account liabilities ; type: Liability +account equity ; type: Equity +account revenues ; type: Revenue +account expenses ; type: Expense + + +File: hledger.info, Node: Auto-detected account types, Next: Interference from auto-detected account types, Prev: Declaring account types, Up: Account types + +11.22.4.2 Auto-detected account types +..................................... + +If you happen to use common english top-level account names, you may not +need to declare account types, as they will be detected automatically +using the following rules: + +If name matches regular account +expression: type is: +------------------------------------------------- +'^assets?(:|$)' 'Asset' +'^(debts?|liabilit(y|ies))(:|$)' 'Liability' +'^equity(:|$)' 'Equity' +'^(income|revenue)s?(:|$)' 'Revenue' +'^expenses?(:|$)' 'Expense' + +If account type is 'Asset' and name does not contain account type +regular expression: is: +-------------------------------------------------------------------------- +'(investment|receivable|:A/R|:fixed)' 'Cash' + + Even so, explicit declarations may be a good idea, for clarity and +predictability. + + +File: hledger.info, Node: Interference from auto-detected account types, Next: Old account type syntax, Prev: Auto-detected account types, Up: Account types + +11.22.4.3 Interference from auto-detected account types +....................................................... + +If you assign any account type, it's a good idea to assign all of them, +to prevent any confusion from mixing declared and auto-detected types. +Although it's unlikely to happen in real life, here's an example: with +the following journal, 'balancesheetequity' shows "liabilities" in both +Liabilities and Equity sections. Declaring another account as +'type:Liability' would fix it: + +account liabilities ; type:Equity + +2020-01-01 + assets 1 + liabilities 1 + equity -2 + + +File: hledger.info, Node: Old account type syntax, Prev: Interference from auto-detected account types, Up: Account types + +11.22.4.4 Old account type syntax +................................. + +In some hledger journals you might instead see this old syntax (the +letters ALERX, separated from the account name by two or more spaces); +this is deprecated and may be removed soon: + +account assets A +account liabilities L +account equity E +account revenues R +account expenses X + + +File: hledger.info, Node: Account display order, Prev: Account types, Up: Declaring accounts + +11.22.5 Account display order +----------------------------- + +Account directives also set the order in which accounts are displayed, +eg in reports, the hledger-ui accounts screen, and the hledger-web +sidebar. By default accounts are listed in alphabetical order. But if +you have these account directives in the journal: + +account assets +account liabilities +account equity +account revenues +account expenses + + you'll see those accounts displayed in declaration order, not +alphabetically: + +$ hledger accounts -1 +assets +liabilities +equity +revenues +expenses + + Undeclared accounts, if any, are displayed last, in alphabetical +order. + + Note that sorting is done at each level of the account tree (within +each group of sibling accounts under the same parent). And currently, +this directive: + +account other:zoo + + would influence the position of 'zoo' among 'other''s subaccounts, +but not the position of 'other' among the top-level accounts. This +means: + + * you will sometimes declare parent accounts (eg 'account other' + above) that you don't intend to post to, just to customize their + display order + * sibling accounts stay together (you couldn't display 'x:y' in + between 'a:b' and 'a:c'). + + +File: hledger.info, Node: Rewriting accounts, Next: Default parent account, Prev: Declaring accounts, Up: JOURNAL FORMAT + +11.23 Rewriting accounts +======================== + +You can define account alias rules which rewrite your account names, or +parts of them, before generating reports. This can be useful for: + + * expanding shorthand account names to their full form, allowing + easier data entry and a less verbose journal + * adapting old journals to your current chart of accounts + * experimenting with new account organisations, like a new hierarchy + or combining two accounts into one + * customising reports + + Account aliases also rewrite account names in account directives. +They do not affect account names being entered via hledger add or +hledger-web. + + See also Rewrite account names. + +* Menu: + +* Basic aliases:: +* Regex aliases:: +* Combining aliases:: +* Aliases and multiple files:: +* end aliases:: + + +File: hledger.info, Node: Basic aliases, Next: Regex aliases, Up: Rewriting accounts + +11.23.1 Basic aliases +--------------------- + +To set an account alias, use the 'alias' directive in your journal file. +This affects all subsequent journal entries in the current file or its +included files. The spaces around the = are optional: + +alias OLD = NEW + + Or, you can use the '--alias 'OLD=NEW'' option on the command line. +This affects all entries. It's useful for trying out aliases +interactively. + + OLD and NEW are case sensitive full account names. hledger will +replace any occurrence of the old account name with the new one. +Subaccounts are also affected. Eg: + +alias checking = assets:bank:wells fargo:checking +; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a" + + +File: hledger.info, Node: Regex aliases, Next: Combining aliases, Prev: Basic aliases, Up: Rewriting accounts + +11.23.2 Regex aliases +--------------------- + +There is also a more powerful variant that uses a regular expression, +indicated by the forward slashes: + +alias /REGEX/ = REPLACEMENT + + or '--alias '/REGEX/=REPLACEMENT''. + + REGEX is a case-insensitive regular expression. Anywhere it matches +inside an account name, the matched part will be replaced by +REPLACEMENT. If REGEX contains parenthesised match groups, these can be +referenced by the usual numeric backreferences in REPLACEMENT. Eg: + +alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3 +; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking" + + Also note that REPLACEMENT continues to the end of line (or on +command line, to end of option argument), so it can contain trailing +whitespace. + + +File: hledger.info, Node: Combining aliases, Next: Aliases and multiple files, Prev: Regex aliases, Up: Rewriting accounts + +11.23.3 Combining aliases +------------------------- + +You can define as many aliases as you like, using journal directives +and/or command line options. + + Recursive aliases - where an account name is rewritten by one alias, +then by another alias, and so on - are allowed. Each alias sees the +effect of previously applied aliases. + + In such cases it can be important to understand which aliases will be +applied and in which order. For (each account name in) each journal +entry, we apply: + + 1. 'alias' directives preceding the journal entry, most recently + parsed first (ie, reading upward from the journal entry, bottom to + top) + 2. '--alias' options, in the order they appeared on the command line + (left to right). + + In other words, for (an account name in) a given journal entry: + + * the nearest alias declaration before/above the entry is applied + first + * the next alias before/above that will be be applied next, and so on + * aliases defined after/below the entry do not affect it. + + This gives nearby aliases precedence over distant ones, and helps +provide semantic stability - aliases will keep working the same way +independent of which files are being read and in which order. + + In case of trouble, adding '--debug=6' to the command line will show +which aliases are being applied when. + + +File: hledger.info, Node: Aliases and multiple files, Next: end aliases, Prev: Combining aliases, Up: Rewriting accounts + +11.23.4 Aliases and multiple files +---------------------------------- + +As explained at Directives and multiple files, 'alias' directives do not +affect parent or sibling files. Eg in this command, + +hledger -f a.aliases -f b.journal + + account aliases defined in a.aliases will not affect b.journal. +Including the aliases doesn't work either: + +include a.aliases + +2020-01-01 ; not affected by a.aliases + foo 1 + bar + + This means that account aliases should usually be declared at the +start of your top-most file, like this: + +alias foo=Foo +alias bar=Bar + +2020-01-01 ; affected by aliases above + foo 1 + bar + +include c.journal ; also affected + + +File: hledger.info, Node: end aliases, Prev: Aliases and multiple files, Up: Rewriting accounts + +11.23.5 'end aliases' +--------------------- + +You can clear (forget) all currently defined aliases with the 'end +aliases' directive: + +end aliases + + +File: hledger.info, Node: Default parent account, Next: Periodic transactions, Prev: Rewriting accounts, Up: JOURNAL FORMAT + +11.24 Default parent account +============================ + +You can specify a parent account which will be prepended to all accounts +within a section of the journal. Use the 'apply account' and 'end apply +account' directives like so: + +apply account home + +2010/1/1 + food $10 + cash + +end apply account + + which is equivalent to: + +2010/01/01 + home:food $10 + home:cash $-10 + + If 'end apply account' is omitted, the effect lasts to the end of the +file. Included files are also affected, eg: + +apply account business +include biz.journal +end apply account +apply account personal +include personal.journal + + Prior to hledger 1.0, legacy 'account' and 'end' spellings were also +supported. + + A default parent account also affects account directives. It does +not affect account names being entered via hledger add or hledger-web. +If account aliases are present, they are applied after the default +parent account. + + +File: hledger.info, Node: Periodic transactions, Next: Auto postings, Prev: Default parent account, Up: JOURNAL FORMAT + +11.25 Periodic transactions +=========================== + +Periodic transaction rules describe transactions that recur. They allow +hledger to generate temporary future transactions to help with +forecasting, so you don't have to write out each one in the journal, and +it's easy to try out different forecasts. + + Periodic transactions can be a little tricky, so before you use them, +read this whole section - or at least these tips: + + 1. Two spaces accidentally added or omitted will cause you trouble - + read about this below. + 2. For troubleshooting, show the generated transactions with 'hledger + print --forecast tag:generated' or 'hledger register --forecast + tag:generated'. + 3. Forecasted transactions will begin only after the last + non-forecasted transaction's date. + 4. Forecasted transactions will end 6 months from today, by default. + See below for the exact start/end rules. + 5. period expressions can be tricky. Their documentation needs + improvement, but is worth studying. + 6. Some period expressions with a repeating interval must begin on a + natural boundary of that interval. Eg in 'weekly from DATE', DATE + must be a monday. '~ weekly from 2019/10/1' (a tuesday) will give + an error. + 7. Other period expressions with an interval are automatically + expanded to cover a whole number of that interval. (This is done + to improve reports, but it also affects periodic transactions. + Yes, it's a bit inconsistent with the above.) Eg: '~ every 10th + day of month from 2020/01', which is equivalent to '~ every 10th + day of month from 2020/01/01', will be adjusted to start on + 2019/12/10. + + Periodic transaction rules also have a second meaning: they are used +to define budget goals, shown in budget reports. + +* Menu: + +* Periodic rule syntax:: +* Two spaces between period expression and description!:: +* Forecasting with periodic transactions:: +* Budgeting with periodic transactions:: + + +File: hledger.info, Node: Periodic rule syntax, Next: Two spaces between period expression and description!, Up: Periodic transactions + +11.25.1 Periodic rule syntax +---------------------------- + +A periodic transaction rule looks like a normal journal entry, with the +date replaced by a tilde ('~') followed by a period expression +(mnemonic: '~' looks like a recurring sine wave.): + +~ monthly + expenses:rent $2000 + assets:bank:checking + + There is an additional constraint on the period expression: the start +date must fall on a natural boundary of the interval. Eg 'monthly from +2018/1/1' is valid, but 'monthly from 2018/1/15' is not. + + Partial or relative dates (M/D, D, tomorrow, last week) in the period +expression can work (useful or not). They will be relative to today's +date, unless a Y default year directive is in effect, in which case they +will be relative to Y/1/1. + + +File: hledger.info, Node: Two spaces between period expression and description!, Next: Forecasting with periodic transactions, Prev: Periodic rule syntax, Up: Periodic transactions + +11.25.2 Two spaces between period expression and description! +------------------------------------------------------------- + +If the period expression is followed by a transaction description, these +must be separated by *two or more spaces*. This helps hledger know +where the period expression ends, so that descriptions can not +accidentally alter their meaning, as in this example: + +; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020" +; || +; vv +~ every 2 months in 2020, we will review + assets:bank:checking $1500 + income:acme inc + + So, + + * Do write two spaces between your period expression and your + transaction description, if any. + * Don't accidentally write two spaces in the middle of your period + expression. + + +File: hledger.info, Node: Forecasting with periodic transactions, Next: Budgeting with periodic transactions, Prev: Two spaces between period expression and description!, Up: Periodic transactions + +11.25.3 Forecasting with periodic transactions +---------------------------------------------- + +The '--forecast' flag activates any periodic transaction rules in the +journal. They will generate temporary recurring transactions, which are +not saved in the journal, but will appear in all reports (eg print). +This can be useful for estimating balances into the future, or +experimenting with different scenarios. Or, it can be used as a data +entry aid: describe recurring transactions, and every so often copy the +output of 'print --forecast' into the journal. + + These transactions will have an extra tag indicating which periodic +rule generated them: 'generated-transaction:~ PERIODICEXPR'. And a +similar, hidden tag (beginning with an underscore) which, because it's +never displayed by print, can be used to match transactions generated +"just now": '_generated-transaction:~ PERIODICEXPR'. + + Periodic transactions are generated within some forecast period. By +default, this + + * begins on the later of + * the report start date if specified with -b/-p/date: + * the day after the latest normal (non-periodic) transaction in + the journal, or today if there are no normal transactions. + + * ends on the report end date if specified with -e/-p/date:, or 6 + months (180 days) from today. + + This means that periodic transactions will begin only after the +latest recorded transaction. And a recorded transaction dated in the +future can prevent generation of periodic transactions. (You can avoid +that by writing the future transaction as a one-time periodic rule +instead - put tilde before the date, eg '~ YYYY-MM-DD ...'). + + Or, you can set your own arbitrary "forecast period", which can +overlap recorded transactions, and need not be in the future, by +providing an option argument, like '--forecast=PERIODEXPR'. Note the +equals sign is required, a space won't work. PERIODEXPR is a period +expression, which can specify the start date, end date, or both, like in +a 'date:' query. (See also hledger.1 -> Report start & end date). Some +examples: '--forecast=202001-202004', '--forecast=jan-', +'--forecast=2020'. + + +File: hledger.info, Node: Budgeting with periodic transactions, Prev: Forecasting with periodic transactions, Up: Periodic transactions + +11.25.4 Budgeting with periodic transactions +-------------------------------------------- + +With the '--budget' flag, currently supported by the balance command, +each periodic transaction rule declares recurring budget goals for the +specified accounts. Eg the first example above declares a goal of +spending $2000 on rent (and also, a goal of depositing $2000 into +checking) every month. Goals and actual performance can then be +compared in budget reports. + + See also: Budgeting and Forecasting. + + +File: hledger.info, Node: Auto postings, Prev: Periodic transactions, Up: JOURNAL FORMAT + +11.26 Auto postings +=================== + +"Automated postings" or "auto postings" are extra postings which get +added automatically to transactions which match certain queries, defined +by "auto posting rules", when you use the '--auto' flag. + + An auto posting rule looks a bit like a transaction: + += QUERY + ACCOUNT AMOUNT + ... + ACCOUNT [AMOUNT] + + except the first line is an equals sign (mnemonic: '=' suggests +matching), followed by a query (which matches existing postings), and +each "posting" line describes a posting to be generated, and the posting +amounts can be: + + * a normal amount with a commodity symbol, eg '$2'. This will be + used as-is. + * a number, eg '2'. The commodity symbol (if any) from the matched + posting will be added to this. + * a numeric multiplier, eg '*2' (a star followed by a number N). The + matched posting's amount (and total price, if any) will be + multiplied by N. + * a multiplier with a commodity symbol, eg '*$2' (a star, number N, + and symbol S). The matched posting's amount will be multiplied by + N, and its commodity symbol will be replaced with S. + + Any query term containing spaces must be enclosed in single or double +quotes, as on the command line. Eg, note the quotes around the second +query term below: + += expenses:groceries 'expenses:dining out' + (budget:funds:dining out) *-1 + + Some examples: + +; every time I buy food, schedule a dollar donation += expenses:food + (liabilities:charity) $-1 + +; when I buy a gift, also deduct that amount from a budget envelope subaccount += expenses:gifts + assets:checking:gifts *-1 + assets:checking *1 + +2017/12/1 + expenses:food $10 + assets:checking + +2017/12/14 + expenses:gifts $20 + assets:checking + +$ hledger print --auto +2017-12-01 + expenses:food $10 + assets:checking + (liabilities:charity) $-1 + +2017-12-14 + expenses:gifts $20 + assets:checking + assets:checking:gifts -$20 + assets:checking $20 + +* Menu: + +* Auto postings and multiple files:: +* Auto postings and dates:: +* Auto postings and transaction balancing / inferred amounts / balance assertions:: +* Auto posting tags:: + + +File: hledger.info, Node: Auto postings and multiple files, Next: Auto postings and dates, Up: Auto postings + +11.26.1 Auto postings and multiple files +---------------------------------------- + +An auto posting rule can affect any transaction in the current file, or +in any parent file or child file. Note, currently it will not affect +sibling files (when multiple '-f'/'--file' are used - see #1212). + + +File: hledger.info, Node: Auto postings and dates, Next: Auto postings and transaction balancing / inferred amounts / balance assertions, Prev: Auto postings and multiple files, Up: Auto postings + +11.26.2 Auto postings and dates +------------------------------- + +A posting date (or secondary date) in the matched posting, or (taking +precedence) a posting date in the auto posting rule itself, will also be +used in the generated posting. + + +File: hledger.info, Node: Auto postings and transaction balancing / inferred amounts / balance assertions, Next: Auto posting tags, Prev: Auto postings and dates, Up: Auto postings + +11.26.3 Auto postings and transaction balancing / inferred amounts / +-------------------------------------------------------------------- + +balance assertions Currently, auto postings are added: + + * after missing amounts are inferred, and transactions are checked + for balancedness, + * but before balance assertions are checked. + + Note this means that journal entries must be balanced both before and +after auto postings are added. This changed in hledger 1.12+; see #893 +for background. + + +File: hledger.info, Node: Auto posting tags, Prev: Auto postings and transaction balancing / inferred amounts / balance assertions, Up: Auto postings + +11.26.4 Auto posting tags +------------------------- + +Automated postings will have some extra tags: + + * 'generated-posting:= QUERY' - shows this was generated by an auto + posting rule, and the query + * '_generated-posting:= QUERY' - a hidden tag, which does not appear + in hledger's output. This can be used to match postings generated + "just now", rather than generated in the past and saved to the + journal. + + Also, any transaction that has been changed by auto posting rules +will have these tags added: + + * 'modified:' - this transaction was modified + * '_modified:' - a hidden tag not appearing in the comment; this + transaction was modified "just now". + + +File: hledger.info, Node: CSV FORMAT, Next: TIMECLOCK FORMAT, Prev: JOURNAL FORMAT, Up: Top + +12 CSV FORMAT +************* + +How hledger reads CSV data, and the CSV rules file format. + + hledger can read CSV files (Character Separated Value - usually +comma, semicolon, or tab) containing dated records as if they were +journal files, automatically converting each CSV record into a +transaction. + + (To learn about _writing_ CSV, see CSV output.) + + We describe each CSV file's format with a corresponding _rules file_. +By default this is named like the CSV file with a '.rules' extension +added. Eg when reading 'FILE.csv', hledger also looks for +'FILE.csv.rules' in the same directory as 'FILE.csv'. You can specify a +different rules file with the '--rules-file' option. If a rules file is +not found, hledger will create a sample rules file, which you'll need to +adjust. + + This file contains rules describing the CSV data (header line, fields +layout, date format etc.), and how to construct hledger journal entries +(transactions) from it. Often there will also be a list of conditional +rules for categorising transactions based on their descriptions. Here's +an overview of the CSV rules; these are described more fully below, +after the examples: + +*'skip'* skip one or more header lines or + matched CSV records +*'fields'* name CSV fields, assign them to hledger + fields +*field assignment* assign a value to one hledger field, + with interpolation +*'separator'* a custom field separator +*'if' block* apply some rules to CSV records matched + by patterns +*'if' table* apply some rules to CSV records matched + by patterns, alternate syntax +*'end'* skip the remaining CSV records +*'date-format'* how to parse dates in CSV records +*'decimal-mark'* the decimal mark used in CSV amounts, + if ambiguous +*'newest-first'* disambiguate record order when there's + only one date +*'include'* inline another CSV rules file +*'balance-type'* choose which type of balance + assignments to use + + Note, for best error messages when reading CSV files, use a '.csv', +'.tsv' or '.ssv' file extension or file prefix - see File Extension +below. + + There's an introductory Convert CSV files tutorial on hledger.org. + +* Menu: + +* Examples:: +* CSV rules:: +* Tips:: + + +File: hledger.info, Node: Examples, Next: CSV rules, Up: CSV FORMAT + +12.1 Examples +============= + +Here are some sample hledger CSV rules files. See also the full +collection at: +https://github.com/simonmichael/hledger/tree/master/examples/csv + +* Menu: + +* Basic:: +* Bank of Ireland:: +* Amazon:: +* Paypal:: + + +File: hledger.info, Node: Basic, Next: Bank of Ireland, Up: Examples + +12.1.1 Basic +------------ + +At minimum, the rules file must identify the date and amount fields, and +often it also specifies the date format and how many header lines there +are. Here's a simple CSV file and a rules file for it: + +Date, Description, Id, Amount +12/11/2019, Foo, 123, 10.23 + +# basic.csv.rules +skip 1 +fields date, description, _, amount +date-format %d/%m/%Y + +$ hledger print -f basic.csv +2019-11-12 Foo + expenses:unknown 10.23 + income:unknown -10.23 + + Default account names are chosen, since we didn't set them. + + +File: hledger.info, Node: Bank of Ireland, Next: Amazon, Prev: Basic, Up: Examples + +12.1.2 Bank of Ireland +---------------------- + +Here's a CSV with two amount fields (Debit and Credit), and a balance +field, which we can use to add balance assertions, which is not +necessary but provides extra error checking: + +Date,Details,Debit,Credit,Balance +07/12/2012,LODGMENT 529898,,10.0,131.21 +07/12/2012,PAYMENT,5,,126 + +# bankofireland-checking.csv.rules + +# skip the header line +skip + +# name the csv fields, and assign some of them as journal entry fields +fields date, description, amount-out, amount-in, balance + +# We generate balance assertions by assigning to "balance" +# above, but you may sometimes need to remove these because: +# +# - the CSV balance differs from the true balance, +# by up to 0.0000000000005 in my experience +# +# - it is sometimes calculated based on non-chronological ordering, +# eg when multiple transactions clear on the same day + +# date is in UK/Ireland format +date-format %d/%m/%Y + +# set the currency +currency EUR + +# set the base account for all txns +account1 assets:bank:boi:checking + +$ hledger -f bankofireland-checking.csv print +2012-12-07 LODGMENT 529898 + assets:bank:boi:checking EUR10.0 = EUR131.2 + income:unknown EUR-10.0 + +2012-12-07 PAYMENT + assets:bank:boi:checking EUR-5.0 = EUR126.0 + expenses:unknown EUR5.0 + + The balance assertions don't raise an error above, because we're +reading directly from CSV, but they will be checked if these entries are +imported into a journal file. + + +File: hledger.info, Node: Amazon, Next: Paypal, Prev: Bank of Ireland, Up: Examples + +12.1.3 Amazon +------------- + +Here we convert amazon.com order history, and use an if block to +generate a third posting if there's a fee. (In practice you'd probably +get this data from your bank instead, but it's an example.) + +"Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID" +"Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL" +"Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL" + +# amazon-orders.csv.rules + +# skip one header line +skip 1 + +# name the csv fields, and assign the transaction's date, amount and code. +# Avoided the "status" and "amount" hledger field names to prevent confusion. +fields date, _, toorfrom, name, amzstatus, amzamount, fees, code + +# how to parse the date +date-format %b %-d, %Y + +# combine two fields to make the description +description %toorfrom %name + +# save the status as a tag +comment status:%amzstatus + +# set the base account for all transactions +account1 assets:amazon +# leave amount1 blank so it can balance the other(s). +# I'm assuming amzamount excludes the fees, don't remember + +# set a generic account2 +account2 expenses:misc +amount2 %amzamount +# and maybe refine it further: +#include categorisation.rules + +# add a third posting for fees, but only if they are non-zero. +if %fees [1-9] + account3 expenses:fees + amount3 %fees + +$ hledger -f amazon-orders.csv print +2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed + assets:amazon + expenses:misc $20.00 + +2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed + assets:amazon + expenses:misc $25.00 + expenses:fees $1.00 + + +File: hledger.info, Node: Paypal, Prev: Amazon, Up: Examples + +12.1.4 Paypal +------------- + +Here's a real-world rules file for (customised) Paypal CSV, with some +Paypal-specific rules, and a second rules file included: + +"Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note" +"10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99","" +"10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00","" +"10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00","" +"10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00","" +"10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00","" +"10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00","" +"10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41","" + +# paypal-custom.csv.rules + +# Tips: +# Export from Activity -> Statements -> Custom -> Activity download +# Suggested transaction type: "Balance affecting" +# Paypal's default fields in 2018 were: +# "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact" +# This rules file assumes the following more detailed fields, configured in "Customize report fields": +# "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note" + +fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note + +skip 1 + +date-format %-m/%-d/%Y + +# ignore some paypal events +if +In Progress +Temporary Hold +Update to + skip + +# add more fields to the description +description %description_ %itemtitle + +# save some other fields as tags +comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_ + +# convert to short currency symbols +if %currency USD + currency $ +if %currency EUR + currency E +if %currency GBP + currency P + +# generate postings + +# the first posting will be the money leaving/entering my paypal account +# (negative means leaving my account, in all amount fields) +account1 assets:online:paypal +amount1 %netamount + +# the second posting will be money sent to/received from other party +# (account2 is set below) +amount2 -%grossamount + +# if there's a fee, add a third posting for the money taken by paypal. +if %feeamount [1-9] + account3 expenses:banking:paypal + amount3 -%feeamount + comment3 business: + +# choose an account for the second posting + +# override the default account names: +# if the amount is positive, it's income (a debit) +if %grossamount ^[^-] + account2 income:unknown +# if negative, it's an expense (a credit) +if %grossamount ^- + account2 expenses:unknown + +# apply common rules for setting account2 & other tweaks +include common.rules + +# apply some overrides specific to this csv + +# Transfers from/to bank. These are usually marked Pending, +# which can be disregarded in this case. +if +Bank Account +Bank Deposit to PP Account + description %type for %referencetxnid %itemtitle + account2 assets:bank:wf:pchecking + account1 assets:online:paypal + +# Currency conversions +if Currency Conversion + account2 equity:currency conversion + +# common.rules + +if +darcs +noble benefactor + account2 revenues:foss donations:darcshub + comment2 business: + +if +Calm Radio + account2 expenses:online:apps + +if +electronic frontier foundation +Patreon +wikimedia +Advent of Code + account2 expenses:dues + +if Google + account2 expenses:online:apps + description google | music + +$ hledger -f paypal-custom.csv print +2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon@joyful.com, toemail:memberships@calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed + assets:online:paypal $-6.99 = $-6.99 + expenses:online:apps $6.99 + +2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $6.99 = $0.00 + assets:bank:wf:pchecking $-6.99 + +2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon@joyful.com, toemail:support@patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed + assets:online:paypal $-7.00 = $-7.00 + expenses:dues $7.00 + +2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon@joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $7.00 = $0.00 + assets:bank:wf:pchecking $-7.00 + +2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon@joyful.com, toemail:tle@wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed + assets:online:paypal $-2.00 = $-2.00 + expenses:dues $2.00 + expenses:banking:paypal ; business: + +2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $2.00 = $0.00 + assets:bank:wf:pchecking $-2.00 + +2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble@bene.fac.tor, toemail:simon@joyful.com, time:05:07:06, type:Subscription Payment, status:Completed + assets:online:paypal $9.41 = $9.41 + revenues:foss donations:darcshub $-10.00 ; business: + expenses:banking:paypal $0.59 ; business: + + +File: hledger.info, Node: CSV rules, Next: Tips, Prev: Examples, Up: CSV FORMAT + +12.2 CSV rules +============== + +The following kinds of rule can appear in the rules file, in any order. +Blank lines and lines beginning with '#' or ';' are ignored. + +* Menu: + +* skip:: +* fields:: +* field assignment:: +* separator:: +* if block:: +* if table:: +* end:: +* date-format:: +* decimal-mark:: +* newest-first:: +* include:: +* balance-type:: + + +File: hledger.info, Node: skip, Next: fields, Up: CSV rules + +12.2.1 'skip' +------------- + +skip N + + The word "skip" followed by a number (or no number, meaning 1) tells +hledger to ignore this many non-empty lines preceding the CSV data. +(Empty/blank lines are skipped automatically.) You'll need this +whenever your CSV data contains header lines. + + It also has a second purpose: it can be used inside if blocks to +ignore certain CSV records (described below). + + +File: hledger.info, Node: fields, Next: field assignment, Prev: skip, Up: CSV rules + +12.2.2 'fields' +--------------- + +fields FIELDNAME1, FIELDNAME2, ... + + A fields list (the word "fields" followed by comma-separated field +names) is the quick way to assign CSV field values to hledger fields. +It does two things: + + 1. it names the CSV fields. This is optional, but can be convenient + later for interpolating them. + + 2. when you use a standard hledger field name, it assigns the CSV + value to that part of the hledger transaction. + + Here's an example that says "use the 1st, 2nd and 4th fields as the +transaction's date, description and amount; name the last two fields for +later reference; and ignore the others": + +fields date, description, , amount, , , somefield, anotherfield + + Field names may not contain whitespace. Fields you don't care about +can be left unnamed. Currently there must be least two items (there +must be at least one comma). + + Note, always use comma in the fields list, even if your CSV uses +another separator character. + + Here are the standard hledger field/pseudo-field names. For more +about the transaction parts they refer to, see the manual for hledger's +journal format. + +* Menu: + +* Transaction field names:: +* Posting field names:: + + +File: hledger.info, Node: Transaction field names, Next: Posting field names, Up: fields + +12.2.2.1 Transaction field names +................................ + +'date', 'date2', 'status', 'code', 'description', 'comment' can be used +to form the transaction's first line. + + +File: hledger.info, Node: Posting field names, Prev: Transaction field names, Up: fields + +12.2.2.2 Posting field names +............................ + +account 'accountN', where N is 1 to 99, causes a posting to be +generated, with that account name. + + Most often there are two postings, so you'll want to set 'account1' +and 'account2'. Typically 'account1' is associated with the CSV file, +and is set once with a top-level assignment, while 'account2' is set +based on each transaction's description, and in conditional blocks. + + If a posting's account name is left unset but its amount is set (see +below), a default account name will be chosen (like "expenses:unknown" +or "income:unknown"). amount 'amountN' sets posting N's amount. If the +CSV uses separate fields for inflows and outflows, you can use +'amountN-in' and 'amountN-out' instead. By assigning to 'amount1', +'amount2', ... etc. you can generate anywhere from 0 to 99 postings. + + There is also an older, unnumbered form of these names, suitable for +2-posting transactions, which sets both posting 1's and (negated) +posting 2's amount: 'amount', or 'amount-in' and 'amount-out'. This is +still supported because it keeps pre-hledger-1.17 csv rules files +working, and because it can be more succinct, and because it converts +posting 2's amount to cost if there's a transaction price, which can be +useful. + + If you have an existing rules file using the unnumbered form, you +might want to use the numbered form in certain conditional blocks, +without having to update and retest all the old rules. To facilitate +this, posting 1 ignores 'amount'/'amount-in'/'amount-out' if any of +'amount1'/'amount1-in'/'amount1-out' are assigned, and posting 2 ignores +them if any of 'amount2'/'amount2-in'/'amount2-out' are assigned, +avoiding conflicts. currency If the CSV has the currency symbol in a +separate field (ie, not part of the amount field), you can use +'currencyN' to prepend it to posting N's amount. Or, 'currency' with no +number affects all postings. balance 'balanceN' sets a balance +assertion amount (or if the posting amount is left empty, a balance +assignment) on posting N. + + Also, for compatibility with hledger <1.17: 'balance' with no number +is equivalent to 'balance1'. + + You can adjust the type of assertion/assignment with the +'balance-type' rule (see below). comment Finally, 'commentN' sets a +comment on the Nth posting. Comments can also contain tags, as usual. + + See TIPS below for more about setting amounts and currency. + + +File: hledger.info, Node: field assignment, Next: separator, Prev: fields, Up: CSV rules + +12.2.3 field assignment +----------------------- + +HLEDGERFIELDNAME FIELDVALUE + + Instead of or in addition to a fields list, you can use a "field +assignment" rule to set the value of a single hledger field, by writing +its name (any of the standard hledger field names above) followed by a +text value. The value may contain interpolated CSV fields, referenced +by their 1-based position in the CSV record ('%N'), or by the name they +were given in the fields list ('%CSVFIELDNAME'). Some examples: + +# set the amount to the 4th CSV field, with " USD" appended +amount %4 USD + +# combine three fields to make a comment, containing note: and date: tags +comment note: %somefield - %anotherfield, date: %1 + + Interpolation strips outer whitespace (so a CSV value like '" 1 "' +becomes '1' when interpolated) (#1051). See TIPS below for more about +referencing other fields. + + +File: hledger.info, Node: separator, Next: if block, Prev: field assignment, Up: CSV rules + +12.2.4 'separator' +------------------ + +You can use the 'separator' rule to read other kinds of +character-separated data. The argument is any single separator +character, or the words 'tab' or 'space' (case insensitive). Eg, for +comma-separated values (CSV): + +separator , + + or for semicolon-separated values (SSV): + +separator ; + + or for tab-separated values (TSV): + +separator TAB + + If the input file has a '.csv', '.ssv' or '.tsv' file extension (or a +'csv:', 'ssv:', 'tsv:' prefix), the appropriate separator will be +inferred automatically, and you won't need this rule. + + +File: hledger.info, Node: if block, Next: if table, Prev: separator, Up: CSV rules + +12.2.5 'if' block +----------------- + +if MATCHER + RULE + +if +MATCHER +MATCHER +MATCHER + RULE + RULE + + Conditional blocks ("if blocks") are a block of rules that are +applied only to CSV records which match certain patterns. They are +often used for customising account names based on transaction +descriptions. + +* Menu: + +* Matching the whole record:: +* Matching individual fields:: +* Combining matchers:: +* Rules applied on successful match:: + + +File: hledger.info, Node: Matching the whole record, Next: Matching individual fields, Up: if block + +12.2.5.1 Matching the whole record +.................................. + +Each MATCHER can be a record matcher, which looks like this: + +REGEX + + REGEX is a case-insensitive regular expression which tries to match +anywhere within the CSV record. It is a POSIX ERE (extended regular +expression) that also supports GNU word boundaries ('\b', '\B', '\<', +'\>'), and nothing else. If you have trouble, be sure to check our +https://hledger.org/hledger.html#regular-expressions doc. + + Important note: the record that is matched is not the original +record, but a synthetic one, with any enclosing double quotes (but not +enclosing whitespace) removed, and always comma-separated (which means +that a field containing a comma will appear like two fields). Eg, if +the original record is '2020-01-01; "Acme, Inc."; 1,000', the REGEX will +actually see '2020-01-01,Acme, Inc., 1,000'). + + +File: hledger.info, Node: Matching individual fields, Next: Combining matchers, Prev: Matching the whole record, Up: if block + +12.2.5.2 Matching individual fields +................................... + +Or, MATCHER can be a field matcher, like this: + +%CSVFIELD REGEX + + which matches just the content of a particular CSV field. CSVFIELD +is a percent sign followed by the field's name or column number, like +'%date' or '%1'. + + +File: hledger.info, Node: Combining matchers, Next: Rules applied on successful match, Prev: Matching individual fields, Up: if block + +12.2.5.3 Combining matchers +........................... + +A single matcher can be written on the same line as the "if"; or +multiple matchers can be written on the following lines, non-indented. +Multiple matchers are OR'd (any one of them can match), unless one +begins with an '&' symbol, in which case it is AND'ed with the previous +matcher. + +if +MATCHER +& MATCHER + RULE + + +File: hledger.info, Node: Rules applied on successful match, Prev: Combining matchers, Up: if block + +12.2.5.4 Rules applied on successful match +.......................................... + +After the patterns there should be one or more rules to apply, all +indented by at least one space. Three kinds of rule are allowed in +conditional blocks: + + * field assignments (to set a hledger field) + * skip (to skip the matched CSV record) + * end (to skip all remaining CSV records). + + Examples: + +# if the CSV record contains "groceries", set account2 to "expenses:groceries" +if groceries + account2 expenses:groceries + +# if the CSV record contains any of these patterns, set account2 and comment as shown +if +monthly service fee +atm transaction fee +banking thru software + account2 expenses:business:banking + comment XXX deductible ? check it + + +File: hledger.info, Node: if table, Next: end, Prev: if block, Up: CSV rules + +12.2.6 'if' table +----------------- + +if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn +MATCHER1,VALUE11,VALUE12,...,VALUE1n +MATCHER2,VALUE21,VALUE22,...,VALUE2n +MATCHER3,VALUE31,VALUE32,...,VALUE3n + + + Conditional tables ("if tables") are a different syntax to specify +field assignments that will be applied only to CSV records which match +certain patterns. + + MATCHER could be either field or record matcher, as described above. +When MATCHER matches, values from that row would be assigned to the CSV +fields named on the 'if' line, in the same order. + + Therefore 'if' table is exactly equivalent to a sequence of of 'if' +blocks: + +if MATCHER1 + CSVFIELDNAME1 VALUE11 + CSVFIELDNAME2 VALUE12 + ... + CSVFIELDNAMEn VALUE1n + +if MATCHER2 + CSVFIELDNAME1 VALUE21 + CSVFIELDNAME2 VALUE22 + ... + CSVFIELDNAMEn VALUE2n + +if MATCHER3 + CSVFIELDNAME1 VALUE31 + CSVFIELDNAME2 VALUE32 + ... + CSVFIELDNAMEn VALUE3n + + Each line starting with MATCHER should contain enough (possibly +empty) values for all the listed fields. + + Rules would be checked and applied in the order they are listed in +the table and, like with 'if' blocks, later rules (in the same or +another table) or 'if' blocks could override the effect of any rule. + + Instead of ',' you can use a variety of other non-alphanumeric +characters as a separator. First character after 'if' is taken to be +the separator for the rest of the table. It is the responsibility of +the user to ensure that separator does not occur inside MATCHERs and +values - there is no way to escape separator. + + Example: + +if,account2,comment +atm transaction fee,expenses:business:banking,deductible? check it +%description groceries,expenses:groceries, +2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out + + +File: hledger.info, Node: end, Next: date-format, Prev: if table, Up: CSV rules + +12.2.7 'end' +------------ + +This rule can be used inside if blocks (only), to make hledger stop +reading this CSV file and move on to the next input file, or to command +execution. Eg: + +# ignore everything following the first empty record +if ,,,, + end + + +File: hledger.info, Node: date-format, Next: decimal-mark, Prev: end, Up: CSV rules + +12.2.8 'date-format' +-------------------- + +date-format DATEFMT + + This is a helper for the 'date' (and 'date2') fields. If your CSV +dates are not formatted like 'YYYY-MM-DD', 'YYYY/MM/DD' or 'YYYY.MM.DD', +you'll need to add a date-format rule describing them with a strptime +date parsing pattern, which must parse the CSV date value completely. +Some examples: + +# MM/DD/YY +date-format %m/%d/%y + +# D/M/YYYY +# The - makes leading zeros optional. +date-format %-d/%-m/%Y + +# YYYY-Mmm-DD +date-format %Y-%h-%d + +# M/D/YYYY HH:MM AM some other junk +# Note the time and junk must be fully parsed, though only the date is used. +date-format %-m/%-d/%Y %l:%M %p some other junk + + For the supported strptime syntax, see: +https://hackage.haskell.org/package/time/docs/Data-Time-Format.html#v:formatTime + + +File: hledger.info, Node: decimal-mark, Next: newest-first, Prev: date-format, Up: CSV rules + +12.2.9 'decimal-mark' +--------------------- + +decimal-mark . + + or: + +decimal-mark , + + hledger automatically accepts either period or comma as a decimal +mark when parsing numbers (cf Amounts). However if any numbers in the +CSV contain digit group marks, such as thousand-separating commas, you +should declare the decimal mark explicitly with this rule, to avoid +misparsed numbers. + + +File: hledger.info, Node: newest-first, Next: include, Prev: decimal-mark, Up: CSV rules + +12.2.10 'newest-first' +---------------------- + +hledger always sorts the generated transactions by date. Transactions +on the same date should appear in the same order as their CSV records, +as hledger can usually auto-detect whether the CSV's normal order is +oldest first or newest first. But if all of the following are true: + + * the CSV might sometimes contain just one day of data (all records + having the same date) + * the CSV records are normally in reverse chronological order (newest + at the top) + * and you care about preserving the order of same-day transactions + + then, you should add the 'newest-first' rule as a hint. Eg: + +# tell hledger explicitly that the CSV is normally newest first +newest-first + + +File: hledger.info, Node: include, Next: balance-type, Prev: newest-first, Up: CSV rules + +12.2.11 'include' +----------------- + +include RULESFILE + + This includes the contents of another CSV rules file at this point. +'RULESFILE' is an absolute file path or a path relative to the current +file's directory. This can be useful for sharing common rules between +several rules files, eg: + +# someaccount.csv.rules + +## someaccount-specific rules +fields date,description,amount +account1 assets:someaccount +account2 expenses:misc + +## common rules +include categorisation.rules + + +File: hledger.info, Node: balance-type, Prev: include, Up: CSV rules + +12.2.12 'balance-type' +---------------------- + +Balance assertions generated by assigning to balanceN are of the simple +'=' type by default, which is a single-commodity, subaccount-excluding +assertion. You may find the subaccount-including variants more useful, +eg if you have created some virtual subaccounts of checking to help with +budgeting. You can select a different type of assertion with the +'balance-type' rule: + +# balance assertions will consider all commodities and all subaccounts +balance-type ==* + + Here are the balance assertion types for quick reference: + += single commodity, exclude subaccounts +=* single commodity, include subaccounts +== multi commodity, exclude subaccounts +==* multi commodity, include subaccounts + + +File: hledger.info, Node: Tips, Prev: CSV rules, Up: CSV FORMAT + +12.3 Tips +========= + +* Menu: + +* Rapid feedback:: +* Valid CSV:: +* File Extension:: +* Reading multiple CSV files:: +* Valid transactions:: +* Deduplicating importing:: +* Setting amounts:: +* Setting currency/commodity:: +* Referencing other fields:: +* How CSV rules are evaluated:: + + +File: hledger.info, Node: Rapid feedback, Next: Valid CSV, Up: Tips + +12.3.1 Rapid feedback +--------------------- + +It's a good idea to get rapid feedback while creating/troubleshooting +CSV rules. Here's a good way, using entr from +http://eradman.com/entrproject : + +$ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC' + + A desc: query (eg) is used to select just one, or a few, transactions +of interest. "bash -c" is used to run multiple commands, so we can echo +a separator each time the command re-runs, making it easier to read the +output. + + +File: hledger.info, Node: Valid CSV, Next: File Extension, Prev: Rapid feedback, Up: Tips + +12.3.2 Valid CSV +---------------- + +hledger accepts CSV conforming to RFC 4180. When CSV values are +enclosed in quotes, note: + + * they must be double quotes (not single quotes) + * spaces outside the quotes are not allowed + + +File: hledger.info, Node: File Extension, Next: Reading multiple CSV files, Prev: Valid CSV, Up: Tips + +12.3.3 File Extension +--------------------- + +To help hledger identify the format and show the right error messages, +CSV/SSV/TSV files should normally be named with a '.csv', '.ssv' or +'.tsv' filename extension. Or, the file path should be prefixed with +'csv:', 'ssv:' or 'tsv:'. Eg: + +$ hledger -f foo.ssv print + + or: + +$ cat foo | hledger -f ssv:- foo + + You can override the file extension with a separator rule if needed. +See also: Input files in the hledger manual. + + +File: hledger.info, Node: Reading multiple CSV files, Next: Valid transactions, Prev: File Extension, Up: Tips + +12.3.4 Reading multiple CSV files +--------------------------------- + +If you use multiple '-f' options to read multiple CSV files at once, +hledger will look for a correspondingly-named rules file for each CSV +file. But if you use the '--rules-file' option, that rules file will be +used for all the CSV files. + + +File: hledger.info, Node: Valid transactions, Next: Deduplicating importing, Prev: Reading multiple CSV files, Up: Tips + +12.3.5 Valid transactions +------------------------- + +After reading a CSV file, hledger post-processes and validates the +generated journal entries as it would for a journal file - balancing +them, applying balance assignments, and canonicalising amount styles. +Any errors at this stage will be reported in the usual way, displaying +the problem entry. + + There is one exception: balance assertions, if you have generated +them, will not be checked, since normally these will work only when the +CSV data is part of the main journal. If you do need to check balance +assertions generated from CSV right away, pipe into another hledger: + +$ hledger -f file.csv print | hledger -f- print + + +File: hledger.info, Node: Deduplicating importing, Next: Setting amounts, Prev: Valid transactions, Up: Tips + +12.3.6 Deduplicating, importing +------------------------------- + +When you download a CSV file periodically, eg to get your latest bank +transactions, the new file may overlap with the old one, containing some +of the same records. + + The import command will (a) detect the new transactions, and (b) +append just those transactions to your main journal. It is idempotent, +so you don't have to remember how many times you ran it or with which +version of the CSV. (It keeps state in a hidden '.latest.FILE.csv' +file.) This is the easiest way to import CSV data. Eg: + +# download the latest CSV files, then run this command. +# Note, no -f flags needed here. +$ hledger import *.csv [--dry] + + This method works for most CSV files. (Where records have a stable +chronological order, and new records appear only at the new end.) + + A number of other tools and workflows, hledger-specific and +otherwise, exist for converting, deduplicating, classifying and managing +CSV data. See: + + * https://hledger.org -> sidebar -> real world setups + * https://plaintextaccounting.org -> data import/conversion + + +File: hledger.info, Node: Setting amounts, Next: Setting currency/commodity, Prev: Deduplicating importing, Up: Tips + +12.3.7 Setting amounts +---------------------- + +A posting amount can be set in one of these ways: + + * by assigning (with a fields list or field assignment) to 'amountN' + (posting N's amount) or 'amount' (posting 1's amount) + + * by assigning to 'amountN-in' and 'amountN-out' (or 'amount-in' and + 'amount-out'). For each CSV record, whichever of these has a + non-zero value will be used, with appropriate sign. If both + contain a non-zero value, this may not work. + + * by assigning to 'balanceN' (or 'balance') instead of the above, + setting the amount indirectly via a balance assignment. If you do + this the default account name may be wrong, so you should set that + explicitly. + + There is some special handling for an amount's sign: + + * If an amount value is parenthesised, it will be de-parenthesised + and sign-flipped. + * If an amount value begins with a double minus sign, those cancel + out and are removed. + * If an amount value begins with a plus sign, that will be removed + + +File: hledger.info, Node: Setting currency/commodity, Next: Referencing other fields, Prev: Setting amounts, Up: Tips + +12.3.8 Setting currency/commodity +--------------------------------- + +If the currency/commodity symbol is included in the CSV's amount +field(s): + +2020-01-01,foo,$123.00 + + you don't have to do anything special for the commodity symbol, it +will be assigned as part of the amount. Eg: + +fields date,description,amount + +2020-01-01 foo + expenses:unknown $123.00 + income:unknown $-123.00 + + If the currency is provided as a separate CSV field: + +2020-01-01,foo,USD,123.00 + + You can assign that to the 'currency' pseudo-field, which has the +special effect of prepending itself to every amount in the transaction +(on the left, with no separating space): + +fields date,description,currency,amount + +2020-01-01 foo + expenses:unknown USD123.00 + income:unknown USD-123.00 + + Or, you can use a field assignment to construct the amount yourself, +with more control. Eg to put the symbol on the right, and separated by +a space: + +fields date,description,cur,amt +amount %amt %cur + +2020-01-01 foo + expenses:unknown 123.00 USD + income:unknown -123.00 USD + + Note we used a temporary field name ('cur') that is not 'currency' - +that would trigger the prepending effect, which we don't want here. + + +File: hledger.info, Node: Referencing other fields, Next: How CSV rules are evaluated, Prev: Setting currency/commodity, Up: Tips + +12.3.9 Referencing other fields +------------------------------- + +In field assignments, you can interpolate only CSV fields, not hledger +fields. In the example below, there's both a CSV field and a hledger +field named amount1, but %amount1 always means the CSV field, not the +hledger field: + +# Name the third CSV field "amount1" +fields date,description,amount1 + +# Set hledger's amount1 to the CSV amount1 field followed by USD +amount1 %amount1 USD + +# Set comment to the CSV amount1 (not the amount1 assigned above) +comment %amount1 + + Here, since there's no CSV amount1 field, %amount1 will produce a +literal "amount1": + +fields date,description,csvamount +amount1 %csvamount USD +# Can't interpolate amount1 here +comment %amount1 + + When there are multiple field assignments to the same hledger field, +only the last one takes effect. Here, comment's value will be be B, or +C if "something" is matched, but never A: + +comment A +comment B +if something + comment C + + +File: hledger.info, Node: How CSV rules are evaluated, Prev: Referencing other fields, Up: Tips + +12.3.10 How CSV rules are evaluated +----------------------------------- + +Here's how to think of CSV rules being evaluated (if you really need +to). First, + + * 'include' - all includes are inlined, from top to bottom, depth + first. (At each include point the file is inlined and scanned for + further includes, recursively, before proceeding.) + + Then "global" rules are evaluated, top to bottom. If a rule is +repeated, the last one wins: + + * 'skip' (at top level) + * 'date-format' + * 'newest-first' + * 'fields' - names the CSV fields, optionally sets up initial + assignments to hledger fields + + Then for each CSV record in turn: + + * test all 'if' blocks. If any of them contain a 'end' rule, skip + all remaining CSV records. Otherwise if any of them contain a + 'skip' rule, skip that many CSV records. If there are multiple + matched 'skip' rules, the first one wins. + * collect all field assignments at top level and in matched 'if' + blocks. When there are multiple assignments for a field, keep only + the last one. + * compute a value for each hledger field - either the one that was + assigned to it (and interpolate the %CSVFIELDNAME references), or a + default + * generate a synthetic hledger transaction from these values. + + This is all part of the CSV reader, one of several readers hledger +can use to parse input files. When all files have been read +successfully, the transactions are passed as input to whichever hledger +command the user specified. + + +File: hledger.info, Node: TIMECLOCK FORMAT, Next: TIMEDOT FORMAT, Prev: CSV FORMAT, Up: Top + +13 TIMECLOCK FORMAT +******************* + +The time logging format of timeclock.el, as read by hledger. + + hledger can read time logs in timeclock format. As with Ledger, +these are (a subset of) timeclock.el's format, containing clock-in and +clock-out entries as in the example below. The date is a simple date. +The time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are +optional. The timezone, if present, must be four digits and is ignored +(currently the time is always interpreted as a local time). + +i 2015/03/30 09:00:00 some:account name optional description after two spaces +o 2015/03/30 09:20:00 +i 2015/03/31 22:21:45 another account +o 2015/04/01 02:00:34 + + hledger treats each clock-in/clock-out pair as a transaction posting +some number of hours to an account. Or if the session spans more than +one day, it is split into several transactions, one for each day. For +the above time log, 'hledger print' generates these journal entries: + +$ hledger -f t.timeclock print +2015-03-30 * optional description after two spaces + (some:account name) 0.33h + +2015-03-31 * 22:21-23:59 + (another account) 1.64h + +2015-04-01 * 00:00-02:00 + (another account) 2.01h + + Here is a sample.timeclock to download and some queries to try: + +$ hledger -f sample.timeclock balance # current time balances +$ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009 +$ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week + + To generate time logs, ie to clock in and clock out, you could: + + * use emacs and the built-in timeclock.el, or the extended + timeclock-x.el and perhaps the extras in ledgerutils.el + + * at the command line, use these bash aliases: 'shell alias ti="echo + i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o + `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG"' + + * or use the old 'ti' and 'to' scripts in the ledger 2.x repository. + These rely on a "timeclock" executable which I think is just the + ledger 2 executable renamed. + + +File: hledger.info, Node: TIMEDOT FORMAT, Next: COMMON TASKS, Prev: TIMECLOCK FORMAT, Up: Top + +14 TIMEDOT FORMAT +***************** + +hledger's human-friendly time logging format. + + Timedot is a plain text format for logging dated, categorised +quantities (of time, usually), supported by hledger. It is convenient +for approximate and retroactive time logging, eg when the real-time +clock-in/out required with a timeclock file is too precise or too +interruptive. It can be formatted like a bar chart, making clear at a +glance where time was spent. + + Though called "timedot", this format is read by hledger as +commodityless quantities, so it could be used to represent dated +quantities other than time. In the docs below we'll assume it's time. + + A timedot file contains a series of day entries. A day entry begins +with a non-indented hledger-style simple date (Y-M-D, Y/M/D, Y.M.D..) +Any additional text on the same line is used as a transaction +description for this day. + + This is followed by optionally-indented timelog items for that day, +one per line. Each timelog item is a note, usually a +hledger:style:account:name representing a time category, followed by two +or more spaces, and a quantity. Each timelog item generates a hledger +transaction. + + Quantities can be written as: + + * dots: a sequence of dots (.) representing quarter hours. Spaces + may optionally be used for grouping. Eg: .... .. + + * an integral or decimal number, representing hours. Eg: 1.5 + + * an integral or decimal number immediately followed by a unit symbol + 's', 'm', 'h', 'd', 'w', 'mo', or 'y', representing seconds, + minutes, hours, days weeks, months or years respectively. Eg: 90m. + The following equivalencies are assumed, currently: 1m = 60s, 1h = + 60m, 1d = 24h, 1w = 7d, 1mo = 30d, 1y=365d. + + There is some flexibility allowing notes and todo lists to be kept +right in the time log, if needed: + + * Blank lines and lines beginning with '#' or ';' are ignored. + + * Lines not ending with a double-space and quantity are parsed as + items taking no time, which will not appear in balance reports by + default. (Add -E to see them.) + + * Org mode headlines (lines beginning with one or more '*' followed + by a space) can be used as date lines or timelog items (the stars + are ignored). Also all org headlines before the first date line + are ignored. This means org users can manage their timelog as an + org outline (eg using org-mode/orgstruct-mode in Emacs), for + organisation, faster navigation, controlling visibility etc. + + Examples: + +# on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc. +2016/2/1 +inc:client1 .... .... .... .... .... .... +fos:haskell .... .. +biz:research . + +2016/2/2 +inc:client1 .... .... +biz:research . + +2016/2/3 +inc:client1 4 +fos:hledger 3 +biz:research 1 + +* Time log +** 2020-01-01 +*** adm:time . +*** adm:finance . + +* 2020 Work Diary +** Q1 +*** 2020-02-29 +**** DONE +0700 yoga +**** UNPLANNED +**** BEGUN +hom:chores + cleaning ... + water plants + outdoor - one full watering can + indoor - light watering +**** TODO +adm:planning: trip +*** LATER + + Reporting: + +$ hledger -f t.timedot print date:2016/2/2 +2016-02-02 * + (inc:client1) 2.00 + +2016-02-02 * + (biz:research) 0.25 + +$ hledger -f t.timedot bal --daily --tree +Balance changes in 2016-02-01-2016-02-03: + + || 2016-02-01d 2016-02-02d 2016-02-03d +============++======================================== + biz || 0.25 0.25 1.00 + research || 0.25 0.25 1.00 + fos || 1.50 0 3.00 + haskell || 1.50 0 0 + hledger || 0 0 3.00 + inc || 6.00 2.00 4.00 + client1 || 6.00 2.00 4.00 +------------++---------------------------------------- + || 7.75 2.25 8.00 + + I prefer to use period for separating account components. We can +make this work with an account alias: + +2016/2/4 +fos.hledger.timedot 4 +fos.ledger .. + +$ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree + 4.50 fos + 4.00 hledger:timedot + 0.50 ledger +-------------------- + 4.50 + + Here is a sample.timedot. + + +File: hledger.info, Node: COMMON TASKS, Next: LIMITATIONS, Prev: TIMEDOT FORMAT, Up: Top + +15 COMMON TASKS *************** Here are some quick examples of how to do some basic tasks with hledger. @@ -4007,7 +7344,7 @@ https://hledger.org.  File: hledger.info, Node: Getting help, Next: Constructing command lines, Up: COMMON TASKS -10.1 Getting help +15.1 Getting help ================= $ hledger # show available commands @@ -4024,7 +7361,7 @@ https://hledger.org#help-feedback  File: hledger.info, Node: Constructing command lines, Next: Starting a journal file, Prev: Getting help, Up: COMMON TASKS -10.2 Constructing command lines +15.2 Constructing command lines =============================== hledger has an extensive and powerful command line interface. We strive @@ -4044,7 +7381,7 @@ happens, here are some tips that may help:  File: hledger.info, Node: Starting a journal file, Next: Setting opening balances, Prev: Constructing command lines, Up: COMMON TASKS -10.3 Starting a journal file +15.3 Starting a journal file ============================ hledger looks for your accounting data in a journal file, @@ -4083,7 +7420,7 @@ Market prices : 0 ()  File: hledger.info, Node: Setting opening balances, Next: Recording transactions, Prev: Starting a journal file, Up: COMMON TASKS -10.4 Setting opening balances +15.4 Setting opening balances ============================= Pick a starting date for which you can look up the balances of some @@ -4166,7 +7503,7 @@ $ git commit -m 'initial balances' 2020.journal  File: hledger.info, Node: Recording transactions, Next: Reconciling, Prev: Setting opening balances, Up: COMMON TASKS -10.5 Recording transactions +15.5 Recording transactions =========================== As you spend or receive money, you can record these transactions using @@ -4192,7 +7529,7 @@ and hledger.org for more ideas:  File: hledger.info, Node: Reconciling, Next: Reporting, Prev: Recording transactions, Up: COMMON TASKS -10.6 Reconciling +15.6 Reconciling ================ Periodically you should reconcile - compare your hledger-reported @@ -4247,7 +7584,7 @@ $ git commit -m 'txns' 2020.journal  File: hledger.info, Node: Reporting, Next: Migrating to a new file, Prev: Reconciling, Up: COMMON TASKS -10.7 Reporting +15.7 Reporting ============== Here are some basic reports. @@ -4395,7 +7732,7 @@ $ hledger activity -W  File: hledger.info, Node: Migrating to a new file, Prev: Reporting, Up: COMMON TASKS -10.8 Migrating to a new file +15.8 Migrating to a new file ============================ At the end of the year, you may want to continue your journal in a new @@ -4406,42 +7743,9 @@ close command. If using version control, don't forget to 'git add' the new file.  -File: hledger.info, Node: ENVIRONMENT, Next: LIMITATIONS, Prev: COMMON TASKS, Up: Top +File: hledger.info, Node: LIMITATIONS, Next: TROUBLESHOOTING, Prev: COMMON TASKS, Up: Top -11 ENVIRONMENT -************** - -*LEDGER_FILE* The journal file path when not specified with '-f'. -Default: '~/.hledger.journal' (on windows, perhaps -'C:/Users/USER/.hledger.journal'). - - A typical value is '~/DIR/YYYY.journal', where DIR is a -version-controlled finance directory and YYYY is the current year. Or -'~/DIR/current.journal', where current.journal is a symbolic link to -YYYY.journal. - - On Mac computers, you can set this and other environment variables in -a more thorough way that also affects applications started from the GUI -(say, an Emacs dock icon). Eg on MacOS Catalina I have a -'~/.MacOSX/environment.plist' file containing - -{ - "LEDGER_FILE" : "~/finance/current.journal" -} - - To see the effect you may need to 'killall Dock', or reboot. - - *COLUMNS* The screen width used by the register command. Default: -the full terminal width. - - *NO_COLOR* If this variable exists with any value, hledger will not -use ANSI color codes in terminal output. This overrides the --color/-colour option. - - -File: hledger.info, Node: LIMITATIONS, Next: TROUBLESHOOTING, Prev: ENVIRONMENT, Up: Top - -12 LIMITATIONS +16 LIMITATIONS ************** The need to precede add-on command options with '--' when invoked from @@ -4469,7 +7773,7 @@ Ledger.  File: hledger.info, Node: TROUBLESHOOTING, Prev: LIMITATIONS, Up: Top -13 TROUBLESHOOTING +17 TROUBLESHOOTING ****************** Here are some issues you might encounter when you run hledger (and @@ -4542,215 +7846,425 @@ $ LANG=en_US.UTF-8 hledger -f my.journal print  Tag Table: Node: Top68 -Node: OPTIONS2414 -Ref: #options2514 -Node: General options2656 -Ref: #general-options2781 -Node: Command options6182 -Ref: #command-options6333 -Node: Command arguments6733 -Ref: #command-arguments6891 -Node: Special characters7771 -Ref: #special-characters7934 -Node: Single escaping shell metacharacters8097 -Ref: #single-escaping-shell-metacharacters8338 -Node: Double escaping regular expression metacharacters8739 -Ref: #double-escaping-regular-expression-metacharacters9050 -Node: Triple escaping for add-on commands9576 -Ref: #triple-escaping-for-add-on-commands9836 -Node: Less escaping10480 -Ref: #less-escaping10634 -Node: Unicode characters10958 -Ref: #unicode-characters11123 -Node: Regular expressions12535 -Ref: #regular-expressions12675 -Node: DATA FILES14411 -Ref: #data-files14526 -Node: Data formats15065 -Ref: #data-formats15183 -Node: Multiple files16458 -Ref: #multiple-files16600 -Node: Strict mode17069 -Ref: #strict-mode17184 -Node: TIME PERIODS17832 -Ref: #time-periods17949 -Node: Smart dates18047 -Ref: #smart-dates18173 -Node: Report start & end date19499 -Ref: #report-start-end-date19674 -Node: Report intervals21207 -Ref: #report-intervals21375 -Node: Period expressions21765 -Ref: #period-expressions21905 -Node: DEPTH26348 -Ref: #depth26448 -Node: QUERIES26780 -Ref: #queries26881 -Node: VALUATION30843 -Ref: #valuation30951 -Node: -B Cost31640 -Ref: #b-cost31738 -Node: -V Value31871 -Ref: #v-value32011 -Node: -X Value in specified commodity32206 -Ref: #x-value-in-specified-commodity32399 -Node: Valuation date32548 -Ref: #valuation-date32710 -Node: Market prices33147 -Ref: #market-prices33321 -Node: --infer-value market prices from transactions34242 -Ref: #infer-value-market-prices-from-transactions34485 -Node: Valuation commodity35746 -Ref: #valuation-commodity35949 -Node: Simple valuation examples37154 -Ref: #simple-valuation-examples37350 -Node: --value Flexible valuation38009 -Ref: #value-flexible-valuation38211 -Node: More valuation examples40158 -Ref: #more-valuation-examples40361 -Node: Effect of valuation on reports42366 -Ref: #effect-of-valuation-on-reports42548 -Node: PIVOTING49567 -Ref: #pivoting49672 -Node: OUTPUT51348 -Ref: #output51448 -Node: Output destination51499 -Ref: #output-destination51630 -Node: Output format52055 -Ref: #output-format52176 -Node: COMMANDS54343 -Ref: #commands54451 -Node: accounts57836 -Ref: #accounts57934 -Node: activity58633 -Ref: #activity58743 -Node: add59126 -Ref: #add59227 -Node: aregister62020 -Ref: #aregister62132 -Node: aregister and custom posting dates63626 -Ref: #aregister-and-custom-posting-dates63790 -Node: balance64611 -Ref: #balance64728 -Node: Classic balance report66354 -Ref: #classic-balance-report66527 -Node: Customising the classic balance report67851 -Ref: #customising-the-classic-balance-report68079 -Node: Colour support70155 -Ref: #colour-support70322 -Node: Flat mode70418 -Ref: #flat-mode70566 -Node: Depth limited balance reports70979 -Ref: #depth-limited-balance-reports71164 -Node: Percentages71620 -Ref: #percentages71777 -Node: Sorting by amount72914 -Ref: #sorting-by-amount73080 -Node: Multicolumn balance report73574 -Ref: #multicolumn-balance-report73760 -Node: Budget report79357 -Ref: #budget-report79491 -Node: Budget report start date84780 -Ref: #budget-report-start-date84945 -Node: Nested budgets86277 -Ref: #nested-budgets86422 -Node: balancesheet89862 -Ref: #balancesheet89998 -Node: balancesheetequity91635 -Ref: #balancesheetequity91784 -Node: cashflow93003 -Ref: #cashflow93125 -Node: check94459 -Ref: #check94562 -Node: Basic checks95167 -Ref: #basic-checks95283 -Node: Strict checks95776 -Ref: #strict-checks95915 -Node: Other checks96158 -Ref: #other-checks96296 -Node: Add-on checks96594 -Ref: #add-on-checks96712 -Node: close97165 -Ref: #close97267 -Node: close usage98789 -Ref: #close-usage98882 -Node: codes101695 -Ref: #codes101803 -Node: commodities102515 -Ref: #commodities102642 -Node: descriptions102724 -Ref: #descriptions102852 -Node: diff103156 -Ref: #diff103262 -Node: files104309 -Ref: #files104409 -Node: help104556 -Ref: #help104656 -Node: import105737 -Ref: #import105851 -Node: Importing balance assignments106773 -Ref: #importing-balance-assignments106954 -Node: Commodity display styles107603 -Ref: #commodity-display-styles107774 -Node: incomestatement107903 -Ref: #incomestatement108036 -Node: notes109498 -Ref: #notes109611 -Node: payees109979 -Ref: #payees110085 -Node: prices110505 -Ref: #prices110611 -Node: print110952 -Ref: #print111062 -Node: print-unique115858 -Ref: #print-unique115984 -Node: register116269 -Ref: #register116396 -Node: Custom register output120845 -Ref: #custom-register-output120974 -Node: register-match122311 -Ref: #register-match122445 -Node: rewrite122796 -Ref: #rewrite122911 -Node: Re-write rules in a file124817 -Ref: #re-write-rules-in-a-file124978 -Node: Diff output format126127 -Ref: #diff-output-format126308 -Node: rewrite vs print --auto127400 -Ref: #rewrite-vs.-print---auto127558 -Node: roi128114 -Ref: #roi128212 -Node: stats140422 -Ref: #stats140521 -Node: tags141309 -Ref: #tags141407 -Node: test141926 -Ref: #test142040 -Node: About add-on commands142787 -Ref: #about-add-on-commands142922 -Node: COMMON TASKS144196 -Ref: #common-tasks144319 -Node: Getting help144726 -Ref: #getting-help144860 -Node: Constructing command lines145413 -Ref: #constructing-command-lines145607 -Node: Starting a journal file146304 -Ref: #starting-a-journal-file146504 -Node: Setting opening balances147692 -Ref: #setting-opening-balances147890 -Node: Recording transactions151031 -Ref: #recording-transactions151213 -Node: Reconciling151769 -Ref: #reconciling151914 -Node: Reporting154171 -Ref: #reporting154313 -Node: Migrating to a new file158312 -Ref: #migrating-to-a-new-file158462 -Node: ENVIRONMENT158761 -Ref: #environment158885 -Node: LIMITATIONS159870 -Ref: #limitations159997 -Node: TROUBLESHOOTING160740 -Ref: #troubleshooting160855 +Node: OPTIONS2488 +Ref: #options2589 +Node: General options2731 +Ref: #general-options2856 +Node: Command options6257 +Ref: #command-options6408 +Node: Command arguments6808 +Ref: #command-arguments6966 +Node: Special characters7846 +Ref: #special-characters8009 +Node: Single escaping shell metacharacters8172 +Ref: #single-escaping-shell-metacharacters8413 +Node: Double escaping regular expression metacharacters8814 +Ref: #double-escaping-regular-expression-metacharacters9125 +Node: Triple escaping for add-on commands9651 +Ref: #triple-escaping-for-add-on-commands9911 +Node: Less escaping10555 +Ref: #less-escaping10709 +Node: Unicode characters11033 +Ref: #unicode-characters11198 +Node: Regular expressions12610 +Ref: #regular-expressions12750 +Node: ENVIRONMENT14486 +Ref: #environment14602 +Node: DATA FILES15587 +Ref: #data-files15706 +Node: Data formats16245 +Ref: #data-formats16363 +Node: Multiple files17700 +Ref: #multiple-files17842 +Node: Strict mode18311 +Ref: #strict-mode18426 +Node: TIME PERIODS19074 +Ref: #time-periods19191 +Node: Smart dates19289 +Ref: #smart-dates19415 +Node: Report start & end date20741 +Ref: #report-start-end-date20916 +Node: Report intervals22449 +Ref: #report-intervals22617 +Node: Period expressions23007 +Ref: #period-expressions23147 +Node: DEPTH27590 +Ref: #depth27690 +Node: QUERIES28022 +Ref: #queries28123 +Node: VALUATION32085 +Ref: #valuation32193 +Node: -B Cost32882 +Ref: #b-cost32980 +Node: -V Value33113 +Ref: #v-value33253 +Node: -X Value in specified commodity33448 +Ref: #x-value-in-specified-commodity33641 +Node: Valuation date33790 +Ref: #valuation-date33952 +Node: Market prices34389 +Ref: #market-prices34563 +Node: --infer-value market prices from transactions35484 +Ref: #infer-value-market-prices-from-transactions35727 +Node: Valuation commodity36988 +Ref: #valuation-commodity37191 +Node: Simple valuation examples38396 +Ref: #simple-valuation-examples38592 +Node: --value Flexible valuation39251 +Ref: #value-flexible-valuation39453 +Node: More valuation examples41400 +Ref: #more-valuation-examples41603 +Node: Effect of valuation on reports43608 +Ref: #effect-of-valuation-on-reports43790 +Node: PIVOTING50809 +Ref: #pivoting50914 +Node: OUTPUT52590 +Ref: #output52690 +Node: Output destination52741 +Ref: #output-destination52872 +Node: Output format53297 +Ref: #output-format53418 +Node: COMMANDS55585 +Ref: #commands55697 +Node: accounts59062 +Ref: #accounts59162 +Node: activity59861 +Ref: #activity59973 +Node: add60356 +Ref: #add60459 +Node: aregister63252 +Ref: #aregister63366 +Node: aregister and custom posting dates64860 +Ref: #aregister-and-custom-posting-dates65026 +Node: balance65847 +Ref: #balance65966 +Node: Classic balance report67592 +Ref: #classic-balance-report67767 +Node: Customising the classic balance report69091 +Ref: #customising-the-classic-balance-report69321 +Node: Colour support71397 +Ref: #colour-support71566 +Node: Flat mode71662 +Ref: #flat-mode71812 +Node: Depth limited balance reports72225 +Ref: #depth-limited-balance-reports72412 +Node: Percentages72868 +Ref: #percentages73027 +Node: Sorting by amount74164 +Ref: #sorting-by-amount74332 +Node: Multicolumn balance report74826 +Ref: #multicolumn-balance-report75014 +Node: Budget report80611 +Ref: #budget-report80747 +Node: Budget report start date86036 +Ref: #budget-report-start-date86203 +Node: Nested budgets87535 +Ref: #nested-budgets87682 +Node: balancesheet91122 +Ref: #balancesheet91260 +Node: balancesheetequity92897 +Ref: #balancesheetequity93048 +Node: cashflow94267 +Ref: #cashflow94391 +Node: check95725 +Ref: #check95830 +Node: Basic checks96435 +Ref: #basic-checks96553 +Node: Strict checks97046 +Ref: #strict-checks97187 +Node: Other checks97430 +Ref: #other-checks97570 +Node: Add-on checks97868 +Ref: #add-on-checks97988 +Node: close98441 +Ref: #close98545 +Node: close usage100067 +Ref: #close-usage100162 +Node: codes102975 +Ref: #codes103085 +Node: commodities103797 +Ref: #commodities103926 +Node: descriptions104008 +Ref: #descriptions104138 +Node: diff104442 +Ref: #diff104550 +Node: files105597 +Ref: #files105699 +Node: help105846 +Ref: #help105948 +Node: import106999 +Ref: #import107115 +Node: Importing balance assignments108037 +Ref: #importing-balance-assignments108220 +Node: Commodity display styles108869 +Ref: #commodity-display-styles109042 +Node: incomestatement109171 +Ref: #incomestatement109306 +Node: notes110768 +Ref: #notes110883 +Node: payees111251 +Ref: #payees111359 +Node: prices111779 +Ref: #prices111887 +Node: print112228 +Ref: #print112340 +Node: print-unique117136 +Ref: #print-unique117264 +Node: register117549 +Ref: #register117678 +Node: Custom register output122127 +Ref: #custom-register-output122258 +Node: register-match123595 +Ref: #register-match123731 +Node: rewrite124082 +Ref: #rewrite124199 +Node: Re-write rules in a file126105 +Ref: #re-write-rules-in-a-file126268 +Node: Diff output format127417 +Ref: #diff-output-format127600 +Node: rewrite vs print --auto128692 +Ref: #rewrite-vs.-print---auto128852 +Node: roi129408 +Ref: #roi129508 +Node: stats141718 +Ref: #stats141819 +Node: tags142607 +Ref: #tags142707 +Node: test143226 +Ref: #test143342 +Node: About add-on commands144089 +Ref: #about-add-on-commands144226 +Node: JOURNAL FORMAT145500 +Ref: #journal-format145628 +Node: Transactions147794 +Ref: #transactions147909 +Node: Dates148923 +Ref: #dates149039 +Node: Simple dates149104 +Ref: #simple-dates149224 +Node: Secondary dates149733 +Ref: #secondary-dates149881 +Node: Posting dates151217 +Ref: #posting-dates151340 +Node: Status152712 +Ref: #status152829 +Node: Description154537 +Ref: #description154667 +Node: Payee and note154987 +Ref: #payee-and-note155095 +Node: Comments155430 +Ref: #comments155552 +Node: Tags156746 +Ref: #tags-1156857 +Node: Postings158250 +Ref: #postings158374 +Node: Virtual postings159400 +Ref: #virtual-postings159511 +Node: Account names160816 +Ref: #account-names160953 +Node: Amounts161440 +Ref: #amounts161575 +Node: Digit group marks162699 +Ref: #digit-group-marks162844 +Node: Commodity display style163782 +Ref: #commodity-display-style163956 +Node: Rounding165669 +Ref: #rounding165787 +Node: Transaction prices166199 +Ref: #transaction-prices166365 +Node: Lot prices lot dates168796 +Ref: #lot-prices-lot-dates168979 +Node: Balance assertions169467 +Ref: #balance-assertions169645 +Node: Assertions and ordering170678 +Ref: #assertions-and-ordering170860 +Node: Assertions and included files171560 +Ref: #assertions-and-included-files171797 +Node: Assertions and multiple -f options172130 +Ref: #assertions-and-multiple--f-options172380 +Node: Assertions and commodities172512 +Ref: #assertions-and-commodities172738 +Node: Assertions and prices173895 +Ref: #assertions-and-prices174103 +Node: Assertions and subaccounts174543 +Ref: #assertions-and-subaccounts174766 +Node: Assertions and virtual postings175090 +Ref: #assertions-and-virtual-postings175326 +Node: Assertions and precision175468 +Ref: #assertions-and-precision175655 +Node: Balance assignments175922 +Ref: #balance-assignments176092 +Node: Balance assignments and prices177256 +Ref: #balance-assignments-and-prices177422 +Node: Directives177646 +Ref: #directives177809 +Node: Directives and multiple files183052 +Ref: #directives-and-multiple-files183248 +Node: Comment blocks183912 +Ref: #comment-blocks184089 +Node: Including other files184265 +Ref: #including-other-files184439 +Node: Default year185363 +Ref: #default-year185526 +Node: Declaring commodities185933 +Ref: #declaring-commodities186110 +Node: Commodity error checking187954 +Ref: #commodity-error-checking188104 +Node: Default commodity188361 +Ref: #default-commodity188541 +Node: Declaring market prices189430 +Ref: #declaring-market-prices189619 +Node: Declaring accounts190476 +Ref: #declaring-accounts190656 +Node: Account error checking191858 +Ref: #account-error-checking192024 +Node: Account comments193203 +Ref: #account-comments193387 +Node: Account subdirectives193811 +Ref: #account-subdirectives193996 +Node: Account types194309 +Ref: #account-types194483 +Node: Declaring account types195219 +Ref: #declaring-account-types195398 +Node: Auto-detected account types196048 +Ref: #auto-detected-account-types196289 +Node: Interference from auto-detected account types197186 +Ref: #interference-from-auto-detected-account-types197463 +Node: Old account type syntax197946 +Ref: #old-account-type-syntax198143 +Node: Account display order198443 +Ref: #account-display-order198603 +Node: Rewriting accounts199754 +Ref: #rewriting-accounts199933 +Node: Basic aliases200690 +Ref: #basic-aliases200826 +Node: Regex aliases201530 +Ref: #regex-aliases201692 +Node: Combining aliases202411 +Ref: #combining-aliases202594 +Node: Aliases and multiple files203870 +Ref: #aliases-and-multiple-files204069 +Node: end aliases204648 +Ref: #end-aliases204795 +Node: Default parent account204896 +Ref: #default-parent-account205086 +Node: Periodic transactions205970 +Ref: #periodic-transactions206153 +Node: Periodic rule syntax208070 +Ref: #periodic-rule-syntax208270 +Node: Two spaces between period expression and description!208974 +Ref: #two-spaces-between-period-expression-and-description209287 +Node: Forecasting with periodic transactions209971 +Ref: #forecasting-with-periodic-transactions210270 +Node: Budgeting with periodic transactions212325 +Ref: #budgeting-with-periodic-transactions212558 +Node: Auto postings212967 +Ref: #auto-postings213103 +Node: Auto postings and multiple files215282 +Ref: #auto-postings-and-multiple-files215480 +Node: Auto postings and dates215689 +Ref: #auto-postings-and-dates215957 +Node: Auto postings and transaction balancing / inferred amounts / balance assertions216132 +Ref: #auto-postings-and-transaction-balancing-inferred-amounts-balance-assertions216477 +Node: Auto posting tags216819 +Ref: #auto-posting-tags217028 +Node: CSV FORMAT217664 +Ref: #csv-format217792 +Node: Examples220378 +Ref: #examples220481 +Node: Basic220689 +Ref: #basic220791 +Node: Bank of Ireland221333 +Ref: #bank-of-ireland221470 +Node: Amazon222932 +Ref: #amazon223052 +Node: Paypal224771 +Ref: #paypal224867 +Node: CSV rules232511 +Ref: #csv-rules232629 +Node: skip232941 +Ref: #skip233036 +Node: fields233411 +Ref: #fields233535 +Node: Transaction field names234700 +Ref: #transaction-field-names234862 +Node: Posting field names234973 +Ref: #posting-field-names235127 +Node: field assignment237497 +Ref: #field-assignment237642 +Node: separator238460 +Ref: #separator238597 +Node: if block239137 +Ref: #if-block239264 +Node: Matching the whole record239665 +Ref: #matching-the-whole-record239842 +Node: Matching individual fields240646 +Ref: #matching-individual-fields240852 +Node: Combining matchers241076 +Ref: #combining-matchers241274 +Node: Rules applied on successful match241587 +Ref: #rules-applied-on-successful-match241780 +Node: if table242434 +Ref: #if-table242555 +Node: end244293 +Ref: #end244407 +Node: date-format244631 +Ref: #date-format244765 +Node: decimal-mark245514 +Ref: #decimal-mark245659 +Node: newest-first245998 +Ref: #newest-first246141 +Node: include246824 +Ref: #include246957 +Node: balance-type247401 +Ref: #balance-type247523 +Node: Tips248223 +Ref: #tips248314 +Node: Rapid feedback248570 +Ref: #rapid-feedback248689 +Node: Valid CSV249149 +Ref: #valid-csv249281 +Node: File Extension249473 +Ref: #file-extension249627 +Node: Reading multiple CSV files250056 +Ref: #reading-multiple-csv-files250243 +Node: Valid transactions250484 +Ref: #valid-transactions250664 +Node: Deduplicating importing251292 +Ref: #deduplicating-importing251473 +Node: Setting amounts252506 +Ref: #setting-amounts252677 +Node: Setting currency/commodity253664 +Ref: #setting-currencycommodity253858 +Node: Referencing other fields255032 +Ref: #referencing-other-fields255234 +Node: How CSV rules are evaluated256131 +Ref: #how-csv-rules-are-evaluated256306 +Node: TIMECLOCK FORMAT257757 +Ref: #timeclock-format257897 +Node: TIMEDOT FORMAT259958 +Ref: #timedot-format260096 +Node: COMMON TASKS264372 +Ref: #common-tasks264501 +Node: Getting help264908 +Ref: #getting-help265042 +Node: Constructing command lines265595 +Ref: #constructing-command-lines265789 +Node: Starting a journal file266486 +Ref: #starting-a-journal-file266686 +Node: Setting opening balances267874 +Ref: #setting-opening-balances268072 +Node: Recording transactions271213 +Ref: #recording-transactions271395 +Node: Reconciling271951 +Ref: #reconciling272096 +Node: Reporting274353 +Ref: #reporting274495 +Node: Migrating to a new file278494 +Ref: #migrating-to-a-new-file278644 +Node: LIMITATIONS278943 +Ref: #limitations279071 +Node: TROUBLESHOOTING279814 +Ref: #troubleshooting279929  End Tag Table diff --git a/hledger/hledger.txt b/hledger/hledger.txt index ac6080ab6..9b4fa8bd7 100644 --- a/hledger/hledger.txt +++ b/hledger/hledger.txt @@ -379,6 +379,33 @@ OPTIONS ing to the shell and so must be escaped at least once more. See Spe- cial characters. +ENVIRONMENT + LEDGER_FILE The journal file path when not specified with -f. Default: + ~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour- + nal). + + A typical value is ~/DIR/YYYY.journal, where DIR is a version-con- + trolled finance directory and YYYY is the current year. Or ~/DIR/cur- + rent.journal, where current.journal is a symbolic link to YYYY.journal. + + On Mac computers, you can set this and other environment variables in a + more thorough way that also affects applications started from the GUI + (say, an Emacs dock icon). Eg on MacOS Catalina I have a ~/.MacOSX/en- + vironment.plist file containing + + { + "LEDGER_FILE" : "~/finance/current.journal" + } + + To see the effect you may need to killall Dock, or reboot. + + COLUMNS The screen width used by the register command. Default: the + full terminal width. + + NO_COLOR If this variable exists with any value, hledger will not use + ANSI color codes in terminal output. This overrides the + --color/--colour option. + DATA FILES hledger reads transactions from one or more data files. The default data file is $HOME/.hledger.journal (or on Windows, something like @@ -408,13 +435,13 @@ DATA FILES journals, for transactions .ledger time- timeclock files, for precise time log- .timeclock clock ging - - timedot timedot files, for approximate time .timedot logging csv comma/semicolon/tab/other-separated .csv .ssv .tsv values, for data import + These formats are described in their own sections, below. + hledger detects the format automatically based on the file extensions shown above. If it can't recognise the file extension, it assumes journal format. So for non-journal files, it's important to use a @@ -478,7 +505,6 @@ TIME PERIODS 2004.9.1 is 4+ digits, month is 1-12, day is 1-31 2004 start of year 2004/10 start of month - 10/1 month and day in current year 21 day in current month october, oct start of month in current year @@ -659,6 +685,7 @@ TIME PERIODS each month -p "every 11/05" yearly periods with boundaries on 5th of Nov -p "every 5th Nov" same + -p "every Nov 5th" same Show historical balances at end of 15th each month (N is exclusive end @@ -1104,8 +1131,6 @@ VALUATION signments register - - starting cost value at day not sup- value at day value at balance before report ported before report DATE/today (-H) or journal or journal @@ -1166,6 +1191,8 @@ VALUATION row aver- ages of dis- ages of dis- ported ages of dis- ages of dis- ages (-T, played values played values played values played values -A) + + column to- sums of dis- sums of dis- not sup- sums of dis- sums of dis- tals played values played values ported played values played values grand to- sum, average sum, average not sup- sum, average sum, average @@ -1365,12 +1392,12 @@ COMMANDS Miscellaneous reports: - o accounts (a) - show account names + o accounts - show account names o activity - show postings-per-interval bar charts - o balance (b, bal) - show balance changes/end balances/budgets in any - accounts + o balance (bal) - show balance changes/end balances/budgets in any ac- + counts o codes - show transaction codes @@ -1388,12 +1415,12 @@ COMMANDS o prices - show market price records - o print (p, txns) - show transactions (journal entries) + o print - show transactions (journal entries) o print-unique - show only transactions with unique descriptions - o register (r, reg) - show postings in one or more accounts & running - total + o register (reg) - show postings in one or more accounts & running to- + tal o register-match - show a recent posting that best matches a descrip- tion @@ -2554,7 +2581,7 @@ COMMANDS $ hledger help Please choose a manual by typing "hledger help MANUAL" (a substring is ok). - Manuals: hledger hledger-ui hledger-web journal csv timeclock timedot + Manuals: hledger hledger-ui hledger-web $ hledger help h --man @@ -3419,6 +3446,2667 @@ COMMANDS $ hledger-web --serve +JOURNAL FORMAT + hledger's default file format, representing a General Journal. + + hledger's usual data source is a plain text file containing journal en- + tries in hledger journal format. This file represents a standard ac- + counting general journal. I use file names ending in .journal, but + that's not required. The journal file contains a number of transaction + entries, each describing a transfer of money (or any commodity) between + two or more named accounts, in a simple format readable by both hledger + and humans. + + hledger's journal format is a compatible subset, mostly, of ledger's + journal format, so hledger can work with compatible ledger journal + files as well. It's safe, and encouraged, to run both hledger and + ledger on the same journal file, eg to validate the results you're get- + ting. + + You can use hledger without learning any more about this file; just use + the add or web or import commands to create and update it. + + Many users, though, edit the journal file with a text editor, and track + changes with a version control system such as git. Editor addons such + as ledger-mode or hledger-mode for Emacs, vim-ledger for Vim, and + hledger-vscode for Visual Studio Code, make this easier, adding colour, + formatting, tab completion, and useful commands. See Editor configura- + tion at hledger.org for the full list. + + Here's a description of each part of the file format (and hledger's + data model). These are mostly in the order you'll use them, but in + some cases related concepts have been grouped together for easy refer- + ence, or linked before they are introduced, so feel free to skip over + anything that looks unnecessary right now. + + Transactions + Transactions are the main unit of information in a journal file. They + represent events, typically a movement of some quantity of commodities + between two or more named accounts. + + Each transaction is recorded as a journal entry, beginning with a sim- + ple date in column 0. This can be followed by any of the following op- + tional fields, separated by spaces: + + o a status character (empty, !, or *) + + o a code (any short number or text, enclosed in parentheses) + + o a description (any remaining text until end of line or a semicolon) + + o a comment (any remaining text following a semicolon until end of + line, and any following indented lines beginning with a semicolon) + + o 0 or more indented posting lines, describing what was transferred and + the accounts involved (indented comment lines are also allowed, but + not blank lines or non-indented lines). + + Here's a simple journal file containing one transaction: + + 2008/01/01 income + assets:bank:checking $1 + income:salary $-1 + + Dates + Simple dates + Dates in the journal file use simple dates format: YYYY-MM-DD or + YYYY/MM/DD or YYYY.MM.DD, with leading zeros optional. The year may be + omitted, in which case it will be inferred from the context: the cur- + rent transaction, the default year set with a default year directive, + or the current date when the command is run. Some examples: + 2010-01-31, 2010/01/31, 2010.1.31, 1/31. + + (The UI also accepts simple dates, as well as the more flexible smart + dates documented in the hledger manual.) + + Secondary dates + Real-life transactions sometimes involve more than one date - eg the + date you write a cheque, and the date it clears in your bank. When you + want to model this, for more accurate daily balances, you can specify + individual posting dates. + + Or, you can use the older secondary date feature (Ledger calls it aux- + iliary date or effective date). Note: we support this for compatibil- + ity, but I usually recommend avoiding this feature; posting dates are + almost always clearer and simpler. + + A secondary date is written after the primary date, following an equals + sign. If the year is omitted, the primary date's year is assumed. + When running reports, the primary (left) date is used by default, but + with the --date2 flag (or --aux-date or --effective), the secondary + (right) date will be used instead. + + The meaning of secondary dates is up to you, but it's best to follow a + consistent rule. Eg "primary = the bank's clearing date, secondary = + date the transaction was initiated, if different", as shown here: + + 2010/2/23=2/19 movie ticket + expenses:cinema $10 + assets:checking + + $ hledger register checking + 2010-02-23 movie ticket assets:checking $-10 $-10 + + $ hledger register checking --date2 + 2010-02-19 movie ticket assets:checking $-10 $-10 + + Posting dates + You can give individual postings a different date from their parent + transaction, by adding a posting comment containing a tag (see below) + like date:DATE. This is probably the best way to control posting dates + precisely. Eg in this example the expense should appear in May re- + ports, and the deduction from checking should be reported on 6/1 for + easy bank reconciliation: + + 2015/5/30 + expenses:food $10 ; food purchased on saturday 5/30 + assets:checking ; bank cleared it on monday, date:6/1 + + $ hledger -f t.j register food + 2015-05-30 expenses:food $10 $10 + + $ hledger -f t.j register checking + 2015-06-01 assets:checking $-10 $-10 + + DATE should be a simple date; if the year is not specified it will use + the year of the transaction's date. You can set the secondary date + similarly, with date2:DATE2. The date: or date2: tags must have a + valid simple date value if they are present, eg a date: tag with no + value is not allowed. + + Ledger's earlier, more compact bracketed date syntax is also supported: + [DATE], [DATE=DATE2] or [=DATE2]. hledger will attempt to parse any + square-bracketed sequence of the 0123456789/-.= characters in this way. + With this syntax, DATE infers its year from the transaction and DATE2 + infers its year from DATE. + + Status + Transactions, or individual postings within a transaction, can have a + status mark, which is a single character before the transaction de- + scription or posting account name, separated from it by a space, indi- + cating one of three statuses: + + mark status + ------------------ + unmarked + ! pending + * cleared + + When reporting, you can filter by status with the -U/--unmarked, + -P/--pending, and -C/--cleared flags; or the status:, status:!, and + status:* queries; or the U, P, C keys in hledger-ui. + + Note, in Ledger and in older versions of hledger, the "unmarked" state + is called "uncleared". As of hledger 1.3 we have renamed it to un- + marked for clarity. + + To replicate Ledger and old hledger's behaviour of also matching pend- + ing, combine -U and -P. + + Status marks are optional, but can be helpful eg for reconciling with + real-world accounts. Some editor modes provide highlighting and short- + cuts for working with status. Eg in Emacs ledger-mode, you can toggle + transaction status with C-c C-e, or posting status with C-c C-c. + + What "uncleared", "pending", and "cleared" actually mean is up to you. + Here's one suggestion: + + status meaning + -------------------------------------------------------------------------- + uncleared recorded but not yet reconciled; needs review + pending tentatively reconciled (if needed, eg during a big reconcil- + iation) + cleared complete, reconciled as far as possible, and considered cor- + rect + + With this scheme, you would use -PC to see the current balance at your + bank, -U to see things which will probably hit your bank soon (like un- + cashed checks), and no flags to see the most up-to-date state of your + finances. + + Description + A transaction's description is the rest of the line following the date + and status mark (or until a comment begins). Sometimes called the + "narration" in traditional bookkeeping, it can be used for whatever you + wish, or left blank. Transaction descriptions can be queried, unlike + comments. + + Payee and note + You can optionally include a | (pipe) character in descriptions to sub- + divide the description into separate fields for payee/payer name on the + left (up to the first |) and an additional note field on the right (af- + ter the first |). This may be worthwhile if you need to do more pre- + cise querying and pivoting by payee or by note. + + Comments + Lines in the journal beginning with a semicolon (;) or hash (#) or star + (*) are comments, and will be ignored. (Star comments cause org-mode + nodes to be ignored, allowing emacs users to fold and navigate their + journals with org-mode or orgstruct-mode.) + + You can attach comments to a transaction by writing them after the de- + scription and/or indented on the following lines (before the postings). + Similarly, you can attach comments to an individual posting by writing + them after the amount and/or indented on the following lines. Transac- + tion and posting comments must begin with a semicolon (;). + + Some examples: + + # a file comment + ; another file comment + * also a file comment, useful in org/orgstruct mode + + comment + A multiline file comment, which continues + until a line containing just "end comment" + (or end of file). + end comment + + 2012/5/14 something ; a transaction comment + ; the transaction comment, continued + posting1 1 ; a comment for posting 1 + posting2 + ; a comment for posting 2 + ; another comment line for posting 2 + ; a file comment (because not indented) + + You can also comment larger regions of a file using comment and end + comment directives. + + Tags + Tags are a way to add extra labels or labelled data to postings and + transactions, which you can then search or pivot on. + + A simple tag is a word (which may contain hyphens) followed by a full + colon, written inside a transaction or posting comment line: + + 2017/1/16 bought groceries ; sometag: + + Tags can have a value, which is the text after the colon, up to the + next comma or end of line, with leading/trailing whitespace removed: + + expenses:food $10 ; a-posting-tag: the tag value + + Note this means hledger's tag values can not contain commas or new- + lines. Ending at commas means you can write multiple short tags on one + line, comma separated: + + assets:checking ; a comment containing tag1:, tag2: some value ... + + Here, + + o "a comment containing" is just comment text, not a tag + + o "tag1" is a tag with no value + + o "tag2" is another tag, whose value is "some value ..." + + Tags in a transaction comment affect the transaction and all of its + postings, while tags in a posting comment affect only that posting. + For example, the following transaction has three tags (A, TAG2, third- + tag) and the posting has four (those plus posting-tag): + + 1/1 a transaction ; A:, TAG2: + ; third-tag: a third transaction tag, <- with a value + (a) $1 ; posting-tag: + + Tags are like Ledger's metadata feature, except hledger's tag values + are simple strings. + + Postings + A posting is an addition of some amount to, or removal of some amount + from, an account. Each posting line begins with at least one space or + tab (2 or 4 spaces is common), followed by: + + o (optional) a status character (empty, !, or *), followed by a space + + o (required) an account name (any text, optionally containing single + spaces, until end of line or a double space) + + o (optional) two or more spaces or tabs followed by an amount. + + Positive amounts are being added to the account, negative amounts are + being removed. + + The amounts within a transaction must always sum up to zero. As a con- + venience, one amount may be left blank; it will be inferred so as to + balance the transaction. + + Be sure to note the unusual two-space delimiter between account name + and amount. This makes it easy to write account names containing spa- + ces. But if you accidentally leave only one space (or tab) before the + amount, the amount will be considered part of the account name. + + Virtual postings + A posting with a parenthesised account name is called a virtual posting + or unbalanced posting, which means it is exempt from the usual rule + that a transaction's postings must balance add up to zero. + + This is not part of double entry accounting, so you might choose to + avoid this feature. Or you can use it sparingly for certain special + cases where it can be convenient. Eg, you could set opening balances + without using a balancing equity account: + + 1/1 opening balances + (assets:checking) $1000 + (assets:savings) $2000 + + A posting with a bracketed account name is called a balanced virtual + posting. The balanced virtual postings in a transaction must add up to + zero (separately from other postings). Eg: + + 1/1 buy food with cash, update budget envelope subaccounts, & something else + assets:cash $-10 ; <- these balance + expenses:food $7 ; <- + expenses:food $3 ; <- + [assets:checking:budget:food] $-10 ; <- and these balance + [assets:checking:available] $10 ; <- + (something:else) $5 ; <- not required to balance + + Ordinary non-parenthesised, non-bracketed postings are called real + postings. You can exclude virtual postings from reports with the + -R/--real flag or real:1 query. + + Account names + Account names typically have several parts separated by a full colon, + from which hledger derives a hierarchical chart of accounts. They can + be anything you like, but in finance there are traditionally five top- + level accounts: assets, liabilities, income, expenses, and equity. + + Account names may contain single spaces, eg: assets:accounts receiv- + able. Because of this, they must always be followed by two or more + spaces (or newline). + + Account names can be aliased. + + Amounts + After the account name, there is usually an amount. (Important: be- + tween account name and amount, there must be two or more spaces.) + + hledger's amount format is flexible, supporting several international + formats. Here are some examples. Amounts have a number (the "quan- + tity"): + + 1 + + ..and usually a currency or commodity name (the "commodity"). This is + a symbol, word, or phrase, to the left or right of the quantity, with + or without a separating space: + + $1 + 4000 AAPL + + If the commodity name contains spaces, numbers, or punctuation, it must + be enclosed in double quotes: + + 3 "no. 42 green apples" + + Amounts can be preceded by a minus sign (or a plus sign, though plus is + the default), The sign can be written before or after a left-side com- + modity symbol: + + -$1 + $-1 + + One or more spaces between the sign and the number are acceptable when + parsing (but they won't be displayed in output): + + + $1 + $- 1 + + Scientific E notation is allowed: + + 1E-6 + EUR 1E3 + + A decimal mark can be written as a period or a comma: + + 1.23 + 1,23456780000009 + + Digit group marks + In the integer part of the quantity (left of the decimal mark), groups + of digits can optionally be separated by a "digit group mark" - a + space, comma, or period (different from the decimal mark): + + $1,000,000.00 + EUR 2.000.000,00 + INR 9,99,99,999.00 + 1 000 000.9455 + + Note, a number containing a single group mark and no decimal mark is + ambiguous. Are these group marks or decimal marks ? + + 1,000 + 1.000 + + hledger will treat them both as decimal marks by default (cf #793). If + you use digit group marks, to prevent confusion and undetected typos we + recommend you write commodity directives at the top of the file to ex- + plicitly declare the decimal mark (and optionally a digit group mark). + Note, these formats ("amount styles") are specific to each commodity, + so if your data uses multiple formats, hledger can handle it: + + commodity $1,000.00 + commodity EUR 1.000,00 + commodity INR 9,99,99,999.00 + commodity 1 000 000.9455 + + Commodity display style + For the amounts in each commodity, hledger chooses a consistent display + style. (Excluding price amounts, which are always displayed as writ- + ten). The display style is chosen as follows: + + o If there is a commodity directive (or default commodity directive) + for the commodity, its style is used (see examples above). + + o Otherwise the style is inferred from the amounts in that commodity + seen in the journal. + + o Or if there are no such amounts in the journal, a default style is + used (like $1000.00). + + A style is inferred from the journal amounts in a commodity as follows: + + o Use the general style (decimal mark, symbol placement) of the first + amount + + o Use the first-seen digit group style (digit group mark, digit group + sizes), if any + + o Use the maximum number of decimal places of all. + + Transaction price amounts don't affect the commodity display style di- + rectly, but occasionally they can do so indirectly (eg when a posting's + amount is inferred using a transaction price). If you find this caus- + ing problems, use a commodity directive to fix the display style. + + In summary, each commodity's amounts will be normalised to + + o the style declared by a commodity directive + + o or, the style of the first posting amount in the journal, with the + first-seen digit group style and the maximum-seen number of decimal + places. + + So if your reports are showing amounts in a way you don't like, eg with + too many decimal places, use a commodity directive to set the commod- + ity's display style. For example: + + # declare euro, dollar and bitcoin commodities and set their display styles: + commodity EUR 1.000, + commodity $1000.00 + commodity 1000.00000000 BTC + + Rounding + Amounts are stored internally as decimal numbers with up to 255 decimal + places, and displayed with the number of decimal places specified by + the commodity display style. Note, hledger uses banker's rounding: it + rounds to the nearest even number, eg 0.5 displayed with zero decimal + places is "0"). (Guaranteed since hledger 1.17.1; in older versions + this could vary if hledger was built with Decimal < 0.5.1.) + + Transaction prices + Within a transaction, you can note an amount's price in another commod- + ity. This can be used to document the cost (in a purchase) or selling + price (in a sale). For example, transaction prices are useful to + record purchases of a foreign currency. Note transaction prices are + fixed at the time of the transaction, and do not change over time. See + also market prices, which represent prevailing exchange rates on a cer- + tain date. + + There are several ways to record a transaction price: + + 1. Write the price per unit, as @ UNITPRICE after the amount: + + 2009/1/1 + assets:euros EUR100 @ $1.35 ; one hundred euros purchased at $1.35 each + assets:dollars ; balancing amount is -$135.00 + + 2. Write the total price, as @@ TOTALPRICE after the amount: + + 2009/1/1 + assets:euros EUR100 @@ $135 ; one hundred euros purchased at $135 for the lot + assets:dollars + + 3. Specify amounts for all postings, using exactly two commodities, and + let hledger infer the price that balances the transaction: + + 2009/1/1 + assets:euros EUR100 ; one hundred euros purchased + assets:dollars $-135 ; for $135 + + 4. Like 1, but the @ is parenthesised, i.e. (@); this is for compati- + bility with Ledger journals (Virtual posting costs), and is equiva- + lent to 1 in hledger. + + 5. Like 2, but as in 4 the @@ is parenthesised, i.e. (@@); in hledger, + this is equivalent to 2. + + Use the -B/--cost flag to convert amounts to their transaction price's + commodity, if any. (mnemonic: "B" is from "cost Basis", as in Ledger). + Eg here is how -B affects the balance report for the example above: + + $ hledger bal -N --flat + $-135 assets:dollars + EUR100 assets:euros + $ hledger bal -N --flat -B + $-135 assets:dollars + $135 assets:euros # <- the euros' cost + + Note -B is sensitive to the order of postings when a transaction price + is inferred: the inferred price will be in the commodity of the last + amount. So if example 3's postings are reversed, while the transaction + is equivalent, -B shows something different: + + 2009/1/1 + assets:dollars $-135 ; 135 dollars sold + assets:euros EUR100 ; for 100 euros + + $ hledger bal -N --flat -B + EUR-100 assets:dollars # <- the dollars' selling price + EUR100 assets:euros + + Lot prices, lot dates + Ledger allows another kind of price, lot price (four variants: {UNIT- + PRICE}, {{TOTALPRICE}}, {=FIXEDUNITPRICE}, {{=FIXEDTOTALPRICE}}), + and/or a lot date ([DATE]) to be specified. These are normally used to + select a lot when selling investments. hledger will parse these, for + compatibility with Ledger journals, but currently ignores them. A + transaction price, lot price and/or lot date may appear in any order, + after the posting amount and before the balance assertion if any. + + Balance assertions + hledger supports Ledger-style balance assertions in journal files. + These look like, for example, = EXPECTEDBALANCE following a posting's + amount. Eg here we assert the expected dollar balance in accounts a + and b after each posting: + + 2013/1/1 + a $1 =$1 + b =$-1 + + 2013/1/2 + a $1 =$2 + b $-1 =$-2 + + After reading a journal file, hledger will check all balance assertions + and report an error if any of them fail. Balance assertions can pro- + tect you from, eg, inadvertently disrupting reconciled balances while + cleaning up old entries. You can disable them temporarily with the + -I/--ignore-assertions flag, which can be useful for troubleshooting or + for reading Ledger files. (Note: this flag currently does not disable + balance assignments, below). + + Assertions and ordering + hledger sorts an account's postings and assertions first by date and + then (for postings on the same day) by parse order. Note this is dif- + ferent from Ledger, which sorts assertions only by parse order. (Also, + Ledger assertions do not see the accumulated effect of repeated post- + ings to the same account within a transaction.) + + So, hledger balance assertions keep working if you reorder differently- + dated transactions within the journal. But if you reorder same-dated + transactions or postings, assertions might break and require updating. + This order dependence does bring an advantage: precise control over the + order of postings and assertions within a day, so you can assert intra- + day balances. + + Assertions and included files + With included files, things are a little more complicated. Including + preserves the ordering of postings and assertions. If you have multi- + ple postings to an account on the same day, split across different + files, and you also want to assert the account's balance on the same + day, you'll have to put the assertion in the right file. + + Assertions and multiple -f options + Balance assertions don't work well across files specified with multiple + -f options. Use include or concatenate the files instead. + + Assertions and commodities + The asserted balance must be a simple single-commodity amount, and in + fact the assertion checks only this commodity's balance within the + (possibly multi-commodity) account balance. This is how assertions + work in Ledger also. We could call this a "partial" balance assertion. + + To assert the balance of more than one commodity in an account, you can + write multiple postings, each asserting one commodity's balance. + + You can make a stronger "total" balance assertion by writing a double + equals sign (== EXPECTEDBALANCE). This asserts that there are no other + unasserted commodities in the account (or, that their balance is 0). + + 2013/1/1 + a $1 + a 1EUR + b $-1 + c -1EUR + + 2013/1/2 ; These assertions succeed + a 0 = $1 + a 0 = 1EUR + b 0 == $-1 + c 0 == -1EUR + + 2013/1/3 ; This assertion fails as 'a' also contains 1EUR + a 0 == $1 + + It's not yet possible to make a complete assertion about a balance that + has multiple commodities. One workaround is to isolate each commodity + into its own subaccount: + + 2013/1/1 + a:usd $1 + a:euro 1EUR + b + + 2013/1/2 + a 0 == 0 + a:usd 0 == $1 + a:euro 0 == 1EUR + + Assertions and prices + Balance assertions ignore transaction prices, and should normally be + written without one: + + 2019/1/1 + (a) $1 @ EUR1 = $1 + + We do allow prices to be written there, however, and print shows them, + even though they don't affect whether the assertion passes or fails. + This is for backward compatibility (hledger's close command used to + generate balance assertions with prices), and because balance assign- + ments do use them (see below). + + Assertions and subaccounts + The balance assertions above (= and ==) do not count the balance from + subaccounts; they check the account's exclusive balance only. You can + assert the balance including subaccounts by writing =* or ==*, eg: + + 2019/1/1 + equity:opening balances + checking:a 5 + checking:b 5 + checking 1 ==* 11 + + Assertions and virtual postings + Balance assertions are checked against all postings, both real and vir- + tual. They are not affected by the --real/-R flag or real: query. + + Assertions and precision + Balance assertions compare the exactly calculated amounts, which are + not always what is shown by reports. Eg a commodity directive may + limit the display precision, but this will not affect balance asser- + tions. Balance assertion failure messages show exact amounts. + + Balance assignments + Ledger-style balance assignments are also supported. These are like + balance assertions, but with no posting amount on the left side of the + equals sign; instead it is calculated automatically so as to satisfy + the assertion. This can be a convenience during data entry, eg when + setting opening balances: + + ; starting a new journal, set asset account balances + 2016/1/1 opening balances + assets:checking = $409.32 + assets:savings = $735.24 + assets:cash = $42 + equity:opening balances + + or when adjusting a balance to reality: + + ; no cash left; update balance, record any untracked spending as a generic expense + 2016/1/15 + assets:cash = $0 + expenses:misc + + The calculated amount depends on the account's balance in the commodity + at that point (which depends on the previously-dated postings of the + commodity to that account since the last balance assertion or assign- + ment). Note that using balance assignments makes your journal a little + less explicit; to know the exact amount posted, you have to run hledger + or do the calculations yourself, instead of just reading it. + + Balance assignments and prices + A transaction price in a balance assignment will cause the calculated + amount to have that price attached: + + 2019/1/1 + (a) = $1 @ EUR2 + + $ hledger print --explicit + 2019-01-01 + (a) $1 @ EUR2 = $1 @ EUR2 + + Directives + A directive is a line in the journal beginning with a special keyword, + that influences how the journal is processed. hledger's directives are + based on a subset of Ledger's, but there are many differences (and also + some differences between hledger versions). + + Directives' behaviour and interactions can get a little bit complex, so + here is a table summarising the directives and their effects, with + links to more detailed docs. Note part of this table is hidden when + viewed in a web browser - scroll it sideways to see more. + + direc- end di- subdi- purpose can affect (as of + tive rective rec- 2018/06) + tives + ------------------------------------------------------------------------------------ + account any document account names, de- all entries in all + text clare account types & dis- files, before or + play order after + alias end rewrite account names following entries + aliases until end of cur- + rent file or end + directive + apply end apply prepend a common parent to following entries + account account account names until end of cur- + rent file or end + directive + comment end com- ignore part of journal following entries + ment until end of cur- + rent file or end + directive + commod- format declare a commodity and its number notation: + ity number notation & display following entries + style in that commodity + in all files ; dis- + play style: amounts + of that commodity + in reports + D declare a commodity to be default commodity: + used for commodityless following commod- + amounts, and its number no- ityless entries un- + tation & display style til end of current + file; number nota- + tion: following en- + tries in that com- + modity until end of + current file; dis- + play style: amounts + of that commodity + in reports + include include entries/directives what the included + from another file directives affect + P declare a market price for a amounts of that + commodity commodity in re- + ports, when -V is + used + Y declare a year for yearless following entries + dates until end of cur- + rent file + = declare an auto posting all entries in par- + rule, adding postings to ent/current/child + other transactions files (but not sib- + ling files, see + #1212) + + And some definitions: + + subdi- optional indented directive line immediately following a parent + rec- directive + tive + number how to interpret numbers when parsing journal entries (the iden- + nota- tity of the decimal separator character). (Currently each com- + tion modity can have its own notation, even in the same file.) + dis- how to display amounts of a commodity in reports (symbol side + play and spacing, digit groups, decimal separator, decimal places) + style + direc- which entries and (when there are multiple files) which files + tive are affected by a directive + scope + + As you can see, directives vary in which journal entries and files they + affect, and whether they are focussed on input (parsing) or output (re- + ports). Some directives have multiple effects. + + Directives and multiple files + If you use multiple -f/--file options, or the include directive, + hledger will process multiple input files. But note that directives + which affect input (see above) typically last only until the end of the + file in which they occur. + + This may seem inconvenient, but it's intentional; it makes reports sta- + ble and deterministic, independent of the order of input. Otherwise + you could see different numbers if you happened to write -f options in + a different order, or if you moved includes around while cleaning up + your files. + + It can be surprising though; for example, it means that alias direc- + tives do not affect parent or sibling files (see below). + + Comment blocks + A line containing just comment starts a commented region of the file, + and a line containing just end comment (or the end of the current file) + ends it. See also comments. + + Including other files + You can pull in the content of additional files by writing an include + directive, like this: + + include FILEPATH + + Only journal files can include, and only journal, timeclock or timedot + files can be included (not CSV files, currently). + + If the file path does not begin with a slash, it is relative to the + current file's folder. + + A tilde means home directory, eg: include ~/main.journal. + + The path may contain glob patterns to match multiple files, eg: include + *.journal. + + There is limited support for recursive wildcards: **/ (the slash is re- + quired) matches 0 or more subdirectories. It's not super convenient + since you have to avoid include cycles and including directories, but + this can be done, eg: include */**/*.journal. + + The path may also be prefixed to force a specific file format, overrid- + ing the file extension (as described in hledger.1 -> Input files): in- + clude timedot:~/notes/2020*.md. + + Default year + You can set a default year to be used for subsequent dates which don't + specify a year. This is a line beginning with Y followed by the year. + Eg: + + Y2009 ; set default year to 2009 + + 12/15 ; equivalent to 2009/12/15 + expenses 1 + assets + + Y2010 ; change default year to 2010 + + 2009/1/30 ; specifies the year, not affected + expenses 1 + assets + + 1/31 ; equivalent to 2010/1/31 + expenses 1 + assets + + Declaring commodities + The commodity directive has several functions: + + 1. It declares commodities which may be used in the journal. This is + currently not enforced, but can serve as documentation. + + 2. It declares what decimal mark character (period or comma) to expect + when parsing input - useful to disambiguate international number + formats in your data. (Without this, hledger will parse both 1,000 + and 1.000 as 1). + + 3. It declares a commodity's display style in output - decimal and + digit group marks, number of decimal places, symbol placement etc. + + You are likely to run into one of the problems solved by commodity di- + rectives, sooner or later, so it's a good idea to just always use them + to declare your commodities. + + A commodity directive is just the word commodity followed by an amount. + It may be written on a single line, like this: + + ; commodity EXAMPLEAMOUNT + + ; display AAAA amounts with the symbol on the right, space-separated, + ; using period as decimal point, with four decimal places, and + ; separating thousands with comma. + commodity 1,000.0000 AAAA + + or on multiple lines, using the "format" subdirective. (In this case + the commodity symbol appears twice and should be the same in both + places.): + + ; commodity SYMBOL + ; format EXAMPLEAMOUNT + + ; display indian rupees with currency name on the left, + ; thousands, lakhs and crores comma-separated, + ; period as decimal point, and two decimal places. + commodity INR + format INR 1,00,00,000.00 + + The quantity of the amount does not matter; only the format is signifi- + cant. The number must include a decimal mark: either a period or a + comma, followed by 0 or more decimal digits. + + Note hledger normally uses banker's rounding, so 0.5 displayed with + zero decimal digits is "0". (More at Commodity display style.) + + Commodity error checking + In strict mode, enabled with the -s/--strict flag, hledger will report + an error if a commodity symbol is used that has not been declared by a + commodity directive. This works similarly to account error checking, + see the notes there for more details. + + Default commodity + The D directive sets a default commodity, to be used for amounts with- + out a commodity symbol (ie, plain numbers). This commodity will be ap- + plied to all subsequent commodity-less amounts, or until the next D di- + rective. (Note, this is different from Ledger's D.) + + For compatibility/historical reasons, D also acts like a commodity di- + rective, setting the commodity's display style (for output) and decimal + mark (for parsing input). As with commodity, the amount must always be + written with a decimal mark (period or comma). If both directives are + used, commodity's style takes precedence. + + The syntax is D AMOUNT. Eg: + + ; commodity-less amounts should be treated as dollars + ; (and displayed with the dollar sign on the left, thousands separators and two decimal places) + D $1,000.00 + + 1/1 + a 5 ; <- commodity-less amount, parsed as $5 and displayed as $5.00 + b + + Declaring market prices + The P directive declares a market price, which is an exchange rate be- + tween two commodities on a certain date. (In Ledger, they are called + "historical prices".) These are often obtained from a stock exchange, + cryptocurrency exchange, or the foreign exchange market. + + Here is the format: + + P DATE COMMODITYA COMMODITYBAMOUNT + + o DATE is a simple date + + o COMMODITYA is the symbol of the commodity being priced + + o COMMODITYBAMOUNT is an amount (symbol and quantity) in a second com- + modity, giving the price in commodity B of one unit of commodity A. + + These two market price directives say that one euro was worth 1.35 US + dollars during 2009, and $1.40 from 2010 onward: + + P 2009/1/1 EUR $1.35 + P 2010/1/1 EUR $1.40 + + The -V, -X and --value flags use these market prices to show amount + values in another commodity. See Valuation. + + Declaring accounts + account directives can be used to declare accounts (ie, the places that + amounts are transferred from and to). Though not required, these dec- + larations can provide several benefits: + + o They can document your intended chart of accounts, providing a refer- + ence. + + o They can help hledger know your accounts' types (asset, liability, + equity, revenue, expense), useful for reports like balancesheet and + incomestatement. + + o They control account display order in reports, allowing non-alpha- + betic sorting (eg Revenues to appear above Expenses). + + o They can store extra information about accounts (account numbers, + notes, etc.) + + o They help with account name completion in the add command, hledger- + iadd, hledger-web, ledger-mode etc. + + o In strict mode, they restrict which accounts may be posted to by + transactions, which helps detect typos. + + The simplest form is just the word account followed by a hledger-style + account name, eg this account directive declares the assets:bank:check- + ing account: + + account assets:bank:checking + + Account error checking + By default, accounts come into existence when a transaction references + them by name. This is convenient, but it means hledger can't warn you + when you mis-spell an account name in the journal. Usually you'll find + the error later, as an extra account in balance reports, or an incor- + rect balance when reconciling. + + In strict mode, enabled with the -s/--strict flag, hledger will report + an error if any transaction uses an account name that has not been de- + clared by an account directive. Some notes: + + o The declaration is case-sensitive; transactions must use the correct + account name capitalisation. + + o The account directive's scope is "whole file and below" (see direc- + tives). This means it affects all of the current file, and any files + it includes, but not parent or sibling files. The position of ac- + count directives within the file does not matter, though it's usual + to put them at the top. + + o Accounts can only be declared in journal files (but will affect in- + cluded files in other formats). + + o It's currently not possible to declare "all possible subaccounts" + with a wildcard; every account posted to must be declared. + + Account comments + Comments, beginning with a semicolon, can be added: + + o on the same line, after two or more spaces (because ; is allowed in + account names) + + o on the next lines, indented + + An example of both: + + account assets:bank:checking ; same-line comment, note 2+ spaces before ; + ; next-line comment + ; another with tag, acctno:12345 (not used yet) + + Same-line comments are not supported by Ledger, or hledger <1.13. + + Account subdirectives + We also allow (and ignore) Ledger-style indented subdirectives, just + for compatibility.: + + account assets:bank:checking + format blah blah ; <- subdirective, ignored + + Here is the full syntax of account directives: + + account ACCTNAME [ACCTTYPE] [;COMMENT] + [;COMMENTS] + [LEDGER-STYLE SUBDIRECTIVES, IGNORED] + + Account types + hledger recognises five main types of account, corresponding to the ac- + count classes in the accounting equation: + + Asset, Liability, Equity, Revenue, Expense. + + These account types are important for controlling which accounts appear + in the balancesheet, balancesheetequity, incomestatement reports (and + probably for other things in future). + + Additionally, we recognise the Cash type, which is also an Asset, and + which causes accounts to appear in the cashflow report. ("Cash" here + means liquid assets, eg bank balances but typically not investments or + receivables.) + + Declaring account types + Generally, to make these reports work you should declare your top-level + accounts and their types, using account directives with type: tags. + + The tag's value should be one of: Asset, Liability, Equity, Revenue, + Expense, Cash, A, L, E, R, X, C (all case insensitive). The type is + inherited by all subaccounts except where they override it. Here's a + complete example: + + account assets ; type: Asset + account assets:bank ; type: Cash + account assets:cash ; type: Cash + account liabilities ; type: Liability + account equity ; type: Equity + account revenues ; type: Revenue + account expenses ; type: Expense + + Auto-detected account types + If you happen to use common english top-level account names, you may + not need to declare account types, as they will be detected automati- + cally using the following rules: + + If name matches regular account type is: + expression: + ---------------------------------------------- + ^assets?(:|$) Asset + ^(debts?|lia- Liability + bilit(y|ies))(:|$) + ^equity(:|$) Equity + ^(income|revenue)s?(:|$) Revenue + ^expenses?(:|$) Expense + + If account type is Asset and name does not contain regu- account type + lar expression: is: + -------------------------------------------------------------------------- + (investment|receivable|:A/R|:fixed) Cash + + Even so, explicit declarations may be a good idea, for clarity and pre- + dictability. + + Interference from auto-detected account types + If you assign any account type, it's a good idea to assign all of them, + to prevent any confusion from mixing declared and auto-detected types. + Although it's unlikely to happen in real life, here's an example: with + the following journal, balancesheetequity shows "liabilities" in both + Liabilities and Equity sections. Declaring another account as type:Li- + ability would fix it: + + account liabilities ; type:Equity + + 2020-01-01 + assets 1 + liabilities 1 + equity -2 + + Old account type syntax + In some hledger journals you might instead see this old syntax (the + letters ALERX, separated from the account name by two or more spaces); + this is deprecated and may be removed soon: + + account assets A + account liabilities L + account equity E + account revenues R + account expenses X + + Account display order + Account directives also set the order in which accounts are displayed, + eg in reports, the hledger-ui accounts screen, and the hledger-web + sidebar. By default accounts are listed in alphabetical order. But if + you have these account directives in the journal: + + account assets + account liabilities + account equity + account revenues + account expenses + + you'll see those accounts displayed in declaration order, not alphabet- + ically: + + $ hledger accounts -1 + assets + liabilities + equity + revenues + expenses + + Undeclared accounts, if any, are displayed last, in alphabetical order. + + Note that sorting is done at each level of the account tree (within + each group of sibling accounts under the same parent). And currently, + this directive: + + account other:zoo + + would influence the position of zoo among other's subaccounts, but not + the position of other among the top-level accounts. This means: + + o you will sometimes declare parent accounts (eg account other above) + that you don't intend to post to, just to customize their display or- + der + + o sibling accounts stay together (you couldn't display x:y in between + a:b and a:c). + + Rewriting accounts + You can define account alias rules which rewrite your account names, or + parts of them, before generating reports. This can be useful for: + + o expanding shorthand account names to their full form, allowing easier + data entry and a less verbose journal + + o adapting old journals to your current chart of accounts + + o experimenting with new account organisations, like a new hierarchy or + combining two accounts into one + + o customising reports + + Account aliases also rewrite account names in account directives. They + do not affect account names being entered via hledger add or hledger- + web. + + See also Rewrite account names. + + Basic aliases + To set an account alias, use the alias directive in your journal file. + This affects all subsequent journal entries in the current file or its + included files. The spaces around the = are optional: + + alias OLD = NEW + + Or, you can use the --alias 'OLD=NEW' option on the command line. This + affects all entries. It's useful for trying out aliases interactively. + + OLD and NEW are case sensitive full account names. hledger will re- + place any occurrence of the old account name with the new one. Subac- + counts are also affected. Eg: + + alias checking = assets:bank:wells fargo:checking + ; rewrites "checking" to "assets:bank:wells fargo:checking", or "checking:a" to "assets:bank:wells fargo:checking:a" + + Regex aliases + There is also a more powerful variant that uses a regular expression, + indicated by the forward slashes: + + alias /REGEX/ = REPLACEMENT + + or --alias '/REGEX/=REPLACEMENT'. + + REGEX is a case-insensitive regular expression. Anywhere it matches + inside an account name, the matched part will be replaced by REPLACE- + MENT. If REGEX contains parenthesised match groups, these can be ref- + erenced by the usual numeric backreferences in REPLACEMENT. Eg: + + alias /^(.+):bank:([^:]+):(.*)/ = \1:\2 \3 + ; rewrites "assets:bank:wells fargo:checking" to "assets:wells fargo checking" + + Also note that REPLACEMENT continues to the end of line (or on command + line, to end of option argument), so it can contain trailing white- + space. + + Combining aliases + You can define as many aliases as you like, using journal directives + and/or command line options. + + Recursive aliases - where an account name is rewritten by one alias, + then by another alias, and so on - are allowed. Each alias sees the + effect of previously applied aliases. + + In such cases it can be important to understand which aliases will be + applied and in which order. For (each account name in) each journal + entry, we apply: + + 1. alias directives preceding the journal entry, most recently parsed + first (ie, reading upward from the journal entry, bottom to top) + + 2. --alias options, in the order they appeared on the command line + (left to right). + + In other words, for (an account name in) a given journal entry: + + o the nearest alias declaration before/above the entry is applied first + + o the next alias before/above that will be be applied next, and so on + + o aliases defined after/below the entry do not affect it. + + This gives nearby aliases precedence over distant ones, and helps pro- + vide semantic stability - aliases will keep working the same way inde- + pendent of which files are being read and in which order. + + In case of trouble, adding --debug=6 to the command line will show + which aliases are being applied when. + + Aliases and multiple files + As explained at Directives and multiple files, alias directives do not + affect parent or sibling files. Eg in this command, + + hledger -f a.aliases -f b.journal + + account aliases defined in a.aliases will not affect b.journal. In- + cluding the aliases doesn't work either: + + include a.aliases + + 2020-01-01 ; not affected by a.aliases + foo 1 + bar + + This means that account aliases should usually be declared at the start + of your top-most file, like this: + + alias foo=Foo + alias bar=Bar + + 2020-01-01 ; affected by aliases above + foo 1 + bar + + include c.journal ; also affected + + end aliases + You can clear (forget) all currently defined aliases with the end + aliases directive: + + end aliases + + Default parent account + You can specify a parent account which will be prepended to all ac- + counts within a section of the journal. Use the apply account and end + apply account directives like so: + + apply account home + + 2010/1/1 + food $10 + cash + + end apply account + + which is equivalent to: + + 2010/01/01 + home:food $10 + home:cash $-10 + + If end apply account is omitted, the effect lasts to the end of the + file. Included files are also affected, eg: + + apply account business + include biz.journal + end apply account + apply account personal + include personal.journal + + Prior to hledger 1.0, legacy account and end spellings were also sup- + ported. + + A default parent account also affects account directives. It does not + affect account names being entered via hledger add or hledger-web. If + account aliases are present, they are applied after the default parent + account. + + Periodic transactions + Periodic transaction rules describe transactions that recur. They al- + low hledger to generate temporary future transactions to help with + forecasting, so you don't have to write out each one in the journal, + and it's easy to try out different forecasts. + + Periodic transactions can be a little tricky, so before you use them, + read this whole section - or at least these tips: + + 1. Two spaces accidentally added or omitted will cause you trouble - + read about this below. + + 2. For troubleshooting, show the generated transactions with hledger + print --forecast tag:generated or hledger register --forecast + tag:generated. + + 3. Forecasted transactions will begin only after the last non-fore- + casted transaction's date. + + 4. Forecasted transactions will end 6 months from today, by default. + See below for the exact start/end rules. + + 5. period expressions can be tricky. Their documentation needs im- + provement, but is worth studying. + + 6. Some period expressions with a repeating interval must begin on a + natural boundary of that interval. Eg in weekly from DATE, DATE + must be a monday. ~ weekly from 2019/10/1 (a tuesday) will give an + error. + + 7. Other period expressions with an interval are automatically expanded + to cover a whole number of that interval. (This is done to improve + reports, but it also affects periodic transactions. Yes, it's a bit + inconsistent with the above.) Eg: ~ every 10th day of month from + 2020/01, which is equivalent to ~ every 10th day of month from + 2020/01/01, will be adjusted to start on 2019/12/10. + + Periodic transaction rules also have a second meaning: they are used to + define budget goals, shown in budget reports. + + Periodic rule syntax + A periodic transaction rule looks like a normal journal entry, with the + date replaced by a tilde (~) followed by a period expression (mnemonic: + ~ looks like a recurring sine wave.): + + ~ monthly + expenses:rent $2000 + assets:bank:checking + + There is an additional constraint on the period expression: the start + date must fall on a natural boundary of the interval. Eg monthly from + 2018/1/1 is valid, but monthly from 2018/1/15 is not. + + Partial or relative dates (M/D, D, tomorrow, last week) in the period + expression can work (useful or not). They will be relative to today's + date, unless a Y default year directive is in effect, in which case + they will be relative to Y/1/1. + + Two spaces between period expression and description! + If the period expression is followed by a transaction description, + these must be separated by two or more spaces. This helps hledger know + where the period expression ends, so that descriptions can not acciden- + tally alter their meaning, as in this example: + + ; 2 or more spaces needed here, so the period is not understood as "every 2 months in 2020" + ; || + ; vv + ~ every 2 months in 2020, we will review + assets:bank:checking $1500 + income:acme inc + + So, + + o Do write two spaces between your period expression and your transac- + tion description, if any. + + o Don't accidentally write two spaces in the middle of your period ex- + pression. + + Forecasting with periodic transactions + The --forecast flag activates any periodic transaction rules in the + journal. They will generate temporary recurring transactions, which + are not saved in the journal, but will appear in all reports (eg + print). This can be useful for estimating balances into the future, or + experimenting with different scenarios. Or, it can be used as a data + entry aid: describe recurring transactions, and every so often copy the + output of print --forecast into the journal. + + These transactions will have an extra tag indicating which periodic + rule generated them: generated-transaction:~ PERIODICEXPR. And a simi- + lar, hidden tag (beginning with an underscore) which, because it's + never displayed by print, can be used to match transactions generated + "just now": _generated-transaction:~ PERIODICEXPR. + + Periodic transactions are generated within some forecast period. By + default, this + + o begins on the later of + + o the report start date if specified with -b/-p/date: + + o the day after the latest normal (non-periodic) transaction in the + journal, or today if there are no normal transactions. + + o ends on the report end date if specified with -e/-p/date:, or 6 + months (180 days) from today. + + This means that periodic transactions will begin only after the latest + recorded transaction. And a recorded transaction dated in the future + can prevent generation of periodic transactions. (You can avoid that + by writing the future transaction as a one-time periodic rule instead - + put tilde before the date, eg ~ YYYY-MM-DD ...). + + Or, you can set your own arbitrary "forecast period", which can overlap + recorded transactions, and need not be in the future, by providing an + option argument, like --forecast=PERIODEXPR. Note the equals sign is + required, a space won't work. PERIODEXPR is a period expression, which + can specify the start date, end date, or both, like in a date: query. + (See also hledger.1 -> Report start & end date). Some examples: + --forecast=202001-202004, --forecast=jan-, --forecast=2020. + + Budgeting with periodic transactions + With the --budget flag, currently supported by the balance command, + each periodic transaction rule declares recurring budget goals for the + specified accounts. Eg the first example above declares a goal of + spending $2000 on rent (and also, a goal of depositing $2000 into + checking) every month. Goals and actual performance can then be com- + pared in budget reports. + + See also: Budgeting and Forecasting. + + Auto postings + "Automated postings" or "auto postings" are extra postings which get + added automatically to transactions which match certain queries, de- + fined by "auto posting rules", when you use the --auto flag. + + An auto posting rule looks a bit like a transaction: + + = QUERY + ACCOUNT AMOUNT + ... + ACCOUNT [AMOUNT] + + except the first line is an equals sign (mnemonic: = suggests match- + ing), followed by a query (which matches existing postings), and each + "posting" line describes a posting to be generated, and the posting + amounts can be: + + o a normal amount with a commodity symbol, eg $2. This will be used + as-is. + + o a number, eg 2. The commodity symbol (if any) from the matched post- + ing will be added to this. + + o a numeric multiplier, eg *2 (a star followed by a number N). The + matched posting's amount (and total price, if any) will be multiplied + by N. + + o a multiplier with a commodity symbol, eg *$2 (a star, number N, and + symbol S). The matched posting's amount will be multiplied by N, and + its commodity symbol will be replaced with S. + + Any query term containing spaces must be enclosed in single or double + quotes, as on the command line. Eg, note the quotes around the second + query term below: + + = expenses:groceries 'expenses:dining out' + (budget:funds:dining out) *-1 + + Some examples: + + ; every time I buy food, schedule a dollar donation + = expenses:food + (liabilities:charity) $-1 + + ; when I buy a gift, also deduct that amount from a budget envelope subaccount + = expenses:gifts + assets:checking:gifts *-1 + assets:checking *1 + + 2017/12/1 + expenses:food $10 + assets:checking + + 2017/12/14 + expenses:gifts $20 + assets:checking + + $ hledger print --auto + 2017-12-01 + expenses:food $10 + assets:checking + (liabilities:charity) $-1 + + 2017-12-14 + expenses:gifts $20 + assets:checking + assets:checking:gifts -$20 + assets:checking $20 + + Auto postings and multiple files + An auto posting rule can affect any transaction in the current file, or + in any parent file or child file. Note, currently it will not affect + sibling files (when multiple -f/--file are used - see #1212). + + Auto postings and dates + A posting date (or secondary date) in the matched posting, or (taking + precedence) a posting date in the auto posting rule itself, will also + be used in the generated posting. + + Auto postings and transaction balancing / inferred amounts / balance asser- + tions + Currently, auto postings are added: + + o after missing amounts are inferred, and transactions are checked for + balancedness, + + o but before balance assertions are checked. + + Note this means that journal entries must be balanced both before and + after auto postings are added. This changed in hledger 1.12+; see #893 + for background. + + Auto posting tags + Automated postings will have some extra tags: + + o generated-posting:= QUERY - shows this was generated by an auto post- + ing rule, and the query + + o _generated-posting:= QUERY - a hidden tag, which does not appear in + hledger's output. This can be used to match postings generated "just + now", rather than generated in the past and saved to the journal. + + Also, any transaction that has been changed by auto posting rules will + have these tags added: + + o modified: - this transaction was modified + + o _modified: - a hidden tag not appearing in the comment; this transac- + tion was modified "just now". + +CSV FORMAT + How hledger reads CSV data, and the CSV rules file format. + + hledger can read CSV files (Character Separated Value - usually comma, + semicolon, or tab) containing dated records as if they were journal + files, automatically converting each CSV record into a transaction. + + (To learn about writing CSV, see CSV output.) + + We describe each CSV file's format with a corresponding rules file. By + default this is named like the CSV file with a .rules extension added. + Eg when reading FILE.csv, hledger also looks for FILE.csv.rules in the + same directory as FILE.csv. You can specify a different rules file + with the --rules-file option. If a rules file is not found, hledger + will create a sample rules file, which you'll need to adjust. + + This file contains rules describing the CSV data (header line, fields + layout, date format etc.), and how to construct hledger journal entries + (transactions) from it. Often there will also be a list of conditional + rules for categorising transactions based on their descriptions. + Here's an overview of the CSV rules; these are described more fully be- + low, after the examples: + + skip skip one or more header lines or matched + CSV records + fields name CSV fields, assign them to hledger + fields + field assignment assign a value to one hledger field, + with interpolation + separator a custom field separator + if block apply some rules to CSV records matched + by patterns + if table apply some rules to CSV records matched + by patterns, alternate syntax + end skip the remaining CSV records + date-format how to parse dates in CSV records + decimal-mark the decimal mark used in CSV amounts, if + ambiguous + newest-first disambiguate record order when there's + only one date + include inline another CSV rules file + balance-type choose which type of balance assignments + to use + + Note, for best error messages when reading CSV files, use a .csv, .tsv + or .ssv file extension or file prefix - see File Extension below. + + There's an introductory Convert CSV files tutorial on hledger.org. + + Examples + Here are some sample hledger CSV rules files. See also the full col- + lection at: + https://github.com/simonmichael/hledger/tree/master/examples/csv + + Basic + At minimum, the rules file must identify the date and amount fields, + and often it also specifies the date format and how many header lines + there are. Here's a simple CSV file and a rules file for it: + + Date, Description, Id, Amount + 12/11/2019, Foo, 123, 10.23 + + # basic.csv.rules + skip 1 + fields date, description, _, amount + date-format %d/%m/%Y + + $ hledger print -f basic.csv + 2019-11-12 Foo + expenses:unknown 10.23 + income:unknown -10.23 + + Default account names are chosen, since we didn't set them. + + Bank of Ireland + Here's a CSV with two amount fields (Debit and Credit), and a balance + field, which we can use to add balance assertions, which is not neces- + sary but provides extra error checking: + + Date,Details,Debit,Credit,Balance + 07/12/2012,LODGMENT 529898,,10.0,131.21 + 07/12/2012,PAYMENT,5,,126 + + # bankofireland-checking.csv.rules + + # skip the header line + skip + + # name the csv fields, and assign some of them as journal entry fields + fields date, description, amount-out, amount-in, balance + + # We generate balance assertions by assigning to "balance" + # above, but you may sometimes need to remove these because: + # + # - the CSV balance differs from the true balance, + # by up to 0.0000000000005 in my experience + # + # - it is sometimes calculated based on non-chronological ordering, + # eg when multiple transactions clear on the same day + + # date is in UK/Ireland format + date-format %d/%m/%Y + + # set the currency + currency EUR + + # set the base account for all txns + account1 assets:bank:boi:checking + + $ hledger -f bankofireland-checking.csv print + 2012-12-07 LODGMENT 529898 + assets:bank:boi:checking EUR10.0 = EUR131.2 + income:unknown EUR-10.0 + + 2012-12-07 PAYMENT + assets:bank:boi:checking EUR-5.0 = EUR126.0 + expenses:unknown EUR5.0 + + The balance assertions don't raise an error above, because we're read- + ing directly from CSV, but they will be checked if these entries are + imported into a journal file. + + Amazon + Here we convert amazon.com order history, and use an if block to gener- + ate a third posting if there's a fee. (In practice you'd probably get + this data from your bank instead, but it's an example.) + + "Date","Type","To/From","Name","Status","Amount","Fees","Transaction ID" + "Jul 29, 2012","Payment","To","Foo.","Completed","$20.00","$0.00","16000000000000DGLNJPI1P9B8DKPVHL" + "Jul 30, 2012","Payment","To","Adapteva, Inc.","Completed","$25.00","$1.00","17LA58JSKRD4HDGLNJPI1P9B8DKPVHL" + + # amazon-orders.csv.rules + + # skip one header line + skip 1 + + # name the csv fields, and assign the transaction's date, amount and code. + # Avoided the "status" and "amount" hledger field names to prevent confusion. + fields date, _, toorfrom, name, amzstatus, amzamount, fees, code + + # how to parse the date + date-format %b %-d, %Y + + # combine two fields to make the description + description %toorfrom %name + + # save the status as a tag + comment status:%amzstatus + + # set the base account for all transactions + account1 assets:amazon + # leave amount1 blank so it can balance the other(s). + # I'm assuming amzamount excludes the fees, don't remember + + # set a generic account2 + account2 expenses:misc + amount2 %amzamount + # and maybe refine it further: + #include categorisation.rules + + # add a third posting for fees, but only if they are non-zero. + if %fees [1-9] + account3 expenses:fees + amount3 %fees + + $ hledger -f amazon-orders.csv print + 2012-07-29 (16000000000000DGLNJPI1P9B8DKPVHL) To Foo. ; status:Completed + assets:amazon + expenses:misc $20.00 + + 2012-07-30 (17LA58JSKRD4HDGLNJPI1P9B8DKPVHL) To Adapteva, Inc. ; status:Completed + assets:amazon + expenses:misc $25.00 + expenses:fees $1.00 + + Paypal + Here's a real-world rules file for (customised) Paypal CSV, with some + Paypal-specific rules, and a second rules file included: + + "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note" + "10/01/2019","03:46:20","PDT","Calm Radio","Subscription Payment","Completed","USD","-6.99","0.00","-6.99","simon@joyful.com","memberships@calmradio.com","60P57143A8206782E","MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month","","I-R8YLY094FJYR","","-6.99","" + "10/01/2019","03:46:20","PDT","","Bank Deposit to PP Account ","Pending","USD","6.99","0.00","6.99","","simon@joyful.com","0TU1544T080463733","","","60P57143A8206782E","","0.00","" + "10/01/2019","08:57:01","PDT","Patreon","PreApproved Payment Bill User Payment","Completed","USD","-7.00","0.00","-7.00","simon@joyful.com","support@patreon.com","2722394R5F586712G","Patreon* Membership","","B-0PG93074E7M86381M","","-7.00","" + "10/01/2019","08:57:01","PDT","","Bank Deposit to PP Account ","Pending","USD","7.00","0.00","7.00","","simon@joyful.com","71854087RG994194F","Patreon* Membership","","2722394R5F586712G","","0.00","" + "10/19/2019","03:02:12","PDT","Wikimedia Foundation, Inc.","Subscription Payment","Completed","USD","-2.00","0.00","-2.00","simon@joyful.com","tle@wikimedia.org","K9U43044RY432050M","Monthly donation to the Wikimedia Foundation","","I-R5C3YUS3285L","","-2.00","" + "10/19/2019","03:02:12","PDT","","Bank Deposit to PP Account ","Pending","USD","2.00","0.00","2.00","","simon@joyful.com","3XJ107139A851061F","","","K9U43044RY432050M","","0.00","" + "10/22/2019","05:07:06","PDT","Noble Benefactor","Subscription Payment","Completed","USD","10.00","-0.59","9.41","noble@bene.fac.tor","simon@joyful.com","6L8L1662YP1334033","Joyful Systems","","I-KC9VBGY2GWDB","","9.41","" + + # paypal-custom.csv.rules + + # Tips: + # Export from Activity -> Statements -> Custom -> Activity download + # Suggested transaction type: "Balance affecting" + # Paypal's default fields in 2018 were: + # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Shipping Address","Address Status","Item Title","Item ID","Shipping and Handling Amount","Insurance Amount","Sales Tax","Option 1 Name","Option 1 Value","Option 2 Name","Option 2 Value","Reference Txn ID","Invoice Number","Custom Number","Quantity","Receipt ID","Balance","Address Line 1","Address Line 2/District/Neighborhood","Town/City","State/Province/Region/County/Territory/Prefecture/Republic","Zip/Postal Code","Country","Contact Phone Number","Subject","Note","Country Code","Balance Impact" + # This rules file assumes the following more detailed fields, configured in "Customize report fields": + # "Date","Time","TimeZone","Name","Type","Status","Currency","Gross","Fee","Net","From Email Address","To Email Address","Transaction ID","Item Title","Item ID","Reference Txn ID","Receipt ID","Balance","Note" + + fields date, time, timezone, description_, type, status_, currency, grossamount, feeamount, netamount, fromemail, toemail, code, itemtitle, itemid, referencetxnid, receiptid, balance, note + + skip 1 + + date-format %-m/%-d/%Y + + # ignore some paypal events + if + In Progress + Temporary Hold + Update to + skip + + # add more fields to the description + description %description_ %itemtitle + + # save some other fields as tags + comment itemid:%itemid, fromemail:%fromemail, toemail:%toemail, time:%time, type:%type, status:%status_ + + # convert to short currency symbols + if %currency USD + currency $ + if %currency EUR + currency E + if %currency GBP + currency P + + # generate postings + + # the first posting will be the money leaving/entering my paypal account + # (negative means leaving my account, in all amount fields) + account1 assets:online:paypal + amount1 %netamount + + # the second posting will be money sent to/received from other party + # (account2 is set below) + amount2 -%grossamount + + # if there's a fee, add a third posting for the money taken by paypal. + if %feeamount [1-9] + account3 expenses:banking:paypal + amount3 -%feeamount + comment3 business: + + # choose an account for the second posting + + # override the default account names: + # if the amount is positive, it's income (a debit) + if %grossamount ^[^-] + account2 income:unknown + # if negative, it's an expense (a credit) + if %grossamount ^- + account2 expenses:unknown + + # apply common rules for setting account2 & other tweaks + include common.rules + + # apply some overrides specific to this csv + + # Transfers from/to bank. These are usually marked Pending, + # which can be disregarded in this case. + if + Bank Account + Bank Deposit to PP Account + description %type for %referencetxnid %itemtitle + account2 assets:bank:wf:pchecking + account1 assets:online:paypal + + # Currency conversions + if Currency Conversion + account2 equity:currency conversion + + # common.rules + + if + darcs + noble benefactor + account2 revenues:foss donations:darcshub + comment2 business: + + if + Calm Radio + account2 expenses:online:apps + + if + electronic frontier foundation + Patreon + wikimedia + Advent of Code + account2 expenses:dues + + if Google + account2 expenses:online:apps + description google | music + + $ hledger -f paypal-custom.csv print + 2019-10-01 (60P57143A8206782E) Calm Radio MONTHLY - $1 for the first 2 Months: Me - Order 99309. Item total: $1.00 USD first 2 months, then $6.99 / Month ; itemid:, fromemail:simon@joyful.com, toemail:memberships@calmradio.com, time:03:46:20, type:Subscription Payment, status:Completed + assets:online:paypal $-6.99 = $-6.99 + expenses:online:apps $6.99 + + 2019-10-01 (0TU1544T080463733) Bank Deposit to PP Account for 60P57143A8206782E ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:46:20, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $6.99 = $0.00 + assets:bank:wf:pchecking $-6.99 + + 2019-10-01 (2722394R5F586712G) Patreon Patreon* Membership ; itemid:, fromemail:simon@joyful.com, toemail:support@patreon.com, time:08:57:01, type:PreApproved Payment Bill User Payment, status:Completed + assets:online:paypal $-7.00 = $-7.00 + expenses:dues $7.00 + + 2019-10-01 (71854087RG994194F) Bank Deposit to PP Account for 2722394R5F586712G Patreon* Membership ; itemid:, fromemail:, toemail:simon@joyful.com, time:08:57:01, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $7.00 = $0.00 + assets:bank:wf:pchecking $-7.00 + + 2019-10-19 (K9U43044RY432050M) Wikimedia Foundation, Inc. Monthly donation to the Wikimedia Foundation ; itemid:, fromemail:simon@joyful.com, toemail:tle@wikimedia.org, time:03:02:12, type:Subscription Payment, status:Completed + assets:online:paypal $-2.00 = $-2.00 + expenses:dues $2.00 + expenses:banking:paypal ; business: + + 2019-10-19 (3XJ107139A851061F) Bank Deposit to PP Account for K9U43044RY432050M ; itemid:, fromemail:, toemail:simon@joyful.com, time:03:02:12, type:Bank Deposit to PP Account, status:Pending + assets:online:paypal $2.00 = $0.00 + assets:bank:wf:pchecking $-2.00 + + 2019-10-22 (6L8L1662YP1334033) Noble Benefactor Joyful Systems ; itemid:, fromemail:noble@bene.fac.tor, toemail:simon@joyful.com, time:05:07:06, type:Subscription Payment, status:Completed + assets:online:paypal $9.41 = $9.41 + revenues:foss donations:darcshub $-10.00 ; business: + expenses:banking:paypal $0.59 ; business: + + CSV rules + The following kinds of rule can appear in the rules file, in any order. + Blank lines and lines beginning with # or ; are ignored. + + skip + skip N + + The word "skip" followed by a number (or no number, meaning 1) tells + hledger to ignore this many non-empty lines preceding the CSV data. + (Empty/blank lines are skipped automatically.) You'll need this when- + ever your CSV data contains header lines. + + It also has a second purpose: it can be used inside if blocks to ignore + certain CSV records (described below). + + fields + fields FIELDNAME1, FIELDNAME2, ... + + A fields list (the word "fields" followed by comma-separated field + names) is the quick way to assign CSV field values to hledger fields. + It does two things: + + 1. it names the CSV fields. This is optional, but can be convenient + later for interpolating them. + + 2. when you use a standard hledger field name, it assigns the CSV value + to that part of the hledger transaction. + + Here's an example that says "use the 1st, 2nd and 4th fields as the + transaction's date, description and amount; name the last two fields + for later reference; and ignore the others": + + fields date, description, , amount, , , somefield, anotherfield + + Field names may not contain whitespace. Fields you don't care about + can be left unnamed. Currently there must be least two items (there + must be at least one comma). + + Note, always use comma in the fields list, even if your CSV uses an- + other separator character. + + Here are the standard hledger field/pseudo-field names. For more about + the transaction parts they refer to, see the manual for hledger's jour- + nal format. + + Transaction field names + date, date2, status, code, description, comment can be used to form the + transaction's first line. + + Posting field names + account + accountN, where N is 1 to 99, causes a posting to be generated, with + that account name. + + Most often there are two postings, so you'll want to set account1 and + account2. Typically account1 is associated with the CSV file, and is + set once with a top-level assignment, while account2 is set based on + each transaction's description, and in conditional blocks. + + If a posting's account name is left unset but its amount is set (see + below), a default account name will be chosen (like "expenses:unknown" + or "income:unknown"). + + amount + amountN sets posting N's amount. If the CSV uses separate fields for + inflows and outflows, you can use amountN-in and amountN-out instead. + By assigning to amount1, amount2, ... etc. you can generate anywhere + from 0 to 99 postings. + + There is also an older, unnumbered form of these names, suitable for + 2-posting transactions, which sets both posting 1's and (negated) post- + ing 2's amount: amount, or amount-in and amount-out. This is still + supported because it keeps pre-hledger-1.17 csv rules files working, + and because it can be more succinct, and because it converts posting + 2's amount to cost if there's a transaction price, which can be useful. + + If you have an existing rules file using the unnumbered form, you might + want to use the numbered form in certain conditional blocks, without + having to update and retest all the old rules. To facilitate this, + posting 1 ignores amount/amount-in/amount-out if any of + amount1/amount1-in/amount1-out are assigned, and posting 2 ignores them + if any of amount2/amount2-in/amount2-out are assigned, avoiding con- + flicts. + + currency + If the CSV has the currency symbol in a separate field (ie, not part of + the amount field), you can use currencyN to prepend it to posting N's + amount. Or, currency with no number affects all postings. + + balance + balanceN sets a balance assertion amount (or if the posting amount is + left empty, a balance assignment) on posting N. + + Also, for compatibility with hledger <1.17: balance with no number is + equivalent to balance1. + + You can adjust the type of assertion/assignment with the balance-type + rule (see below). + + comment + Finally, commentN sets a comment on the Nth posting. Comments can also + contain tags, as usual. + + See TIPS below for more about setting amounts and currency. + + field assignment + HLEDGERFIELDNAME FIELDVALUE + + Instead of or in addition to a fields list, you can use a "field as- + signment" rule to set the value of a single hledger field, by writing + its name (any of the standard hledger field names above) followed by a + text value. The value may contain interpolated CSV fields, referenced + by their 1-based position in the CSV record (%N), or by the name they + were given in the fields list (%CSVFIELDNAME). Some examples: + + # set the amount to the 4th CSV field, with " USD" appended + amount %4 USD + + # combine three fields to make a comment, containing note: and date: tags + comment note: %somefield - %anotherfield, date: %1 + + Interpolation strips outer whitespace (so a CSV value like " 1 " be- + comes 1 when interpolated) (#1051). See TIPS below for more about ref- + erencing other fields. + + separator + You can use the separator rule to read other kinds of character-sepa- + rated data. The argument is any single separator character, or the + words tab or space (case insensitive). Eg, for comma-separated values + (CSV): + + separator , + + or for semicolon-separated values (SSV): + + separator ; + + or for tab-separated values (TSV): + + separator TAB + + If the input file has a .csv, .ssv or .tsv file extension (or a csv:, + ssv:, tsv: prefix), the appropriate separator will be inferred automat- + ically, and you won't need this rule. + + if block + if MATCHER + RULE + + if + MATCHER + MATCHER + MATCHER + RULE + RULE + + Conditional blocks ("if blocks") are a block of rules that are applied + only to CSV records which match certain patterns. They are often used + for customising account names based on transaction descriptions. + + Matching the whole record + Each MATCHER can be a record matcher, which looks like this: + + REGEX + + REGEX is a case-insensitive regular expression which tries to match + anywhere within the CSV record. It is a POSIX ERE (extended regular + expression) that also supports GNU word boundaries (\b, \B, \<, \>), + and nothing else. If you have trouble, be sure to check our + https://hledger.org/hledger.html#regular-expressions doc. + + Important note: the record that is matched is not the original record, + but a synthetic one, with any enclosing double quotes (but not enclos- + ing whitespace) removed, and always comma-separated (which means that a + field containing a comma will appear like two fields). Eg, if the + original record is 2020-01-01; "Acme, Inc."; 1,000, the REGEX will ac- + tually see 2020-01-01,Acme, Inc., 1,000). + + Matching individual fields + Or, MATCHER can be a field matcher, like this: + + %CSVFIELD REGEX + + which matches just the content of a particular CSV field. CSVFIELD is + a percent sign followed by the field's name or column number, like + %date or %1. + + Combining matchers + A single matcher can be written on the same line as the "if"; or multi- + ple matchers can be written on the following lines, non-indented. Mul- + tiple matchers are OR'd (any one of them can match), unless one begins + with an & symbol, in which case it is AND'ed with the previous matcher. + + if + MATCHER + & MATCHER + RULE + + Rules applied on successful match + After the patterns there should be one or more rules to apply, all in- + dented by at least one space. Three kinds of rule are allowed in con- + ditional blocks: + + o field assignments (to set a hledger field) + + o skip (to skip the matched CSV record) + + o end (to skip all remaining CSV records). + + Examples: + + # if the CSV record contains "groceries", set account2 to "expenses:groceries" + if groceries + account2 expenses:groceries + + # if the CSV record contains any of these patterns, set account2 and comment as shown + if + monthly service fee + atm transaction fee + banking thru software + account2 expenses:business:banking + comment XXX deductible ? check it + + if table + if,CSVFIELDNAME1,CSVFIELDNAME2,...,CSVFIELDNAMEn + MATCHER1,VALUE11,VALUE12,...,VALUE1n + MATCHER2,VALUE21,VALUE22,...,VALUE2n + MATCHER3,VALUE31,VALUE32,...,VALUE3n + + + Conditional tables ("if tables") are a different syntax to specify + field assignments that will be applied only to CSV records which match + certain patterns. + + MATCHER could be either field or record matcher, as described above. + When MATCHER matches, values from that row would be assigned to the CSV + fields named on the if line, in the same order. + + Therefore if table is exactly equivalent to a sequence of of if blocks: + + if MATCHER1 + CSVFIELDNAME1 VALUE11 + CSVFIELDNAME2 VALUE12 + ... + CSVFIELDNAMEn VALUE1n + + if MATCHER2 + CSVFIELDNAME1 VALUE21 + CSVFIELDNAME2 VALUE22 + ... + CSVFIELDNAMEn VALUE2n + + if MATCHER3 + CSVFIELDNAME1 VALUE31 + CSVFIELDNAME2 VALUE32 + ... + CSVFIELDNAMEn VALUE3n + + Each line starting with MATCHER should contain enough (possibly empty) + values for all the listed fields. + + Rules would be checked and applied in the order they are listed in the + table and, like with if blocks, later rules (in the same or another ta- + ble) or if blocks could override the effect of any rule. + + Instead of ',' you can use a variety of other non-alphanumeric charac- + ters as a separator. First character after if is taken to be the sepa- + rator for the rest of the table. It is the responsibility of the user + to ensure that separator does not occur inside MATCHERs and values - + there is no way to escape separator. + + Example: + + if,account2,comment + atm transaction fee,expenses:business:banking,deductible? check it + %description groceries,expenses:groceries, + 2020/01/12.*Plumbing LLC,expenses:house:upkeep,emergency plumbing call-out + + end + This rule can be used inside if blocks (only), to make hledger stop + reading this CSV file and move on to the next input file, or to command + execution. Eg: + + # ignore everything following the first empty record + if ,,,, + end + + date-format + date-format DATEFMT + + This is a helper for the date (and date2) fields. If your CSV dates + are not formatted like YYYY-MM-DD, YYYY/MM/DD or YYYY.MM.DD, you'll + need to add a date-format rule describing them with a strptime date + parsing pattern, which must parse the CSV date value completely. Some + examples: + + # MM/DD/YY + date-format %m/%d/%y + + # D/M/YYYY + # The - makes leading zeros optional. + date-format %-d/%-m/%Y + + # YYYY-Mmm-DD + date-format %Y-%h-%d + + # M/D/YYYY HH:MM AM some other junk + # Note the time and junk must be fully parsed, though only the date is used. + date-format %-m/%-d/%Y %l:%M %p some other junk + + For the supported strptime syntax, see: + https://hackage.haskell.org/package/time/docs/Data-Time-For- + mat.html#v:formatTime + + decimal-mark + decimal-mark . + + or: + + decimal-mark , + + hledger automatically accepts either period or comma as a decimal mark + when parsing numbers (cf Amounts). However if any numbers in the CSV + contain digit group marks, such as thousand-separating commas, you + should declare the decimal mark explicitly with this rule, to avoid + misparsed numbers. + + newest-first + hledger always sorts the generated transactions by date. Transactions + on the same date should appear in the same order as their CSV records, + as hledger can usually auto-detect whether the CSV's normal order is + oldest first or newest first. But if all of the following are true: + + o the CSV might sometimes contain just one day of data (all records + having the same date) + + o the CSV records are normally in reverse chronological order (newest + at the top) + + o and you care about preserving the order of same-day transactions + + then, you should add the newest-first rule as a hint. Eg: + + # tell hledger explicitly that the CSV is normally newest first + newest-first + + include + include RULESFILE + + This includes the contents of another CSV rules file at this point. + RULESFILE is an absolute file path or a path relative to the current + file's directory. This can be useful for sharing common rules between + several rules files, eg: + + # someaccount.csv.rules + + ## someaccount-specific rules + fields date,description,amount + account1 assets:someaccount + account2 expenses:misc + + ## common rules + include categorisation.rules + + balance-type + Balance assertions generated by assigning to balanceN are of the simple + = type by default, which is a single-commodity, subaccount-excluding + assertion. You may find the subaccount-including variants more useful, + eg if you have created some virtual subaccounts of checking to help + with budgeting. You can select a different type of assertion with the + balance-type rule: + + # balance assertions will consider all commodities and all subaccounts + balance-type ==* + + Here are the balance assertion types for quick reference: + + = single commodity, exclude subaccounts + =* single commodity, include subaccounts + == multi commodity, exclude subaccounts + ==* multi commodity, include subaccounts + + Tips + Rapid feedback + It's a good idea to get rapid feedback while creating/troubleshooting + CSV rules. Here's a good way, using entr from http://eradman.com/entr- + project : + + $ ls foo.csv* | entr bash -c 'echo ----; hledger -f foo.csv print desc:SOMEDESC' + + A desc: query (eg) is used to select just one, or a few, transactions + of interest. "bash -c" is used to run multiple commands, so we can + echo a separator each time the command re-runs, making it easier to + read the output. + + Valid CSV + hledger accepts CSV conforming to RFC 4180. When CSV values are en- + closed in quotes, note: + + o they must be double quotes (not single quotes) + + o spaces outside the quotes are not allowed + + File Extension + To help hledger identify the format and show the right error messages, + CSV/SSV/TSV files should normally be named with a .csv, .ssv or .tsv + filename extension. Or, the file path should be prefixed with csv:, + ssv: or tsv:. Eg: + + $ hledger -f foo.ssv print + + or: + + $ cat foo | hledger -f ssv:- foo + + You can override the file extension with a separator rule if needed. + See also: Input files in the hledger manual. + + Reading multiple CSV files + If you use multiple -f options to read multiple CSV files at once, + hledger will look for a correspondingly-named rules file for each CSV + file. But if you use the --rules-file option, that rules file will be + used for all the CSV files. + + Valid transactions + After reading a CSV file, hledger post-processes and validates the gen- + erated journal entries as it would for a journal file - balancing them, + applying balance assignments, and canonicalising amount styles. Any + errors at this stage will be reported in the usual way, displaying the + problem entry. + + There is one exception: balance assertions, if you have generated them, + will not be checked, since normally these will work only when the CSV + data is part of the main journal. If you do need to check balance as- + sertions generated from CSV right away, pipe into another hledger: + + $ hledger -f file.csv print | hledger -f- print + + Deduplicating, importing + When you download a CSV file periodically, eg to get your latest bank + transactions, the new file may overlap with the old one, containing + some of the same records. + + The import command will (a) detect the new transactions, and (b) append + just those transactions to your main journal. It is idempotent, so you + don't have to remember how many times you ran it or with which version + of the CSV. (It keeps state in a hidden .latest.FILE.csv file.) This + is the easiest way to import CSV data. Eg: + + # download the latest CSV files, then run this command. + # Note, no -f flags needed here. + $ hledger import *.csv [--dry] + + This method works for most CSV files. (Where records have a stable + chronological order, and new records appear only at the new end.) + + A number of other tools and workflows, hledger-specific and otherwise, + exist for converting, deduplicating, classifying and managing CSV data. + See: + + o https://hledger.org -> sidebar -> real world setups + + o https://plaintextaccounting.org -> data import/conversion + + Setting amounts + A posting amount can be set in one of these ways: + + o by assigning (with a fields list or field assignment) to amountN + (posting N's amount) or amount (posting 1's amount) + + o by assigning to amountN-in and amountN-out (or amount-in and amount- + out). For each CSV record, whichever of these has a non-zero value + will be used, with appropriate sign. If both contain a non-zero + value, this may not work. + + o by assigning to balanceN (or balance) instead of the above, setting + the amount indirectly via a balance assignment. If you do this the + default account name may be wrong, so you should set that explicitly. + + There is some special handling for an amount's sign: + + o If an amount value is parenthesised, it will be de-parenthesised and + sign-flipped. + + o If an amount value begins with a double minus sign, those cancel out + and are removed. + + o If an amount value begins with a plus sign, that will be removed + + Setting currency/commodity + If the currency/commodity symbol is included in the CSV's amount + field(s): + + 2020-01-01,foo,$123.00 + + you don't have to do anything special for the commodity symbol, it will + be assigned as part of the amount. Eg: + + fields date,description,amount + + 2020-01-01 foo + expenses:unknown $123.00 + income:unknown $-123.00 + + If the currency is provided as a separate CSV field: + + 2020-01-01,foo,USD,123.00 + + You can assign that to the currency pseudo-field, which has the special + effect of prepending itself to every amount in the transaction (on the + left, with no separating space): + + fields date,description,currency,amount + + 2020-01-01 foo + expenses:unknown USD123.00 + income:unknown USD-123.00 + + Or, you can use a field assignment to construct the amount yourself, + with more control. Eg to put the symbol on the right, and separated by + a space: + + fields date,description,cur,amt + amount %amt %cur + + 2020-01-01 foo + expenses:unknown 123.00 USD + income:unknown -123.00 USD + + Note we used a temporary field name (cur) that is not currency - that + would trigger the prepending effect, which we don't want here. + + Referencing other fields + In field assignments, you can interpolate only CSV fields, not hledger + fields. In the example below, there's both a CSV field and a hledger + field named amount1, but %amount1 always means the CSV field, not the + hledger field: + + # Name the third CSV field "amount1" + fields date,description,amount1 + + # Set hledger's amount1 to the CSV amount1 field followed by USD + amount1 %amount1 USD + + # Set comment to the CSV amount1 (not the amount1 assigned above) + comment %amount1 + + Here, since there's no CSV amount1 field, %amount1 will produce a lit- + eral "amount1": + + fields date,description,csvamount + amount1 %csvamount USD + # Can't interpolate amount1 here + comment %amount1 + + When there are multiple field assignments to the same hledger field, + only the last one takes effect. Here, comment's value will be be B, or + C if "something" is matched, but never A: + + comment A + comment B + if something + comment C + + How CSV rules are evaluated + Here's how to think of CSV rules being evaluated (if you really need + to). First, + + o include - all includes are inlined, from top to bottom, depth first. + (At each include point the file is inlined and scanned for further + includes, recursively, before proceeding.) + + Then "global" rules are evaluated, top to bottom. If a rule is re- + peated, the last one wins: + + o skip (at top level) + + o date-format + + o newest-first + + o fields - names the CSV fields, optionally sets up initial assignments + to hledger fields + + Then for each CSV record in turn: + + o test all if blocks. If any of them contain a end rule, skip all re- + maining CSV records. Otherwise if any of them contain a skip rule, + skip that many CSV records. If there are multiple matched skip + rules, the first one wins. + + o collect all field assignments at top level and in matched if blocks. + When there are multiple assignments for a field, keep only the last + one. + + o compute a value for each hledger field - either the one that was as- + signed to it (and interpolate the %CSVFIELDNAME references), or a de- + fault + + o generate a synthetic hledger transaction from these values. + + This is all part of the CSV reader, one of several readers hledger can + use to parse input files. When all files have been read successfully, + the transactions are passed as input to whichever hledger command the + user specified. + +TIMECLOCK FORMAT + The time logging format of timeclock.el, as read by hledger. + + hledger can read time logs in timeclock format. As with Ledger, these + are (a subset of) timeclock.el's format, containing clock-in and clock- + out entries as in the example below. The date is a simple date. The + time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional. + The timezone, if present, must be four digits and is ignored (currently + the time is always interpreted as a local time). + + i 2015/03/30 09:00:00 some:account name optional description after two spaces + o 2015/03/30 09:20:00 + i 2015/03/31 22:21:45 another account + o 2015/04/01 02:00:34 + + hledger treats each clock-in/clock-out pair as a transaction posting + some number of hours to an account. Or if the session spans more than + one day, it is split into several transactions, one for each day. For + the above time log, hledger print generates these journal entries: + + $ hledger -f t.timeclock print + 2015-03-30 * optional description after two spaces + (some:account name) 0.33h + + 2015-03-31 * 22:21-23:59 + (another account) 1.64h + + 2015-04-01 * 00:00-02:00 + (another account) 2.01h + + Here is a sample.timeclock to download and some queries to try: + + $ hledger -f sample.timeclock balance # current time balances + $ hledger -f sample.timeclock register -p 2009/3 # sessions in march 2009 + $ hledger -f sample.timeclock register -p weekly --depth 1 --empty # time summary by week + + To generate time logs, ie to clock in and clock out, you could: + + o use emacs and the built-in timeclock.el, or the extended timeclock- + x.el and perhaps the extras in ledgerutils.el + + o at the command line, use these bash aliases: shell alias ti="echo + i `date '+%Y-%m-%d %H:%M:%S'` \$* >>$TIMELOG" alias to="echo o + `date '+%Y-%m-%d %H:%M:%S'` >>$TIMELOG" + + o or use the old ti and to scripts in the ledger 2.x repository. These + rely on a "timeclock" executable which I think is just the ledger 2 + executable renamed. + +TIMEDOT FORMAT + hledger's human-friendly time logging format. + + Timedot is a plain text format for logging dated, categorised quanti- + ties (of time, usually), supported by hledger. It is convenient for + approximate and retroactive time logging, eg when the real-time clock- + in/out required with a timeclock file is too precise or too interrup- + tive. It can be formatted like a bar chart, making clear at a glance + where time was spent. + + Though called "timedot", this format is read by hledger as commodity- + less quantities, so it could be used to represent dated quantities + other than time. In the docs below we'll assume it's time. + + A timedot file contains a series of day entries. A day entry begins + with a non-indented hledger-style simple date (Y-M-D, Y/M/D, Y.M.D..) + Any additional text on the same line is used as a transaction descrip- + tion for this day. + + This is followed by optionally-indented timelog items for that day, one + per line. Each timelog item is a note, usually a hledger:style:ac- + count:name representing a time category, followed by two or more spa- + ces, and a quantity. Each timelog item generates a hledger transac- + tion. + + Quantities can be written as: + + o dots: a sequence of dots (.) representing quarter hours. Spaces may + optionally be used for grouping. Eg: .... .. + + o an integral or decimal number, representing hours. Eg: 1.5 + + o an integral or decimal number immediately followed by a unit symbol + s, m, h, d, w, mo, or y, representing seconds, minutes, hours, days + weeks, months or years respectively. Eg: 90m. The following equiva- + lencies are assumed, currently: 1m = 60s, 1h = 60m, 1d = 24h, 1w = + 7d, 1mo = 30d, 1y=365d. + + There is some flexibility allowing notes and todo lists to be kept + right in the time log, if needed: + + o Blank lines and lines beginning with # or ; are ignored. + + o Lines not ending with a double-space and quantity are parsed as items + taking no time, which will not appear in balance reports by default. + (Add -E to see them.) + + o Org mode headlines (lines beginning with one or more * followed by a + space) can be used as date lines or timelog items (the stars are ig- + nored). Also all org headlines before the first date line are ig- + nored. This means org users can manage their timelog as an org out- + line (eg using org-mode/orgstruct-mode in Emacs), for organisation, + faster navigation, controlling visibility etc. + + Examples: + + # on this day, 6h was spent on client work, 1.5h on haskell FOSS work, etc. + 2016/2/1 + inc:client1 .... .... .... .... .... .... + fos:haskell .... .. + biz:research . + + 2016/2/2 + inc:client1 .... .... + biz:research . + + 2016/2/3 + inc:client1 4 + fos:hledger 3 + biz:research 1 + + * Time log + ** 2020-01-01 + *** adm:time . + *** adm:finance . + + * 2020 Work Diary + ** Q1 + *** 2020-02-29 + **** DONE + 0700 yoga + **** UNPLANNED + **** BEGUN + hom:chores + cleaning ... + water plants + outdoor - one full watering can + indoor - light watering + **** TODO + adm:planning: trip + *** LATER + + Reporting: + + $ hledger -f t.timedot print date:2016/2/2 + 2016-02-02 * + (inc:client1) 2.00 + + 2016-02-02 * + (biz:research) 0.25 + + $ hledger -f t.timedot bal --daily --tree + Balance changes in 2016-02-01-2016-02-03: + + || 2016-02-01d 2016-02-02d 2016-02-03d + ============++======================================== + biz || 0.25 0.25 1.00 + research || 0.25 0.25 1.00 + fos || 1.50 0 3.00 + haskell || 1.50 0 0 + hledger || 0 0 3.00 + inc || 6.00 2.00 4.00 + client1 || 6.00 2.00 4.00 + ------------++---------------------------------------- + || 7.75 2.25 8.00 + + I prefer to use period for separating account components. We can make + this work with an account alias: + + 2016/2/4 + fos.hledger.timedot 4 + fos.ledger .. + + $ hledger -f t.timedot --alias /\\./=: bal date:2016/2/4 --tree + 4.50 fos + 4.00 hledger:timedot + 0.50 ledger + -------------------- + 4.50 + + Here is a sample.timedot. + COMMON TASKS Here are some quick examples of how to do some basic tasks with hledger. For more details, see the reference section below, the @@ -3790,33 +6478,6 @@ COMMON TASKS If using version control, don't forget to git add the new file. -ENVIRONMENT - LEDGER_FILE The journal file path when not specified with -f. Default: - ~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour- - nal). - - A typical value is ~/DIR/YYYY.journal, where DIR is a version-con- - trolled finance directory and YYYY is the current year. Or ~/DIR/cur- - rent.journal, where current.journal is a symbolic link to YYYY.journal. - - On Mac computers, you can set this and other environment variables in a - more thorough way that also affects applications started from the GUI - (say, an Emacs dock icon). Eg on MacOS Catalina I have a ~/.MacOSX/en- - vironment.plist file containing - - { - "LEDGER_FILE" : "~/finance/current.journal" - } - - To see the effect you may need to killall Dock, or reboot. - - COLUMNS The screen width used by the register command. Default: the - full terminal width. - - NO_COLOR If this variable exists with any value, hledger will not use - ANSI color codes in terminal output. This overrides the - --color/--colour option. - LIMITATIONS The need to precede add-on command options with -- when invoked from hledger is awkward.