]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/user/internals.itely
* lily/music.cc (name): bugfix
[lilypond.git] / Documentation / user / internals.itely
index 3664cef1c354e737e6e351c717008c36dd96b249..3ab73dc1072c0bc286d36746b3967c37ca079d06 100644 (file)
 @c before saving changes
 
 
-@node Internals
-@chapter Internals
+@node Advanced Topics
+@chapter Advanced Topics
 
-@menu
-* Conversion stages::          Lilypond is a multi-pass program.
-* Moment::                     
-* Grobs::                      Graphical object  
-* Duration::                   
-* Pitch data type::            
-* Engraver::                   
-* Music_iterator::             
-* Music::                      
-* Molecules::                  Molecules are stand-alone descriptions of output
-* Font metrics::               Font metrics
-* Miscellaneous Scheme functions::  
-@end menu
-
-@node Conversion stages
-@section Conversion stages
 
 When translating the input to notation, there are number of distinct
 phases.  We list them here:
 
-@table @code
+@c todo: moved from refman. 
+
+The purpose of LilyPond is explained informally by the term `music
+typesetter'.  This is not a fully correct name: Not only does the
+program print musical symbols, it also makes aesthetic decisions.
+Symbols and their placements are @emph{generated} from a high-level
+musical description.  In other words, LilyPond would be best described
+to be a `music compiler' or `music to notation compiler'.
+
+LilyPond is linked to GUILE, GNU's Scheme library for extension
+programming.  The Scheme library provides the glue that holds together
+the low-level routines and separate modules which are written in C++.
+
+When lilypond is run to typeset sheet music, the following happens:
+
+@itemize @bullet
+@item GUILE initialization: Various scheme files are read.
+
+@item Parsing: First standard @code{ly} initialization files are read,
+then the user @file{ly} file is read.
+
+@item Interpretation: The music in the file is processed `in playing
+order', i.e., the order that you use to read sheet music, or the
+order in which notes are played.  The result of this step is a
+typesetting specification.
+
+@item Typesetting: The typesetting specification is solved: positions
+and formatting is calculated.
+
+@item The visible results ("virtual ink") are written to the output file.
+@end itemize
+
+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 is written to an output file.
+
+These threemanship of tasks (parsing, translating, typesetting) and
+data-structures (music, context, graphical objects) permeates the entire
+design of the program.
 
-@item Parsing:
 
-The .ly file is read, and converted to a list of @code{Scores}, which
-each contain @code{Music} and paper/midi-definitions.
+@table @b
+
+@item Parsing
+
+The @code{ly} file is read and converted to a list of @code{Scores}, which
+each contain @code{Music} and paper/midi-definitions.  Here @code{Music},
+@code{Pitch}, and @code{Duration} objects are created.
 
 @item Interpreting music
 @cindex interpreting music
 
-All music events are "read" in the same order as they would be played
-(or read from paper). At every step of the interpretation, musical
-events are delivered to
-interpretation contexts,
+All music events are `read' in the same order as they would be played
+(or read from paper).  At every step of the interpretation, musical
+events are delivered to interpretation contexts,
 @cindex engraver
-which use them to build grobs (or MIDI objects, for MIDI output).
+which use them to build @code{Grob}s (or MIDI objects for MIDI output).
 
-@item Prebreaking
+In this stage @code{Music_iterators} do a traversal of the @code{Music}
+structure.  The music events thus encountered are reported to
+@code{Translator}s, a set of objects that collectively form interpretation
+contexts.
 
+@item Prebreaking
 @cindex prebreaking
 
 At places where line breaks may occur, clefs and bars are prepared for
 a possible line break. 
 
 @item Preprocessing
-
 @cindex preprocessing
 
 In this stage, all information that is needed to determine line breaking
 is computed. 
 
-@item Break calculation:
+@item Break calculation
 
 The lines and horizontal positions of the columns are determined.
 
 @item Breaking
 
 Relations between all grobs are modified to reflect line breaks: When a
-spanner, eg. a slur, crosses a line-break, then the spanner is "broken
-into pieces", for every line that the spanner is in, a copy of the grob
-is made. A substitution process redirects all grob-reference so that
-spanner grob will only reference other grobs in the same line.
+spanner, e.g. a slur, crosses a line break, then the spanner is `broken
+into pieces'; for every line that the spanner is in, a copy of the grob
+is made.  A substitution process redirects all grob references so that
+each spanner grob will only reference other grobs in the same line.
 
-@item Outputting:
+@item Outputting
 
 All vertical dimensions and spanning objects are computed, and all grobs
-are output, line by line.
+are output, line by line.  The output is encoded in the form of
+@code{Molecule}s
 
 @end table
 
-@node Moment
-@section Moment
+The data types that are mentioned here are all discussed in this
+section.
+
+
+@c FIXME: Note entry vs Music entry at top level menu is confusing.
+@c . {Music entry}
+@menu
+* Interpretation context::      
+* Syntactic details::           
+* Lexical details::             
+* Output details::               
+@end menu
+
+
+@node Interpretation context
+@section Interpretation context
+
+@menu
+* Creating contexts::           
+* Default contexts::            
+* Context properties::          
+* Engravers and performers::    
+* Changing context definitions::  
+* Defining new contexts::       
+@end menu
+
+
+Interpretation contexts are objects that only exist during a run of
+LilyPond.  During the interpretation phase of LilyPond (when it prints
+@code{interpreting music} to standard output), the music expression in
+a @code{\score} block is interpreted in time order.  This is the same
+order that humans hear and play the music.
 
-Moment is a rational number. Since GUILE doesn't support them natively,
-so we created our own rational data type.
+During this interpretation, the interpretation context holds the
+state for the current point within the music.  It contains information
+like
 
-@defun moment?
-@end defun
+@itemize @bullet
+@item What notes are playing at this point?
+
+@item What symbols will be printed at this point?
+
+@item What is the current key signature, time signature, point within
+the measure, etc.?
+@end itemize
 
-@defun make-moment num den
-create the rational number @var{num}/@var{den}. 
-@end defun
+Contexts are grouped hierarchically: A @internalsref{Voice} context is
+contained in a @internalsref{Staff} context (because a staff can contain
+multiple voices at any point), a @internalsref{Staff} context is contained in
+@internalsref{Score}, @internalsref{StaffGroup}, or
+@internalsref{ChoirStaff} context.
 
-@node Grobs
-@section Grobs
+Contexts associated with sheet music output are called @emph{notation
+contexts}, those for sound output are called @emph{performance
+contexts}.  The default definitions of the standard notation and
+performance contexts can be found in @file{ly/engraver-init.ly} and
+@file{ly/performer-init.ly}, respectively.
 
-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}:
+@node Creating contexts
+@subsection Creating contexts
+@cindex @code{\context}
+@cindex context selection
+
+Contexts for a music expression can be selected manually, using the
+following music expression.
 
 @example
-        \property Voice.Stem \override #'direction = #1
+\context @var{contexttype} [= @var{contextname}] @var{musicexpr}
 @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 defintion
-of the "Stem" grob with the setting @code{direction := 1}.  Of course
-there are many more ways of customizing Lily output, and since most of
-them involve Grobs in some form, this section explains some details of
-how grobs work.
+@noindent
+This instructs lilypond to interpret @var{musicexpr} within the context
+of type @var{contexttype} and with name @var{contextname}.  If this
+context does not exist, it will be created.  
 
-@menu
-* What is a grob?::            
-* Callbacks::                  
-* Setting grob properties::    
-* Items and Spanners::         
-* Grob Scheme functions::      
-@end menu
+@lilypond[verbatim,singleline]
+\score {
+  \notes \relative c'' {
+    c4 <d4 \context Staff = "another" e4> f
+  }
+}
+@end lilypond
 
+@noindent
+In this example, the @code{c} and @code{d} are printed on the
+default staff.  For the @code{e}, a context Staff called
+@code{another} is specified; since that does not exist, a new
+context is created.  Within @code{another}, a (default) Voice context
+is created for the @code{e4}.  When all music referring to a
+context is finished, the context is ended as well.  So after the
+third quarter, @code{another} is removed.
 
 
-@node What is a grob?
-@subsection What is a grob?
-
-[TODO: document/explain interfaces]
-
-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 node in that
-graph. A grob stores references to other grobs, the directed edges in
-the graph.
-
-The objective of this big graph of grobs, is to specify the notation
-problem. The solution of this problem is a description of the printout
-that is in closed form, i.e. but 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, or 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. Whenever 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 (ie. 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.
-
-Often, a grob also is associated with a symbol. However, some
-grobs do not print any symbols, but take care of grouping objects. For
-example, there is a separate grob that stacks staffs vertically, so they
-are not printed in overstrike. The @code{NoteCollision} is another
-example of an abstract grob.  It only moves around chords, but doesn't
-print anything.
-
-A complete list of grob types is found in 
-@ref{(lilypond-internals)LilyPond backend}
-
-Grobs are created in the "Interpreting music" phase, by objects in
-LilyPond called engravers.  In this phase of the translation, a load of
-grobs are created, and they are linked into a giant network of objects.
-This network of grobs forms the "specification" of the print
-problem. This problem is then solved: configurations, directions,
-dimensions, line breaks, etc.  are calculated. Finally,   the printing
-description in the form of Molecules (@ref{Molecules})  is extracted from
-the network. These are then dumped into the output file
-
-@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))
-        )
+@node Default contexts
+@subsection Default contexts
 
-....
+Most music expressions don't need an explicit @code{\context}
+declaration: they inherit the notation context from their parent.  Each
+note is a music expression, and as you can see in the following example,
+only the sequential music enclosing the three notes has an explicit context. 
 
-        \property Voice.Stem \override #'Y-offset-callbacks = #(list
-                        my-callback)
+@lilypond[verbatim,singleline]
+\score { \notes \context Voice = goUp { c'4 d' e' } } 
+@end lilypond
+
+There are some quirks that you must keep in mind when dealing with
+defaults:
+
+First, every top level music is interpreted by the Score context; in other
+words, you may think of @code{\score} working like
+
+@example
+\score @{
+  \context Score @var{music}
+@}
 @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.
+Second, contexts are created automatically to be able to interpret the
+music expressions.  Consider the following example.
 
-(note: Y-offset-callbacks is also a property) 
+@lilypond[verbatim, singleline]
+\score { \context Score \notes { c'4 ( d' )e' } }
+@end lilypond
 
+@noindent
+The sequential music is interpreted by the Score context initially
+(notice that the @code{\context} specification is redundant), but when a
+note is encountered, contexts are setup to accept that note.  In this
+case, a Thread, Voice, and Staff context are created.  The rest of the
+sequential music is also interpreted with the same Thread, Voice, and
+Staff context, putting the notes on the same staff, in the same voice.
 
-Offset callbacks can be stacked, ie.
+This is a convenient mechanism, but do not expect opening chords to work
+without @code{\context}.  For every note, a separate staff is
+instantiated.
 
-@example
-        \property .... \override #'Y-offset-callbacks = #(list
-                callback1 callback2 callback3)
+@cindex explicit context
+@cindex starting with chords
+@cindex chords, starting with
 
-@end example
+@lilypond[verbatim, singleline]
+\score { \notes <c'4 es'> } 
+@end lilypond
 
-The callbacks will be executed in the order 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, for the staccato there are two callbacks: one callback
-that positions the grob above or below the note head, and one callback
-that rounds the Y-position of the grob to the nearest open space.
+Of course, if the chord is preceded by a normal note in sequential
+music, the chord will be interpreted by the Thread of the preceding
+note:
 
-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.
+@lilypond[verbatim,singleline]
+\score { \notes { c'4 <c'4 es'> } }
+@end lilypond
 
 
-@node Setting grob properties
-@subsection Setting grob properties
+@node Context properties
+@subsection Context properties
 
-Grob properties are stored as GUILE association lists, with symbols as
-keys.   From C++, element properties can be accessed using the functions
+Notation contexts have properties.  These properties are from
+the @file{.ly} file using the following expression:
+@cindex @code{\property}
 
 @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);
+\property @var{contextname}.@var{propname} = @var{value}
 @end example
 
-In GUILE, LilyPond provides
+@noindent
+Sets the @var{propname} property of the context @var{contextname} to the
+specified Scheme expression @var{value}.  All @var{propname} and
+@var{contextname} are strings, which are typically unquoted.
+
+Properties that are set in one context are inherited by all of the
+contained contexts.  This means that a property valid for the
+@internalsref{Voice} context can be set in the @internalsref{Score} context
+(for example) and thus take effect in all @internalsref{Voice} contexts.
+
+@cindex @code{Current}
+If you don't wish to specify the name of the context in the
+@code{\property}-expression itself, you can refer to the abstract context
+name, @code{Current}.  The @code{Current} context is the latest
+used context.  This will typically mean the @internalsref{Thread}
+context, but you can force another context with the
+@code{\property}-command.  Hence the expressions
 
 @example
-        ly-get-grob-property GROB SYMBOL
-        ly-set-grob-property GROB SYMBOL VALUE
+\property @var{contextname}.@var{propname} = @var{value}
 @end example
 
-All lookup functions identify undefined properties with 
-end-of-list (ie. @code{'()} in Scheme or @code{SCM_EOL} in C)
+@noindent
+and
 
-Properties are stored in two ways:
-@itemize @bullet
-@item mutable properties:
-element properties that change from object to object. The storage of
-these are private to a grob. Typically this is used to store lists of
-pointers to other grobs
-
-@item immutable properties:
-element 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 values for shared element
-properties are read from @file{scm/element-description.scm}.
-@end itemize
+@example
+\context @var{contextname}
+\property Current.@var{propname} = @var{value}
+@end example
 
-There are two ways to manually set grob properties.
+@noindent
+do the same thing.
+The main use for this is in macros -- allowing the specification of a
+property-setting without restriction to a specific context.
 
-You can change immutable grob properties. This is done with the
-\override syntax:
+Properties can be unset using the following expression:
 
 @example
-        \property Voice.Stem \override #'direction = #1
+\property @var{contextname}.@var{propname} \unset
 @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/element-description.scm}. This can be undone by 
+@cindex properties, unsetting
+@cindex @code{\unset} 
+
+@noindent
+This removes the definition of @var{propname} in @var{contextname}.  If
+@var{propname} was not defined in @var{contextname} (but was inherited
+from a higher context), then this has no effect.
+
+@refbugs
+
+The syntax of @code{\unset} is asymmetric: @code{\property \unset} is not
+the inverse of @code{\property \set}.
+
+
+@node Engravers and performers
+@subsection Engravers and performers
+
+[TODO]
+
+Basic building blocks of translation are called engravers; they are
+special C++ classes.
+
+
+@node Changing context definitions
+@subsection Changing context definitions
+@cindex context definition
+@cindex translator definition
+
+The most common way to define a context is by extending an existing
+context.  You can change an existing context from the paper block by
+first initializing a translator with an existing context identifier:
 
 @example
-        \property Voice.stem \revert #'direction
+\paper @{
+  \translator @{
+    @var{context-identifier}
+  @}
+@}
 @end example
 
-If you use this a lot, this gets old quickly. So we also have a
-shorthand,
+@noindent
+Then you can add and remove engravers using the following syntax:
 
 @example
-        \property Context.GrobType \set #'prop = #VAL
+\remove @var{engravername}
+\consists @var{engravername}
 @end example
 
-this does a @code{\revert} followed by a @code{\override}
+@noindent
+Here @var{engravername} is a string, the name of an engraver in the
+system.
+
+@lilypond[verbatim,singleline]
+\score {
+  \notes {
+    c'4 c'4
+  }
+  \paper {
+    \translator {
+      \StaffContext
+      \remove Clef_engraver
+    }
+  }
+}
+@end lilypond
+
+@cindex engraver
 
-The second way is \outputproperty. This construct looks like
+You can also set properties in a translator definition.  The syntax is as
+follows:
 
 @example
-        \context ContextName \outputproperty @var{pred} #@var{sym} = #@var{val}
+@var{propname} = @var{value}
+@var{propname} \set @var{grob-propname} = @var{pvalue}
+@var{propname} \override @var{grob-propname} = @var{pvalue}
+@var{propname} \revert @var{grob-propname} 
 @end example
 
-In this case, in every grob that satisfies @var{pred}, the property
-assignment @var{sym} = @var{val} is done.  For example
+@noindent
+@var{propname} is a string, @var{grob-propname} a symbol, @var{value}
+and @code{pvalue} are Scheme expressions.  These types of property
+assignments happen before interpretation starts, so a @code{\property}
+command will override any predefined settings.
 
-@example
-        \outputproperty
-                #(lambda (gr) (string? (ly-get-grob-property gr
-                        'text)))
-                #'extra-offset = #'(-1.0 . 0.0)
-@end example
+To simplify editing translators, all standard contexts have standard
+identifiers called @var{name}@code{Context}, e.g. @code{StaffContext},
+@code{VoiceContext}; see @file{ly/engraver-init.ly}.
 
-This shifts all elements 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 Items and Spanners
-@unnumberedsubsec Items and Spanners
+@node Defining new contexts
+@subsection Defining new contexts
 
-Grobs can also be distinguished in their role in the horizontal spacing.
-A lot of 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}.
+If you want to build a context from scratch, you must also supply the
+following extra information:
 
-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.
+@itemize @bullet
+@item A name, specified by @code{\name @var{contextname}}.
 
-Some items need special treatment for line breaking. For example, a
-clef is normally only printed at the start of a line (ie. 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.
+@item A cooperation module.  This is specified by @code{\type
+@var{typename}}.
+@end itemize
 
-Whether these versions are visible and take up space, is determined by
-the outcome of the visibility-lambda. This is a function taking a
-direction (-1, 0 or 1) and returns a cons of booleans, signifying wether
-this grob should be transparent and have no extent.
+This is an example:
 
+@example
+\translator @code{
+  \type "Engraver_group_engraver"
+  \name "SimpleStaff"
+  \alias "Staff"
+  \consists "Staff_symbol_engraver"
+  \consists "Note_head_engraver"
+  \consistsend "Axis_group_engraver"
+}@
+@end example
 
-@node Grob Scheme functions
-@unnumberedsubsec Grob Scheme functions
+@noindent
+The argument of @code{\type} is the name for a special engraver that
+handles cooperation between simple engravers such as
+@code{Note_head_engraver} and @code{Staff_symbol_engraver}.  Alternatives
+for this engraver are the following:
 
+@table @code
+@cindex @code{Engraver_group_engraver}
 
-@defun ly-get-grob-property g sym
-  Get the value of a value in grob @var{g} of property @var{sym}. It
-will return @code{'()} (end-of-list) if @var{g} doesn't have @var{sym} set.
-@end  defun
+@item @code{Engraver_group_engraver}  
+The standard cooperation engraver.
 
-@defun ly-set-grob-property g sym val
-Set @var{sym} in grob @var{g} to value @var{val}
-@end defun
+@cindex @code{Score_engraver}
+@item @code{Score_engraver}  
+This is a cooperation module that should be in the top level context.
+@end table 
 
-@defun ly-get-spanner-bound spanner dir
-Get one of the bounds of @var{spanner}. @var{dir} may be @code{-1} for
-left, and @code{1} for right.
-@end defun
+Other modifiers are
 
-@defun ly-grob? g
-Typecheck: is @var{g} a grob?
-@end defun
+@itemize @bullet
+@item @code{\alias} @var{alternate-name}:
+This specifies a different name.  In the above example,
+@code{\property Staff.X = Y} will also work on @code{SimpleStaff}s
+
+@item @code{\consistsend} @var{engravername}:
+Analogous to @code{\consists}, but makes sure that
+@var{engravername} is always added to the end of the list of
+engravers.
+
+Some engraver types need to be at the end of the list; this
+insures they stay there even if a user adds or removes engravers.
+End-users generally don't need this command.
+    
+@item @code{\accepts} @var{contextname}:
+Add @var{contextname} to the list of contexts this context can
+contain in the context hierarchy.  The first listed context is the
+context to create by default.
+
+@item @code{\denies}:
+The opposite of @code{\accepts}.  Added for
+completeness, but is never used in practice.
+
+@item @code{\name} @var{contextname}:
+This sets the type name of the context, e.g. @internalsref{Staff},
+@internalsref{Voice}.  If the name is not specified, the translator won't do
+anything. 
+@end itemize
 
-@node Duration
-@section Duration
+In the @code{\paper} block, it is also possible to define translator
+identifiers.  Like other block identifiers, the identifier can only
+be used as the very first item of a translator.  In order to define
+such an identifier outside of @code{\score}, you must do
+
+@example 
+\paper @{
+  foo = \translator @{ @dots{} @}
+@}
+\score @{
+  \notes @{
+    @dots{}
+  @}
+  \paper @{
+    \translator @{ \foo @dots{} @}
+  @}
+@} 
+@end example 
+
+@cindex paper types, engravers, and pre-defined translators
+
+      
+@node Syntactic details
+@section Syntactic details
+@cindex Syntactic details
+
+This section describes details that were too boring to be put elsewhere.
 
-@defun make-duration length dotcount
+@menu
+* Identifiers::                 
+* Music expressions::           
+* Manipulating music expressions::  
+* Span requests::               
+* Assignments::                 
+* Lexical modes::               
+* Ambiguities::                 
+@end menu
 
-@var{length} is the negative logarithm (base 2) of the duration:
-1 is a half note, 2 is a quarter note, 3 is an eighth
-note, etc.  The number of dots after the note is given by
-@var{dotcount}.
-@end defun
+@c .  {Identifiers}
+@node Identifiers
+@subsection Identifiers
+@cindex Identifiers
 
+@ignore
+What has this section got to do with identifiers?
+It seems more appropriate in the introduction to Chapter 4,
+"Internals".
 
-@defun duration? d
-type predicate for Duration
-@end defun
+  /MB
+@end ignore
 
-@node Pitch data type
-@section Pitch data type
+All of the information in a LilyPond input file is internally
+represented as a Scheme value.  In addition to normal Scheme data types
+(such as pair, number, boolean, etc.), LilyPond has a number of
+specialized data types,
 
+@itemize @bullet
+@item Input
+@item c++-function
+@item Music
+@item Identifier
+@item Translator_def
+@item Duration
+@item Pitch
+@item Score
+@item Music_output_def
+@item Moment (rational number)
+@end itemize
 
+LilyPond also includes some transient object types.  Objects of these
+types are built during a LilyPond run, and do not `exist' per se within
+your input file.  These objects are created as a result of your input
+file, so you can include commands in the input to manipulate them,
+during a LilyPond run.
 
-@defun make-pitch octave note shift
+@itemize @bullet
+@item Grob: short for `Graphical object'.
 
-@var{octave} is specified by an integer, zero for the octave
-containing middle C.  @var{note} is a number from 0 to 7, with 0
-corresponding to C and 7 corresponding to B.  The shift is zero for a
-natural, negative to add flats, or positive to add sharps.
-@end defun
+@item Molecule: Device-independent page output object,
+including dimensions.  Produced by some Grob functions.
 
-@defun pitch-octave p 
-extract the octave from pitch @var{p}.
-@end defun
+@item Translator: An object that produces audio objects or Grobs.  This is
+not yet user-accessible.
 
-@defun pitch-notename
-extract the note name from pitch  @var{p}.
-@end defun
+@item Font_metric: An object representing a font.
+@end itemize
 
-@defun pitch-alteration
-extract the alteration from pitch  @var{p}.
-@end defun
 
-@defun pitch-semitones
-calculate the number of semitones of @var{p} from central C.
-@end defun
+@node Music expressions
+@subsection Music expressions
+@cindex music expressions
 
-@defun Pitch::transpose t p
-Transpose @var{p} by the amount @var{t}, where @var{t} is the pitch that
-central C is transposed to. 
-@end defun
+Music in LilyPond is entered as a music expression.  Notes, rests, lyric
+syllables are music expressions, and you can combine music expressions
+to form new ones, for example by enclosing a list of expressions in
+@code{\sequential @{ @}} or @code{< >}.  In the following example, a
+compound expression is formed out of the quarter note @code{c} and a
+quarter note @code{d}:
 
-@node Engraver
-@section Engraver
+@example 
+\sequential @{ c4 d4 @} 
+@end example 
 
-Engravers are building blocks of contexts. They are not yet user accessible.
+@cindex Sequential music
+@cindex @code{\sequential}
+@cindex sequential music
+@cindex @code{<}
+@cindex @code{>}
+@cindex Simultaneous music
+@cindex @code{\simultaneous}
 
-@defun ly-get-trans-property tr sym
-retrieve the value of @var{sym} from context @var{tr}
-@end defun
+The two basic compound music expressions are simultaneous and
+sequential music.
 
-@defun ly-set-trans-property tr sym val
-set value of property @var{sym} in context @var{tr} to @var{val}.
-@end defun
+@example
+\sequential @code{@{} @var{musicexprlist} @code{@}}
+\simultaneous @code{@{} @var{musicexprlist} @code{@}}
+@end example
 
-@node Music_iterator
-@section Music_iterator
+For both, there is a shorthand:
 
-This data-type is a direct hook into some C++ constructor functions. It
-is not yet user-serviceable.
+@example
+@code{@{} @var{musicexprlist} @code{@}}
+@end example
 
-@defun c++-function?
-type predicate for c++-function.
-@end defun
+@noindent
+for sequential and
 
-@node Music
-@section Music
+@example
+@code{<} @var{musicexprlist} @code{>}
+@end example
 
-Music is the data type that music expressions are stored in. The data
-type does not yet offer many manipulations.
+@noindent
+for simultaneous music.
+In principle, the way in which you nest sequential and simultaneous to
+produce music is not relevant.  In the following example, three chords
+are expressed in two different ways:
 
-@defun ly-get-mus-property m sym
-Get the property @var{sym} of music expression @var{m}.
-@end defun
+@lilypond[fragment,verbatim,center]
+\notes \context Voice {
+  <a c'> <b d'> <c' e'>
+  < { a b c' } { c' d' e' } >
+}
+@end lilypond
 
-@defun ly-set-mus-property m sym val
-Set property @var{sym} in music expression @var{m} to @var{val}.
-@end defun
+Other compound music expressions include
 
-@defun ly-make-music name
-Make a music object/expression of type @var{name}. Warning: this
-interface will likely change in the near future.
-@end defun
+@example
+\repeat @var{expr}
+\transpose @var{pitch} @var{expr}
+\apply @var{func} @var{expr}
+\context @var{type} = @var{id} @var{expr}
+\times @var{fraction} @var{expr}
+@end example
 
-@node Molecules
-@section Molecules
 
-@cindex Molecule
-@cindex Atom
-@cindex Output description
+@c . {Manipulating music expressions}
+@node Manipulating music expressions
+@subsection Manipulating music expressions
 
-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
+The @code{\apply} mechanism gives you access to the internal
+representation of music.  You can write Scheme-functions that operate
+directly on it.  The syntax is 
 
 @example
-        PUT glyph AT (x,y)
-        PUT glyph AT (x,y)
-        PUT glyph AT (x,y) 
+\apply #@var{func} @var{music}
 @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 an
-object that combines dimension information (how large is this glyph ?)
-with what-to-print-where.
+@noindent
+This means that @var{func} is applied to @var{music}.  The function
+@var{func} should return a music expression.
+
+This example replaces the text string of a script.  It also shows a dump
+of the music it processes, which is useful if you want to know more
+about how music is stored.
+
+@lilypond[verbatim,singleline]
+#(define (testfunc x)
+  (if (equal? (ly:get-mus-property x 'text) "foo")
+      (ly:set-mus-property! x 'text "bar"))
+  ;; recurse
+  (ly:set-mus-property! x 'elements
+    (map testfunc (ly:get-mus-property x 'elements)))
+  (display x)
+  x)
+
+\score {
+  \notes
+  \apply #testfunc { c'4_"foo" }
+} 
+@end lilypond
+
+For more information on what is possible, see the automatically
+generated documentation.
+
+Directly accessing internal representations is dangerous: The
+implementation is subject to changes, so you should avoid this feature
+if possible.
+
+A final example is a function that reverses a piece of music in time:
+
+@lilypond[verbatim,singleline]
+#(define (reverse-music music)
+  (let* ((elements (ly:get-mus-property music 'elements))
+         (reversed (reverse elements))
+         (span-dir (ly:get-mus-property music 'span-direction)))
+    (ly:set-mus-property! music 'elements reversed)
+    (if (dir? span-dir)
+        (ly:set-mus-property! music 'span-direction (- span-dir)))
+    (map reverse-music reversed)
+    music))
+
+music = \notes { c'4 d'4( e'4 f'4 }
+
+\score {
+  \context Voice {
+    \music
+    \apply #reverse-music \music
+  }
+}
+@end lilypond
+
+More examples are given in the distributed example files in
+@code{input/test/}.
+
+@c .   {Assignments}
+@node Assignments
+@subsection Assignments
+@cindex Assignments
+
+Identifiers allow objects to be assigned to names during the parse
+stage.  To assign an identifier, use @var{name}@code{=}@var{value}.
+To refer to an identifier, precede its name with a backslash:
+`@code{\}@var{name}'.  @var{value} is any valid Scheme value or any of
+the input-types listed above.  Identifier assignments can appear at top
+level in the LilyPond file, but also in @code{\paper} blocks.
+
+An identifier can be created with any string for its name, but you will
+only be able to refer to identifiers whose names begin with a letter,
+being entirely alphabetical.  It is impossible to refer to an identifier
+whose name is the same as the name of a keyword.
+
+The right hand side of an identifier assignment is parsed completely
+before the assignment is done, so it is allowed to redefine an
+identifier in terms of its old value, e.g.
+
+@example
+foo = \foo * 2.0
+@end example
 
-Conceptually, Molecules can be constructed from Scheme code, by
-translating a Molecule and by combining two molecules. In BNF
-notation:
+When an identifier is referenced, the information it points to is
+copied.  For this reason, an identifier reference must always be the
+first item in a block.
 
 @example
- Molecule = COMBINE Molecule Molecule
-           | TRANSLATE Offset Molecule
-           | GLYPH-DESCRIPTION
-           ;
+\paper @{
+  foo = 1.0
+  \paperIdent % wrong and invalid
+@}
 @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 onto the output file.
+@example
+\paper @{
+  \paperIdent % correct
+  foo = 1.0
+@}
+@end example
 
-(refer to the C++ code for more details). All visible,
-i.e. non-transparant, 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.
 
-[insert example of write your own.]
+@c .  {Lexical modes}
+@node Lexical modes
+@subsection Lexical modes
+@cindex Lexical modes
+@cindex input mode
+@cindex mode, input 
+@cindex @code{\notes}
+@cindex @code{\chords}
+@cindex @code{\lyrics}
 
-@defun molecule? m
-type predicate.
-@end defun
+To simplify entering notes, lyrics, and chords, LilyPond has three
+special input modes in addition to the default mode: note, lyrics, and
+chords mode.  These input modes change the way that normal, unquoted
+words are interpreted: For example, the word @code{cis} may be
+interpreted as a C-sharp, as a lyric syllable `cis' or as a C-sharp
+major triad respectively.
 
-@defun ly-combine-molecule-at-edge  mol1 axis dir mol2 padding
-Construct a molecule by putting @var{mol2} next to
-@var{mol1}. @var{axis} can be 0 (x-axis) or 1 (y-axis), @var{dir} can be
--1 (left or down) or 1 (right or up).  @var{padding} specifies extra
-space to add in between.  The unit is global staff space.  is the
-@end defun
+A mode switch is entered as a compound music expression
 
-@defun ly-get-molecule-extent! mol axis
-Return a pair of numbers signifying the extent of @var{mol} in
-@var{axis} direction (0 or 1 for x and y axis respectively).
-@end defun
+@example
+@code{\notes} @var{musicexpr}
+@code{\chords} @var{musicexpr}
+@code{\lyrics} @var{musicexpr}
+@end example
 
-@defun ly-set-molecule-extent! mol axis extent
-Set the extent (@var{extent} must be a pair of numbers) of @var{mol} in 
-@var{axis} direction (0 or 1 for x and y axis respectively).
-@end defun
+@noindent
+In each of these cases, these expressions do not add anything to the
+meaning of their arguments.  They just instruct the parser in what mode
+to parse their arguments.
 
-@node Font metrics
-@section Font metrics
+Different input modes may be nested.
 
-The font object represents the metric information of a font. Every font
-that is loaded into LilyPond can be accessed via Scheme. 
 
-LilyPond only needs to know the dimension of glyph to be able to process
-them. This information is stored in font metric files. LilyPond can
-read two types of font-metrics: @TeX{} Font Metric files (tfm files) and
-Adobe Font Metric files (@file{.afm} files).  LilyPond will always try
-to load afm files first since @file{.afm} files are more versatile.
+@c .  {Ambiguities}
+@node Ambiguities
+@subsection Ambiguities
+@cindex ambiguities
+@cindex grammar
 
-@defun ly-get-default-font gr
-This returns the default font for grob @var{gr}.
-@end defun
+The grammar contains a number of ambiguities.  We hope to resolve them at
+some time.
 
-@defun ly-find-glyph-by-name font name
-This function retrieves a Molecule for the glyph named @var{name} in
-@var{font}.  The font must be available as a afm file.
-@cindex afm file
+@itemize @bullet
+@item The assignment
+
+@example 
+foo = bar 
+@end example 
+
+@noindent
+is interpreted as the string identifier assignment.  However,
+it can also be interpreted as making a string identifier @code{\foo}
+containing @code{"bar"}, or a music identifier @code{\foo} containing
+the syllable `bar'.  The former interpretation is chosen.
+
+@item If you do a nested repeat like
+
+@example 
+\repeat @dots{}
+\repeat @dots{}
+\alternative 
+@end example 
+
+@noindent
+then it is ambiguous to which @code{\repeat} the
+@code{\alternative} belongs.  This is the classic if-then-else
+dilemma.  It may be solved by using braces.
+@end itemize
 
-@end defun
 
-@node Miscellaneous Scheme functions
-@section Miscellaneous Scheme functions
+@c .  {Lexical details}
+@node Lexical details
+@section Lexical details
 
-@defun ly-input-location?
-type predicate
-@end defun
-@defun ly-warn msg
-Scheme callable function to issue the warning @code{msg}.
-@end defun
+Even more boring details, now on the lexical side of the input parser.
 
-@defun ly-version
-Return the current lilypond version as a list, e.g.
-@code{(1 3 127 uu1)}. 
-@end defun
+@menu
+* Direct Scheme::               
+* Reals::                       
+* Strings::                     
+@end menu
+
+
+@node Direct Scheme
+@subsection Direct Scheme
+@cindex Scheme
+@cindex GUILE
+@cindex Scheme, in-line code
+@cindex accessing Scheme
+@cindex evaluating Scheme
+@cindex LISP
+
+LilyPond internally uses GUILE, a Scheme-interpreter.  Scheme is a
+language from the LISP family.  You can learn more about Scheme at
+@uref{http://www.scheme.org}.  It is used to represent data throughout
+the whole program.  The hash-sign (@code{#}) accesses GUILE directly: The
+code following the hash-sign is evaluated as Scheme.  The boolean value
+@var{true} is @code{#t} in Scheme, so for LilyPond @var{true} looks like
+@code{##t}.
+
+LilyPond contains a Scheme interpreter (the GUILE library) for
+internal use.  In some places, Scheme expressions also form valid syntax:
+Wherever it is allowed,
+
+@example
+#@var{scheme}
+@end example
+
+@noindent
+evaluates the specified Scheme code.  Example:
+
+@example
+\property Staff.TestObject \override #'foobar = #(+ 1 2)
+@end example
+
+@code{\override} expects two Scheme expressions.
+The first one is a symbol (@code{foobar}), the second one
+an integer (namely, 3).
+
+In-line Scheme may be used at the top level.  In this case the result is
+discarded.
+
+Scheme is a full-blown programming language, and a full discussion is
+outside the scope of this document.  Interested readers are referred to
+the website @uref{http://www.schemers.org/} for more information on
+Scheme.
+
+
+@node Reals
+@subsection Reals
+@cindex real numbers
+
+Formed from an optional minus sign and a sequence of digits followed
+by a @emph{required} decimal point and an optional exponent such as
+@code{-1.2e3}.  Reals can be built up using the usual operations:
+`@code{+}', `@code{-}', `@code{*}', and
+`@code{/}', with parentheses for grouping.
+
+@cindex @code{\mm}
+@cindex @code{\in}
+@cindex @code{\cm}
+@cindex @code{\pt}
+@cindex dimensions
+
+A real constant can be followed by one of the dimension keywords:
+@code{\mm} @code{\pt}, @code{\in}, or @code{\cm}, for millimeters,
+points, inches and centimeters, respectively.  This converts the number
+that is the internal representation of that dimension.
+
+
+@node Strings
+@subsection Strings
+@cindex string
+@cindex concatenate
+
+Begins and ends with the @code{"} character.  To include a @code{"}
+character in a string write @code{\"}.  Various other backslash
+sequences have special interpretations as in the C language.  A string
+that contains no spaces can be written without the quotes.  Strings can
+be concatenated with the @code{+} operator.
+
+
+@c .  {Output details}
+@node Output details
+@section Output details
+
+LilyPond's default output format is @TeX{}.  Using the option @option{-f}
+(or @option{--format}) other output formats can be selected also, but
+currently none of them reliably work.
+
+At the beginning of the output file, various global parameters are defined.
+It also contains a large @code{\special} call to define PostScript routines
+to draw items not representable with @TeX{}, mainly slurs and ties.  A DVI
+driver must be able to understand such embedded PostScript, or the output
+will be rendered incompletely.
+
+Then the file @file{lilyponddefs.tex} is loaded to define the macros used
+in the code which follows.  @file{lilyponddefs.tex} includes various other
+files, partially depending on the global parameters.
+
+Now the music is output system by system (a `system' consists of all
+staves belonging together).  From @TeX{}'s point of view, a system is an
+@code{\hbox} which contains a lowered @code{\vbox} so that it is centered
+vertically on the baseline of the text.  Between systems,
+@code{\interscoreline} is inserted vertically to have stretchable space.
+The horizontal dimension of the @code{\hbox} is given by the
+@code{linewidth} parameter from LilyPond's @code{\paper} block (using the
+natural line width if its value is@w{ }@minus{}1).
+
+After the last system LilyPond emits a stronger variant of
+@code{\interscoreline} only if the macro @code{\lilypondpaperlastpagefill}
+is not defined (flushing the systems to the top of the page).  You can
+avoid that manually by saying
 
-@defun ly-gulp-file name
-read file named @var{name}, and return its contents in a string. This
-uses the lilypond search path.
+@example
+\def\lilypondpaperlastpagefill@{1@}
+@end example
 
-@end defun
+@noindent
+or by setting the variable @code{lastpagefill} in LilyPond's @code{\paper}
+block.
 
-@defun dir?
-type predicate. A direction is a -1, 0 or 1.
-@end defun
+It is possible to fine-tune the vertical offset further by defining the
+macro @code{\lilypondscoreshift}.  Example:
+
+@example
+\def\lilypondscoreshift@{0.25\baselineskip@}
+@end example
+
+@noindent
+@code{\baselineskip} is the distance from one text line to the next.
+
+The code produced by LilyPond can be used by both @TeX{} and La@TeX{}.
+
+Here an example how to embed a small LilyPond file @code{foo.ly} into
+running La@TeX{} text without using the @code{lilypond-book} script
+(@pxref{Integrating text and music with lilypond-book}).
+
+@example
+\documentclass@{article@}
+
+\def\lilypondpaperlastpagefill@{@}
+\lineskip 5pt
+\def\lilypondscoreshift@{0.25\baselineskip@}
+
+\begin@{document@}
+This is running text which includes an example music file
+\input@{foo.tex@}
+right here.
+\end@{document@}
+@end example
+
+The file @file{foo.tex} has been simply produced with
+
+@example
+lilypond foo.ly
+@end example
 
-@defun ly-number->string num
- converts @var{num} without generating many decimals. It leaves a space
-at the end.
-@end defun
+It is important to set the @code{indent} parameter to zero in the
+@code{\paper} block of @file{foo.ly}.
 
+The call to @code{\lineskip} assures that there is enough vertical space
+between the LilyPond box and the surrounding text lines.
 
+@c EOF