# 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

```text
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

```text
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](objects.md#definitions-from-another-file)). `movement from`
takes one chapter, by its id, into this book. `exercise from` takes one exercise
into this collection ([collections](collections.md#link-an-exercise-from-another-file)).

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
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

```text
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.
