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 sounding element, 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 playback;
- 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.
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.
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 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.
Normative note. This distinction is a refinement of the 0.5 spec, where
[…]and"…"were considered semantically equivalent. Existing documents are backward-compatible (the annotations"…"continue to exist as text); the only operational difference is the selective binding from PLAY/FORM and the behavior of[? …](see §4).
3.2 Temporal anchoring¶
- A marker refers to the start of the measure in which it appears.
- 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:
| [A]
| "freely"
Invalid example:
|[A] // ambiguous: could be interpreted as a volta
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 UX property of the marker: the user
can expand/collapse the section in the reading interface
(accordion). The expanded/collapsed state is a user preference, saved in
the user-index (Firestore users/{uid}/song_view_state/{songId}) 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 user collapses them explicitly; the state is then persistent in the user-index.
The ? in the marker is clearly highlighted in the UI (chevron in the
margin, distinct title style) so that the presence of collapsible sections is
immediately recognizable, even when all are expanded.
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 UX 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 is UX-only: the player executes a collapsible section exactly like an ordinary section, regardless of whether the user has collapsed or expanded it in the view.
A collapsed section is not "skipped" by the player. 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: the accordion UX compresses 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 on the UX side: the user toggle is ignored on render (the section remains always expanded).
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.
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) |