all repos

clerk @ d12c0794480a4e65333d20e93d8a9f24a53ea056

missing tooling for ledger/hledger

clerk/journal/printer/amount.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
printer: add commodity-space option, 13 days ago
1
package printer
2
3
import (
4
	"olexsmir.xyz/clerk/internal/decimal"
5
	"olexsmir.xyz/clerk/journal/ast"
6
)
7
8
func (p *printer) writeAmount(a *ast.Amount) {
9
	if a == nil {
10
		return
11
	}
12
13
	if a.IsExpr {
14
		if a.Expr != "" {
15
			// parenthesized expression, e.g. (amount * 0.5)
16
			p.buf.WriteByte('(')
17
			p.buf.WriteString(a.Expr)
18
			p.buf.WriteByte(')')
19
			return
20
		} else {
21
			// bare scaling expr, e.g. `*-1`, `*.33` — parser stored the value in Quantity
22
			p.buf.WriteByte('*')
23
		}
24
	}
25
26
	prec := max(a.QuantityFmt.Precision, 2)
27
28
	comm := a.Commodity
29
	if comm == "" {
30
		p.writeDecimal(a.Quantity, a.QuantityFmt, prec)
31
		return
32
	}
33
34
	switch p.cfg.CommodityPos {
35
	case CommodityPosBefore:
36
		p.buf.WriteString(comm)
37
		p.writeCommoditySpace(a)
38
		p.writeDecimal(a.Quantity, a.QuantityFmt, prec)
39
	case CommodityPosAfter:
40
		p.writeDecimal(a.Quantity, a.QuantityFmt, prec)
41
		p.writeCommoditySpace(a)
42
		p.buf.WriteString(comm)
43
	default:
44
		panic("impossible CommodityPos value")
45
	}
46
}
47
48
func (p *printer) writeCommoditySpace(a *ast.Amount) {
49
	switch p.cfg.CommoditySpace {
50
	case CommoditySpacePreserve:
51
		if a.HasSpace {
52
			p.buf.WriteByte(' ')
53
		}
54
	case CommoditySpaceAlways:
55
		p.buf.WriteByte(' ')
56
	case CommoditySpaceNever:
57
	default:
58
		panic("impossible CommoditySpace value")
59
	}
60
}
61
62
func (p *printer) writeCost(c *ast.Cost) {
63
	if c.IsTotal {
64
		p.buf.WriteString(" @@ ")
65
	} else {
66
		p.buf.WriteString(" @ ")
67
	}
68
	p.writeAmount(&c.Amount)
69
}
70
71
func (p *printer) writeBalanceAssertion(ba *ast.BalanceAssertion) {
72
	if ba == nil {
73
		return
74
	}
75
	switch {
76
	case ba.IsStrict && ba.IsInclusive:
77
		p.buf.WriteString("=== ")
78
	case ba.IsStrict:
79
		p.buf.WriteString("== ")
80
	case ba.IsInclusive:
81
		p.buf.WriteString("=* ")
82
	default:
83
		p.buf.WriteString("= ")
84
	}
85
	p.writeAmount(&ba.Amount)
86
	if ba.Cost != nil {
87
		p.writeCost(ba.Cost)
88
	}
89
}
90
91
func (p *printer) writeDecimal(d decimal.Decimal, fmt ast.QuantityFormat, forcePrec int) {
92
	d.WriteFixed(&p.buf, forcePrec, fmt.Decimal, fmt.Thousands)
93
}