Skip to main content
Topic: Markup.rg (Read 18774 times) previous topic - next topic


Markup.rg is a User plugin for text markup that is attached to a single point in a score.
It is not designed for positioning text between two or more items.

To install, save the Lua attachment as:
Code: [Select · Download]
%ProgramData%\Noteworthy Software\nwc2\UserPlugins\Markup.rg.nwcuser.Lua
Registered user since 1996

Re: Markup.rg

Reply #1
I'm absolutely not in the mood to study lua just to use this plugin, and furthermore I'm not sure even then I'll be able to understand all anyway.
Call it cryptic! The more I look the less I understand.
At this point I'll find an alternative solution but, Rick, what about something less ermetic? Just a little help?

Re: Markup.rg

Reply #2
Google says that "ermetic" is Romanian for hermetic.
There are some examples in the attachment.
Registered user since 1996

Re: Markup.rg

Reply #4
I have replaced this text now (July 2021) with this "construction site" remark, as this will become the posting where I assemble a documentation of Rick's object plugin. I'll present my text proposals in postings at the end of this thread, so that we can discuss them - at places, I certainly have problems with some feature, or may be plain wrong, or believe that some code is dead, but this might not be so. But I'd like to keep these discussions separate from the "user manual", which will develop here.


Re: Markup.rg

Reply #5
After my little experiment to recreate jfb's 5/8 tempo marker with this plugin, I have - once again - thought about "salvaging" this object, even if only to pay respect to Rick's expertise.

Rick designed a object for "computer wizards", with five very typical design decisions:
  • "imperative command" semantics - you do not say what you want; but what steps an "interpreter" should do to arrive at the result;
  • not caring for readable parameters for special values like notation and other symbols;
  • very terse single letter commands;
  • the semantics (behavior) are based on, and can modify an internal state.
  • no consideration for other readability issues, like comments or line breaks.
All these decisions are typical for "power user" languages - I could share examples of very useful languages I have designed myself according to exactly these principles (one is used in our company by a large number of software engineers building our flagship product).
However, all five, but especially the latter three, make the object almost impossible to use for people not accustomed to "computer think".

When I designed my XText.hmm object, I knew I would run into exactly these decisions and problems. It took me hours to find a user interface design that (barely) scrapes by (I hope) these problems, by, for example,
  • disguising the "imperative structure" as 6 visible "command areas";
  • having a more limited command repertoire visible as fixed parameters (Rick's y command is my "offset" field, for example);
  • adding special notation for important symbols (like %ff% for fortissimo, %1/4%, for a quarter note etc.);
  • no internal state besides the "obvious" "text position"; and only a single sort of command that modifies this state, namely the "jump back" %-1%, %-2% etc. (but even this may be beyond the grasp of a typical user ...).

From that experience, I thought about possible enhancement options for Markup.rg. Here are a few that seem to make sense to me:
  • I could just document what it does.
  • The code shows that there are a few possibilities that can, right now, not be used out of the box. I could enable that code (and, probably, fix bugs with it that did not surface until now);
  • ... however, part of that code seems not really useful: E.g., specifying that a Markup object is only active during Print or during Edit.
  • Usability makeover 1: One could split the "markup steps" into separate fields, somewhat like in my XText.hmm object. Because NWC has a limitation of 32 input fields, and Rick has 10 special fields in his code, this would limit the numer of steps to 22; however, in all his examples, the maximum number of steps is 13, so this would be sufficient. The single letter commands would either survive, but adding longer names (e.g. font= instead of /f) would be helpful.
  • Usability makeover 2: Separate name and parameters into fields; this would allow to select the command from a drop-down box, but the parameters would still remain terse text; and only 11 commands would then be possible.


Re: Markup.rg

Reply #6
I could just document what it does.
Speaking for myself (and myself alone), a simple explication should suffice.
By the way: by now I had to learn a bit of lua and I know something more of the inlets of plugins.
Maybe now I could understand it better, if I had the will to study that plugin.

Re: Markup.rg

Reply #7
I had a brief private conversation with Rick back when he wrote this object. He created it at a time when there were still relatively few objects out there, which you can see by his examples, which include an arpeggio, 8va mark, and more detailed tempo, all of which now have dedicated objects. At the time, he told me that he never expected anyone else to use the object, but he provided examples so those who were interested could see what it did and how it could be used. I opened his sample score and viewed the command string, and it only took me a few minutes to work out the basic syntax. But then I am a programmer, and reverse engineering things is what I sometimes do to solve problems.

I am paraphrasing him here, but he considered it a sort of toolbox to be able to solve one-off issues in a score, to be able to create something that NWC could not do natively. It's also worth noting that Markup.rg is a display/print only tool - it has no ability to play back. Thus, any of the examples that include extra notes or playback modification like arpeggios or 8va would have to have a hidden staff that does the playback.

Re: Markup.rg

Reply #8
@Mike - yes, of course.

But - being just a little bit confused - does this mean that you are against documenting it? I mean, this plugin has gotten its fair share of thumb-downs because of its arcane syntax (for non-programmers, at least) and "only Rick knows ...", but, on the other hand, one can definitely do some nice things with it. And it's small enough that documenting it takes just a few hours, I'd say ...


Re: Markup.rg

Reply #9
Oh, no, I didn't mean that at all. I actually considered documenting it in the past, but did not want to impinge on someone else's territory. However, I think Rick wouldn't mind us doing that now.  However, unless you discovered a nasty bug in the process, I wouldn't make any enhancements to the object; I would document it as is, making the best guess as to functionality and intent.

Re: Markup.rg

Reply #10
Ok! - I'll make an attempt in the next days ...

Re: Markup.rg - documentation proposal - part 1

Reply #11
This is my first proposal of a documentation of Rick's Markup.rg plugin. I have now completed all 8 sections; and invite you to criticize and amend it them, because, among others: I certainly do not understand all the object's possibilities; my first language is not English; I might misconstrue Rick's intentions; etc. Lastly, my explanations tend to be wordy - so if someone has suggestions (or merely suggests) to make them shorter, I'll try to heed such advice. Thanks for any help!


1. Basic functionality
Edit: Started on July 17th, 13:40

Rick's "Markup.rg" is a small plugin that can draw text - including music notation - with many parameters into a staff. The "how" and "where" of the text is specified with small commands - something like write the following text in italics, 3 staff spaces higher and at an angle of 45 degrees. Each markup is provided as a sequence of text commands, interspersed with the text to be shown - this is what is called a markup language, where language is a computer science term meaning "something textual with certain rules". As an example, we use such a markup language in this forum to make text bold with [ b ] ... [ /b ] or quoting a text with [ quote ] ... [ /quote ]. For controlling the text and line drawing with his Markup.rg object, Rick invented a small markup language of his own, which I'll explain in the following.

The "Markup.rg language" consists of small commands, where each command looks as follows:


  • Each command starts with a slash.
  • The following letter is, mostly, the beginning of a word describing what the command does. For example, there is a command starting with /f to set the font of the following text; or another command /a which changes the angle of a subsequent text (i.e., the text is written on an upwards or downwards slope).
  • The number after the command letter is interpreted differently by each command - I'll explain this for each command separately.

A complete markup consists of a sequence of texts and commands. Here is a first example:


This markup consists of five elements:
  • plain text small;
  • the markup command /m2, where /m is the command for "magnify", which changes the size of following texts. The number 2 in this command multiplies the font size by a factor of 2, i.e., following texts will have double size;
  • the word large;
  • /m1.5 changes the font size once again, this time increasing it by another 50% (it is now three times the size of the first "small" text, as 2 times 1.5 equals 3);
  • finally, the word huge.
The result of this markup can be seen in the attached file MarkupExample1_SmallLargeHuge.png. One can see that large is twice as large as small, and huge is 50% larger than large.

2. "State", or what a sequence of commands "remembers"
Edit: Added on July 17th, 17:07; edited July 18th, 15:25

The small-large-huge example above shows that while processing the commands and text pieces, the Markup object remembers the last size of the text, so that the /m command can multiply it by some factor. Actually, there is more information remembered:
  • Text information: Mainly, a current magnification, current font, and a current font style (italic and bold); in addition, a current text angle, a "whiteout state", a "stroke state" and a "lyrics offset" are also remembered.
  • Position information: Most important is the current position (a horizontal and a vertical coordinate) where drawing is done; additionally, a "home position" (only a horizontal coordinate) is also remembered - see more below under "Location commands".
The text information is only changed by explicit commands. The position information is updated by text drawing itself so that the text pieces are drawn nicely one after the other (and not on top of each other). However, it can also be changed with commands - in that case, drawing will continue "somewhere else" - a very useful feature.

The remembered information must start out with initial values. Those are:
  • Magnification = 100%; font = "Staff Italic" (font no.3); font style = regular, i.e. neither italic nor bold; text angle = 0, i.e. horizontal; whiteout = no, i.e. black text; stroke = no, i.e. standard text drawing; lyrics offset = 0.
  • Current position: horizontal position is at the previous symbol in the staff - this means that typically, one puts a Markup object after the symbols to be adorned with text or music notation; vertical position is the height of the object on the staff (which can be changed as usual with the Position value in the object's dialog or via selecting and pressing Ctrl-Shift-Up or -Down). The home location is initially at the same place.
As a side note, there is no color in the state; the color of the symbols drawn is selected in the Visibility tab of NWC's object dialog, and hence it cannot be changed inside the markup.

3. Text commands
Edit: Added on July 17th, 18:03; edited July 18th, 15:25

Here is a list of the text commands, in alphabetical order. Commands that are important in my opinion are in boldface. I'll give a few simple examples below:
  • /aangle: Change text angle. The current angle, in degrees, is set to the value provided.
  • /ccharacternumber: This draws the character with the given number. This is very useful if the character does not have a visible representation in the text box, which happens for special characters.
  • /ffontnumber: Change font. The fonts are numbered as in the drop-down box for a text, i.e., 1="Staff Symbols", 2="Staff Cue Symbols", 3="Staff Italic" (initial setting), 4="Staff Bold" etc.
  • /kstroking: If stroking is the number 1, text is written as an outline, i.e., only the boundaries of the symbols (characters or musical notation) is drawn. Setting it to 0 activates standard drawing.
  • /mmagnification: Change font size. The current size is multipled by the magnification factor to yield the new size.
  • /sstylenumber: Change style. The styles are numbered as follows: 1=regular (neither italic nor bold), 2=bold, 3=italic, 4=bold and italic.
  • /wwhiteout: If whiteout is the number 1, text is written in white. Mike suggests that this could be use to actually white-out notation as drawn by NWC, and then redraw at some better place in special circumstances. Setting it to 0 activates standard drawing.
Here are some examples - you can view them in the MarkupExamples2_Text.nwctxt and MarkupExamples2_Text.png attachments of this posting:
  • /a22.5upwards!/a-30down first sets the angle to 22.5 degrees and draws the text upwards!; then it does the same going down -30 degrees.
  • /f1  /c123 sets the font to "Staff Symbols", then draws two spaces and character 123. In normal text, this would be the { character, but in NWC's font, this is a block (two-bar) rest.
  • /f5reg/s2 bold/k1 stroked: With font 5 = "Staff Lyric", draw text "reg"; then, set style to 2 = bold and draw text " bold"; finally, activate stroking (while keeping style bold) and draw " stroked".
Each example is anchored to a "Broken Single" bar to the left of it.

4. Location (placement) commands
Edit: Added on July 17th, 19:41, extended 20:33

There are five of these. I present them in logical order. The first two influence only the current position:
  • /xhor.distance: Increase the horizontal position by distance; if distance is negative, this will shift the position to the left. In addition to this command, the horizontal position is shifted to the right by the text's width when a piece of text is drawn (there is one small bug here, which can be seen in the /a example above: If the text is going up or down, especially vertically, the horizontal position should only be shifted by the length of the projection of the text. But this is rarely a problem).
  • /yvert.location: Set the vertical position. Note that /x increases (or decreases) the position, whereas /y sets it.
The next two manipulate and use the "home position". This is useful if one wants an "anchor" that is different from the default home position:
  • /hhor.offset: Set the home position to the initial horizontal position offset by distance. In addition, this also sets the current horizontal position.
  • /rvert.location: Return the horizontal position to the home position; and set the vertical position.
Finally, there is a command for setting a "lyrics vertical position"
  • /vvert.location: ___NOT YET RESEARCHED___
The location commands are useful to place texts e.g. in multiple lines, as in the following example:


/h1 places the home position one notehead width to the right of the previous item (the broken bar, in my examples). After drawing "reg", /r-3 returns to this horizontal position, but now at vertical position -3, which is about one text line lower, to draw "bold". After this, /r-6 again returns to the home position still farther down for drawing "stroked". The result is shown as the last example in the MarkupExamples2_Text.nwctxt and MarkupExamples2_Text.png .

However, all the location commands are more important, and outright necessary to create complex musical symbols - see the respective section below.

5. Musical symbols
Edit: Added on July 17th, 19:41, extended 21:27

Musical symbols, in NWC, are nothing else than text, in a special font. Thus, Rick's Markup object can be used to create (non-sounding) musical notation, from simple to complex. In order to write such notation, it is useful to know the characters by heart that create musical symbols*. Therefore, here is a short list of the most important ones:
  • space (character 32) ... normal space
  • C (character 67) ... short horizontal line
  • F (character 70) ... tiny half note
  • G (character 71) ... tiny quarter note
  • H (character 72) ... tiny eighth note
  • _ (character 95) ... short space
  • d (character 100) ... sharp symbol
  • e (character 101) ... natural symbol
  • f (character 102) ... flat symbol
  • g (character 103) ... double-sharp symbol
  • h (character 104) ... double-flat symbol
  • i (character 105) ... whole notehead
  • j (character 106) ... half notehead
  • k (character 107) ... standard notehead
  • l...r (characters 108...114) ... rest symbols
  • | (character 124) ... short segment of a notestem
Open attachment AllSymbols.nwctxt for all other symbols - shown, incidentally, by using Markup.rg.
With these symbols, one can e.g. create Rick's first example:

  /f4Andante Expressivo  /f2/y0.5k/x-0.03/y1/c124/y2/c124/y0/f4 = 76-88

Here is a breakdown of the commands:
  • /f4 sets the font to "Staff Bold" for the subsequent text.
  • /f2 starts the "symbol part", with symbols reduced to cue size.
  • Placed a little bit above the base line (/y0.5), k represents a notehead.
  • Going minimally back with /x and up (/y1), the lower part of the stem is drawn (/c124).
  • Going up once more (/y2), another /c124 completes the stem.
  • /y0 returns to the base line, and with /f4 the rest of the text can be drawn.
For the result, see Rick's first posting in this thread (I'm not sure why Rick created the quarter note "from scratch", instead of using symbol G; however, it seems that his result has a more prominent notehead, which might be what he wanted).

* Unfortunately, you cannot use the "Char Map" feature of the Text item for this, as - for whatever reason - the numbers are offset by 61440 (hexadecimal F000) there.

6. Drawing lines
Edit: Added on July 18th, 13:30

Lines, like everything, are also text. The list above shows the characters in the "Staff Symbols" font that can be used for lines: C for the line, and space and _ for long and short empty spaces. With these, one can create lines as follows:
  • solid line: /f1CCCCCC
  • dashed line with large gaps: /f1C C C C
  • dashed line with short gaps: /f1C__C__C__C
  • dashed line with tiny gaps: /f1C_C_C_C
Using /f2, i.e. "Staff Cue Symbols", will scale down the line.

Using such lines, one can e.g. draw an open hairpin, which could be used for a crescendo after a system break:


Here is breakdown of the commands:
  • /f2 ... select staff font
  • /a4 ... slant upwards
  • CCCC... upper line
  • /r-2 ... return to home
  • /a-4 ... slant downwards
  • CCCC... lower line
The markup can be seen and studied at the end of attachments MarkupExamples3_Notation.nwctxt and MarkupExamples3_Notation.png. Rick's initial posting contains some more examples with line drawing in them.

7. How to create complex musical symbols
Edit: Added on July 18th, 15:25

I have, actually, already covered the assembly of complex notation in all the previous examples. But let me explain the conceptual idea here more explicitly: For a complex symbol, one creates a sequence of command groups, each of which consists of up to three parts:

    move to position; select font and other text properties; draw text
For example, the open hairpin above has two of these groups, one for each line:
  • first group: /f2/a4CCCC... positioning is implicit (we start at the note); then, set font and angle; finally emit the first line.
  • second group: /r-2/a-4CCCC... position somewhat below home; set new angle (font remains the same); and draw second line.
Using this group strategy, one can create arbitrarily complex notation. Here is, as a final example, Rick's creation of a cluster chord from p.248 of "Behind Bars" - see again attachments MarkupExamples3_Notation.nwctxt and MarkupExamples3_Notation.png:


It consists of the following groups:
  • /f1/h1k ... set font and home position; and draw first notehead (see bar 2 in the attachment. Home is positioned one notehead width to the right, so that we can attach noteheads and the slanted line conveniently; bar 3 shows that without that, the first notehead would end up to the left and need additional positioning);
  • /r1/x-1.8e ... place natural symbol (bar 4);
  • /x2.35d ... place sharp symbol (bar 5);
  • /r1/x-1k ... place next notehead;
  • /x2k ... and another one;
  • /r2k ... and the last one (bar 6);
  • /r5/a336/m0.55CCCCC ... draw a thin slanted line connecting the f-sharp to the chord (bar 7);
Incidentally, this "group think" is also very helpful when decoding a markup written by someone else (e.g. Rick): Splitting the object after each text helps to understand the structure of the symbol; and if this still is not enough, one can experimentally drop later groups and thereby find out what the earlier ones do, as shown in the "deconstruction" of the cluster chord.

This concludes my manual of Rick's versatile Markup.rg object - I hope you have learned how to tackle it, and how to create useful, but also esoteric musical notation for all sorts of purposes.

8. Features that are not active
Edit: Added on July 18th, 20:53

Rick's code contains a number of options that could be set to various values for modifying the drawn text. However, the code currently misses the necessary declarations to make these parameters visible to the user. These options are:
  • Width ... set the width used by NWC's layout to a value larger than 0.
  • Media ... show text only in certain contexts; these can be: edit, view, print, or selector;
  • Anchor ... use different anchor for text; the anchor method can be one of xyAlignAnchor, xyAnchor, xyStemAnchor, or xyStemTip (if I understand the code correctly);
  • Box ... surround the text with a rectangular box;
  • Ellipse ...  surround the text with a round box;
  • Index ... anchor text not to previous item, but to some other item farther away;
  • Justify ... adjust text; possible values are Right and Center.
  • Pen ... set pen for text drawing;
  • PgLeft ... use alternate location if at the left of the page (I do not yet understand how this works);
  • PrintWidth ... use different width for printing.
(Maybe we discuss enabling these options below.)

Re: Markup.rg

Reply #12
Looks good to me so far buddy!
I plays 'Bones, crumpets, coronets, floosgals, youfonymums 'n tubies.

Re: Markup.rg

Reply #13
A few minor comments/suggestions.

... the Markup object somehow remembers the last size of the text ...
I would remove the word "somehow". I understand that you are reverse engineering the code and it might not be obvious how it remembers the previous size, but I'd just say that it does.  It's possible that the "remembering" might be part of the plugin API.

/wwhiteout: If whiteout is the number 1, text is written in white (I wouldn't know a good use for this, actually). Setting it to 0 activates standard drawing.
(Emphasis mine)  I have used the whiteout feature in at least one of my plugins, to put a white number on a black dot in a guitar chord chart.  However, I believe that Rick has used the command as its actual namesake, to "white out" some actual notation so it can be redrawn "properly". This take careful positioning.  Anyway, you might include one or more of these examples in your manual.

Re: Markup.rg

Reply #14
I would remove the word "somehow".
...I believe that Rick has used the command as its actual namesake, to "white out" some actual notation so it can be redrawn "properly". This take careful positioning.  Anyway, you might include one or more of these examples in your manual.
I have added this suggestion (with your name  :D ). I would rather not add more examples, but leave it with the few I have attached. Adding "intricate usage examples" could be done in additional postings, I'd say ...

Thanks for feedback!


Re: Markup.rg

Reply #15
Rick used whiteout cover large sections of unwanted staves – a typical instruction being /f-9/y-6/c9608.18/h0/y20/a270/c9608.8.

It does take some lining up and use of spacers. And it doesn't cover things like key signatures.

Re: Markup.rg

Reply #16
Rick used whiteout cover large sections of unwanted staves – a typical instruction being /f-9/y-6/c9608.18/h0/y20/a270/c9608.8.
Interesting. However, for MarkupPage.rg, he invented a different markup language - e.g. with the repetition feature; and so he did not have to use the whiteout text property in such cases, it seems. Anyone going to write a manual for MarkupPage.rg?


Re: Markup.rg

Reply #17
I have now completed all 8 sections. I'd wait for your suggestions & critique; and then, after some consensus, move it to the topmost posting I can change. Also, there is the question of whether, and how, to enable the object's "hidden options".


Re: Markup.rg

Reply #18
Quite verbous compared to Rick's standards.  :))
Thank you very much, H.M.!

Re: Markup.rg

Reply #19
Very useful, H.M.

My first attempt, after some tuning:

Code: [Select · Download]
|User|Markup.rg|Pos:2|Class:StaffSig|Markup:"/m0.7/x-2 1/y-7/x-1.5 2"
|Clef|Type:Treble|OctaveShift:Octave Down|Visibility:Always
Always look on the bright side of life!

Re: Markup.rg

Reply #20
Hey Opagust...  Umm, what's it supposed to do?  If it's put the numbers 1 and 2 to the left of the staff then it didn't work for me...
I plays 'Bones, crumpets, coronets, floosgals, youfonymums 'n tubies.

Re: Markup.rg

Reply #21
It did for me - if I (a) name the staff Tenors    (with about 3 spaces after the name), (b) set "Staff Labels" to e.g. First System and (c) view it with Alt-F-V (Viewer Mode, i.e. F11, doesn't show anything to the left of the staff's beginning, it seems). Nice usage as a StaffSig, BTW - I didn't think about that ...


Re: Markup.rg

Reply #22
Hey Opagust...  Umm, what's it supposed to do?  If it's put the numbers 1 and 2 to the left of the staff then it didn't work for me...

I did some more experiments.
It seems that, when the staff has no bracket nor brace, the 1 and 2 ar not visible in edit mode, nor in viewer mode.
However, they do appear in print preview.

But this has of course nothing to do with the markup object itself, but rather with the way the editor sets its margins.
Always look on the bright side of life!

Re: Markup.rg

Reply #23
Perhaps if your example was a .nwctxt of the whole file instead of the single staff..?
I plays 'Bones, crumpets, coronets, floosgals, youfonymums 'n tubies.

Re: Markup.rg

Reply #25
Cool, thank you - I can see how it works now.
I plays 'Bones, crumpets, coronets, floosgals, youfonymums 'n tubies.

Re: Markup.rg

Reply #26
Great work with the documentation hmm! It's just what I need to put some musica ficta (modern usage of the term) accidentals on a Palestrina piece I'm working on, where I want to display editorial accidentals above the staff instead of in their regular place (this distinguishes them from accidentals written on the original score).
However, I believe that Rick has used the command as its actual namesake, to "white out" some actual notation so it can be redrawn "properly". This take careful positioning.  Anyway, you might include one or more of these examples in your manual.
To convert a notated accidental to an above-the-score, I had written a very simple markup object placed after the flattened note "/f1/w1f/w0/f2/x0.4/y6f".
Choose the symbols font, white out on, (white) flat sign, choose the smaller symbols font, move across a tiny bit and above the staff and draw in a new flat. However, there are two snags here.
1) the whiting out is incomplete, as the black flat underneath it bleeds around the edges. Making a larger whiteout flat sort of works, but it leaves a larger hole on several of the staff lines (which I hadn't yet worked on to tidy up)
Okay, so I 've now worked on it and started redrawing lines but it now looks messy, a bit like Mr Bean's repairs on Whistler's Mother!
2) if we ever transpose the part (probably not a consideration with Early music transcriptions), then we need to adjust the white out (easy with Ctrl-Shift-Up/Down, but this then moves the accidental above the staff). Okay, let's ignore this hypothetical snag. (Also, the concept of transposing a written sung line is a modern one, and I should probably be using proper accidentals in that case!)

In the end I decided to put a MIDI transpose (Coarse Tuning) up and back down around this note to remove the accidental.
I'll need to learn how to make an object that combines these two elements.

Here's the code:
Code: (nwc) [Select · Download]
Pictures in the attachments.

Does anyone have any other suggestions for solutions?


Re: Markup.rg

Reply #27
Try a hidden tied grace note for the accidental.

Re: Markup.rg

Reply #28
That's a good idea! Thanks Peter.

Re: Markup.rg

Reply #29
It's more than a good idea, Peter.
My original stab was uploaded last week, but the Scripto's previewer doesn't recognise the channel transpose!
I revisited the work and got rid of not only the MPCs doing the transposition, but the use of Markup, as I discovered with a clearer head that it can now all be done very easily with text.
A new version has been submitted to Rich.