Markers¶
1. What is a Marker¶
A marker is a non-musical structural element that identifies a significant point in the flow of the song. Markers do not refer to a musical event, have no musical duration of their own, and do not directly affect musical content (notes, chords, rhythms), but serve to:
- segment the song into logical sections;
- facilitate human reading and orientation;
- provide semantic anchors for rendering, navigation, and execution;
- support musical forms, repeats, and references.
Markers are part of the musical datapack, but belong to the domain of structure, not musical notation.
Semantic scope¶
A marker semantically belongs to a measure.
It identifies, labels, or qualifies a measure as a structural unit of the song and is not tied to the musical flow or the execution order.
2. Markers line¶
Markers are contained in a markers line, which may be:
- explicitly declared with the line marker
M); - implicitly deduced from the content of the line.
2.1 Position within the datapack¶
- The markers line, if present, is the first line of the datapack.
- It is optional.
- Only one markers line may appear per datapack. If two appear, the parser
merges them without diagnostics, field by field, and for each field (section,
annotation) the last one holds:
M) [A]followed byM) "poco;a poco" [B]gives sectionBwith the annotation. The rewritten document makes them a single line, with the section before the annotation (M) | [B] "poco;a poco" |).
Best practice: place the measure decorators (volta, segno, coda, etc.) in the markers line as well, in order to concentrate the formal structure in a single location.
A decorator written on the markers line applies to the same measure as the aligned barline, exactly as if it were on the notes/chords line: the effect on rendering and execution is identical. A flow-only barline at the start of a section is also allowed, with no other text on the line — e.g. M) |@ (coda) or M) |$ (segno). If two lines carry divergent decorators on the same measure, the line written first in the datapack wins — the markers line, which comes first — and the parser emits warning W159 on the losing line (neumaRk_datapack.md §7.3); identical decorators on the two lines (visual alignment) produce no warning.
3. Marker syntax¶
A marker is expressed in two container forms, which differ in their structural role and in the presence of the graphic box:
[<text>]— section: a structural unit of the song, with a box;"<text>"— annotation: descriptive text, without a box.
[Intro] section (with box)
[A] section
"freely" annotation
"swing feel" annotation
The marker admits the text markup defined in
neumaRk_text_markup.md. The default style is bold, body size, in
both forms.
3.1 Section vs annotation¶
The two containers have different semantic value:
| Form | Type | Structural value | PLAY/FORM target | Closes collapsible scope |
|---|---|---|---|---|
[…] |
section | yes (unit of the song) | yes | yes |
"…" |
annotation | no (descriptive text) | no | no |
A section can also be written ["NAME"]: it means [NAME], the quotes
delimit the name and are not part of it (nor of the PLAY)/FORM) target),
and they do not open an annotation.
A section identifies a recallable and referenceable structural
unit (Intro, Verse, Chorus, A, B, …). Sections are the
targets of PLAY) / FORM) (see neumaRk_play_and_form.md §3.1) and
delimit the scope of the collapsible sections (see §4).
An annotation is free text without structural value (e.g.
"freely", "swing feel", "con feeling"). Annotations are not
referenceable from PLAY) / FORM) and do not close the scope of a
collapsible section.
A ; in the annotation breaks the line (neumaRk_text_markup.md §3bis):
the stack sits above the staff and grows upward, the last line stays where
the single line would be, left-aligned.
M) | "poco;a poco" | // → poco
// a poco
The section name […] is excluded: there ; stays literal.
In a section name \] is a literal ] and does not close the box, as
in labels and annotations (neumaRk_text_markup.md §4):
M) | [Coda \] finale] | // section "Coda ] finale"
N) | c4 d e f |
PLAY) and FORM) reference it with the same escaped name
(neumaRk_play_and_form.md §3.1).
Normative note.
[…](section) and"…"(annotation) differ in only two operational respects:"…"annotations are notPLAY)/FORM)targets and do not interact with the scope of the collapsible sections[? …](§4). Otherwise both remain formattable text.
3.2 Temporal anchoring¶
- A marker refers to the start of the measure in which it appears.
- A measure has one section
[…]and one annotation"…": the first counts, the others in the same measure are discarded with W186 (§7). A[…]written inside an annotation is text of the annotation, not a section. - If preceded by a barline and in the box form
[…], it must be separated from it by at least one space, to avoid ambiguity with the volta decorators. - The
"…"form does not collide with the volta decorators and may be adjacent to the barline; the space is nevertheless recommended for readability.
Valid example:
M) | [A]
M) | "freely"
Without the M) marker, a line containing a "…" annotation is deduced as a
chord row, with the "…" as a row label: the predicate of implicit Markers
admits only […], barlines and spaces (neumaRk_datapack.md §3.bis.4). Marker
annotations are therefore written on the M) row.
Invalid example:
M) |[A] // read as a volta labelled A, not as a section
4. Collapsible sections¶
A section may be declared collapsible (also called
optional) by prefixing ? (the character ? followed by
one space) inside the marker:
[? Verse]
[? Solo 2]
[? Outro]
A collapsible section is a reading property of the marker: an interactive rendering may let the reader expand or collapse the section. The expanded/collapsed state is a preference of the reader, kept by the host and not in the NRK file.
4.1 Scope of the collapsible section¶
The scope of [? NAME] extends from the marker's measure up to the
first of the following events:
- the start of another section
[…](of any name, collapsible or not, including the anonymous marker[!]of §4.2); - the end of the document.
The annotations "…" interposed do not close the scope:
they nevertheless belong to the current collapsible section.
M) [? Verse] | … | "freely" | … | [Chorus] | …
└─────── scope of Verse ─────┘
└ Chorus opens a new scope
4.2 Anonymous marker [!] (implicit closure of an optional section)¶
When an optional section ends and there is no following marker
that closes it naturally (because "anonymous" flow follows, not
structured as a section), the special token [!] is used (square
brackets with a single !, no spaces).
[!] is semantically a marker for the opening of an anonymous
non-optional section: it adheres to the convention "marker = start-of-measure" (§3.2)
and the closure of the preceding scope is the natural side-effect of
rule §4.1.
M) [? Coda] | … | … | [!] | … |
└── scope of Coda ─┘
└ non-collapsible, anonymous flow
Properties:
- Not rendered as a marker (no box, no label).
- Not referenceable from
PLAY)/FORM): it has no NAME. If used as a reference it is reference-broken (seeneumaRk_play_and_form.md§7.3). - Admitted anywhere:
[!]does not require an open optional section. If there is no scope to close the token is redundant (warning W146, non-blocking).
4.3 No nesting¶
A [? Inner] internal to another [? Outer] closes the scope of
Outer and opens that of Inner, according to the general rule §4.1. There is
no mechanism for nested collapsible sections.
M) [? Outer] | … | [? Inner] | … |
└ Outer ──┘ └─ Inner ─────…
4.4 Default state¶
When opening a song for the first time, the collapsible sections are expanded. The reader collapses them explicitly; the host keeps the state (§4).
Reference rendering (informative). The label of an expanded collapsible section carries a chevron
▾after the name, so that the presence of collapsible sections is recognizable even when they are all expanded; a collapsed section shrinks to the labelNAME ▸on a row of its own. The chevron is the handle that expands or collapses: it belongs to the interactive rendering, and static exports (PDF) do not show it: the[NAME]label stays.
4.5 References from PLAY/FORM¶
A [? NAME] section is referenced from PLAY) / FORM) using only the
NAME, without the ? prefix:
M) [? Verse] | … | [Chorus] | …
PLAY) [Verse] [Chorus]
The ? prefix is a reading property of the section, not part of the
structural name. The binding between PLAY) and M) is by text-equality on
the NAME, ignoring the ? prefix.
4.6 Execution¶
The collapsed/expanded state concerns reading only: a collapsible section is executed exactly like an ordinary section, regardless of whether the reader has collapsed or expanded it.
A collapsed section is not "skipped" in execution. To omit
a section from execution there are other mechanisms (versions,
an explicit PLAY) that excludes it).
4.7 Start-of-staff constraint¶
A collapsible section must start and end at the start of a staff (= at the start of a system / datapack). Concretely:
- the marker
[? NAME]must appear in the first measure of the system in which it appears; - the closure of the scope (any other
[…]or[!]) must in turn appear in the first measure of the system in which it appears; - the scope also terminates at EOF (a valid case).
Rationale: collapsing a section removes whole staves; a section that starts or ends mid-staff would produce an ambiguous rendering (half a staff would disappear, leaving a visual stub).
In case of violation:
- W151 is emitted (warning, non-blocking);
- the section is not collapsible: it always stays expanded, in an interactive rendering too.
5. Identity relevance¶
The ~ prefix on a section marker declares it identity-bearing: it
flags its theme as the one that characterizes the song ("the part that
makes the piece recognizable"). It is a structural and portable property
of the composition — it travels with the file — not host data.
M) [Intro] | … |
M) [~ Theme] | … | ← identity-bearing section of the song
M) [Coda] | … |
~ is not rendered (no box, no extra label: the section is drawn like a
plain [Theme]) and is preserved in round-trip by the serializer.
Identity relevance is a musical annotation, not a host label: it indicates which music characterizes the song. The marker is agnostic to the analysis dimension: the host may derive whatever it needs under any profile — melody, harmony, rhythm, harmonic rhythm, etc. (non-exhaustive list). The spec defines which region is identity-bearing; what is extracted from it and on which dimension is outside the language.
5.1 Scope of the identity region¶
The scope of [~ NAME] extends from the marker's measure to the first of
the following events:
- the start of a new section
[…]without the~prefix; - the end of the document.
A following section that also carries ~ does not close the region:
it continues it. Consecutive ~ sections therefore form a single
identity region; only a section without ~ closes it.
M) [~ A] | … | [~ B] | … | [C] | … | [~ D] | …
└──── identity region 1 (A+B) ───┘ └ region 2 (D)
└ C not identity, closes region 1
The interposed annotations "…" do not close the scope (as in §4.1).
5.2 Multiple regions per song¶
Multiple identity regions are allowed within the same song (non-consecutive
~ markers are distinct regions, see [~ D] above). How the host uses one or
more regions (e.g. which one to consider for which purpose) is not a matter of
language.
5.3 Default (no ~ marker)¶
In the absence of any [~ …] in the song, the identity-bearing region is
implicitly the stretch from the start of the song to the first section
(exclusive) (or to EOF if there are no sections). Songs that do not use the
marker therefore have a well-defined, host-independent identity region.
5.4 Anonymous marker [~]¶
[~] (square brackets with a single ~, no spaces) is an anonymous
identity-bearing section: it behaves like the anonymous marker [!] (§4.2) —
it opens a non-optional section and closes the previous scope — but is
flagged ~. It serves to mark "from here it is identity-bearing" when the
theme is not a named section. Conversely, a [!] (without ~) following an
identity region closes it (it is a section without ~, §5.1).
5.5 Composition with ? (collapsible + identity)¶
A section can be both collapsible and identity-bearing. The two prefixes
are accepted in free order on input: [?~ NAME] and [~? NAME] are
equivalent. Being semantically identical, the serializer normalizes
them to the canonical form [?~ NAME] (as it already normalizes spacing and
other marker aspects).
M) [?~ Bridge] | … |
5.6 References from PLAY/FORM¶
As for ? (§4.5), a [~ NAME] section is referenced from PLAY) / FORM)
using only the NAME, without the prefix. The binding is by text-equality on
the NAME, ignoring the ~ and ? prefixes.
M) [~ Theme] | … |
PLAY) [Intro] [Theme] [Coda]
5.7 Anchoring¶
[~ NAME] / [~] follow the anchoring of sections (§3.2, §4.7): they appear at
the start of a measure; the scope boundaries (a section without ~, or EOF)
fall at the start of a staff like any other section boundary.
6. Play directive on the M) line¶
The M) line admits, in addition to the textual markers […] / "…", also
play directives in the form (=Style,Tempo) to change the style
and/or the tempo of the song starting from a specific measure. See
neumaRk_play_directive.md for the full spec.
The play directive coexists freely with the textual markers in the same measure. The disambiguation between the tokens is by delimiters:
| Token | Type |
|---|---|
[…] |
section (structural marker) |
[? …] |
collapsible section (see §4) |
[~ …] |
identity-bearing section (§5) |
[!] |
anonymous non-optional section (§4.2) |
[~] |
anonymous identity-bearing section (§5.4) |
"…" |
annotation (descriptive text) |
(=…) |
play directive |
Example:
M) | [Intro] (=Rock,120bpm) | | | [A] (=swing,140bpm) |
7. Validity rules¶
A markers line is valid if it:
- contains only sections
[…]/[? …]/[~ …], anonymous markers[!]/[~], annotations"…", and play directives(=…), separated by spaces and barlines; - does not contain patterns reducible to notes or chords;
- respects the rules of separation from barlines.
In case of violation:
- the line is not recognized as a markers line;
- the parsing of the datapack continues according to the standard deduction rules.
A line written with the M) marker, instead, stays a markers line: every
token that is not a section, an annotation, a play directive or a context
object at a measure boundary (neumaRk_datapack.md §7.3) is discarded with
W186. A detached key has its own message (W186.key_free_position): to
change key, glue it to the barline.
M) | [A] foo | (Bb) | // W186 on `foo`, W186.key_free_position on `(Bb)`
N) | c4 d e f | g a b c |
The second section or the second annotation in the same measure (§3.2) is also
discarded with W186 (W186.section_extra, W186.annotation_extra): the
first counts. For more lines of text write a single annotation and break the
line with ; (§3.1).
M) | [A] [B] "poco" "a poco" | // W186 on `[B]` and on `"a poco"`
N) | c4 d e f |
M) | [A] "poco;a poco" | // one section, one annotation on two lines
N) | c4 d e f |
7.1 Diagnostic codes¶
| Code | Severity | Description |
|---|---|---|
| W146 | WARNING | [!] redundant: no optional section to close |
| W151 | WARNING | Optional section not collapsible: [? NAME] or its closure not at start of staff (§4.7) |
| W186 | WARNING | Token outside the M) row vocabulary (W186.key_free_position for a detached key), second section or annotation in the same measure (W186.section_extra, W186.annotation_extra): discarded (§3.2, §7) |