Skip to content

Commit 62be50b

Browse files
committed
feat: comments stay attached to each part of transaction
Comments will flow through and stay attached to the payee or account they where attached to in the file, and printing keeps the comments in same location. No longer bunch comments to before the transaction.
1 parent 9427bee commit 62be50b

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

ledger/cmd/print.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,26 @@ func WriteTransaction(w io.Writer, trans *ledger.Transaction, columns int) {
144144
return trans.AccountChanges[i].Name < trans.AccountChanges[j].Name
145145
})
146146

147-
fmt.Fprintf(w, "%s %s\n", trans.Date.Format(transactionDateFormat), trans.Payee)
147+
fmt.Fprintf(w, "%s %s", trans.Date.Format(transactionDateFormat), trans.Payee)
148+
if len(trans.PayeeComment) > 0 {
149+
spaceCount := columns - 10 - utf8.RuneCountInString(trans.Payee)
150+
if spaceCount < 1 {
151+
spaceCount = 1
152+
}
153+
fmt.Fprintf(w, "%s%s", strings.Repeat(" ", spaceCount), trans.PayeeComment)
154+
}
155+
fmt.Fprintln(w, "")
148156
for _, accChange := range trans.AccountChanges {
149157
outBalanceString := accChange.Balance.StringFixedBank()
150158
spaceCount := columns - 4 - utf8.RuneCountInString(accChange.Name) - utf8.RuneCountInString(outBalanceString)
151159
if spaceCount < 1 {
152160
spaceCount = 1
153161
}
154-
fmt.Fprintf(w, " %s%s%s\n", accChange.Name, strings.Repeat(" ", spaceCount), outBalanceString)
162+
fmt.Fprintf(w, " %s%s%s", accChange.Name, strings.Repeat(" ", spaceCount), outBalanceString)
163+
if len(accChange.Comment) > 0 {
164+
fmt.Fprintf(w, " %s", accChange.Comment)
165+
}
166+
fmt.Fprintln(w, "")
155167
}
156168
fmt.Fprintln(w, "")
157169
}

parse.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,19 @@ func parseLedger(filename string, ledgerReader io.Reader, callback func(t *Trans
9797
trimmedLine := strings.TrimSpace(line)
9898
lp.lineCount++
9999

100+
var currentComment string
100101
// handle comments
101102
if commentIdx := strings.Index(trimmedLine, ";"); commentIdx >= 0 {
102-
lp.comments = append(lp.comments, trimmedLine[commentIdx:])
103+
currentComment = trimmedLine[commentIdx:]
103104
trimmedLine = trimmedLine[:commentIdx]
104105
trimmedLine = strings.TrimSpace(trimmedLine)
105106
}
106107

107108
// Skip empty lines
108109
if len(trimmedLine) == 0 {
110+
if len(currentComment) > 0 {
111+
lp.comments = append(lp.comments, currentComment)
112+
}
109113
continue
110114
}
111115

@@ -115,6 +119,9 @@ func parseLedger(filename string, ledgerReader io.Reader, callback func(t *Trans
115119
fmt.Errorf("Unable to parse payee line: %s", line))) {
116120
return true
117121
}
122+
if len(currentComment) > 0 {
123+
lp.comments = append(lp.comments, currentComment)
124+
}
118125
continue
119126
}
120127
switch before {
@@ -138,7 +145,7 @@ func parseLedger(filename string, ledgerReader io.Reader, callback func(t *Trans
138145
}
139146
}
140147
default:
141-
trans, transErr := lp.parseTransaction(before, after)
148+
trans, transErr := lp.parseTransaction(before, after, currentComment)
142149
if transErr != nil {
143150
if callback(nil, fmt.Errorf("%s:%d: Unable to parse transaction: %w", lp.filename, lp.lineCount, transErr)) {
144151
return true
@@ -189,12 +196,12 @@ func (lp *parser) parseDate(dateString string) (transDate time.Time, err error)
189196
return
190197
}
191198

192-
func (lp *parser) parseTransaction(dateString, payeeString string) (trans *Transaction, err error) {
199+
func (lp *parser) parseTransaction(dateString, payeeString, payeeComment string) (trans *Transaction, err error) {
193200
transDate, derr := lp.parseDate(dateString)
194201
if derr != nil {
195202
return nil, derr
196203
}
197-
trans = &Transaction{Payee: payeeString, Date: transDate}
204+
trans = &Transaction{Payee: payeeString, Date: transDate, PayeeComment: payeeComment}
198205

199206
var line string
200207
for lp.scanner.Scan() {
@@ -203,12 +210,14 @@ func (lp *parser) parseTransaction(dateString, payeeString string) (trans *Trans
203210
trimmedLine := strings.TrimSpace(line)
204211
lp.lineCount++
205212

213+
var currentComment string
206214
// handle comments
207215
if commentIdx := strings.Index(trimmedLine, ";"); commentIdx >= 0 {
208-
lp.comments = append(lp.comments, trimmedLine[commentIdx:])
216+
currentComment = trimmedLine[commentIdx:]
209217
trimmedLine = trimmedLine[:commentIdx]
210218
trimmedLine = strings.TrimSpace(trimmedLine)
211219
if len(trimmedLine) == 0 {
220+
lp.comments = append(lp.comments, currentComment)
212221
continue
213222
}
214223
}
@@ -225,6 +234,7 @@ func (lp *parser) parseTransaction(dateString, payeeString string) (trans *Trans
225234

226235
var accChange Account
227236
accChange.Name = trimmedLine
237+
accChange.Comment = currentComment
228238
if i := strings.LastIndexFunc(trimmedLine, unicode.IsSpace); i >= 0 {
229239
acc := strings.TrimSpace(trimmedLine[:i])
230240
amt := trimmedLine[i+1:]

parse_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,16 @@ var testCases = []testCase{
214214
},
215215
{
216216
"comment after payee",
217-
`1970-01-01 Payee ; payee comment
217+
`; before trans
218+
1970-01-01 Payee ; payee comment
218219
Expense/test 123
219220
Assets
220221
`,
221222
[]*Transaction{
222223
{
223-
Payee: "Payee",
224-
Date: time.Unix(0, 0).UTC(),
224+
Payee: "Payee",
225+
Date: time.Unix(0, 0).UTC(),
226+
PayeeComment: "; payee comment",
225227
AccountChanges: []Account{
226228
{
227229
Name: "Expense/test",
@@ -233,7 +235,7 @@ var testCases = []testCase{
233235
},
234236
},
235237
Comments: []string{
236-
"; payee comment",
238+
"; before trans",
237239
},
238240
},
239241
},
@@ -287,6 +289,7 @@ var testCases = []testCase{
287289
{
288290
Name: "Assets",
289291
Balance: decimal.NewFromFloat(-58),
292+
Comment: "; comment in trans",
290293
},
291294
{
292295
Name: "Expense/unbalanced",
@@ -295,7 +298,6 @@ var testCases = []testCase{
295298
},
296299
Comments: []string{
297300
"; comment",
298-
"; comment in trans",
299301
},
300302
},
301303
},

types.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ import (
1010
type Account struct {
1111
Name string
1212
Balance decimal.Decimal
13+
Comment string
1314
}
1415

1516
// Transaction is the basis of a ledger. The ledger holds a list of transactions.
1617
// A Transaction has a Payee, Date (with no time, or to put another way, with
1718
// hours,minutes,seconds values that probably doesn't make sense), and a list of
1819
// Account values that hold the value of the transaction for each account.
1920
type Transaction struct {
20-
Payee string
2121
Date time.Time
22+
Payee string
23+
PayeeComment string
2224
AccountChanges []Account
2325
Comments []string
2426
}

0 commit comments

Comments
 (0)