When translating the input to notation, there are number of distinct
phases. We list them here:
-
@c todo: moved from refman.
The purpose of LilyPond is explained informally by the term `music
During these stages different types of data play the the main role:
during parsing, @strong{Music} objects are created. During the
-interpretation, @strong{contexts} are constructed, and with these contexts
-a network of @strong{graphical objects} (``grobs'') is created. These
-grobs contain unknown variables, and the network forms a set of
-equations. After solving the equations and filling in these variables,
-the printed output (in the form of @strong{molecules}) is written to an
-output file.
+interpretation, @strong{contexts} are constructed, and with these
+contexts a network of @strong{graphical objects} (``grobs'') is
+created. These grobs contain unknown variables, and the network forms a
+set of equations. After solving the equations and filling in these
+variables, the printed output is written to an output file.
These threemanship of tasks (parsing, translating, typesetting) and
data-structures (music, context, graphical objects) permeates the entire
The data types that are mentioned here are all discussed in this
section.
-@menu
-* Grobs:: Graphical object
-* Molecules:: Molecules are stand-alone descriptions of output
-@end menu
-
-@node Grobs
-@section Grobs
-
-This section is about Grobs (short for Graphical Objects), which are
-formatting objects used to create the final output. This material is
-normally the domain of LilyPond gurus, but occasionally, a normal user
-also has to deal with grobs.
-
-The most simple interaction with Grobs are when you use
-@code{\override}:
-
-@example
- \property Voice.Stem \override #'direction = #1
-@end example
-
-This piece of lily input causes all stem objects to be stem-up
-henceforth. In effect, you are telling lilypond to extend the definition
-of the `Stem' grob with the setting @code{direction := 1}.
-
-@menu
-* What is a grob?::
-* Callbacks::
-* Setting grob properties::
-* Grob interfaces::
-* Items and Spanners::
-* Grob Scheme functions::
-@end menu
-
-
-
-@node What is a grob?
-@subsection What is a grob?
-
-In music notation, lots of symbols are related in some way. You can
-think of music notation as a graph where nodes are formed by the
-symbols, and the arcs by their relations. A grob is a node in that graph.
-The directed edges in the graph are formed by references to other grobs
-(i.e. pointers).
-This big graph of grobs specifies the notation problem. The solution of
-this problem is a description of the printout in closed form, i.e. a
-list of values. These values are Molecules. (see @ref{Molecules})
-
-All grobs have an X and Y-position on the page. These X and Y positions
-are stored in a relative format, so they can easily be combined by
-stacking them, hanging one grob to the side of another, and coupling
-them into a grouping-grob.
-
-Each grob has a reference point (a.k.a. parent): the position of a grob
-is stored relative to that reference point. For example the X-reference
-point of a staccato dot usually is the note head that it applies
-to. When the note head is moved, the staccato dot moves along
-automatically.
-
-If you keep following offset reference points, you will always end up at
-the root object. This root object is called @code{Line_of_score}, and it
-represents a system (i.e. a line of music).
-
-All grobs carry a set of grob-properties. In the Stem example above,
-the property @code{direction} is set to value @code{1}. The function
-that draws the symbol (@code{Stem::brew_molecule}) uses the value of
-@code{direction} to determine how to print the stem and the flag. The
-appearance of a grob is determined solely by the values of its
-properties.
-
-A grob is often associated with a symbol, but some grobs do not print
-any symbols. They take care of grouping objects. For example, there is a
-separate grob that stacks staves vertically. The @code{NoteCollision}
-is also an abstract grob: it only moves around chords, but doesn't print
-anything.
-
-A complete list of grob types is found in the generated documentation.
-
-
-@node Callbacks
-@subsection Callbacks
-
-Offsets of grobs are relative to a parent reference point. Most
-positions are not known when an object is created, so these are
-calculated as needed. This is done by adding a callback for a specific
-direction.
-
-Suppose you have the following code in a .ly file.
-@example
- #(define (my-callback gr axis)
- (* 2.0 (get-grob-property gr 'direction))
- )
-
-....
-
- \property Voice.Stem \override #'Y-offset-callbacks = #(list
- my-callback)
-@end example
-
-When the Y-offset of a Stem object is needed, LilyPond will
-automatically execute all callbacks for that object. In this case, it
-will find @code{my-callback}, and execute that. The result is that the
-stem is translated by two staff spaces in its direction.
-
-(note: @code{Y-offset-callbacks} is also a property)
-
-
-
-Offset callbacks can be stacked, i.e.
-
-@example
- \property .... \override #'Y-offset-callbacks = #(list
- callback1 callback2 callback3)
-
-@end example
-
-The callbacks will be executed in the order @code{callback3 callback2
-callback1}. This is used for quantized positioning: the staccato dot is
-above or below a note head, and it must not be on a staff-line. To
-achieve this, the staccato dot has two callbacks: one that positions the
-grob above or below the note head, and one that rounds the Y-position of
-the grob to the nearest open space.
-
-Similarly, the size of a grob are determined through callbacks, settable
-with grob properties @code{X-extent-callback} and
-@code{Y-extent-callback}. There can be only one extent-callback for
-each axis. No callback (Scheme value @code{#f}) means: "empty in this
-direction". If you fill in a pair of numbers, that pair hard-codes the
-extent in that coordinate.
-
-
-@node Setting grob properties
-@subsection Setting grob properties
-
-Grob properties are stored as GUILE association lists, with symbols as
-keys. In GUILE you can access these using functions described in
-Section @ref{Grob Scheme functions}. From C++, grob properties can be
-accessed using these functions:
-
-@example
- SCM get_grob_property (SCM) const;
- void set_grob_property (const char * , SCM val);
- void set_immutable_grob_property (const char * , SCM val);
- void set_immutable_grob_property (SCM key, SCM val);
- void set_grob_property (SCM , SCM val);
- void set_grob_pointer (const char*, SCM val);
- SCM remove_grob_property (const char* nm);
-@end example
-
-All lookup functions identify undefined properties with end-of-list
-(i.e. @code{'()} in Scheme or @code{SCM_EOL} in C)
-
-Properties are stored in two ways:
-@itemize @bullet
-@item mutable properties.
-Grob properties that change from object to object. The storage of
-these are private to a grob. For example pointers to other grobs are
-always stored in the mutable properties.
-
-@item immutable properties.
-Grob properties that are shared across different grobs of the same
-type. The storage is shared, and hence it is read-only. Typically, this
-is used to store function callbacks, and default settings. They are
-initially read from @file{scm/grob-description.scm}.
-@end itemize
-
-You can change immutable grob properties with the \override syntax:
-
-@example
- \property Voice.Stem \override #'direction = #1
-@end example
-
-This will push the entry @code{'(direction . 1)} on the immutable
-property list for stems, in effect overriding the setting from
-@file{scm/grob-description.scm}. This can be undone by
-
-@example
- \property Voice.stem \revert #'direction
-@end example
-
-There is also a shorthand,
-
-@example
- \property Context.GrobType \set #'prop = #VAL
-@end example
-
-this does a @code{\revert} followed by a @code{\override}
-
-You can change mutable properties with \outputproperty. This construct
-looks like
-
-@example
- \context ContextName \outputproperty @var{pred} #@var{sym} = #@var{val}
-@end example
-
-In this case, in every grob that satisfies @var{pred}, the grob property
- @var{sym} is set to @var{val}. For example
-
-@example
- \outputproperty
- #(lambda (gr) (string? (ly-get-grob-property gr
- 'text)))
- #'extra-offset = #'(-1.0 . 0.0)
-@end example
-
-This shifts all grobs that have a @code{text} property one staff
-space to the left. This mechanism is rather clumsy to use, but it allows
-you tweak any setting of any grob.
-
-
-@node Grob interfaces
-@unnumberedsubsec Grob interfaces
-
-Grob properties form a name space where you can set variables per
-object. Each object however, may have multiple functions. For example,
-consider a dynamic symbol, such @code{\ff} (fortissimo). It is printed
-above or below the staff, it is a dynamic sign, and it is a kind of
-text.
-
-To reflect this different functions of a grob, procedures and variables
-are grouped into so-called interfaces. The dynamic text for example
-supports the following interfaces:
-@table @code
-@item font-interface
- The glyph is built from characters from a font, hence the
-@code{font-interface}. For objects supporting @code{font-interface}, you
-can select alternate fonts by setting @code{font-style},
-@code{font-point-size}, etc.
-
-@item dynamic-interface
- Dynamic interface is not associated with any variable or function in
-particular, but this makes it possible to distinguish this grob from
-other similar grobs (like @code{TextScript}), that have no meaning of
-dynamics.
-
-@item text-interface
- This interface is for texts that are to be set using special routines
-to stack text into lines, using kerning, etc.
-
-@item general-grob-interface
- This interface is supported by all grob types.
-@end table
-
-
-
-@node Items and Spanners
-@unnumberedsubsec Items and Spanners
-
-Grobs can also be distinguished in their role in the horizontal spacing.
-Many grobs define constraints on the spacing by their sizes. For
-example, note heads, clefs, stems, and all other symbols with a fixed
-shape. These grobs form a subtype called @code{Item}.
-
-Other grobs have a shape that depends on the horizontal spacing. For
-example, slur, beam, tie, etc. These grobs form a subtype called
-@code{Spanner}. All spanners have two span-points (these must be
-@code{Item}s), one on the left and one on the right. The left bound is
-also the X-reference point of the spanner.
-
-Some items need special treatment for line breaking. For example, a
-clef is normally only printed at the start of a line (i.e. after a line
-break). To model this, `breakable' items (clef, key signature, bar lines,
-etc.) are copied twice. Then we have three versions of each breakable
-item: one version if there is no line break, one version that is printed
-before the line break (at the end of a system), one version that is
-printed after the line break.
-
-Whether these versions are visible and take up space, is determined by
-the outcome of the @code{visibility-lambda}. This grob property is a
-function taking a direction (-1, 0 or 1) as argument. It returns a cons
-of booleans, signifying whether this grob should be transparent and have
-no extent.
-
-@node Grob Scheme functions
-@unnumberedsubsec Grob Scheme functions
-
-Grob properties can be manipulated from Scheme. In practice, most
-manipulations are coded in C++ because of tradition.
-
-
-
-@node Molecules
-@section Molecules
-
-@cindex Molecule
-@cindex Atom
-@cindex Output description
-
-The objective of any typesetting system is to put ink on paper in the
-right places. For LilyPond, this final stage is left to the @TeX{} and
-the printer subsystem. For lily, the last stage in processing a score is
-outputting a description of what to put where. This description roughly
-looks like
-
-@example
- PUT glyph AT (x,y)
- PUT glyph AT (x,y)
- PUT glyph AT (x,y)
-@end example
-
-you merely have to look at the tex output of lily to see this.
-Internally these instructions are encoded in Molecules.@footnote{At some
-point LilyPond also contained Atom-objects, but they have been replaced
-by Scheme expressions, making the name outdated.} A molecule is
-what-to-print-where information that also contains dimension information
-(how large is this glyph?).
-
-Conceptually, Molecules can be constructed from Scheme code, by
-translating a Molecule and by combining two molecules. In BNF
-notation:
-
-@example
-Molecule :: COMBINE Molecule Molecule
- | TRANSLATE Offset Molecule
- | GLYPH-DESCRIPTION
- ;
-@end example
-
-If you are interested in seeing how this information is stored, you
-can run with the @code{-f scm} option. The scheme expressions are then
-dumped in the output file.
-
-All visible, i.e. non-transparent, grobs have a callback to create a
-Molecule. The name of the property is @code{molecule-callback}, and its
-value should be a Scheme function taking one argument (the grob) and
-returning a Molecule. Most molecule callbacks are written in C++, but
-you can also write them in Scheme. An example is provided in
-@code{input/regression/molecule-hacking.ly}.
-
-
-