Files
songbook/CLAUDE.md
shahondin1624 5378bdbc24 docs: update CLAUDE.md to reflect current codebase
Add ForewordParser pipeline step, document all Song/SongLine fields,
Foreword type, ForewordPage variant, BookConfig subtypes, all ChordPro
directives, and new Configuration section for songbook.yaml options.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 10:01:48 +01:00

5.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build & Test Commands

# Build everything
gradle build

# Run all tests
gradle test

# Run tests for a specific module
gradle :parser:test
gradle :layout:test
gradle :renderer-pdf:test
gradle :app:test

# Run a single test class
gradle :parser:test --tests ChordProParserTest

# Run a single test method
gradle :parser:test --tests "ChordProParserTest.parse complete song"

# Build and run CLI
gradle :cli:run --args="build -d /path/to/project"
gradle :cli:run --args="validate -d /path/to/project"

# Launch GUI
gradle :gui:run

Requires Java 21 (configured in gradle.properties). Kotlin 2.1.10, Gradle 9.3.1.

Architecture

Pipeline: Parse → Validate → Measure → Paginate → Render

SongbookPipeline (in app) orchestrates the full flow:

  1. ConfigParser reads songbook.yamlBookConfig
  2. ChordProParser reads .chopro/.cho/.crd files → Song objects
  3. ForewordParser reads optional foreword.txtForeword (if configured)
  4. Validator checks config and songs
  5. MeasurementEngine calculates each song's height in mm using FontMetrics
  6. TocGenerator estimates TOC page count and creates entries
  7. PaginationEngine arranges songs into pages (greedy spread packing)
  8. PdfBookRenderer generates the PDF via OpenPDF

Module dependency graph:

model ← parser
model ← layout
model ← renderer-pdf
parser, layout, renderer-pdf ← app
app ← cli (Clikt)
app, parser ← gui (Compose Desktop)

model is the foundation with no dependencies — all data classes, the FontMetrics interface, and the BookRenderer interface live here. The FontMetrics abstraction decouples layout from rendering: PdfFontMetrics is the real implementation (in renderer-pdf), StubFontMetrics is used in layout tests.

Pagination constraint: Songs spanning 2 pages must start on a left (even) page. The PaginationEngine inserts filler images or blank pages to enforce this.

Key Types

  • Song → sections → SongLineLineSegment(chord?, text) — chord is placed above the text segment. Also has aliases, lyricist, composer, key, tags, notes: List<String>, references: Map<String, Int> (bookId → page), capo
  • SongLine — holds segments plus optional imagePath (when set, the line is an inline image)
  • Forewordquote, paragraphs, signatures — parsed from a plain-text file
  • PageContent — sealed class: SongPage, FillerImage, BlankPage, ForewordPage
  • SectionType — enum: VERSE, CHORUS, BRIDGE, REPEAT
  • BookConfig — top-level config with FontsConfig, LayoutConfig, TocConfig, ForewordConfig, ReferenceBook list. FontSpec.file supports custom font files. LayoutConfig.metadataLabels ("abbreviated" or "german") and metadataPosition ("top" or "bottom") control metadata rendering
  • BuildResult — returned by SongbookPipeline.build() with success/errors/counts

Song Format

ChordPro-compatible .chopro/.cho/.crd files: directives in {braces}, chords in [brackets] inline with lyrics, comments with #. See songs/ for examples.

Metadata directives: {title: } / {t: }, {alias: }, {lyricist: }, {composer: }, {key: }, {tags: }, {note: }, {capo: }

Section directives: {start_of_verse} / {sov}, {end_of_verse} / {eov}, {start_of_chorus} / {soc}, {end_of_chorus} / {eoc}, {start_of_repeat} / {sor}, {end_of_repeat} / {eor}. Section starts accept an optional label. {chorus} inserts a chorus reference, {repeat} sets a repeat label.

Notes block: {start_of_notes} / {son}{end_of_notes} / {eon} — multi-paragraph rich-text notes rendered at the end of a song.

Inline image: {image: path} — embeds an image within a song section.

Reference: {ref: bookId pageNumber} — cross-reference to a page in another songbook (configured in reference_books).

Configuration

songbook.yaml at the project root. Key options beyond the basics:

  • fonts.<role>.file — path to a custom font file (TTF/OTF) for any font role (lyrics, chords, title, metadata, toc)
  • layout.metadata_labels"abbreviated" (M:/T:) or "german" (Worte:/Weise:)
  • layout.metadata_position"top" (after title) or "bottom" (bottom of last page)
  • toc.highlight_column — abbreviation of the reference-book column to highlight (e.g. "CL")
  • foreword.file — path to a foreword text file (default ./foreword.txt)
  • reference_books — list of {id, name, abbreviation} for cross-reference columns in the TOC
  • songs.order"alphabetical" or "manual" (file-system order)

Test Patterns

Tests use kotlin.test annotations with Kotest assertions (shouldBe, shouldHaveSize, etc.) on JUnit 5. Layout tests use StubFontMetrics to avoid PDF font dependencies. App integration tests create temp directories with song files and config.

Package

All code under de.pfadfinder.songbook.* — subpackages match module names (.model, .parser, .layout, .renderer.pdf, .app, .cli, .gui).