summaryrefslogtreecommitdiff
path: root/format.cc
diff options
context:
space:
mode:
Diffstat (limited to 'format.cc')
-rw-r--r--format.cc82
1 files changed, 65 insertions, 17 deletions
diff --git a/format.cc b/format.cc
index 378e13f6..2872e794 100644
--- a/format.cc
+++ b/format.cc
@@ -6,29 +6,32 @@
namespace ledger {
+format_t::elision_style_t format_t::elision_style = ABBREVIATE;
+int format_t::abbrev_length = 2;
+
bool format_t::ansi_codes = false;
bool format_t::ansi_invert = false;
-std::string truncated(const std::string& str, unsigned int width,
- const int style)
+std::string format_t::truncate(const std::string& str, unsigned int width,
+ const bool is_account)
{
const int len = str.length();
if (len <= width)
return str;
- assert(width < 254);
+ assert(width < 4095);
- char buf[256];
+ char buf[4096];
- switch (style) {
- case 0:
+ switch (elision_style) {
+ case TRUNCATE_LEADING:
// This method truncates at the beginning.
std::strncpy(buf, str.c_str() + (len - width), width);
buf[0] = '.';
buf[1] = '.';
break;
- case 1:
+ case TRUNCATE_MIDDLE:
// This method truncates in the middle.
std::strncpy(buf, str.c_str(), width / 2);
std::strncpy(buf + width / 2,
@@ -38,7 +41,52 @@ std::string truncated(const std::string& str, unsigned int width,
buf[width / 2] = '.';
break;
- case 2:
+ case ABBREVIATE:
+ if (is_account) {
+ std::list<std::string> parts;
+ std::string::size_type beg = 0;
+ for (std::string::size_type pos = str.find(':');
+ pos != std::string::npos;
+ beg = pos + 1, pos = str.find(':', beg))
+ parts.push_back(std::string(str, beg, pos - beg));
+ parts.push_back(std::string(str, beg));
+
+ std::string result;
+ int newlen = len;
+ for (std::list<std::string>::iterator i = parts.begin();
+ i != parts.end();
+ i++) {
+ // Don't contract the last element
+ std::list<std::string>::iterator x = i;
+ if (++x == parts.end()) {
+ result += *i;
+ break;
+ }
+
+ if (newlen > width) {
+ result += std::string(*i, 0, abbrev_length);
+ result += ":";
+ newlen -= (*i).length() - abbrev_length;
+ } else {
+ result += *i;
+ result += ":";
+ }
+ }
+
+ if (newlen > width) {
+ // Even abbreviated its too big to show the last account, so
+ // abbreviate all but the last and truncate at the beginning.
+ std::strncpy(buf, result.c_str() + (result.length() - width), width);
+ buf[0] = '.';
+ buf[1] = '.';
+ } else {
+ std::strcpy(buf, result.c_str());
+ }
+ break;
+ }
+ // fall through...
+
+ case TRUNCATE_TRAILING:
// This method truncates at the end (the default).
std::strncpy(buf, str.c_str(), width - 2);
buf[width - 2] = '.';
@@ -543,7 +591,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
char buf[256];
std::strftime(buf, 255, elem->chars.c_str(), date.localtime());
- out << (elem->max_width == 0 ? buf : truncated(buf, elem->max_width));
+ out << (elem->max_width == 0 ? buf : truncate(buf, elem->max_width));
break;
}
@@ -572,9 +620,9 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
std::strcat(buf, "=");
std::strcat(buf, ebuf);
- out << (elem->max_width == 0 ? buf : truncated(buf, elem->max_width));
+ out << (elem->max_width == 0 ? buf : truncate(buf, elem->max_width));
} else {
- out << (elem->max_width == 0 ? abuf : truncated(abuf, elem->max_width));
+ out << (elem->max_width == 0 ? abuf : truncate(abuf, elem->max_width));
}
break;
}
@@ -621,8 +669,8 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
case element_t::PAYEE:
if (details.entry)
out << (elem->max_width == 0 ?
- details.entry->payee : truncated(details.entry->payee,
- elem->max_width));
+ details.entry->payee : truncate(details.entry->payee,
+ elem->max_width));
break;
case element_t::OPT_NOTE:
@@ -633,8 +681,8 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
case element_t::NOTE:
if (details.xact)
out << (elem->max_width == 0 ?
- details.xact->note : truncated(details.xact->note,
- elem->max_width));
+ details.xact->note : truncate(details.xact->note,
+ elem->max_width));
break;
case element_t::OPT_ACCOUNT:
@@ -661,7 +709,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
if (details.xact && details.xact->flags & TRANSACTION_VIRTUAL) {
if (elem->max_width > 2)
- name = truncated(name, elem->max_width - 2);
+ name = truncate(name, elem->max_width - 2, true);
if (details.xact->flags & TRANSACTION_BALANCE)
name = "[" + name + "]";
@@ -669,7 +717,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
name = "(" + name + ")";
}
else if (elem->max_width > 0)
- name = truncated(name, elem->max_width);
+ name = truncate(name, elem->max_width, true);
out << name;
} else {