diff --git a/doc/MANUAL.md b/doc/MANUAL.md index 3ab0b4a56..e6c7e0ace 100644 --- a/doc/MANUAL.md +++ b/doc/MANUAL.md @@ -1,12 +1,18 @@ -# User manual +# User Manual -For: hledger 0.22.1 +This manual is for + + +hledger 0.22.98 (the latest pre-0.23 HEAD). + +It is partly an introduction, but mainly a reference manual for hledger. +For a more gradual introduction, see [[step-by-step]] and [[more docs]]. ## Introduction -[hledger](http://hledger.org) is a program for tracking money, time, +[[home|hledger]] is a program for tracking money, time, or any other commodity, using a simple, editable file format and double-entry accounting, inspired by and largely compatible with [ledger](http://ledger-cli.org). hledger is Free Software released @@ -32,9 +38,9 @@ latest release with cabal-install, like so: $ cabal install hledger [hledger-web] ... $ hledger --version - hledger 0.19.3 + hledger 0.22.1 -For more help with this, and other install options, see the [Installation Guide](INSTALL.html). +For more help with this, and other install options, see the [[installing|Installation Guide]]. ## Basic Usage @@ -62,17 +68,17 @@ enter some transactions. Or, save this [sample file](https://raw.github.com/simonmichael/hledger/master/data/sample.journal) as `.hledger.journal` in your home directory. Now try commands like these: - $ hledger # show available commands - $ hledger add # add more transactions to the journal file - $ hledger balance # all accounts with aggregated balances - $ hledger balance --help # show help for balance command - $ hledger balance --depth 1 # only top-level accounts - $ hledger register # show a register of postings from all transactions - $ hledger reg income # show postings to/from income accounts - $ hledger reg checking # show postings to/from checking account - $ hledger reg desc:shop # show postings with shop in the description - $ hledger activity # show transactions per day as a bar chart - + $ hledger # show available commands + $ hledger add # add more transactions to the journal file + $ hledger balance # all accounts with aggregated balances + $ hledger balance --help # show help for balance command + $ hledger balance --depth 1 # only top-level accounts + $ hledger register # show a register of postings from all transactions + $ hledger reg income # show postings to/from income accounts + $ hledger reg checking # show postings to/from checking account + $ hledger reg desc:shop # show postings with shop in the description + $ hledger activity # show transactions per day as a bar chart + ## Data format ### Journal files @@ -138,9 +144,7 @@ The posting amounts within a transaction must always balance, ie add up to Within a journal file, transaction dates always follow a year/month/day format, although several different separator characters are accepted. Some -examples: - -> `2010/01/31`, `2010/1/31`, `2010-1-31`, `2010.1.31` +examples: `2010/01/31`, `2010/1/31`, `2010-1-31`, `2010.1.31`. Writing the year is optional if you set a default year with a Y directive. This is a line containing `Y` and the year; it affects subsequent @@ -270,11 +274,17 @@ parse order. This is different from ledger, which currently goes strictly by parse order. Sorting by date means balance assertions will still work if you reorder your entries. +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 can run into trouble depending on where the assertion is located. + Also note the asserted balance must be a simple amount - it's not currently possible to assert a balance containing multiple commodities. -The impact of balance assertions on parsing time for large files is -not yet known. +The impact of many balance assertions on parsing time for large files is +unknown. #### Prices @@ -332,31 +342,31 @@ hledger will parse and ignore ledger-style historical price directives: ; $1.40 from 2010/1/1 on. P 2009/1/1 € $1.35 P 2010/1/1 € $1.40 - + #### Comments -A semicolon in the journal file marks the start of a comment. You can -write comments on their own line between transactions, like so: +- A semicolon (`;`) or hash (`#`) in column 0 starts a journal comment line, which hledger will ignore. - ; Also known as a "journal comment". Whitespace before the ; is allowed. +- A semicolon after a transaction's description and/or indented on the following lines +starts a transaction comment. -You can also write transaction- or posting-specific comments following the -transaction's first line or the posting, on the same line and/or indented -on following lines. Some examples: +- A semicolon after a posting's amount and/or indented on the following lines starts a posting comment. - ; a journal comment - 2012/5/14 something ; and now a transaction comment - ; another comment for this transaction - posting1 1 ; a comment for posting 1 - posting2 - ; a comment for posting 2 - ; another comment for posting 2 - ; another journal comment (because not indented) +Transaction and posting comments are displayed by [[#print]], can contain [[#tags]] and can be [[#queries|queried]]. -Currently `print` preserves transaction and posting comments but not -journal comments. +Some examples: + + # a journal comment + + ; also a journal 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 journal comment (because not indented) -Comments may contain [tags](#tags). #### Tags @@ -391,25 +401,33 @@ Eg: To forget all aliases defined to this point, use: end aliases - -See also [How to use account aliases](ALIASES.html). + +You can also specify aliases on the command line: + + $ hledger --alias 'my earning=income:business' ... + +Journal directive aliases are applied first, then command-line aliases, +and at most one of each will be applied to each account name. + +See also [[How to use account aliases]]. ##### Default commodity You can set a default commodity, to be used for any subsequent amounts -which have no commodity symbol, with the D directive: +which have no commodity symbol (including [[#add|added]] amounts), with the D directive: ; set british pound as default commodity ; also sets canonical style for pound amounts, since it's the first one - ; (pound symbol on left, comma thousands separator, two decimal places) D £1,000.00 2010/1/1 - a 2340 ; no symbol, will use pound + a 2340 ; no symbol, will use default commodity and style + ; (pound symbol on left, comma thousands separator, two decimal places) b -A default commodity directive may also influence the canonical -[amount style](#commodity-display-settings) for the commodity. +A default commodity directive can also influence the +[[#canonical-amount-styles|canonical amount style]] for the commodity, +as in the example above. ##### Default parent account @@ -467,9 +485,9 @@ are the journal entry's date and amount: Lines beginning with `#` or `;` and blank lines are ignored. The following kinds of rule can appear in any order: -**fields** *CSVFIELDNAME1*, *CSVFIELDNAME1*, ... -: (Field list) This names the CSV fields (names may not contain whitespace or `;` or `#`), - and also assigns them to journal entry fields when you use any of these names: +**fields** *CSVFIELDNAME1*, *CSVFIELDNAME1*, ...\\ +(Field list) This names the CSV fields (names may not contain whitespace or `;` or `#`), +and also assigns them to journal entry fields when you use any of these names: date date2 @@ -484,80 +502,80 @@ The following kinds of rule can appear in any order: amount-in amount-out -*JOURNALFIELDNAME* *FIELDVALUE* -: (Field assignment) This assigns the given text value - to a journal entry field (one of the field names above). - CSV fields can be referenced with `%CSVFIELDNAME` or `%N` (N starts at 1) and will be interpolated. +*JOURNALFIELDNAME* *FIELDVALUE*\\ +(Field assignment) This assigns the given text value +to a journal entry field (one of the field names above). +CSV fields can be referenced with `%CSVFIELDNAME` or `%N` (N starts at 1) and will be interpolated. - You can use a field list, field assignments, or both. - At least the `date` and `amount` fields must be assigned. +You can use a field list, field assignments, or both. +At least the `date` and `amount` fields must be assigned. -**if** *PATTERNS*
  *FIELDASSIGNMENTS* -: (Conditional block) This applies the field assignments only to CSV records matched by one of the PATTERNS. +**if** *PATTERNS*\\ (*INDENT*)*FIELDASSIGNMENTS*\\ +(Conditional block) This applies the field assignments only to CSV records matched by one of the PATTERNS. - PATTERNS is one or more regular expressions, each on its own line. - The first pattern can optionally be written on the same line as - the `if`; patterns on the following lines must start in column 0 - (no indenting). The regular expressions are case insensitive, and - can match anywhere within the whole CSV record. (It's not yet - possible to match within a specific field.) +PATTERNS is one or more regular expressions, each on its own line. +The first pattern can optionally be written on the same line as +the `if`; patterns on the following lines must start in column 0 +(no indenting). The regular expressions are case insensitive, and +can match anywhere within the whole CSV record. (It's not yet +possible to match within a specific field.) - FIELDASSIGNMENTS is one or more field assignments (described - above), each on its own line and indented by at least one - space. (The indent is required for successful parsing.) +FIELDASSIGNMENTS is one or more field assignments (described +above), each on its own line and indented by at least one +space. (The indent is required for successful parsing.) - Example 1. The simplest conditional block has a single pattern and - a single field assignment. Here, any CSV record containing the - pattern `groceries` will have its account2 field set to - `expenses:groceries`. +Example 1. The simplest conditional block has a single pattern and +a single field assignment. Here, any CSV record containing the +pattern `groceries` will have its account2 field set to +`expenses:groceries`. - if groceries - account2 expenses:groceries + if groceries + account2 expenses:groceries - Example 2. Here, CSV records containing any of these patterns will - have their account2 and comment fields set as shown. The - capitalisation is not required, that's just how I copied them from - my bank's CSV. +Example 2. Here, CSV records containing any of these patterns will +have their account2 and comment fields set as shown. The +capitalisation is not required, that's just how I copied them from +my bank's CSV. - if - MONTHLY SERVICE FEE - ATM TRANSACTION FEE - FOREIGN CURR CONV - OVERDRAFT TRANSFER FEE - BANKING THRU SOFTWARE:FEE - INTERNATIONAL PURCHASE TRANSACTION FEE - WIRE TRANS SVC CHARGE - FEE FOR TRANSFER - VISA ISA FEE - account2 expenses:business:banking - comment XXX probably deductible, check + if + MONTHLY SERVICE FEE + ATM TRANSACTION FEE + FOREIGN CURR CONV + OVERDRAFT TRANSFER FEE + BANKING THRU SOFTWARE:FEE + INTERNATIONAL PURCHASE TRANSACTION FEE + WIRE TRANS SVC CHARGE + FEE FOR TRANSFER + VISA ISA FEE + account2 expenses:business:banking + comment XXX probably deductible, check -**skip** [*N*] -: Skip this number of CSV records (1 by default). - Use this to skip CSV header lines. - - - +**skip** [*N*]\\ +Skip this number of CSV records (1 by default). +Use this to skip CSV header lines. + + + -**date-format** *DATEFMT* -: This is required if the values for `date` or `date2` fields are not in YYYY/MM/DD format (or close to it). - DATEFMT specifies a strptime-style date parsing pattern containing [year/month/date format codes](http://hackage.haskell.org/packages/archive/time/latest/doc/html/Data-Time-Format.html#v:formatTime). - Note the pattern must parse the CSV date value completely. Some examples: +**date-format** *DATEFMT*\\ +This is required if the values for `date` or `date2` fields are not in YYYY/MM/DD format (or close to it). +DATEFMT specifies a strptime-style date parsing pattern containing [year/month/date format codes](http://hackage.haskell.org/packages/archive/time/latest/doc/html/Data-Time-Format.html#v:formatTime). +Note the pattern must parse the CSV date value completely. Some examples: - # "6/11/2013" - date-format %-d/%-m/%Y + # "6/11/2013" + date-format %-d/%-m/%Y - # "11/06/2013" - date-format %m/%d/%Y - - # "2013-Nov-06" - date-format %Y-%h-%d + # "11/06/2013" + date-format %m/%d/%Y - # "11/6/2013 11:32 PM" - date-format %-m/%-d/%Y %l:%M %p + # "2013-Nov-06" + date-format %Y-%h-%d -**include** *RULESFILE* -: Include another rules file at this point. Useful for common rules shared across multiple CSV files. + # "11/6/2013 11:32 PM" + date-format %-m/%-d/%Y %l:%M %p + +**include** *RULESFILE*\\ +Include another rules file at this point. Useful for common rules shared across multiple CSV files. Typically you'll keep one rules file for each account which you download as CSV. For an example, see [How to read CSV @@ -606,10 +624,10 @@ To generate time logs, ie to clock in and clock out, you could: and perhaps the extras in [ledgerutils.el](http://hub.darcs.net/simon/ledgertools/ledgerutils.el) - at the command line, use these bash aliases: - - alias ti="echo i \`date '+%Y-%m-%d %H:%M:%S'\` \$* >>$TIMELOG" - alias to="echo o \`date '+%Y-%m-%d %H:%M:%S'\` >>$TIMELOG" - + ``` + 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](https://github.com/ledger/ledger/tree/maint/scripts). These rely on a "timeclock" executable which I think is just the ledger 2 executable renamed. @@ -759,12 +777,9 @@ an overview: $ for y in 2006 2007 2008 2009 2010; do echo; echo $y; hledger -f $y.journal balance ^expenses --depth 2; done -With `--flat`, a non-hierarchical list of full account names is displayed -instead. This mode shows just the accounts actually contributing to the -balance, making the arithmetic a little more obvious to non-hledger users. -In this mode you can also use `--drop N` to elide the first few account -name components. Note `--depth` doesn't work too well with `--flat` currently; -it hides deeper accounts rather than aggregating them. +With `--flat`, a simple list of full account names is displayed instead, each with it's inclusive balance (including any subaccount balances). +In this mode you can use `--drop N` to elide the first few account name components. +The `--depth` flag also works. With a [reporting interval](#reporting-interval), multiple columns will be shown, one for each period. There are three modes available: @@ -933,9 +948,9 @@ Examples: $ hledger-web -E -B --depth 2 -f some.journal $ hledger-web --server --port 5010 --base-url http://some.vhost.com --debug -\ -\ -\ +\\ +\\ +\\ The following add-ons are examples and experiments provided in the [extra](https://github.com/simonmichael/hledger/tree/master/extra) directory in the hledger source. Add this directory to your PATH to @@ -1038,7 +1053,8 @@ The following common features and options work with most subcommands. Part of hledger's usefulness is being able to report on just a precise subset of your data. Most commands accept an optional query expression, written as arguments after the command name, -to filter the data by date, account name or other criteria. +to filter the data by date, account name or other criteria. Query expressions are also used +in the [[#web|web ui]]'s search form. The query syntax is similar to a Google search expression: one or more space-separated search terms, optional prefixes to match specific @@ -1049,61 +1065,50 @@ A query term can be any of the following: - `acct:REGEX` - same as above - `code:REGEX` - match by transaction code (eg check number) - `desc:REGEX` - match transaction descriptions -- `date:PERIODEXPR` - match dates within the specified [period](#period-expressions) +- `date:PERIODEXPR` - match dates within the specified [[#period-expressions|period]]. *Actually, full period syntax is [[https://github.com/simonmichael/hledger/issues/141|not yet supported]].* - `date2:PERIODEXPR` - as above, but match secondary dates -- `tag:NAME[=REGEX]` - match by (exact, case sensitive) [tag](#tags) name, and optionally match the tag value by regular expression -- `depth:N` - match (or display, depending on command) accounts at or above this [depth](#depth-limiting) +- `tag:NAME[=REGEX]` - match by (exact, case sensitive) [[#tags|tag]] name, and optionally match the tag value by regular expression. Note `tag:` will match a transaction if it or any its postings have the tag, and will match posting if it or its parent transaction has the tag. +- `depth:N` - match (or display, depending on command) accounts at or above this [[#depth-limiting|depth]] - `status:1` or `status:0` - match cleared/uncleared transactions - `real:1` or `real:0` - match real/virtual-ness - `empty:1` or `empty:0` - match if amount is/is not zero - `amt:N` or `amt:=N`, `amt:N` - match postings with a - single-commodity amount equal to, less than, or greater than - N. (Multi-commodity amounts are always matched.) Be warned, the - match is sensitive to the sign of N - this can be used to search for - inflows or outflows. -- `sym:REGEX` - match postings or transactions including any amounts - whose commodity symbol is fully matched by REGEX. (For a partial - match, use `.*REGEX.*`). To match the dollar sign (`$`): you - need to prepend `\` so it's not interpreted as a regular - expression metacharacter, at the command line you need one more level - of quoting to hide it from the shell, so eg do: `hledger print sym:'\$'`. - To strictly limit reports to a single commodity, it may work better - to exclude the others, eg: `hledger bal not:sym:'(EUR|¥|£)'. + single-commodity amount equal to, less than, or greater than N. + (Multi-commodity amounts are not tested, and always match.) + This has two modes of operation: if N is preceded by a `+` or `-` sign, the + actual signed numbers are compared; otherwise the unsigned absolute values are compared. +- `cur:REGEX` - match postings or transactions including any amounts + whose currency/commodity symbol is fully matched by REGEX. (For a + partial match, use `.*REGEX.*`). Note, to match characters which are + regex-significant, like the dollar sign (`$`), you need to prepend `\`. + And when using the command line you need to add one more level + of quoting to hide it from the shell, so eg do: `hledger print cur:'\$'` + or `hledger print cur:\\$`. - `not:` before any of the above negates the match - +#### How query terms combine -Multiple query terms will select transactions/postings/accounts which match -(or negatively match) +hledger query expressions don't support full boolean logic. Instead, multiple query terms +are combined as follows: -> *any of the description terms AND* -> *any of the account terms AND* -> *all the other terms* +- The [[#print]] command selects transactions which: + - match any of the description terms AND + - have any postings matching any of the positive account terms AND + - have no postings matching any of the negative account terms AND + - match all the other terms. + + + +- Other reporting commands (eg [[#register]] and [[#balance]]) select transactions/postings/accounts which match (or negatively match): + - any of the description terms AND + - any of the account terms AND + - all the other terms. +#### Query options vs query arguments -With the [print](#print) command, they select transactions which - -> *match any of the description terms AND* -> *have any postings matching any of the positive account terms AND* -> *have no postings matching any of the negative account terms AND* -> *match all the other terms* - -Many of the query terms above have equivalent command-line flags which predate them. -You can mix and match query arguments and flags, just note that a -[period expression](#period-expressions) overrides any other date terms. - -The same query syntax should work in both the command line and [web](#web) interfaces. - +On the command line, some of the query terms above can also be expressed as command-line flags. +Generally you can mix and match query arguments and flags, and the resulting query will be their intersection. Note within the command-line flags, a `-p` [[#period-expressions|period]] flag causes any `-b` or `-e` flags, and any preceding `-p` flags, to be ignored. ### Smart dates @@ -1292,50 +1297,51 @@ Here are some issues you might encounter when you run hledger [mail list](http://hledger.org/list) or [bug tracker](http://hledger.org/bugs)): -#. **hledger installed, but running hledger says something like No command 'hledger' found** - cabal installs binaries into a special directory, which should be added - to your PATH environment variable. On unix-like systems, it is - ~/.cabal/bin. +### Successfully installed, but "No command 'hledger' found" +cabal installs binaries into a special directory, which should be added +to your PATH environment variable. On unix-like systems, it is +~/.cabal/bin. -#. **hledger fails to parse some valid ledger files** - See [file format differences](FAQ.html#what-are-the-file-format-differences). +### Fails to parse some valid Ledger files +See [[faq#file-format-differences|file format differences]]. -#. **hledger gives "Illegal byte sequence" or "Invalid or incomplete multibyte or wide character" errors** - In order to handle non-ascii letters and symbols (like £), hledger needs - an appropriate locale. This is usually configured system-wide; you can - also configure it temporarily. The locale may need to be one that - supports UTF-8, if you built hledger with GHC < 7.2 (or possibly always, - I'm not sure yet). - - Here's an example of setting the locale temporarily, on ubuntu gnu/linux: - - $ file my.journal - my.journal: UTF-8 Unicode text # <- the file is UTF8-encoded - $ locale -a - C - en_US.utf8 # <- a UTF8-aware locale is available - POSIX - $ LANG=en_US.utf8 hledger -f my.journal print # <- use it for this command +### "Illegal byte sequence" or "Invalid or incomplete multibyte or wide character" errors +In order to handle non-ascii letters and symbols (like £), hledger needs +an appropriate locale. This is usually configured system-wide; you can +also configure it temporarily. The locale may need to be one that +supports UTF-8, if you built hledger with GHC < 7.2 (or possibly always, +I'm not sure yet). - Here's one way to set it permanently, there are probably better ways: +Here's an example of setting the locale temporarily, on ubuntu gnu/linux: - $ echo "export LANG=en_US.UTF-8" >>~/.bash_profile - $ bash --login + $ file my.journal + my.journal: UTF-8 Unicode text # <- the file is UTF8-encoded + $ locale -a + C + en_US.utf8 # <- a UTF8-aware locale is available + POSIX + $ LANG=en_US.utf8 hledger -f my.journal print # <- use it for this command - If we preferred to use eg `fr_FR.utf8`, we might have to install that first: +Here's one way to set it permanently, there are probably better ways: - $ apt-get install language-pack-fr - $ locale -a - C - en_US.utf8 - fr_BE.utf8 - fr_CA.utf8 - fr_CH.utf8 - fr_FR.utf8 - fr_LU.utf8 - POSIX - $ LANG=fr_FR.utf8 hledger -f my.journal print + $ echo "export LANG=en_US.UTF-8" >>~/.bash_profile + $ bash --login + +If we preferred to use eg `fr_FR.utf8`, we might have to install that first: + + $ apt-get install language-pack-fr + $ locale -a + C + en_US.utf8 + fr_BE.utf8 + fr_CA.utf8 + fr_CH.utf8 + fr_FR.utf8 + fr_LU.utf8 + POSIX + $ LANG=fr_FR.utf8 hledger -f my.journal print + +Note some platforms allow variant locale spellings, but not all (ubuntu +accepts `fr_FR.UTF8`, mac osx requires exactly `fr_FR.UTF-8`). - Note some platforms allow variant locale spellings, but not all (ubuntu - accepts `fr_FR.UTF8`, mac osx requires exactly `fr_FR.UTF-8`).