;doc:journal: decimal marks, commodity directives: rewrites

This commit is contained in:
Simon Michael 2023-11-20 10:45:37 -10:00
parent d717732928
commit 4febb74d1e

View File

@ -1175,7 +1175,7 @@ Scientific E notation is allowed:
A *decimal mark* can be written as a period or a comma: A *decimal mark* can be written as a period or a comma:
1.23 1.23
1,23456780000009 1,23
In the integer part of the quantity (left of the decimal mark), groups 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 of digits can optionally be separated by a *digit group mark* - a
@ -1186,22 +1186,17 @@ space, comma, or period (different from the decimal mark):
INR 9,99,99,999.00 INR 9,99,99,999.00
1 000 000.9455 1 000 000.9455
Note, a number containing a single digit group mark and no decimal mark is ambiguous. hledger is not biased towards [period or comma decimal marks][international number formats],
Are these digit group marks or decimal marks ? so a number containing just one period or comma, like `1,000` or `1.000`, is ambiguous.
In such cases hledger assumes it is a decimal mark, parsing both of these as 1.
1,000 [international number formats]: https://en.wikipedia.org/wiki/Decimal_separator#Conventions_worldwide
1.000
If you don't tell it otherwise, hledger will assume both of the above are decimal marks, To disambiguate these and ensure accurate number parsing, especially
parsing both numbers as 1. if you use digit group marks, we recommend declaring the decimal mark.
You can declare it for each file with [`decimal-mark`](#decimal-mark-directive) directives,
To prevent confusing parsing mistakes and undetected typos, or for each commodity with [`commodity`](#commodity-directive) directives
especially if your data contains digit group marks (eg, thousands separators), (described below).
we recommend explicitly declaring the decimal mark character in each journal file,
using a directive at the top of the file.
The [`decimal-mark`](#decimal-mark) directive is best,
otherwise [`commodity`](#commodity-directive) directives will also work.
These are described below.
### Commodity ### Commodity
@ -1278,11 +1273,13 @@ the `-c/--commodity-style` command line option.
### Rounding ### Rounding
Amounts are stored internally as decimal numbers with up to 255 decimal places, 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. They are displayed
Note, hledger uses [banker's rounding](https://en.wikipedia.org/wiki/Bankers_rounding): with their original journal precisions by print and print-like reports,
it rounds to the nearest even number, eg 0.5 displayed with zero decimal places is "0"). and rounded to their display precision (the number of decimal digits specified by the commodity display style)
by other reports.
When rounding, hledger uses [banker's rounding](https://en.wikipedia.org/wiki/Bankers_rounding)
(it rounds to the nearest even digit). So eg 0.5 displayed with zero decimal digits appears as "0".
<a name="transaction-prices"></a> <a name="transaction-prices"></a>
@ -2096,92 +2093,82 @@ $ hledger accounts --alias assets=bassetts type:a
## `commodity` directive ## `commodity` directive
You can use `commodity` directives to declare your commodities. The `commodity` directive performs several functions:
In fact the `commodity` directive performs several functions at once:
1. It declares commodities which may be used in the journal. 1. It declares which commodity symbols may be used in the journal,
This can optionally be enforced, providing useful error checking. enabling useful error checking with [strict mode] or the check command.
(Cf [Commodity error checking](#commodity-error-checking)) (See [Commodity error checking](#commodity-error-checking) below.)
2. It declares which decimal mark character (period or comma), to 2. It declares the precision with which this commodity's amounts
expect when parsing input - useful to disambiguate international should be compared when checking for balanced transactions.
number formats in your data. Without this, hledger will parse both
`1,000` and `1.000` as 1.
(Cf [Amounts](#amounts))
3. It declares how to render the commodity's amounts when displaying 3. It declares how this commodity's amounts should be displayed,
output - the decimal mark, any digit group marks, the number of eg their symbol placement, digit group mark if any, digit group sizes,
decimal places, symbol placement and so on. decimal mark (period or comma), and the number of decimal places.
(Cf [Commodity display style](#commodity-display-style)) (See [Commodity display style](#commodity-display-style) above.)
You will run into one of the problems solved by commodity directives 4. It sets which decimal mark (period or comma) to expect when parsing subsequent amounts in this commodity
sooner or later, so we recommend using them, for robust and (if there is no `decimal-mark` directive in effect.
predictable parsing and display. See [Decimal marks, digit group marks](hledger.md#decimal-marks-digit-group-marks) above.
For related dev discussion, see [#793](https://github.com/simonmichael/hledger/issues/793).)
Generally you should put them at the top of your journal file Declaring commodities solves several common parsing/display problems, so we recommend it.
(since for function 2, they affect only following amounts, Generally you should put `commodity` directives at the top of your journal file (because function 4 is position-sensitive).
cf [#793](https://github.com/simonmichael/hledger/issues/793)).
A commodity directive is just the word `commodity` followed by a ### Commodity directive syntax
sample [amount](#amounts), like this:
A commodity directive is normally the word `commodity` followed by a sample [amount](#amounts) (and optionally a comment).
Only the amount's symbol and format is significant.
Eg:
```journal ```journal
;commodity SAMPLEAMOUNT
commodity $1000.00 commodity $1000.00
commodity 1,000.0000 AAAA ; optional same-line comment commodity 1.000,00 EUR
commodity 1 000 000.0000 ; the no-symbol commodity
``` ```
It may also be written on multiple lines, and use the `format` The sample amount must always include a decimal mark (a period or comma).
subdirective, as in Ledger. Note in this case the commodity symbol To specify no decimal digits, write it at the end:
appears twice; it must be the same in both places:
```journal ```journal
;commodity SYMBOL commodity 1000. AAAA ; show with no decimal digits
; format SAMPLEAMOUNT ```
Commodity symbols containing spaces, numbers, or punctuation must be enclosed in double quotes, [as usual](#commodity):
```journal
commodity 1.0000 "AAAA 2023"
```
Commodity directives normally include a sample amount, but can declare only a symbol (ie, just function 1 above):
```journal
commodity $
commodity INR
commodity "AAAA 2023"
commodity "" ; the no-symbol commodity
```
Commodity directives may also be written with an indented `format` subdirective, as in Ledger.
The symbol is repeated and must be the same in both places.
Other subdirectives are currently ignored:
```journal
; display indian rupees with currency name on the left, ; display indian rupees with currency name on the left,
; thousands, lakhs and crores comma-separated, ; thousands, lakhs and crores comma-separated,
; period as decimal point, and two decimal places. ; period as decimal point, and two decimal places.
commodity INR commodity INR
format INR 1,00,00,000.00 format INR 1,00,00,000.00
an unsupported subdirective ; ignored by hledger
``` ```
Other indented subdirectives are currently ignored.
Remember that if the commodity symbol contains spaces, numbers, or
punctuation, it must be enclosed in double quotes (cf [Commodity](#commodity)).
The amount's quantity does not matter; only the format is significant.
It must include a decimal mark - either a period or a comma - followed
by 0 or more decimal digits.
A few more examples:
```journal
# number formats for $, EUR, INR and the no-symbol commodity:
commodity $1,000.00
commodity EUR 1.000,00
commodity INR 9,99,99,999.0
commodity 1 000 000.
```
Note hledger normally uses
[banker's rounding](https://en.wikipedia.org/wiki/Bankers_rounding),
so 0.5 displayed with zero decimal digits is "0".
(More at [Commodity display style](#commodity-display-style).)
Even in the presence of commodity directives, the commodity display style
can still be [overridden](#commodity-styles) by supplying a command line option.
### Commodity error checking ### Commodity error checking
In [strict mode], enabled with the `-s`/`--strict` flag, hledger will report an error if a In [strict mode] (`-s`/`--strict`) (or when you run `hledger check commodities`),
commodity symbol is used that has not been declared by a [`commodity` directive](#commodity-directive). hledger will report an error if an undeclared commodity symbol is used.
This works similarly to [account error checking](#account-error-checking), see the notes there for more details. (With one exception: zero amounts are always allowed to have no commodity symbol.)
It works like [account error checking](#account-error-checking) (described above).
Note, this disallows amounts without a commodity symbol,
because currently it's not possible (?) to declare the "no-symbol" commodity with a directive.
This is one exception for convenience: zero amounts are always allowed to have no commodity symbol.
## `decimal-mark` directive ## `decimal-mark` directive