diff options
author | Gwyneth Morgan <gwymor@tilde.club> | 2023-09-06 02:45:48 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2024-07-10 09:39:17 -0700 |
commit | 858a1b2fad41f968d5d8d3470629c0cbb20562b8 (patch) | |
tree | ed7f402632c1d49778ea5d1648628a4696d91f50 | |
parent | 92db49d2e0d649c31b93be1e0cd0b5cde5ce57d8 (diff) | |
download | fork-ledger-858a1b2fad41f968d5d8d3470629c0cbb20562b8.tar.gz fork-ledger-858a1b2fad41f968d5d8d3470629c0cbb20562b8.tar.bz2 fork-ledger-858a1b2fad41f968d5d8d3470629c0cbb20562b8.zip |
print: Align amounts even when account names are long
When the account name is longer than the --account-width (default 36),
the amounts stop aligning:
2023/01/01 Transaction with long account names
Assets:Very:Long:Account:Name:That:Will:Push:The:Amount -10 ABC
Assets:Another:Long:Account:Name:That:Will:Push:The:Amount -10 ABC
Expenses:Short 20 ABC
One can set a larger --account-width, but that is not a great solution
for cases where you have only a few accounts with problematically long
names. Instead, keep the current account width wherever possible, but
when an account name is longer than the account width, account for that
and still align the values:
2023/01/01 Transaction with short account names
Assets:Short -10 ABC
Assets:Short -10 ABC
Expenses:Short 20 ABC
2023/01/01 Transaction with long account names
Assets:Very:Long:Account:Name:That:Will:Push:The:Amount -10 ABC
Assets:Another:Long:Account:Name:That:Will:Push:The:Amount -10 ABC
Expenses:Short 20 ABC
This is similar to hledger's behavior.
-rw-r--r-- | src/print.cc | 70 | ||||
-rw-r--r-- | test/regress/align-amounts.test | 24 |
2 files changed, 64 insertions, 30 deletions
diff --git a/src/print.cc b/src/print.cc index bcc8cf9c..4febd871 100644 --- a/src/print.cc +++ b/src/print.cc @@ -100,6 +100,33 @@ namespace { } } + std::ostringstream format_account_name(xact_t& xact, post_t * post) + { + std::ostringstream pbuf; + + if (xact.state() == item_t::UNCLEARED) + pbuf << (post->state() == item_t::CLEARED ? "* " : + (post->state() == item_t::PENDING ? "! " : "")); + + if (post->has_flags(POST_VIRTUAL)) { + if (post->has_flags(POST_MUST_BALANCE)) + pbuf << '['; + else + pbuf << '('; + } + + pbuf << post->account->fullname(); + + if (post->has_flags(POST_VIRTUAL)) { + if (post->has_flags(POST_MUST_BALANCE)) + pbuf << ']'; + else + pbuf << ')'; + } + + return pbuf; + } + void print_xact(report_t& report, std::ostream& out, xact_t& xact) { format_type_t format_type = FMT_WRITTEN; @@ -158,6 +185,18 @@ namespace { std::size_t count = xact.posts.size(); std::size_t index = 0; + std::size_t account_width = + (report.HANDLED(account_width_) ? + lexical_cast<std::size_t>(report.HANDLER(account_width_).str()) : 36); + + // Find the longest account name to line up all amounts when account names + // are long + foreach (post_t * post, xact.posts) { + unistring name = format_account_name(xact, post).str(); + if (account_width < name.length()) + account_width = name.length(); + } + foreach (post_t * post, xact.posts) { index++; @@ -168,37 +207,10 @@ namespace { out << " "; - std::ostringstream pbuf; - - if (xact.state() == item_t::UNCLEARED) - pbuf << (post->state() == item_t::CLEARED ? "* " : - (post->state() == item_t::PENDING ? "! " : "")); - - if (post->has_flags(POST_VIRTUAL)) { - if (post->has_flags(POST_MUST_BALANCE)) - pbuf << '['; - else - pbuf << '('; - } - - pbuf << post->account->fullname(); - - if (post->has_flags(POST_VIRTUAL)) { - if (post->has_flags(POST_MUST_BALANCE)) - pbuf << ']'; - else - pbuf << ')'; - } + std::ostringstream pbuf = format_account_name(xact, post); unistring name(pbuf.str()); - std::size_t account_width = - (report.HANDLED(account_width_) ? - lexical_cast<std::size_t>(report.HANDLER(account_width_).str()) : 36); - - if (account_width < name.length()) - account_width = name.length(); - if (! post->has_flags(POST_CALCULATED) || report.HANDLED(generated)) { out << name.extract(); std::string::size_type slip = @@ -272,8 +284,6 @@ namespace { out << ' '; } out << trailer; - - account_width += unistring(trailer).length(); } } else { out << pbuf.str(); diff --git a/test/regress/align-amounts.test b/test/regress/align-amounts.test new file mode 100644 index 00000000..5e79beb7 --- /dev/null +++ b/test/regress/align-amounts.test @@ -0,0 +1,24 @@ +; Amounts should still align even though the account names are much longer than +; the default --account-width. + +2023/01/01 Transaction with short account names + Assets:Short -10 ABC + Assets:Short -10 ABC + Expenses:Short 20 ABC + +2023/01/01 Transaction with long account names + Assets:Very:Long:Account:Name:That:Will:Push:The:Amount -10 ABC + Assets:Another:Long:Account:Name:That:Will:Push:The:Amount -10 ABC + Expenses:Short 20 ABC + +test print +2023/01/01 Transaction with short account names + Assets:Short -10 ABC + Assets:Short -10 ABC + Expenses:Short 20 ABC + +2023/01/01 Transaction with long account names + Assets:Very:Long:Account:Name:That:Will:Push:The:Amount -10 ABC + Assets:Another:Long:Account:Name:That:Will:Push:The:Amount -10 ABC + Expenses:Short 20 ABC +end test |