Looked at #nepenthe again this morning g for the first time in a while and was surprised to find it in better shape than I thought. Now immersing myself in typescript matters so I can write some tests, etc.
I've been nudging #nepenthe forward inch by inch, trying to organize things in a sane fashion and rewrite brute-force code into something a little more flexible (where needed) and better-commented.
Current status: tantalizingly close to having a functional terminal command.
While working on #nepenthe it occurred to me that I might finally be able to come up with a relatively painless solution for expressing #banjo 5th string notes in standard notation.
... on a five string banjo, the 5th string is pretty much always played as an open string; in the older "stroke" style and more modern clawhammer and scruggs styles, it often functions as a drone. In the classic fingerstyle era, the fifth string is often cleverly used as a way to facilitate left-hand jumps up or down the neck; you don't have to fret it, so a note on the fifth string gives you a little extra time to move your left hand.
Back when banjo music was published in standard notation, the convention for communicating "play this note on the open 5th string" was to engrave the note+duration as usual, but add an upright stem with a sixteenth note flag.
A few years ago a kind soul on the #lilypond mailing list showed me how it is possible to achieve this by using multiple voices and overriding the beaming/duration for the 16th note, but as you might imagine it's a bit of a pain in the ass when you've got multiple 5th string notes in a given piece; it's exciting to think I might be able to implement a #handlebars tag to do most of the dirty work.
Anyway, on to the tip: While thinking about logic for such a tag, I found myself wondering how one would handle a half or whole note on the fifth string; When Lilypond encounters the same note with different durations in two voices, it engraves the two side by side, which makes sense... but not for this highly specific fringe case.
Poking around for solutions, I found that Lilypond has two helpful commands for exactly this situation, '\mergeDifferentlyHeadedOn` and `\mergeDifferentlyDottedOn`.
For the example in the graphic, the Lilypond markup that lets the sixteenth and half notes occupy the same space is:
<<
\fixed c' { \once \mergeDifferentlyHeadedOn \once \mergeDifferentlyDottedOn \once \autoBeamOff g16*8\5 }
\\
\fixed c' { g2\5 }
>> d4 b
... so to automagically generate everything within << >>, I'm imagining a tag like:
{{banjo5thStr dur="2"}}
...with logic to calculate the duration override for that 16th note, and an optional 'pitch' attribute to support the older so-called 'Rice' and 'Briggs' tunings.
... the tradeoff here is that MIDI output from this markup will have that note doubled up; when writing Lilypond "by hand" I've adopted a practice of putting 5th string notes in a separate part with silences between them and then just omitting that part from MIDI, but I'm not about to try to implement support for *that* pattern here. I can live with it.
I should say that I don't think I've ever actually seen a banjo piece with a half or whole note sounded on the fifth string, but I like handling fringe cases when they occur to me.
#handlebars #lilypond #banjo #nepenthe #lilypondtips
#nepenthe progress: I think I've got a handle on the rewrite, and now it's a matter of adding support for various tag attributes, etc, and then mundane build/packaging concerns.
This is what a Nepenthe document looks like now. Explicit `score` and `staff` tags make it a bit more verbose than the first iteration, but having worked on some OG #Lilypond last night I think this is still going to be a more pleasurable way of dealing with wrangling chunks of Lilypond into scores.
All of this work is ongoing on the `dev-typescript` branch of the repository at https://github.com/tinpan-io/nepenthe/tree/dev-typescript (Very much an unstable WIP at the moment.)
I really do seem to have a talent for finding my way straight to use cases that libraries really weren't intended for; in this case I'm trying to use #handlebarsjs with custom helpers to implement my own simple/lightweight #nepenthe document format, and that gets me about 90% of the way there, but the way I'm using custom helpers and partials, I'm realizing there no way to access the root context without explicitly passing it to my under-the-hood helpers and/or partials in the source document.
Which makes sense when considering handlebars from the perspective of a developer tool where you're going to dial in your templates and forget about them... but doesn't make sense when trying to provide a simple document format for myself and others.
I think I've got a workaround though.
...I took the time to write a #nepenthe document spec *before* I attempt to implement a parser for it and that's good, but it also derailed me because writing specs is not the fun part of hacking on personal projects.
I am starting somewhat from scratch on a new branch using #typescript, which is also slow going because it's unfamiliar (and I'm still not super-familiar with node in general) but hopefully the rewrite will go quickly enough once I find a foothold.
Inflection point: I want to implement new {{layout}} and {{staff}} tags to replace the current describe-layouts-in-the-frontmatter pattern, and I feel like I should *probably* do a scorched-earth rewrite of all the various under-the-hood handlebars stuff I've already done, because it's already a bit of a mess in that "I was both learning how to speak handlebars *and* making it up as I went" way.
And then as I review the Lilypond docs for \book and \bookpart I'm wondering if I need to rethink my overall approach slightly to be able to support those idioms, which would also mean optionally supporting multiple \header elements, and that feels like it's getting into "is this actually easier/more convenient than pure Lilypond" territory.
Conceptually, I think it makes sense to enforce a "single file = single score" structure; each file can contain:
* Header info (YAML front-matter)
* Parts (the actual Lilypond markup for one or more instruments or voices)
* Layouts (one or more groupings of available parts using different kinds of staves)
...and if/when I get around to implementing \book / \bookpart support, that can be done with additional tags that include individual score files; that way it would also be possible to assemble multiple book files that combine different layouts from each score. (Book of standard notation, book of tab, book with music transposed to Bb, etc)
It's official: #pitcherplant is now called #nepenthe and a very, very early/rough version is available as a Node package; install with
npm install -g nepenthe
or
yarn global add nepenthe
and 💥 you should be able to run the `nepenthe` command from your terminal.
Parts/Layouts are poorly documented because I've realized that declaring layouts in the YAML front-matter doesn't quite cut it; They really want to be document tags, which means back to the handlebars drawing board. But the example in my last post is pretty representative. #lilypond #npm #nodejs #sheetmusic
#sheetmusic #nodejs #npm #lilypond #nepenthe #PitcherPlant
adam: they'll figure it out ... #nepenthe
adam: they'll never trust us again!