]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/contributor/programming-work.itexi
Doc: [nl] oops, add missing images.
[lilypond.git] / Documentation / contributor / programming-work.itexi
index a48df04ad7ca185f5107bf3d7cb86cb1a4ec67da..bab05ec36dd490f4a5cc3915f09b640964505f2a 100644 (file)
@@ -9,6 +9,7 @@
 * Finding functions::
 * Code style::
 * Debugging LilyPond::
+* Tracing object relationships::
 * Adding or modifying features::
 * Iterator tutorial::
 * Engraver tutorial::
@@ -945,6 +946,95 @@ output to show when the procedure is called and when it exits.
 @code{set-trace-subtree!} traces every step the Scheme evaluator
 performs in evaluating the procedure.
 
+@node Tracing object relationships
+@section Tracing object relationships
+
+Understanding the LilyPond source often boils down to figuring out what
+is happening to the Grobs. Where (and why) are they being created,
+modified and destroyed? Tracing Lily through a debugger in order to
+identify these relationships can be time-consuming and tedious.
+
+In order to simplify this process, a facility has been added to
+display the grobs that are created and the properties that are set
+and modified.  Although it can be complex to get set up, once set up
+it easily provides detailed information about the life of grobs
+in the form of a network graph.
+
+Each of the steps necessary to use the graphviz utility
+is described below.
+
+@enumerate
+
+@item Installing graphviz
+
+In order to create the graph of the object relationships, it is
+first necessary to install Graphviz.  graphviz is available for a
+number of different platforms:
+
+@example
+@uref{http://www.graphviz.org/Download..php}
+@end example
+
+@item Modifying config.make
+
+In order for the Graphviz tool to work, config.make must be modified.
+It is probably a good idea to first save a copy of config.make under
+a different name.  Then, edit config.make by removing every occurence
+of @code{-DNDEBUG}.
+
+@item Rebuilding LilyPond
+
+The executable code of LilyPond must be rebuilt from scratch:
+
+@example
+make -C lily clean && make -C lily
+@end example
+
+@item Create a graphviz-compatible .ly file
+
+In order to use the graphviz utility, the .ly file must include
+@file{ly/graphviz-init.ly}, and should then specify the
+grobs and symbols that should be tracked.  An example of this
+is found in @file{input/regression/graphviz.ly}.
+
+@item Run lilypond with output sent to a log file
+
+The Graphviz data is sent to stderr by lilypond, so it is
+necessary to redirect stderr to a logfile:
+
+@example
+lilypond graphviz.ly 2> graphviz.log
+@end example
+
+@item Edit the logfile
+
+The logfile has standard lilypond output, as well as the Graphviz
+output data.  Delete everything from the beginning of the file
+up to but not including the first occurence of @code{digraph}.
+
+@item Process the logfile with @code{dot}
+
+The directed graph is created from the log file with the program
+@code{dot}:
+
+@example
+dot -Tpdf graphviz.log > graphviz.pdf
+@end example
+
+@end enumerate
+
+The pdf file can then be viewed with any pdf viewer.
+
+When compiled without @code{-DNDEBUG}, lilypond may run slower
+than normal.  The original configuration can be restored by either
+renaming the saved copy of @code{config.make} or rerunning
+@code{configure}.  Then rebuild lilypond with
+
+@example
+make -C lily clean && make -C lily
+@end example
+
+
 @node Adding or modifying features
 @section Adding or modifying features
 
@@ -1198,7 +1288,7 @@ the status.
 @node Iterator tutorial
 @section Iterator tutorial
 
-FIXME -- this is a placeholder for a tutorial on iterators
+TODO -- this is a placeholder for a tutorial on iterators
 
 Iterators are routines written in C++ that process music expressions
 and sent the music events to the appropriate engravers and/or
@@ -1207,14 +1297,17 @@ performers.
 @node Engraver tutorial
 @section Engraver tutorial
 
-FIXME -- This is a placeholder for a tutorial on how engravers work.
-
 Engravers are C++ classes that catch music events and
 create the appropriate grobs for display on the page.  Though the
 majority of engravers are responsible for the creation of a single grob,
 in some cases (e.g. @code{New_fingering_engraver}), several different grobs
 may be created.
 
+Engravers listen for events and acknowledge grobs.  Events are passed to
+the engraver in time-step order during the iteration phase.  Grobs are
+made available to the engraver when they are created by other engravers
+during the iteration phase.
+
 @subsection Useful methods for information processing
 
 An engraver inherits the following public methods from the Translator
@@ -1243,25 +1336,28 @@ automatically or reported with a warning message.
 At each timestep in the music, translation proceeds by calling the
 following methods in turn:
 
-@code{start_translation_timestep ()} is called before any user information enters
-the translators, i.e., no property operations (\set, \override, etc.) or events
-have been processed yet.
+@code{start_translation_timestep ()} is called before any user
+information enters the translators, i.e., no property operations
+(\set, \override, etc.) or events have been processed yet.
 
-@code{process_music ()} and @code{process_acknowledged ()} are called after events
-have been heard, or grobs have been acknowledged.  The latter tends to be used
-exclusively with engravers which only acknowledge grobs, whereas the former is
-the default method for main processing within engravers.
+@code{process_music ()} and @code{process_acknowledged ()} are called
+after all events in the current time step have been heard, or all
+grobs in the current time step have been acknowledged.  The latter
+tends to be used exclusively with engravers which only acknowledge
+grobs, whereas the former is the default method for main processing
+within engravers.
 
-@code{stop_translation_timestep ()} is called after all user information has been
-processed prior to beginning the translation for the next timestep.
+@code{stop_translation_timestep ()} is called after all user
+information has been processed prior to beginning the translation for
+the next timestep.
 
 @subsection Preventing garbage collection for SCM member variables
 
-In certain cases, an engraver might need to ensure private Scheme variables
-(with type SCM) do not get swept away by Guile's garbage collector: for example,
-a cache of the previous key signature which must persist persist between timesteps.
-The method @code{virtual derived_mark () const} can be used in such cases to mark
-such objects as follows:
+In certain cases, an engraver might need to ensure private Scheme
+variables (with type SCM) do not get swept away by Guile's garbage
+collector: for example, a cache of the previous key signature which
+must persist between timesteps.  The method
+@code{virtual derived_mark () const} can be used in such cases:
 
 @example
 Engraver_name::derived_mark ()
@@ -1273,7 +1369,7 @@ Engraver_name::derived_mark ()
 
 @subsection Listening to music events
 
-External interfaces to to the engraver are implemented by protected
+External interfaces to the engraver are implemented by protected
 macros including one or more of the following:
 
 @itemize
@@ -1366,7 +1462,7 @@ the engraver.
 @node Callback tutorial
 @section Callback tutorial
 
-FIXME -- This is a placeholder for a tutorial on callback functions.
+TODO -- This is a placeholder for a tutorial on callback functions.
 
 @node LilyPond scoping
 @section LilyPond scoping
@@ -1412,6 +1508,31 @@ This is a place to dump information that may be of use to developers
 but doesn't yet have a proper home.  Ideally, the length of this section
 would become zero as items are moved to other homes.
 
+@subsection Spacing algorithms
+
+Here is information from an email exchange about spacing algorithms.
+
+On Thu, 2010-02-04 at 15:33 -0500, Boris Shingarov wrote:
+I am experimenting with some modifications to the line breaking code,
+and I am stuck trying to understand how some of it works.  So far my
+understanding is that Simple_spacer operates on a vector of Grobs, and
+it is a well-known Constrained-QP problem (rods = constraints, springs
+= quadratic function to minimize).  What I don't understand is, if the
+spacer operates at the level of Grobs, which are built at an earlier
+stage in the pipeline, how are the changes necessitated by differences
+in line breaking, taken into account?  in other words, if I take the
+last measure of a line and place it on the next line, it is not just a
+matter of literally moving that graphic to where the start of the next
+line is, but I also need to draw a clef, key signature, and possibly
+other fundamental things -- but at that stage in the rendering
+pipeline, is it not too late??
+
+Joe Neeman answered:
+
+We create lots of extra grobs (eg. a BarNumber at every bar line) but
+most of them are not drawn. See the break-visibility property in
+item-interface.
+
 @subsection Info from Han-Wen Email
 
 In 2004, Douglas Linhardt decided to try starting a document that would