summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwyneth Morgan <gwymor@tilde.club>2023-09-06 02:45:48 +0000
committerJohn Wiegley <johnw@newartisans.com>2024-07-10 09:39:17 -0700
commit858a1b2fad41f968d5d8d3470629c0cbb20562b8 (patch)
treeed7f402632c1d49778ea5d1648628a4696d91f50
parent92db49d2e0d649c31b93be1e0cd0b5cde5ce57d8 (diff)
downloadfork-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.cc70
-rw-r--r--test/regress/align-amounts.test24
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