ly.xml package
**************


Introduction
============

This package is concerned with representing a LilyPond structure (e.g.
music) as an XML tree.

The structure of the tree closely follows LilyPond's data structures.
The tree can be parsed or analysed, and could be used to convert the
music to other formats like Mei of MusicXML.

This package tries to define the exact format (dtd or schema) of the
tree.

There will be three ways to build the tree:

* by hand, by creating XML elements (maybe with use of some helper
  methods).

* from a tokenized document

* by LilyPond, using the "xml-export.ily" script that is included.

The latter case is very interesting as all the music parsing and
handling is already done by LilyPond. The exported XML nearly contains
all information of a score or music object. Below, some more
information about the XML.

Note that this is all in heavy development.


Module contents
===============

Routines that manipulate an XML mapping very similar to the Scheme
music structure used by LilyPond itself.

The mapping can also be generated from within LilyPond and then parsed
by other programs.

While designing the mapping, I decided to use xml elements for almost
everything, only values that are very simple in all cases, are
attributes.

Code could be written to convert such an XML music tree to other
formats.

Also code is added to build such trees from scratch and from tokenized
documents.

Code will be added to print LilyPond source. When all is finished,
*ly.dom* is deprecated and *ly.music* will probably use these xml tree
for storage.

A single LilyPond file *xml-export.ily* is also included with this
module; it can be included in a LilyPond document and exports the
"\displayLilyXML" music function.


The "xml-export.ily" file
=========================

Written by Wilbert Berendsen, jan-feb 2015

This LilyPond module defines a function ("xml-export") that converts
LilyPond datastructures to XML. For convenience, a "\displayLilyXML"
music function is added that converts a music expression to XML.

Usage e.g.:

   \include "/path/to/xml-export.ily"
   \displayLilyXML { c d e f }

The XML closely follows the LilyPond music structure.

All "(make-music 'MusicName ...)" objects translate to a "<music
type="MusicName">" tag. The music in the "'element" and "'elements"
properties is put in the "<element>" and "<elements>" tags. (LilyPond
uses "'element" when there is a single music argument, and "'elements"
for a list of music arguments, but for example "\repeat" uses both:
"'element" for the repeated music and "'elements" for the
"\alternatives".)

Thus "<element>", if there, always has one "<music>" child.
"<elements>", if there, can have more than one "<music>" child.

Besides "'element" and "'elements", the following properties of music
objects are handled specially:

* "'origin" => "<origin>" element with "filename", "line" and "char"
  attributes

* "'pitch" => "<pitch>" element with "octave", "notename" and
  "alteration" attributes

* "'duration" => "<duration>" element with "log", "dots", "numer"
  and "denom" attributes

* "'articulations" => "<articulations>" element containing "<music>"
  elements

* "'tweaks" => "<tweaks>" element containing pairs "(symbol .
  value)"

All other properties a music object may have, are translated to a
"<property>" element with a "name" attribute. The value is the child
element and can be any object (string, list, pair, symbol, number
etc.). (Note that the LilyPond command "\displayMusic" does not
display all properties.)

Markup objects are also converted to XML, where a toplevel "<markup>"
element is used. The individual markup commands are converted to an
"<m>" element, with the name in the "name" attribute (e.g. "<m
name="italic"><string value="Hi there!"/></m>"). Arguments to markup
commands may be other commands, or other objects (markup "\score" even
has a score argument, which is also supported).


Example
=======

This LilyPond music:

   \relative {
     c d e
   }

maps to Scheme (using "\displayMusic"):

   (make-music
     'RelativeOctaveMusic
     'element
     (make-music
       'SequentialMusic
       'elements
       (list (make-music
               'NoteEvent
               'pitch
               (ly:make-pitch -1 0 0)
               'duration
               (ly:make-duration 2 0 1))
             (make-music
               'NoteEvent
               'pitch
               (ly:make-pitch -1 1 0)
               'duration
               (ly:make-duration 2 0 1))
             (make-music
               'NoteEvent
               'pitch
               (ly:make-pitch -1 2 0)
               'duration
               (ly:make-duration 2 0 1)))))

and maps to XML (using "\displayLilyXML"):

   <music name="RelativeOctaveMusic">
     <origin filename="/home/wilbert/dev/python-ly/ly/xml/xml-export.ily" line="244" char="17"/>
     <element>
       <music name="SequentialMusic">
         <origin filename="/home/wilbert/dev/python-ly/ly/xml/xml-export.ily" line="244" char="27"/>
         <elements>
           <music name="NoteEvent">
             <origin filename="/home/wilbert/dev/python-ly/ly/xml/xml-export.ily" line="245" char="4"/>
             <pitch octave="-1" notename="0" alteration="0"/>
             <duration log="2" dots="0" numer="1" denom="1"/>
           </music>
           <music name="NoteEvent">
             <origin filename="/home/wilbert/dev/python-ly/ly/xml/xml-export.ily" line="245" char="6"/>
             <pitch octave="-1" notename="1" alteration="0"/>
             <duration log="2" dots="0" numer="1" denom="1"/>
           </music>
           <music name="NoteEvent">
             <origin filename="/home/wilbert/dev/python-ly/ly/xml/xml-export.ily" line="245" char="8"/>
             <pitch octave="-1" notename="2" alteration="0"/>
             <duration log="2" dots="0" numer="1" denom="1"/>
           </music>
         </elements>
       </music>
     </element>
   </music>

By default, the XML is written to standard output.

To automatically export a full LilyPond document to an XML
representation, use the "xml-export-init.ly" script with the "--init"
LilyPond option. That script automatically sets up LilyPond to output
one XML document with a "<document>" root element, containing a
"<book>" element for every book in the LilyPond file. (LilyPond always
creates at least one book, collecting all the music or markup at the
toplevel.)

The "xml-export-init.ly" script is intended to be used via the "--
init" option. It automatically converts every "\book" in the score to
an XML document. In this case the XML is also written to standard
output by default, but you can specify another file with "-dxml-
export=<filename>".

So, to convert a LilyPond source file to an XML file containing the
LilyPond music structure in XML format, use the following command:

   lilypond --init /path/to/xml-export-init.ly -dxml-export=song.xml song.ly

The XML document has a "<document>" root element, containing a
"<book>" element for every book in the LilyPond file.
