Templating for more complicated reports?
In light of recent discussions, I've been thinking about ways to generate more complex documents or reports with ledger. In most languages, this is done by creating a templating or document embedding method, where data is injected next to arbitrary content, ranging from a simple mail merge to more complex behaviors. There seem to be 3 different ways that could be pursued for this: - Come up with a ledger specific templating engine, building on existing work. - Use the new python functionality to implement similar functionality with one of python's templating engines (mako, evoque, etc.) - Change XML output from it's current form (which is similar to bal and reg and is pretty flat) to be more of an output filter that wraps arbitrary queries and other output, then use XSLT or other XML tools to fill templates. Personally, I'm thinking that the 3rd option is likely the easiest/most language neutral/repurposeable for other uses, but #2 is also quite attractive. Has anyone looked into doing something like this? Some (quite horrible) pseudocode that gets at what I think people might be wanting: -- {for $customer in ledger.balance(Company:Customers).has_uncleared} Invoice for {$customer.accountname} Items purchased: {for $transaction in $customer.transactions.uncleared} Item: {$transaction.description} for {$transaction.amount} {/for} Total: {$customer.balance} Thank you for your prompt payment. {/for} -- Thoughts? Zack
Re: Build failure
Check your boost version and verify you have the other prereqes installed. What platform are you building on? On Thu, May 17, 2012 at 8:57 AM, Russell Adams rlad...@adamsinfoserv.com wrote: Reviewed the README-1st, any other advice? ~/software/ledger $ ./acprep update acprep: INFO: Invoking primary phase: update acprep: INFO: Executing phase: update acprep: INFO: Executing phase: pull Already up-to-date. acprep: INFO: Executing phase: submodule acprep: INFO: Executing phase: make acprep: INFO: Executing phase: config acprep: INFO: Executing phase: submodule acprep: INFO: Executing phase: autoconf acprep: INFO: Executing phase: configure acprep: INFO: System type is = Linux acprep: INFO: Looking for Boost in /usr/local/lib64... acprep: INFO: Looking for Boost in /opt/local/lib64... acprep: INFO: Looking for Boost in /sw/lib64... acprep: INFO: Looking for Boost in /usr/lib64... acprep: INFO: Found a Boost library: /usr/lib64/libboost_regex.so.1.40.0 acprep: INFO: Found a Boost suffix = acprep: INFO: Found a Boost file suffix = .so acprep: INFO: Boost was found here: acprep: INFO: Boost home path = /usr acprep: INFO: Boost include path = /usr/include acprep: INFO: Boost library path = /usr/lib64 acprep: INFO: Boost suffix = acprep: INFO: Boost file suffix = .so acprep: INFO: Noticing include directory = /usr/local/include acprep: INFO: Noticing library directory = /usr/local/lib acprep: INFO: Noticing library directory = /usr/lib acprep: INFO: Noticing library directory = /usr/lib64 acprep: INFO: Setting up build flavor = debug make all-recursive make[1]: Entering directory `/home/rladams/software/ledger' Making all in po make[2]: Entering directory `/home/rladams/software/ledger/po' make[2]: Leaving directory `/home/rladams/software/ledger/po' Making all in intl make[2]: Entering directory `/home/rladams/software/ledger/intl' make[2]: Nothing to be done for `all'. make[2]: Leaving directory `/home/rladams/software/ledger/intl' make[2]: Entering directory `/home/rladams/software/ledger' CXX libledger_report_la-stats.lo In file included from /usr/include/boost/graph/adjacency_list.hpp:42, from system.hh:153: /usr/include/boost/property_map/property_map.hpp: In instantiation of 'boost::property_traitsledger::date_specifier_t': /usr/include/boost/graph/two_bit_color_map.hpp:46: instantiated from 'boost::two_bit_color_mapledger::date_specifier_t' src/times.h:481: instantiated from here /usr/include/boost/property_map/property_map.hpp:31: error: no type named 'key_type' in 'class ledger::date_specifier_t' /usr/include/boost/property_map/property_map.hpp:32: error: no type named 'value_type' in 'class ledger::date_specifier_t' /usr/include/boost/property_map/property_map.hpp:33: error: no type named 'reference' in 'class ledger::date_specifier_t' /usr/include/boost/property_map/property_map.hpp:34: error: no type named 'category' in 'class ledger::date_specifier_t' /usr/include/boost/property_map/property_map.hpp: In instantiation of 'boost::property_traitsledger::date_range_t': /usr/include/boost/graph/two_bit_color_map.hpp:46: instantiated from 'boost::two_bit_color_mapledger::date_range_t' src/times.h:483: instantiated from here /usr/include/boost/property_map/property_map.hpp:31: error: no type named 'key_type' in 'class ledger::date_range_t' /usr/include/boost/property_map/property_map.hpp:32: error: no type named 'value_type' in 'class ledger::date_range_t' /usr/include/boost/property_map/property_map.hpp:33: error: no type named 'reference' in 'class ledger::date_range_t' /usr/include/boost/property_map/property_map.hpp:34: error: no type named 'category' in 'class ledger::date_range_t' /usr/include/boost/property_map/property_map.hpp: In instantiation of 'boost::property_traitsbool': /usr/include/boost/graph/two_bit_color_map.hpp:46: instantiated from 'boost::two_bit_color_mapbool' src/value.h:556: instantiated from here /usr/include/boost/property_map/property_map.hpp:31: error: 'bool' is not a class, struct, or union type /usr/include/boost/property_map/property_map.hpp:32: error: 'bool' is not a class, struct, or union type /usr/include/boost/property_map/property_map.hpp:33: error: 'bool' is not a class, struct, or union type /usr/include/boost/property_map/property_map.hpp:34: error: 'bool' is not a class, struct, or union type /usr/include/boost/property_map/property_map.hpp: In instantiation of 'boost::property_traitsboost::posix_time::ptime': /usr/include/boost/graph/two_bit_color_map.hpp:46: instantiated from 'boost::two_bit_color_mapboost::posix_time::ptime' src/value.h:573: instantiated from here /usr/include/boost/property_map/property_map.hpp:31: error: no type named 'key_type' in 'class boost::posix_time::ptime' /usr/include/boost/property_map/property_map.hpp:32: error: no type named 'value_type' in 'class
Re: Build failure
On Thu, May 17, 2012 at 09:27:16AM -0700, Craig Earls wrote: Check your boost version and verify you have the other prereqes installed. The acprep seems to like my boost version. What platform are you building on? Ubuntu 10.04 (yes its old). I'm surprised because I've repeatedly compiled and run ledger on this same platform. I was trying to update to the GIT repo to try out the new features John put in regarding specifying accounts and assertions in metadata. I thought maybe there was a new dependency I was unaware of. Thanks. -- Russell Adamsrlad...@adamsinfoserv.com PGP Key ID: 0x1160DCB3 http://www.adamsinfoserv.com/ Fingerprint:1723 D8CA 4280 1EC9 557F 66E8 1154 E018 1160 DCB3
Re: Templating for more complicated reports?
On Thu, May 17, 2012 at 09:19:09AM -0700, Zack Williams wrote: In light of recent discussions, I've been thinking about ways to generate more complex documents or reports with ledger. In most languages, this is done by creating a templating or document embedding method, where data is injected next to arbitrary content, ranging from a simple mail merge to more complex behaviors. For sharing's sake, I've attached the perl script I use to create expense reports from Ledger data in Latex. It creates several tables of summaries, using a Ledger custom output format to give me data I can quickly parse. It would take me time I can't spare at the moment to create a sample dataset and example report. There seem to be 3 different ways that could be pursued for this: - Come up with a ledger specific templating engine, building on existing work. Violates KISS. I couldn't see a simple template performing more complex reporting and summaries. - Use the new python functionality to implement similar functionality with one of python's templating engines (mako, evoque, etc.) This is a good idea. Using a python program that can interface to Ledger to get data, and then perform custom business logic and pass it on to a template engine would rock. That said, my perl script isn't that different, except I'm calling Ledger via exec and pulling the STDOUT in and parsing it from a custom output format (~ delimited). - Change XML output from it's current form (which is similar to bal and reg and is pretty flat) to be more of an output filter that wraps arbitrary queries and other output, then use XSLT or other XML tools to fill templates. You said XML. -1 Great discussion points though. -- Russell Adamsrlad...@adamsinfoserv.com PGP Key ID: 0x1160DCB3 http://www.adamsinfoserv.com/ Fingerprint:1723 D8CA 4280 1EC9 557F 66E8 1154 E018 1160 DCB3 #!/usr/bin/perl use warnings; use strict; use Getopt::Long;# Options processing use Smart::Comments -ENV, ###; # Ignore my dividers, and use # Smart_Comments=1 to activate use Cwd; use File::Basename; use 5.10.0; use POSIX qw(strftime); use Date::Calc qw(Add_Delta_Days); use Template; my $TT = Template-new( { POST_CHOMP = 1 } ); ## # TODO # # DONE Meal summaries are broken for multi-week reports ## # Options # Is this an internal report? my $ExpenseReportCode = undef; my $Internal = undef; my $SuppressMeals = 0; my $ViewAfter = 0; my $ImageDir = .; my $Anonymize = 0; my $Help = undef; GetOptions( 'c' = \$Internal, 'm' = \$SuppressMeals, 'v' = \$ViewAfter, 'a' = \$Anonymize, 'I' = \$ImageDir, 'e:s'= \$ExpenseReportCode, 'h|help' = \$Help ); # Help defined $Help do { print EOF; Usage: GenerateLatexExpenseReport.pl [OPTION] -e ERCode Options: -c Internal report -m Suppress meals -v View PDF on completion -a Anonymous, omit header/footer -I Image directory -e ER Code (AISER0001) EOF exit -1; }; die Pass -e ExpenseReportCode unless defined $ExpenseReportCode; ## # Report items my @ItemizedExpenses; my $ItemizedTotal = 0.00; my @ItemizedReceipts; my @MealsReport; ## # Remaining options # Where is the ledger binary? my $LedgerBin = ./ledger -f ./.ledger -V; # -E Show empty accounts # -S d Sort by date # -V Convert mileage to $ my $LedgerOpts = --no-color -S d; my $LedgerAcct = ^Dest:Projects; my $LedgerCriteria = % . ER=$ExpenseReportCode; # Internal report? if ( $Internal ) { # No mileage on an internal report # $LedgerCriteria .= !/Mileage/; # This shouldn't matter, just don't put metadata for ER on mileage $LedgerAcct = ^Dest:Internal; } my $CmdLine = $LedgerBin reg $LedgerOpts -E \$LedgerCriteria\ and ^Stub . --format \%(tag('ER'))~%(tag('PROJECT'))~%(tag('NOTE'))\n\; ### $CmdLine my @TempLine = `$CmdLine`; # Match all remaining items $TempLine[0] =~ m,^(?Er.*?)~ (?Project.*?)~ (?Note.*?)\s*$,x; my $ProjectCode= $+{'Project'}; my $Description= $+{'Note'}; ### $ExpenseReportCode ### $ProjectCode ### $Description ### $LedgerAcct ### $Internal ### $Anonymize ### $LedgerAcct ### $LedgerOpts ### $LedgerCriteria ## # Pull main ledger report of line items for the expense report # Using ~ as a delimiter # # Example: #
Re: Build failure
* Russell Adams rlad...@adamsinfoserv.com [2012-05-17 11:53]: What platform are you building on? Ubuntu 10.04 (yes its old). I'm surprised because I've repeatedly compiled and run ledger on this same platform. I was trying to update to the GIT repo to try out the new features John put in regarding specifying accounts and assertions in metadata. Your boost is too old. I already filed a report requesting that acprep should produce an error if boost is too old: http://bugs.ledger-cli.org/show_bug.cgi?id=677 -- Martin Michlmayr http://www.cyrius.com/
Re: Templating for more complicated reports?
XML: +1 vote What ever you decide, please don't remove the command emacs that output S-EXP. Best, Alexandre Rademaker http://arademaker.github.com/ On Thu, May 17, 2012 at 2:05 PM, Russell Adams rlad...@adamsinfoserv.com wrote: On Thu, May 17, 2012 at 09:19:09AM -0700, Zack Williams wrote: In light of recent discussions, I've been thinking about ways to generate more complex documents or reports with ledger. In most languages, this is done by creating a templating or document embedding method, where data is injected next to arbitrary content, ranging from a simple mail merge to more complex behaviors. For sharing's sake, I've attached the perl script I use to create expense reports from Ledger data in Latex. It creates several tables of summaries, using a Ledger custom output format to give me data I can quickly parse. It would take me time I can't spare at the moment to create a sample dataset and example report. There seem to be 3 different ways that could be pursued for this: - Come up with a ledger specific templating engine, building on existing work. Violates KISS. I couldn't see a simple template performing more complex reporting and summaries. - Use the new python functionality to implement similar functionality with one of python's templating engines (mako, evoque, etc.) This is a good idea. Using a python program that can interface to Ledger to get data, and then perform custom business logic and pass it on to a template engine would rock. That said, my perl script isn't that different, except I'm calling Ledger via exec and pulling the STDOUT in and parsing it from a custom output format (~ delimited). - Change XML output from it's current form (which is similar to bal and reg and is pretty flat) to be more of an output filter that wraps arbitrary queries and other output, then use XSLT or other XML tools to fill templates. You said XML. -1 Great discussion points though.
Re: Build failure
I am on boost 1.49 On Thu, May 17, 2012 at 12:11 PM, thierry thierry.dauco...@free.fr wrote: Same OS, but last version, and also I've upgraded to last boost version, and I still get the build failure Cheers Thierry -- Craig, Corona De Tucson, AZ enderw88.wordpress.com