Generating whole scores (also book parts) in scheme without using the parser

A LilyPond score internally is just a Scheme expression, generated by the LilyPond parser. Using Scheme, one can also automatically generate a score without an input file. If you have the music expression in Scheme, a score can be generated by simply calling

(scorify-music music)

on your music. This generates a score object, for which you can then set a custom layout block with

(let* ((layout (ly:output-def-clone $defaultlayout)))
   ; modify the layout here, then assign it:
   (ly:score-add-output-def! score layout)
  )

Finally, all you have to do it to pass this score to LilyPond for typesetting. This snippet defines functions (add-score score), (add-text text), and (add-music music) to pass a complete score, some markup, or some music to LilyPond for typesetting.

This snippet also works for typesetting scores inside a \book {...} block as well as top-level scores. To achieve this, each score scheduled for typesetting is appended to the list of top-level scores, and the top-level book handler (which is a Scheme function called to process a book once a \book{...} block is closed) is modified to insert all collected scores so far to the book.