ChordPro spec
A song body is stored in ChordPro verbatim, exactly as you wrote it. The app reads metadata out of it, but never rewrites or cleans up the text.
Basic syntax
| Element | Syntax | Note |
|---|---|---|
| Chord | [G], [Am7], [C/E] | Placed exactly where it should sound |
| Directive | {key: G} | Must be alone on its line and carry a value |
| Comment / section | {c: Chorus} | Rendered as a section heading |
text
[G]Hello [D]world, this is a [Em]song
ℹ
A directive is only recognised when it stands alone on its own line and has a value after the colon. A directive in the middle of a line is treated as ordinary text.
Metadata directives
These are read on import and fill in the song's fields:
| Directive | Short form | Fills |
|---|---|---|
{title: …} | {t: …} | Title |
{artist: …} | {a: …} | Artist |
{subtitle: …} | {st: …} | Variant (not artist) |
{key: …} | {k: …} | Key |
{tempo: …} | {bpm: …} | BPM — digits only are read |
{time: …} | {meter: …} | Time signature |
{duration: …} | — | Length, as mm:ss or in seconds |
{capo: …} | — | Capo — digits only are read |
{tags: …} | — | Comma-separated tags |
⚠
Watch out for
{subtitle} — in Eutepio it fills neither a subtitle nor the artist, but the song variant. The variant is part of a song's identity, so "Hallelujah / acoustic" and "Hallelujah / live" are two separate songs.Directives the app does not know are not stripped — they stay in the stored song body. They simply are not rendered on stage.
Song sections
In stage mode, section directives render as headings:
| Syntax | Heading |
|---|---|
{soc}, {chorus} | CHORUS |
{sov} | VERSE |
{sob} | BRIDGE |
More flexible is
{c: …} / {comment: …}, whose value is translated through a table (case-insensitive):| Value | Heading |
|---|---|
verse | VERSE |
chorus, refrain | CHORUS |
bridge | BRIDGE |
intro | INTRO |
outro | OUTRO |
solo | SOLO |
break, interlude | INTERLUDE |
| anything else | The text in capitals |
Thanks to that last row you can name a section however you like:
{c: second chorus} renders as SECOND CHORUS.Metadata directives (
{title}, {artist}, {key}, {tempo}, {time}, {duration}, {tags}, {subtitle}) are silently skipped when the body is rendered — they already appear in the header.Transposition
| Property | Value |
|---|---|
| Range | −24 to +24 semitones (two octaves either way) |
| Sharps vs. flats | Automatic from the input, or forced manually |
| Slash chords | Root and bass are transposed independently |
| Unknown chord | Passes through unchanged |
Sharps or flats
By default: what comes in with a flat goes out with a flat. The app can also derive the choice from the target key using the circle of fifths — transposing into a flat key produces flats. Settings let you force one or the other.
Enharmonics
Spellings outside the plain twelve are handled too:
B#, E#, Fb and Cb all convert correctly.German note naming
In Settings → Transposition → Note naming you switch between:
| Mode | Meaning |
|---|---|
| English | B = B natural, Bb = B flat |
| German / Czech | H = B natural, plain B = B flat |
The choice applies to transposition and to chord rendering on stage.
Slash chords
The bass after the slash is transposed on its own and is case-insensitive —
C/e is processed as C/E.Shapes
Chords in the lyrics are not just labels — tapping one opens its shape for guitar, ukulele, bass or piano. See Stage mode.
Capo
{capo: 2} is stored with the song and written back out on export.⚠
The capo value is stored with the song but does not rewrite the chord text by itself — that stays exactly as you entered it. To shift the sounding chords, use transposition.
Example
text
{title: Example Song}
{artist: The Band}
{subtitle: acoustic}
{key: G}
{tempo: 120}
{time: 4/4}
{capo: 2}
{duration: 3:45}
{tags: rock, live}
{c: Intro}
[G] [D] [Em] [C]
{c: Verse}
[G]Woke up this [D]morning, walked [Em]out,
[C]sunlight was [G]right in my [D]eyes.
{soc}
[C]This is the [G]chorus,
[D]sing it with [Em]me.
{c: Interlude}
[Am] [F] [C] [G]