It’s been a long time coming, but an idea that I conceived almost two years ago is finally come to fruition. I first used the extensible nature of LilyPond to customise editions when I was creating an edition for a course at University and was yet unsure of the tactus, meter and transposition I was going to impose on the notation. LilyPond comes with many useful functions such as
\shiftDurations which alters tactus on the fly and a smart
\transpose as well as an endless configuration of variables. After fiddling around with these functions, I found that I could define variables at the beginning of my file to set the transposition and meter, and with a quick change of these variables and recompilation of the file, huge possibilities of editions were instantly accessible. For that edition, transposition and meter was as far as I got, after all, I had decided on everything else. But soon I realised that anything that could be defined with a variable in LilyPond (i.e. literally everything) could be altered and my editions started to fill up with various definitions.
The first large edition which I tackled in earnest was Perotin’s four–part “Viderunt Omnes”. I wanted to see if it was possible to define everything relating to critical and performance editions in terms of variables. Looking back on it now, it was a trial by fire. I had seen on the LilyPond snippet repository that it was possible to use tags to add and remove functions and I tagged everything. The files are barely comprehensible to me now, awash with badly–named tags as they were. But it was possible, it just needed a lot of streamlining. Subsequent editions have all been a learning experience for me, creating complex functions that streamline the process and, put simply, add the tags for me in a way. Instead of tagging two versions of a note—one with rests, one without—I can call a custom function on the note and LilyPond will generate the correct version depending on the configuration.
I initially began documenting all the configurations manually, typing each configuration into the HTML form for submission to the server, which would also have its own copy of the configurations in a different format. Unsurprisingly this was abandoned extremely quickly in favour of an XML document which codifies the questions and possible answers along with their respective configuration variables into an unified format. A custom PHP framework can simultaneously convert this XML into both the HTML forms that customise each edition, and the input for the server.
On the server side, a Redis server holds the jobs which are taken off the queue by worker functions. Each worker function generates a new LilyPond instance in a chroot jail, feeds it the input and edition files and extracts the resulting PDF and thumbnail images. These are all uploaded to the MySQL database which oversees all other database functions, including maintaining a cache of recently made editions along with a compressed store of old editions which can be uncompressed into the cache when required. All this is communicated back to the user using simple AJAX. Cron scripts on the server continuously work through the database, picking out purchased editions and packaging, watermarking and emailing them.
You can get started right here!