ChordShed progression format (chordshed.com) This is a small language read by a parser, not free text. The person pastes the file into the page, which draws each chord as a fretboard grid, names it from its frets, and plays it. Any word the grammar below does not allow is an error, so write only what it allows and nothing else. Grammar. A file is lines; each line is one of: blank # comment %title TEXT the file's title, before everything but comments --- ends a progression, the next begins %name TEXT | %key KEY | %description TEXT | %tag TEXT %key before the first chord; the rest anywhere %alt [NAME] | %or [NAME] | %end an alternatives block (see below) %narration md | %narration txt [--anchor next | --anchor prev] a narration block, up to a line %endnarration (see below) [LABEL:] FRETS [OPTION]... [# comment] a chord FRETS = six STRINGs separated by spaces, low E string first, high E string last STRING = x | MARK ( + MARK )* x is a string not played MARK = [~] FRET [o | x | s | t] FRET is 0 (open) to 24 OPTION = --root NOTE | --rootless | --kind KIND | --fingerings F,F,... | --relax LABEL = a | b | c ... | 1 | 2 | 3 ... optionally preceded by a name: "b tritone:" KEY = NOTE [major | minor] a bare NOTE is major NOTE = C D E F G A B with optional b or #; typed in ASCII: Bb, F#, Db Option names are lower case. %name names a progression and appears once in it; %description and %tag repeat. %title names the whole file and appears once, among its first lines. Narration is prose between progressions. The lines between %narration and %endnarration are taken as written, with no comments, keywords or ---: md is Markdown (CommonMark, with tables and strikethrough; no HTML, images, footnotes, math or task lists), txt is plain paragraphs separated by blank lines. A block stands between progressions: it ends the progression before it, and the lines after %endnarration begin the next, with no --- needed. So a progression's %name, %key, %description and %tag go after %endnarration, with its chords, never before %narration. --anchor next ties the narration to the progression after it, --anchor prev to the one before it, and the page sets the two side by side; only narrations anchored the same way may stand between them, else it is an error. A narration without --anchor belongs to no progression and stands on its own. Tuning and arithmetic. Standard tuning only: strings low to high are E A D G B E; a fret adds that many semitones to the open string. Check every fret this way; the tool names the chord from the frets, so a wrong fret is a wrong chord, not a wrong label. Names go in comments only. x 3 2 0 1 0 C E G C E C x 0 2 2 2 0 A E A C# E A 3 2 0 0 0 3 G B D G B G G 1 3 3 2 1 1 F C F A C F F x 3 2 4 x x C E B Cmaj7 shell voicings: root, 3rd, 7th 5 x 5 5 x x A G C Am7 x 5 x 5 6 x D C F Dm7 3 x 3 4 x x G F B G7 x 5 7 5 7 5 D A C F# A D7 x x 3 5 4 5 F C Eb A F7 8 x 8 9 10 x C Bb E A C7/6 x 3 x 3 4 3 C Bb Eb G Eb6/C, but Cm7 with --root C x 4 x 4 6 x C# B E# C#7, but Db7 with --root Db A comment after a chord is shown under it; a comment on its own line is kept apart. Options, after the six frets and before the comment: --root D read the chord on that root, show each string's degree (R, 3, b7 ...) --rootless with --root, admit a chord whose root does not sound --kind m7add11 state the chord instead of searching for it; needs --root, not --rootless. KIND is a name from the list below, then changes, then a bass: 7b9, maj7#11, m7add11, 9sus4, 7(b9,#11), m7b5/Ab. A change is add9 / no5 / omit5, b or # before a degree (2 3 4 5 6 7 9 11 13), or sus2 / sus4. Every sounding note must belong to the stated chord, or the line is an error. --fingerings 2,1,3 the fingers on the dots, one per sounding string, low string first: 1 to 4, T for the thumb, 0 for an open string; repeat it for another way --relax let a tie hold where it can (see ties) Kind names (ASCII): M maj m min + aug dim o 5 power sus sus2 sus4 7 dom7 maj7 M7 m7 min7 -7 m7b5 mM7 minmaj7 m#7 7+ aug7 +7 augmaj7 +M7 7b5 dom7dim5 dim7 o7 7sus 7sus4 6 m6 min6 6/9 m6/9 7/6 m7/11 add9 m(add9) 9 dom9 maj9 M9 Maj9 m9 min9 mM9 minmaj9 9#5 +9 aug9 augmaj9 +M9 dim9 o9 dimb9 ob9 m9b5 m7b5b9 9sus4 11 dom11 maj11 M11 Maj11 m11 min11 mM11 minmaj11 +11 aug11 augmaj11 +M11 dim11 o11 m11b5 13 dom13 maj13 M13 Maj13 m13 min13 mM13 minmaj13 +13 aug13 augmaj13 +M13 m13b5 13sus4. Altered dominants are a name plus changes: 7b9, 7#9, 7#11, 7b13, 9#11, 13b9, 13#11. Marks on one string, joined by +. The first is the chord's dot. Each later mark is suffixed x, s or t, in that order with none skipped, and is played after the chord, one by one: a melody or a moving voice. A string keeps its last mark, so each step is itself a chord and gets its own name. x 5 7 7+6x+5s+4t 6 x --fingerings 1,3,4,2 # a line falling inside Dm x x ┌───┬───┬───┬───┬───┐ 4fr │ │ │ △ │ │ ├───┼───┼───┼───┼───┤ │ ● │ □ │ │ ├───┼───┼───┼───┼───┤ │ │ │ ✕ ● │ ├───┼───┼───┼───┼───┤ │ │ ● ● │ │ └───┴───┴───┴───┴───┘ 1 3 4 2 ● D A D F ● Dm ✕ D A C♯ F ✕ DmΔ7 □ D A C F □ Dm7 △ D A B F △ Dm6 A mark suffixed o is an optional note: alone on a string it may be added, after + on a string with a dot it may replace the dot. x 3 2 4 3o x --root C # Cmaj7, with the 9th as an option x x ╒═══╤═══╤═══╤═══╤═══╕ │ │ │ │ │ │ ├───┼───┼───┼───┼───┤ │ │ ● │ │ │ ├───┼───┼───┼───┼───┤ │ ● │ │ ○ │ ├───┼───┼───┼───┼───┤ │ │ │ ● │ │ └───┴───┴───┴───┴───┘ C E B CΔ7 R 3 7 ○ (D) CΔ9 ○ (9) x 3 2 0+2o 1 0 # the open G, or the A in its place A tie is ~ before a fret: the note is held from the chord before, which must end that string at the same fret. Without --relax it is an error when only some alternatives before, or only an optional note, end the string there. x 3 2 0 1 0 # C x 3 ~2 0 3 x # C's E held, Cadd9 Alternatives are chords that can replace the same chords of the progression. The first is played by default and the others are offered under it; each may be several chords, and all replace the same span. A block, with an optional name after %alt or %or: %alt 3 x 3 4 x x --root G # V %or tritone x 4 x 4 6 x --root Db # bII7 %or backdoor 1 x 1 1 x x --root F x 1 x 1 3 x --root Bb %end or a label at the start of each line; the set ends at the first unlabelled line: a: 3 x 3 4 x x b tritone: x 4 x 4 6 x There is no syntax for rhythm, durations, bars, repeats, capo, tuning or chord names in the frets. Do not invent any; put such things in %description, a comment or a narration. Checking the file. Check every file before giving it over. The parser and the chord namer that the page uses answer in three ways; use the first that you can. 1. With Node. They are published as a script with no dependencies, no network use once fetched and no limit on the file's size: curl -sO https://chordshed.com/check.js && node check.js progression.txt On a fault it exits with 1. A fetcher that declines JavaScript can read the same script at https://chordshed.com/check.js.txt. 2. Over HTTP, for a file of up to 40 chords and 3000 bytes. POST the file as the request body: curl --data-binary @progression.txt https://chordshed.com/check or, where only an address can be fetched, GET it with the file percent-encoded as text: https://chordshed.com/check?text=%25name%20Shells%0Ax%203%202%204%20x%20x In that address write a space as %20, a line end as %0A, % as %25, # as %23 and + as %2B; a # left as written cuts the file off there. A POST answers a report with status 200, a fault with 422 and a file over the limit with 413. A GET answers all of them with 200, since a fetcher may show the text of no other status, and ends with the number of lines it read; compare it with the file's. A file over the limit is checked one progression at a time. Nothing sent is stored. 3. Through the person. Where neither is possible, ask the person to run the two commands of the first way and paste the output, or to attach check.js where the sandbox has no network. A person can also add the check to their assistant as an MCP server, at https://chordshed.com/mcp (Streamable HTTP, no authentication). It offers two tools: format_guide, which returns this text, and check_progression, which takes the file and gives the same answer, within the same limit. Each way gives the same answer. For a fault it is the line and what is wrong there. Otherwise it is each chord as the page reads it: its line, then per mark the chord's name, the note on each string low to high (. for a string that does not sound) and each note's degree; a name followed by ○ is the chord with the optional notes played. Compare every name with the chord you meant; a missing or different name is a wrong fret, or a chord that needs --root. Before the check: six entries on every chord line; --fingerings has exactly one finger per sounding string; alternatives in a set replace the same number of chords; %key before the first chord. %title Shell voicings %name Blues in Bb: shell voicings %key Bb %tag blues %description Twelve bars, a chord to a bar; the last bar offers the tritone substitute. 6 x 6 7 x x --root Bb --fingerings 2,3,4 # I7 x 6 x 6 8 x --root Eb # IV7 6 x 6 7 x x --root Bb # I7 6 x 6 7 x x --root Bb # I7 x 6 x 6 8 x --root Eb # IV7 x 6 x 6 8 x --root Eb # IV7 6 x 6 7 x x --root Bb # I7 6 x 6 7 x x --root Bb # I7 x 8 x 8 10 x --root F # V7 x 6 x 6 8 x --root Eb # IV7 6 x 6 7 x x --root Bb # I7 a: x 8 x 8 10 x --root F # V7 b tritone: x 2 x 2 4 x --root B # bII7 %narration md ## The same shells with a melody Keep the *shell* under the fingers and let the top string sing. %endnarration %name ii V I in F with a melody %key F 3 x 3 3 x 6+5x+3s --root G # ii7, Bb A G on top x 3 x 3 5 3+0x --root C # V7 1 x 2 2 x 1 --root F # Imaj7