Pages

Monday, March 9, 2015

Writing a libretto in reStructuredText

I'm adapting my February Album Writing Month (FAWM) album in to a musical. I have no experience writing scripts of any sort, so it should be fun.

I was pointed to http://kierenmacmillan.info/perfect-musical-libretto-format/ as a good example of a libretto. I liked it, it looked good. I can now produce something quite similar, from a completely text-based format (by way of an ODT file, allowing third-parties to easily tweak things).

See, the album it is based off of is an art concept album about copyright in the guise of hymn-filk. It was always planned that it would include full sheet music and be released with the most flexible license. This means that the libretto for the musical will be released with the same flexible license (Creative Commons Attribution) as I actually want people to be able to easily modify it.



As to the libretto... I'm not 100% sold on all-caps for any use-case, but I understand the need for something. Unfortunately, there's some inconsistency between the way the actors roles are formatted, which is a pain.

Which is to say, it led to some compromises. My initial design uses "small caps" and bold for the actor roles universally. With a custom reStructuredText role formatted via the ODF writer it was easy to do. (Switching this to caps instead of small caps is a matter of a tick of a box in the style file -- easy to do.)

The Kieren MacMillan example had some novel wrapping for the speaking lines, and I opted for a simple hanging indent. I'm not sure how to do the novel method with reStructuredText without using a table, and that just gets ugly.

I don't really have a good general-purpose solution to this for people. I ran in to some moderately painful idiosyncrasies with regards to table width. (It really wants to be too large.) I also couldn't find a way to have the table itself aligned in the middle and have that setting get obeyed by the ODT writer. I'm using a Makefile and GNU shell tools to work around the issues for now.

As an extra bonus, I thought I could just disable the border on the tables in the styles.odt file, but when I saved it in LibreOffice the ODT Writer (part of the reStructuredText tools) just totally fell over and died. I diagnosed the issue as the "content.xml" file being simplified by LibreOffice and some part of the ODT Writer didn't know what to do with a missing element/attribute.

That was especially annoying, as it means I didn't trust being able to just open and save the "styles.odt" file way you normally would. I settled with tweaking the compiled ODT file to look the way I wanted, saving it, extracting the "odt" file (which is a valid ZIP file) pulling out the "styles.xml" and sticking that in the styles.odt file. (Though I ended up manually tweaking the content.xml file, there is a "--table-border-thickness" setting I never tried, but I suspected that any saving of the file would result in the simplification that would ultimately kill rst2odt.py again.)

The setup is pretty simple. The ODT writer easily supports using custom styles. I use two:

.. role:: actor
.. role:: action

.. default-role:: actor

This allows us to use simple `backticks` for actors and they can get formatted properly regardless of the context. The "action" is a block style which is italic. This allows additional character styles -- such as "actor" -- to work properly.

This also means that the setup paragraph is done like so:

.. container:: action

   (The stage is set like a police line-up. Three villains are in the
   line-up: the `Big Bad Wolf`, `Goldilocks`, and `Troll`. There is an unnamed
   detective -- who we refer to as '`Cop`' -- and three large uniformed
   `Constables`. `Jill` is viewing the police line-up and referring to her
   rather large fairy tale book.)

..

There wasn't a lot of good alternatives to the use of "container". The standard emphasis style is a character style and required special work to get actors to be properly styled. (They couldn't really be properly styled inside *emphasis spans* but you could mostly fake it by breaking the spans up).

The empty comment (..) is needed to prevent the sung part that follows this from being seen as being within this container.

In any case, this is the only way to get the actor to have both the styles of "action" and "actor". I'm loath to drop the `backticks` and just use capitalized letters for this. I thought about it, and I didn't like it. This seemed better.

I had some problems settling on how the song-text would be included. I needed to make sure that simple things would be simple. After messing with it for a bit, I settled on:

        `Jill`

        | This is a fairy tale ending.
        | Where everything seems okay:
        | A lesson learned and life returned
        | To the way it was before.
        | When one door closes, another one opens,
        | And no one is sad anymore.
        | This is a fairy tale ending.
        |

The actor becomes a "blockquote" and that's set to center the text, while the rest is a "lineblock2". Interestingly, each line in a line block is a separate "thing" so you can't just set the amount of text after a multi-line lineblock. I was left with just adding an extra line via the reStructuredText. It's technically a work-around, but it does work and it looks reasonable, so I'm not going to fight to get rid of it.

I didn't see an option for simultaneous parts other than tables. With the above solutions in place, this is as straight-forward as you might expect. Here's two parts, one part, and three parts:

=============================  =======================================
`Jack & Jill`                  `Chorus`
=============================  =======================================
It's not a fairy tale ending.  | Something is wrong.
                               | Something has changed.
                               | Events have rearranged.
                               | And happy ends have been exchanged.
It's not a fairy tale ending.  | Something's amiss.
                               | Something's awry.
                               | The magic well is dry.
                               | and none can willingly supply a remedy!
=============================  =======================================


        `All`

        | Rumpelstilskin kidnaps babies,
        | Snow White choked on an apple core,
        | Little Red Riding Hood contracted rabies...
        |

================================= ================================= ======================
`Sopranos`                        `Jill & Altos`                    `Men`
================================= ================================= ======================
| Once upon a time                | That's not a fairy tale ending, | A fairy tale ending,
| there was a happy ending, [...] | [...]                           | [...]
| there was a happy ending!       | not a fairy tale ending!        | ending!
================================= ================================= ======================

The "Chorus" part explicitly needed the line block characters (|) as otherwise the table looks like there are only two rows and the second column is multi-line. With the line block characters, the table itself can be processed like that, but it doesn't phase the processing.

The three-part section had the line block characters added, but they don't seem to make any difference.

The last caveat is that while the paragraphs are set to a hanging-indent, this is purely ODT style. In the reStructuredText it is seen as a normal paragraph:

`Cop`: We'll find the one responsible, don't you worry, miss. This
whole business will be wrapped up in a neat little package of justice,
gift-wrapped in a simple moral to help you understand the human
condition.

Beyond that, the only thing left to mention is that the page header and footer are seen by ODT as part of the "style.xml" file and once specified there, you can't override them via the command-line options. This isn't a big deal, though, as there didn't seem to be any way to style the header/footer.
]

No comments:

Post a Comment