summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2005-02-09 21:07:11 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 02:40:56 -0400
commit9618057215eb7638475a4299b81cbdca8e1f4e3f (patch)
treea70fe046b2245aca9d2c0a2f75dd0e5ef04fb515
parentf2390964cb22494b78674d02fa542a9116d10f0b (diff)
downloadfork-ledger-9618057215eb7638475a4299b81cbdca8e1f4e3f.tar.gz
fork-ledger-9618057215eb7638475a4299b81cbdca8e1f4e3f.tar.bz2
fork-ledger-9618057215eb7638475a4299b81cbdca8e1f4e3f.zip
Added an Emacs formatter, accessible with the new "emacs" command.
-rw-r--r--Makefile.am2
-rw-r--r--emacs.cc59
-rw-r--r--emacs.h30
-rw-r--r--ledger.h1
-rw-r--r--main.cc59
5 files changed, 135 insertions, 16 deletions
diff --git a/Makefile.am b/Makefile.am
index 07630668..2cfca6e6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,7 @@ libledger_a_SOURCES = \
config.cc \
datetime.cc \
derive.cc \
+ emacs.cc \
format.cc \
journal.cc \
mask.cc \
@@ -45,6 +46,7 @@ pkginclude_HEADERS = \
datetime.h \
debug.h \
derive.h \
+ emacs.h \
error.h \
format.h \
gnucash.h \
diff --git a/emacs.cc b/emacs.cc
new file mode 100644
index 00000000..8a4d7f84
--- /dev/null
+++ b/emacs.cc
@@ -0,0 +1,59 @@
+#include "emacs.h"
+
+namespace ledger {
+
+void format_emacs_transactions::write_entry(entry_t& entry)
+{
+ out << (((unsigned long)entry.beg_pos) + 1) << " ";
+
+ out << (entry.state == entry_t::CLEARED ? "t" : "nil") << " ";
+
+ out << "(" << (entry.date / 65536) << " "
+ << (entry.date % 65536) << " 0) ";
+
+ if (entry.code.empty())
+ out << "nil ";
+ else
+ out << "\"" << entry.code << "\" ";
+
+ if (entry.payee.empty())
+ out << "nil";
+ else
+ out << "\"" << entry.payee << "\"";
+
+ out << "\n";
+}
+
+void format_emacs_transactions::operator()(transaction_t& xact)
+{
+ if (! transaction_has_xdata(xact) ||
+ ! (transaction_xdata_(xact).dflags & TRANSACTION_DISPLAYED)) {
+ if (! last_entry) {
+ out << "((";
+ write_entry(*xact.entry);
+ }
+ else if (xact.entry != last_entry) {
+ out << ")\n (";
+ write_entry(*xact.entry);
+ }
+ else {
+ out << "\n";
+ }
+
+ out << " (\"" << xact.account->fullname() << "\" \""
+ << xact.amount << "\"";
+ if (xact.cost)
+ out << " \"" << *xact.cost << "\"";
+ else if (! xact.note.empty())
+ out << " nil";
+ if (! xact.note.empty())
+ out << " \"" << xact.note << "\"";
+ out << ")";
+
+ last_entry = xact.entry;
+
+ transaction_xdata(xact).dflags |= TRANSACTION_DISPLAYED;
+ }
+}
+
+} // namespace ledger
diff --git a/emacs.h b/emacs.h
new file mode 100644
index 00000000..ea58bad8
--- /dev/null
+++ b/emacs.h
@@ -0,0 +1,30 @@
+#ifndef _EMACS_H
+#define _EMACS_H
+
+#include "journal.h"
+#include "format.h"
+
+namespace ledger {
+
+class format_emacs_transactions : public item_handler<transaction_t>
+{
+ protected:
+ std::ostream& out;
+ entry_t * last_entry;
+
+ public:
+ format_emacs_transactions(std::ostream& _out)
+ : out(_out), last_entry(NULL) {}
+
+ virtual void write_entry(entry_t& entry);
+ virtual void flush() {
+ if (last_entry)
+ out << "))\n";
+ out.flush();
+ }
+ virtual void operator()(transaction_t& xact);
+};
+
+} // namespace ledger
+
+#endif // _REPORT_H
diff --git a/ledger.h b/ledger.h
index c59a4d86..0046600a 100644
--- a/ledger.h
+++ b/ledger.h
@@ -18,6 +18,7 @@
#include <datetime.h>
#include <format.h>
+#include <emacs.h>
#include <quotes.h>
#include <valexpr.h>
#include <walk.h>
diff --git a/main.cc b/main.cc
index c2ff8694..9e0361b3 100644
--- a/main.cc
+++ b/main.cc
@@ -240,6 +240,8 @@ int parse_and_report(int argc, char * argv[], char * envp[])
command = "p";
else if (command == "output")
command = "w";
+ else if (command == "emacs")
+ command = "x";
else if (command == "xml")
command = "X";
else if (command == "entry")
@@ -250,8 +252,6 @@ int parse_and_report(int argc, char * argv[], char * envp[])
command = "P";
else if (command == "pricesdb")
command = "D";
- else if (command == "reconcile")
- command = "R";
else
throw error(std::string("Unrecognized command '") + command + "'");
@@ -313,7 +313,7 @@ int parse_and_report(int argc, char * argv[], char * envp[])
format = &config.format_string;
else if (command == "b")
format = &config.balance_format;
- else if (command == "r" || command == "R")
+ else if (command == "r")
format = &config.register_format;
else if (command == "E")
format = &config.equity_format;
@@ -356,16 +356,25 @@ def vmax(d, val):\n\
// Walk the entries based on the report type and the options
item_handler<transaction_t> * formatter;
+ item_handler<transaction_t> * base_formatter;
std::list<item_handler<transaction_t> *> formatter_ptrs;
if (command == "b" || command == "E")
- formatter = new set_account_value;
+ base_formatter = new set_account_value;
else if (command == "p" || command == "e")
- formatter = new format_entries(*out, *format);
+ base_formatter = new format_entries(*out, *format);
+ else if (command == "x")
+ base_formatter = new format_emacs_transactions(*out);
else if (command == "X")
- formatter = new format_xml_entries(*out, config.show_totals);
+ base_formatter = new format_xml_entries(*out, config.show_totals);
else
- formatter = new format_transactions(*out, *format);
+ base_formatter = new format_transactions(*out, *format);
+
+ transactions_list xacts_to_reconcile;
+ if (! config.reconcile_balance.empty())
+ formatter = new push_to_transactions_list(xacts_to_reconcile);
+ else
+ formatter = base_formatter;
formatter = chain_xact_handlers(command, formatter, journal.get(),
journal->master, formatter_ptrs);
@@ -374,15 +383,6 @@ def vmax(d, val):\n\
walk_transactions(new_entry->transactions, *formatter);
else if (command == "P" || command == "D")
walk_commodities(commodity_t::commodities, *formatter);
- else if (command == "R") {
- account_t * account = journal->find_account_re(*arg);
- if (! account)
- throw error(std::string("Could not find account matching '") +
- *arg + "'");
- reconcile_results_t results = reconcile_account(*journal, *account,
- value_t(*++arg));
- walk_transactions(results.pending_xacts, *formatter);
- }
else if (command == "w")
write_textual_journal(*journal, *arg, *formatter, *out);
else
@@ -391,6 +391,32 @@ def vmax(d, val):\n\
if (command != "P")
formatter->flush();
+ // If we are generating a reconcile report, determine the final set
+ // of transactions.
+
+ if (! config.reconcile_balance.empty()) {
+ bool reconcilable = false;
+ value_t target_balance;
+ if (config.reconcile_balance == "<all>")
+ reconcilable = true;
+ else
+ target_balance = value_t(config.reconcile_balance);
+
+ time_t cutoff = now;
+ if (! config.reconcile_date.empty())
+ parse_date(config.reconcile_date.c_str(), &cutoff);
+
+ reconcile_transactions(xacts_to_reconcile, target_balance, cutoff,
+ reconcilable);
+
+ // Since all the work of the other formatters was completed by
+ // now, simply output the list, ignoring any other special
+ // details.
+ calc_transactions final_formatter(base_formatter);
+ walk_transactions(xacts_to_reconcile, final_formatter);
+ final_formatter.flush();
+ }
+
// For the balance and equity reports, output the sum totals.
if (command == "b") {
@@ -427,6 +453,7 @@ def vmax(d, val):\n\
i != formatter_ptrs.end();
i++)
delete *i;
+ formatter_ptrs.clear();
#endif // DEBUG_LEVEL >= BETA