diff --git a/src/content/blog/2023-11-03-nanoledger.md b/src/content/blog/2023-11-03-nanoledger.md new file mode 100644 index 0000000..86d6712 --- /dev/null +++ b/src/content/blog/2023-11-03-nanoledger.md @@ -0,0 +1,79 @@ ++++ +title = "Introducing NanoLedger, an Android app for recording PTA transactions on the fly" +[taxonomies] +Tags = ["Android", "PTA", "emacs"] ++++ + +In September, I wrote an Android app so I can easily add transactions to my plain text accounting ledger file while on the go. +It was recently published on F-Droid, so I thought, why not write a blog post about it. +I will go over why I made it, some light technical details, and plans I have for it in the future. + + + +## Plain Text Accounting + +Before I get in to the app itself, maybe a short introduction of plain text accounting (PTA) is in order. +PTA is an ecosystem of programs that all work on the same basic idea. +You record financial transactions in a plain text file (with some structure imposed by the tool you're using), and the tool can generate reports about those transactions. +The three main options in this space are ledger, hledger and beancount. +Like all financial tools, the way you use it is tailored to the information you want to get out of it. +If you want a general overview on your personal finances, that's possible. +If you want to use it to generate invoices for clients, that's possible. +If you want to know how much money you spent on cheese in the last year, that's also possible. +I will leave further explanation to [others](https://plaintextaccounting.org/), but definitely check it out if you're interested. + +## Why I wrote this app + +Before NanoLedger, I used [Cone](https://github.com/bradyt/cone) +Unfortunately, the author of Cone has abandoned the app, and I was experiencing some breaking bugs. +When syncing my journal files via Nextcloud, the app just straight up crashes, because it doesn't read the files in a background thread and reading files over Nextcloud does some network calls. +I used Syncthing for a while to sync files, but it used a lot of battery on my phone, so I really wanted to switch to using Nextcloud. + +Also, I've been doing PTA for 5 years now, so my journal file has gotten pretty big. +Because the file is read in the foreground the app just hangs while it is reading (or writing) to the file, which is not a nice experience. + +So, why not just fork Cone and fix it that way? +Well, Cone is written in flutter, which I'm not a big fan of. +Besides that, the technical challenge of writing another Android just seemed like fun to me. +I do consider NanoLedger to be a spritual fork of Cone, given that I definitely was inspired by its functionality when writing NanoLedger. + +## Technical details + +So what framework to use, if not flutter? +I tried to keep to the basics, so a simple native app, using the libraries currently recommended. +This means that the app is written in Kotlin, using the Compose framework, with a Model-View-ViewModel architecture. + +I wrote the app itself in about a week in my free time (so only evenings and weekend). +It's not that big of an app, but I'm still quite proud of myself that I got this done in a week. +I used my favorite editor, emacs, configured with a kotlin-language-server. +This means no memory-hogging Android Studio. +Most of my friends declare me crazy every time I mention this, but I'm so used to emacs that I doubt Android Studio would have allowed me to write this app faster. + +### Parsing journal files + +In fact, most of the time that went into the app, was spent on parsing journal files. +Because the format is mostly about being nice to write, parsing it isn't so nice. +I started out with writing a nice parser using parser combinators (trying out multiple Kotlin libraries to do so along the way). +It quickly became obvious though that this would be far too slow to actually use in practice. +Depending on the library used, parsing the file took anywhere from multiple seconds up to multiple minutes. +In the end, I replaced all this nice parsing work with a simple nested while loop that only tries to extract the information I actually need in the app to show transactions. +The one technical consequence of this is that I can't cleanly reconstruct the file based on the parsed transactions, because along the way I throw away comments, directives, secondary dates, ... + +## Future plans + +While I'm already very happy with it, there are still some improvements possible. +These include but are not limited to +* syntax highlighting of transactions, +* deleting of transactions, and +* editing of transactions. +Because of the way I parse the journal files, these last two won't be very simple but I have some ideas on how to go about implementing them. + +## Closing thoughts + +I wrote this app for myself, to fix a problem I was experiencing. +I submitted it to F-Droid because I thought it could be useful for others. +It seems, however, that others were experiencing the same problems, because I found out on Mastodon first that the app had been published. +It was very nice to see such a warm response. +A colleague of mine also started out with PTA because of NanoLedger, which was also quite nice to hear. +All in all, I'm very happy I took the time to write it. +