Projects: a book made of linked files
A large book keeps its music in more than one file without keeping two copies of anything. The notes live in one place; every file that needs them names that place; and the book itself is a list of the chapters other files own. Edit a definition and every chapter that uses it changes on its next compile. Edit a chapter and every book that lists it changes. Nothing is ever copied into the file that reads it.
The shape
swc/
definitions.scorescript the shared objects and rhythms — the notes' one home
warmups.scorescript the warm-up chapters
keys/c.scorescript a chapter: `use "../definitions.scorescript"`, then applications
keys/f.scorescript
book-trumpet.scorescript the book: text pages, sections, `movement from` per chapter
There is no manifest file and no second format. The book is an ordinary score; it is the project's front door because it is the file that names every other one, not because a marker says so.
Three statements cross a file boundary
use "../definitions.scorescript"
movements arabic {
movement from "keys/c.scorescript" =swc-c-scales
}
exercises {
exercise from "studies.scorescript" =tones
}
use reads every music object and rhythm another file defines at book level (music objects). movement from takes one chapter, by its id, into this book. exercise from takes one exercise into this collection (collections).
Every path is relative to the file that wrote it. A path that does not open, a file that leads back to itself, and a name two used files both define are each refused by name (link.file-not-found, link.cycle, link.ambiguous-definition). A text-only compile — the MCP compile_score endpoint, the wasm build — refuses all three statements with link.no-filesystem, because it has no directory to resolve against.
A chapter keeps its own vocabulary
A chapter pulled into a book brings the definitions its own file read. They arrive as that chapter's own definitions, so two chapters from different files cannot collide over a name, and a definition the book writes for itself does not rewrite a chapter it merely lists.
A pulled chapter is numbered by where it stands in the book that prints it, and its heading is minted from that number. The same chapter can be chapter 13 in one book and chapter 2 in another.
A chapter brings the pages written before it: a text-page in the chapter's own file that says before =c-scales comes into the book with c-scales, unless the book already has a page of that id. The file's other pages stay with the file.
Contents are projected, never typed
scorescript 0.3
score "Two chapters" {
text-page =front {
heading "Table of Contents"
contents sections
}
sections { first-key "C Major" { c-scale } second-key "F Major" { f-scale } }
movements arabic {
movement =c-scale {
number 1
title "C Major Scale"
parts {
tpt
}
tpt {
m1 {
1C5
}
}
}
movement =f-scale {
number 2
title "F Major Scale"
parts {
tpt
}
tpt {
m1 {
1F5
}
}
}
}
}Canonical spelling
scorescript 0.3
score "Two chapters" {
text-page =front {
heading "Table of Contents"
contents sections
}
sections { first-key "C Major" { c-scale } second-key "F Major" { f-scale } }
movements arabic {
movement =c-scale {
number 1
title "C Major Scale"
parts {
tpt
}
tpt {
m1 {
1C5
}
}
}
movement =f-scale {
number 2
title "F Major Scale"
parts {
tpt
}
tpt {
m1 {
1F5
}
}
}
}
}
contents in a text page sets the book's own index there, with the page each entry actually landed on after pagination; contents sections lists one line per book section. The list fills the rest of its page, so any text for that page comes before it. There is no page number to keep true by hand.
Check, inspect, print, verify
scorescript check swc/
scorescript inspect swc/book-trumpet.scorescript
scorescript pdf swc/book-trumpet.scorescript --layout 'Scales with Character' \
-o book.pdf --pages book.pages.txt
scorescript pdf swc/book-trumpet.scorescript --layout 'Scales with Character' \
-o book.pdf --expect-pages book.pages.txt
check <dir> checks every source under the directory, each resolved against its own location, and fails when any of them has an error. inspect prints the book as a database: the files it read, which file owns each definition and chapter, every relation between objects, and the range families fit chooses from. --pages writes the printed book's page index — one row per page, then every contents line with its page — and --expect-pages fails, naming each row, when a new printing moved anything against an approved one.