Toggle Multi-line Comments in LilyPond Files

While I’m happy with having so many posts on Scores of Beauty carrying quite some weight I realized that we should think about adding more lightweight posts, offering “Tips & Tricks” every now and then. So here is a short post about a minor issue I often struggled with until I stumbled over a simple and obvious solution. This may be trivial but I can very well imagine I’m not the only one who had overlooked it …

Code comments are a nice thing in plain text files to, well, comment on arbitrary things, hopefully making your code easier to understand. As you surely know LilyPond has two ways to do so:

{
  c4 d e f | g1 % TODO: Have a second look
}

lets LilyPond ignore the remainder of the current line, while

%{
  This file belongs to one of our greatest
  edition projects. Visit our homepage at
  http://brilliant.example.com
%}

introduces a multi–line comment.

Apart from giving additional information about some code one can also use commenting to easily switch things on and off, e.g. to turn on some “debugging” features or to switch between different alternatives:

%\include "stylesheet-a.ily"
\include "stylesheet-b.ily"

{
  \once \override Slur.thickness = 3
  c \f ( d e f | g1
%{
  \override NoteHead.color = #red
  \override Stem.color = #red
  \override Flag.color = #red
  \override Beam.color = #red
%}
  c4 d e ) f | g1
}

While toggling single-line comments is completely straightforward (simply delete the %) I always found it a little bit awkward to toggle multi-line comments. First I removed the (hopefully empty) line with the opening %{, and because I couldn’t stand the dangling %} line at the end of the block I usually removed that line too. OK, this isn’t really a problem, but if you have to repeatedly do that while developing a score it becomes a tedious and somewhat annoying tasks. Therefore I was pleasantly surprised to realize the following:

%{ is interpreted as the opening of a multi-line comment, so LilyPond will ignore anything until the next %}. By contrast, %%{ is interpreted as a regular line comment because LilyPond first sees a percent character and then something else (but not the {, so the rest of the line is considered a comment, preventing the curly brace to act as a special character combination. So, simply prepending a second % to the opening of a multi-line comment will toggle the comment. And as a side-effect you still have the visual “hook” to the formerly commented section:

{
  c d e f | g1
%%{
  \override NoteHead.color = #red
  \override Stem.color = #red
  \override Flag.color = #red
  \override Beam.color = #red
%}
  c4 d e f | g1
}

10 thoughts on “Toggle Multi-line Comments in LilyPond Files

  1. Jan

    That means “%}” has two different meanings, right?
    Overloading of operator “%}” in normal-, and comment-mode.
    A glitch in the matrix.

    Reply
    1. Urs Liska

      Not really. If %{ comes after % it doesn’t have any meaning at all. This is not an inconsistency but the nature of commenting stuff out. It’s just peculiar that commenting out a multi-line comment results in a single-line one.

      Reply
  2. David Kastrup

    Jan was talking about `%}` here, not `%{`. `%}` will end a multi-line comment, but start a single-line comment.

    Reply
  3. Colin Tennyson

    Clearly, the ability to toggle between single line and multiline comment is a must-have in any source code environment (in this case the code is score source).

    I transcribe choral music. When editing one part, say, soprano, I comment out the alto, tenor and bass parts, so that the score renders faster. Then I comment out the soprano and I comment in the alto, and so on, so that during editing Lilypond is rendering only one part instead of all four. It’s only when all parts are finished that all parts are commented in.

    As pointed out, a %} without a corresponding %{ is parsed as a single line comment, so technically you can leave it in place, but that’s not clean code. By replacing the %{ with %%{ the intended purpose of the %} is still there to see.
    Until now I did the toggling by removing the { from the %{ , but prepending the % is better.

    The crucial part, of course, is that a block can be commented out/in by editing a single position. It sucks if you have to edit in two places to obtain a single change.

    As I’m reading the wikipedia article about code commenting: C-style commenting supports this too; toggling by changing between /* and //* (relevance for me: Javascript)

    But not Python, curiously.
    I noticed that Python doesn’t support toggling between multiline and single line because in Python there is only single line commenting. (I suppose that means that Guido van Rossum felt that programming/debugging workflow should never involve commenting out blocks of code.)

    Reply
    1. Urs Liska

      Yes, that’s somewhat annoying in Python. There you have to rely on an editor that can “comment” a block by inserting line comments in all lines of a selection.

      If you want you could see one “advantage“ in this: If you commit such a block comment the line based approach clearly shows the affected code in the commit and not only the first line.

      Reply
  4. Abraham Lee

    Actually, there are block comments in Python, enclosed in either a triple double-quote (“””) or triple single-quote (”’):

    # this is a single line comment

    “””
    This is a block comment
    “””

    ”’
    This is also a block comment
    ”’

    Reply
  5. Colin Tennyson

    My understanding is that in the Python documentation there is no mention of block comments. Surrounding a section with three double-quote or single-quote marks that section as a docstring.

    In a stackoverflow thread someone wrote:
    I have found libraries that throw errors in Python 3, when \N is in the triple quotes…as it’s read like a doc string. Here’s an example: ”’ (i.e. \Device\NPF_..) ”’ That will result in an error as it reads \N and no longer acts like a true comment, but interprets what is in there.

    Someone else wrote that in specific situations indentation will be affected. This illustrates that using docstring delimiters as a make-do block comment delimiters is not robust.

    That aside, my statement was about _toggling_: no support in Python for block comment toggling. The two requirements for block comment toggling are that there is an opening and a closing delimiter, and an unpaired closing delimiter must be a single line comment. C-style and Lilypond commenting work that way.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *