Added an Emacs formatter, accessible with the new "emacs" command.
This commit is contained in:
parent
f2390964cb
commit
9618057215
5 changed files with 135 additions and 16 deletions
|
|
@ -7,6 +7,7 @@ libledger_a_SOURCES = \
|
||||||
config.cc \
|
config.cc \
|
||||||
datetime.cc \
|
datetime.cc \
|
||||||
derive.cc \
|
derive.cc \
|
||||||
|
emacs.cc \
|
||||||
format.cc \
|
format.cc \
|
||||||
journal.cc \
|
journal.cc \
|
||||||
mask.cc \
|
mask.cc \
|
||||||
|
|
@ -45,6 +46,7 @@ pkginclude_HEADERS = \
|
||||||
datetime.h \
|
datetime.h \
|
||||||
debug.h \
|
debug.h \
|
||||||
derive.h \
|
derive.h \
|
||||||
|
emacs.h \
|
||||||
error.h \
|
error.h \
|
||||||
format.h \
|
format.h \
|
||||||
gnucash.h \
|
gnucash.h \
|
||||||
|
|
|
||||||
59
emacs.cc
Normal file
59
emacs.cc
Normal file
|
|
@ -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
|
||||||
30
emacs.h
Normal file
30
emacs.h
Normal file
|
|
@ -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
|
||||||
1
ledger.h
1
ledger.h
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <datetime.h>
|
#include <datetime.h>
|
||||||
#include <format.h>
|
#include <format.h>
|
||||||
|
#include <emacs.h>
|
||||||
#include <quotes.h>
|
#include <quotes.h>
|
||||||
#include <valexpr.h>
|
#include <valexpr.h>
|
||||||
#include <walk.h>
|
#include <walk.h>
|
||||||
|
|
|
||||||
59
main.cc
59
main.cc
|
|
@ -240,6 +240,8 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
command = "p";
|
command = "p";
|
||||||
else if (command == "output")
|
else if (command == "output")
|
||||||
command = "w";
|
command = "w";
|
||||||
|
else if (command == "emacs")
|
||||||
|
command = "x";
|
||||||
else if (command == "xml")
|
else if (command == "xml")
|
||||||
command = "X";
|
command = "X";
|
||||||
else if (command == "entry")
|
else if (command == "entry")
|
||||||
|
|
@ -250,8 +252,6 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
command = "P";
|
command = "P";
|
||||||
else if (command == "pricesdb")
|
else if (command == "pricesdb")
|
||||||
command = "D";
|
command = "D";
|
||||||
else if (command == "reconcile")
|
|
||||||
command = "R";
|
|
||||||
else
|
else
|
||||||
throw error(std::string("Unrecognized command '") + command + "'");
|
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;
|
format = &config.format_string;
|
||||||
else if (command == "b")
|
else if (command == "b")
|
||||||
format = &config.balance_format;
|
format = &config.balance_format;
|
||||||
else if (command == "r" || command == "R")
|
else if (command == "r")
|
||||||
format = &config.register_format;
|
format = &config.register_format;
|
||||||
else if (command == "E")
|
else if (command == "E")
|
||||||
format = &config.equity_format;
|
format = &config.equity_format;
|
||||||
|
|
@ -356,16 +356,25 @@ def vmax(d, val):\n\
|
||||||
// Walk the entries based on the report type and the options
|
// Walk the entries based on the report type and the options
|
||||||
|
|
||||||
item_handler<transaction_t> * formatter;
|
item_handler<transaction_t> * formatter;
|
||||||
|
item_handler<transaction_t> * base_formatter;
|
||||||
std::list<item_handler<transaction_t> *> formatter_ptrs;
|
std::list<item_handler<transaction_t> *> formatter_ptrs;
|
||||||
|
|
||||||
if (command == "b" || command == "E")
|
if (command == "b" || command == "E")
|
||||||
formatter = new set_account_value;
|
base_formatter = new set_account_value;
|
||||||
else if (command == "p" || command == "e")
|
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")
|
else if (command == "X")
|
||||||
formatter = new format_xml_entries(*out, config.show_totals);
|
base_formatter = new format_xml_entries(*out, config.show_totals);
|
||||||
else
|
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(),
|
formatter = chain_xact_handlers(command, formatter, journal.get(),
|
||||||
journal->master, formatter_ptrs);
|
journal->master, formatter_ptrs);
|
||||||
|
|
@ -374,15 +383,6 @@ def vmax(d, val):\n\
|
||||||
walk_transactions(new_entry->transactions, *formatter);
|
walk_transactions(new_entry->transactions, *formatter);
|
||||||
else if (command == "P" || command == "D")
|
else if (command == "P" || command == "D")
|
||||||
walk_commodities(commodity_t::commodities, *formatter);
|
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")
|
else if (command == "w")
|
||||||
write_textual_journal(*journal, *arg, *formatter, *out);
|
write_textual_journal(*journal, *arg, *formatter, *out);
|
||||||
else
|
else
|
||||||
|
|
@ -391,6 +391,32 @@ def vmax(d, val):\n\
|
||||||
if (command != "P")
|
if (command != "P")
|
||||||
formatter->flush();
|
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.
|
// For the balance and equity reports, output the sum totals.
|
||||||
|
|
||||||
if (command == "b") {
|
if (command == "b") {
|
||||||
|
|
@ -427,6 +453,7 @@ def vmax(d, val):\n\
|
||||||
i != formatter_ptrs.end();
|
i != formatter_ptrs.end();
|
||||||
i++)
|
i++)
|
||||||
delete *i;
|
delete *i;
|
||||||
|
formatter_ptrs.clear();
|
||||||
|
|
||||||
#endif // DEBUG_LEVEL >= BETA
|
#endif // DEBUG_LEVEL >= BETA
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue