One question that will remain is what to do with comments immediately preceding and/or following a transaction. Those are often associated with the transaction and slicing and dicing files to put them back together should probably preserve the comments like that. I'd have to inject comments into the grammar in order to do that (that may not be trivial).
Another ingredient that would help is a very-opinionated,
fully-automated formatter for Beancount syntax, similar to what Black[1]
is to Python. With something like that an hypothetical "sed" equivalent
for Beancount syntax would be able to worry less about getting right
details such as spacing, indentation, etc. --- it will just have to pipe
its output to bean-format(-ng) and be done with it. (But of course this
is assuming that nothing is lost in the concrete syntax -> AST
translation, and most notably comments.)
On Mon, Nov 30, 2020 at 5:12 PM Aaron Lindsay <acli...@gmail.com> wrote:I've been working on automating some accounting tasks lately and am curious for feedback from others on my approach, or ideas for doing it better in the future.I really dislike manually organizing my ledger file. I do still want to look over incoming transactions, but ideally would like everything else to be automated for me - I'd like transactions to be uniformly formatted and ordered. `bean-format` can take care of most of the former, but I've been using `bean-query example.beancount print` (wrapped in a shell script to preserve the options and remove trailing spaces) to do the ordering for me. This isn't ideal since it's actually modifying the ledger in the process. It seems like there are more possibilities for programmatically managing your .beancount file, too: I can imagine keeping prices separate from transactions, maybe automatically moving transactions for certain accounts to their own file, etc.Is there a better way to programmatically rewrite ledgers by hooking into pieces of the beancount internals today? If not, will v3 have any impact on this? I'm looking at the "Intermediate Parsed Data vs. Final List of Directives" section of the v3 document, but am not sure I grok the beancount internals enough to understand the implications there, if any.You cannot reinsert the output of "bean-query print" back into the Ledger, it's just not designed to work that way, that will not work. There's the input syntax, Beancount parses that, and then makes changes to the transactions, some which are dependent on the state of the inventories just before it (chronologically, e.g., matching cost specs to available lots). In fact, if anything in v3 the introduction of currency trading accounts and transfer accounts (for postings from a single transaction at different dates) will make that distinction even more pronounced, as a single transaction will often result in multiple transactions realized in the output stream. It may look like they're the same because the data types coming out of the parser are also reused for the final realization (they're close enough), but they're different. One is the straightforward translation by the parser of what it read to a data structure--its AST, if you will-- an incomplete, partially filled and yet-to-be booked and interpolated and processed directives, and the other is the final result after all the work is done, which you be summed up to compute inventory states. With "bean-query print" you're producing the final result, not a 1:1 translation of the input.
What you may be able to do instead is manipulate the input text. But in v3 I'll provide both beginning and end lines as part of all directive data, so that should allow you to break apart your file cleanly, using the same parser used for processing. Also, I could easily provide some library function to accept a file and produce a mapping of(parser-directive, text)whereby the parser directive is the unprocessed, straightforward translation of your input text to the intermediate data structure, which you could more easily inspect and reason about - keeping in mind that some of the fields may be unset,e.g. if you leave out a number to be interpolated -- in order to decide where to reinsert the corresponding text in your output file. Please file a ticket if this would be useful. I'm in the process of rewriting the parser in C++ (almost done actually).
One question that will remain is what to do with comments immediately preceding and/or following a transaction. Those are often associated with the transaction and slicing and dicing files to put them back together should probably preserve the comments like that. I'd have to inject comments into the grammar in order to do that (that may not be trivial).
On Tuesday, December 1, 2020 at 11:26:13 AM UTC+7 bl...@furius.ca wrote:One question that will remain is what to do with comments immediately preceding and/or following a transaction. Those are often associated with the transaction and slicing and dicing files to put them back together should probably preserve the comments like that. I'd have to inject comments into the grammar in order to do that (that may not be trivial).I've made two or three half-hearted attempts at programmatically reformatting ledgers and this is definitely one of the biggest sticking points. If comments were an actual part of the transaction -- the way docstrings are on a python method, for instance -- it would be great.But there are some other complications:- Markers for code folding and just in general how to handle "sections". Do you want all of your "#europe-holiday-2019" tagged transactions grouped together automatically? Do you want that behaviour for *all* tags? (Probably not!)- How to handle commented out things that should stay close to the non-commented things out they are related to. For instance, I have a custom fava option commented out. But after reformatting it should still be adjacent to all the other fava options!- Handling de-facto multi-line comments (again, on things that aren't transactions, consider a plugin configuration of multiple lines of embedded JSON that has been commented out)- Handling include files
- Comments on things that aren't transactions -- prices, commodities- Inline comments on individual legs of a transaction. For instance I have one transaction that looks like:2017-08-31 * "Transfer to Vietnam"Assets:US:Blah -50 USDExpenses:Bank-Fees 10 USD ; charged by correspondent bank on the wire transferAssets:VN:Foo 40 USD
- Handling all of the non-transaction things that you probably (maybe?) don't want mixed in among transactions. But where *do* you want them? I keep all of mine in separate files: prices in one file, balances in another, etc.In the end I felt like there were so many edge cases and I struggled to see much real benefit outside of my own OCD.
--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/7c27c941-79d8-4d4e-af32-94c394ecf265n%40googlegroups.com.
On Monday, November 30, 2020 at 11:26:13 PM UTC-5 bl...@furius.ca wrote:What you may be able to do instead is manipulate the input text. But in v3 I'll provide both beginning and end lines as part of all directive data, so that should allow you to break apart your file cleanly, using the same parser used for processing. Also, I could easily provide some library function to accept a file and produce a mapping of(parser-directive, text)whereby the parser directive is the unprocessed, straightforward translation of your input text to the intermediate data structure, which you could more easily inspect and reason about - keeping in mind that some of the fields may be unset,e.g. if you leave out a number to be interpolated -- in order to decide where to reinsert the corresponding text in your output file. Please file a ticket if this would be useful. I'm in the process of rewriting the parser in C++ (almost done actually).I do think this would be useful - I'll try to write it up. How would user code hook into beancount to get this listing? Would there just be a parser function call to be imported and called via arbitrary python that would return a list of these tuples?
Now the problem lies in programmatically editing *concrete* syntax, which is a complicated problem in general, due to the amount of information that parsers tend to throw away when converting to ASTs. So, Martin, everything the new Beancount parsers manage to keep (locations, comments, etc.) would be definitely welcome in this respect.
+1
Another ingredient that would help is a very-opinionated, fully-automated formatter for Beancount syntax, similar to what Black[1] is to Python. With something like that an hypothetical "sed" equivalent for Beancount syntax would be able to worry less about getting right details such as spacing, indentation, etc. --- it will just have to pipe its output to bean-format(-ng) and be done with it. (But of course this is assuming that nothing is lost in the concrete syntax -> AST translation, and most notably comments.)
--
Rudd-O
http://rudd-o.com/
--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/37d0dbe1-0d15-4edf-8081-6c876250dcd5n%40googlegroups.com.