HOW I DEVELOP PLUGINS FOR KOREADER Sure, you could get rich and flame out building FarmVille clones for Tim Cook and Larry Page. Or you could live a hermit's life and build silly little plugins for your e-ink powered device, like an app to or or . But how would you accomplish all that, being a hermit and all that? Well... Maybe you've heard of ? Oh. You haven't... Well let me tell you that KOReader is only the best aftermarket document viewer for Kobos, Kindles, PocketBooks and Android (imagine that, fortune strikes after all). KOReader has been around just shy of a decade (though I only found out about its glory two years ago). It boasts a plenty of features to put your first-party e-reading software to shame. In this rambling, I'll cover my workflow for writing, building, and testing code with the KOReader emulator, as well as my workflow for testing on my e-reader, a Kobo Libra H2O. It's not really a tutorial per se (I'll admit the title misleads on this revelation). More like an overly pedantic explanation of my workflow. What I don't cover is how I write Lua or how a person can use KOReader's to build their iPhone-killer plugins. To grasp the lunar language I recommend sifting through . To understand KOReader's front-end modules I'd suggest reading through the , which is a pretty simple plugin and covers most of the conventions you'll need to know. Development Environment and Tools ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ What's a guy need to get going? Just a small satchel of dependencies: , , , and . Oh, and the . That last dep might be a bit tricky to install. If you're reading this rambling like a "how-to" and are having trouble getting your environment setup, reach out the for help. Feel free to ping me @roygbyte, or cast your voice into the void. You'll get help, for sure. Project Structure ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Some people work on their plugins straight out of the `koreader/plugins' folder. This is a fairly straight-forward process and will work if you don't want a separate repository for your plugin. My preferred structure is to dedicate a folder on my machine to KOReader development. Inside that folder I include the project base, as well as the plugins I'm working. For me, this folder looks like: ,---- | /_KOReader | /koreader | /crossword.koplugin | /weather.koplugin | /contrib `---- Concerning the above: `koreader' is the , `crossword.koplugin' and `weather.koplugin' are my two plugins, and `contrib' is KOReader's plugin repository (It's actually not relevant for this rambling, but I'm including it as a "shout-out" and encouragement to my dear reader to check it out, where you'll find some KOReader treasures.) I like this setup because it lets me keep the KOReader project files separate from my plugin development. I can have separate Git repositories for both and not worry about one fan's shit hitting another and causing a real foobar. I use a system link to stitch it all together: ,---- | /_KOReader | /koreader | /plugins | crossword.koplugin -> [...]/_KOReader/crossword.koplugin | /crossword.koplugin `---- The one thing to note is that the system link has to be *absolute*. I learned this the "hard" way, with KOReader fritzing out over relative paths. What a mess that was... Anyways! In the snippet above, I've truncated it, but the full thing reads `/home/scarlett/Development/_KOReader/crossword.koplugin'. Maybe you'd like to try something similar? Well, to create a soft-link navigate to your `=/koreader/plugins=' folder. From this directory, execute the following command (but, like, change the directories to match your file system): ,---- | # FYI: First argument is the target (i.e.: destination folder). | # Second argument is the link name and location. | ln -s /home/scarlett/Development/_KOReader/crossword.koplugin crossword.koplugin `---- If you're copying along, you'll want to confirm the link was successful. Either try and travel through it with `cd' or list the directory contents with `ls'. Running the emulator and then seeing if you plugin exists can also confirm success (or failure!) ,---- | # A happy link will show the link name and the target. | ls -la koreader/plugins | # Or launch the emulator from `koreader`. | ./kodev run `---- Development workflow ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ For my actual development (i.e.: coding, linting, debugging, testing) process, I'm no outlier of genius. As I learned from the wise words of in art school, always start with pseudo-code. After that's done, I slowly turn it over into code-code. Before running the emulator and testing the results, I will check the files over for correct syntax using `luacheck', like so: ,---- | luacheck crossword.koplugin/* `---- (As I'm writing this, I see that Luacheck can be integrated directly into Emacs through the [FlyCheck]() extension. I am absolutely going to be installing this extension next time I work on my plugin!) After linting/syntax analysing, I run the emulator (`./kodev run') and proceed to test the plugin by hand. Then it's a simple matter of rinsing and repeating those steps over and over again. When it comes time to test the plugin on my e-reader, I use `scp' to transfer the files. First, I enable the wifi connection on KOReader. Then I launch KOReader's SSH daemon (Settings > Network > SSH server), set the port to 22 and "login without password". Then I run `scp' with the following arguments (note: you'll have to change the local address to whatever your device indicates): ,---- | scp -r --exclude='.*' crossword.koplugin/* | root@192.168.2.16:/mnt/onboard/.adds/koreader/plugins/crossword.koplugin/ `---- Looking at that snippet now, I can't remember if it works out-of-the-box. I think I had to make `crossword.koplugin' on my Kobo before I could upload to it. And I don't think `scp' even accepts an exclude argument? And probably I should be using `rsync' anyways? Gosh, there's so much to learn. And on that note I better go... bye!