lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

-Very Rough- draft of programming concepts manual


From: Han-Wen Nienhuys
Subject: -Very Rough- draft of programming concepts manual
Date: Sat, 30 Oct 2004 11:45:32 +0200

address@hidden writes:
> I've been spending a little bit of time again trying to understand
> enough about LilyPond that I can create a Fret_diagram context.
> 
> I've been back and reviewed Han-Wen's earlier answer about program
> functionality 
> (http://lists.gnu.org/archive/html/lilypond-devel/2004-03/msg00230.html)
> 
> I've tried to organize this information and add to it a bit of my
> understanding.  I believe that it may be useful to new developers
> trying to get up to speed in LilyPond.
> 
> I don't know how to find the reference tags in the automatically
> generated documentation, so I'm sure some of my references are off.

try @internalsref{Foo bar baz}

@internalsref is a macro that we define for each texi docuemnt
separately.

> I'd appreciate a review to indicate if this information is correct, and
> welcome its inclusion in the documentation if seems to be helpful. 
> OTOH, if its only value is to help me clarify my thoughts,
> it has been worthwhile.

No, it is awesome that someone finally took the effort to write things
down in an organized way.

Further steps are:

  Integrate this with (parts of) the program reference manual.

> Execution of LilyPond begins with the parser (@file{lily/parser.yy}). 
> When the input file is parsed, a Music + Music_output_def object is
> created.  This object leads to a Global_context object (see 
> @file{lily/global-context.cc}).

specifically, \book , \score and toplevel music are passed to a
toplevel-{book,score,music} handler functions by the parser.

> The Global_context object creates a Score context to interpret the music.
> (@file{lily/score.cc}).  Interpreting proceeds, with context objects being
> created as dictated by the Music + Music_output_def object.  When the
> interpretation is complete, Score_context::get_output() returns a
> Music_output object, which is a Paper_score object for notation or a
> Performance object for MIDI.
> 
> FIXME Somehow, during the interpretation process, Music_iterators handle
> the interpretation of Music objects and synchronize the various Contexts
> to ensure that the different Items are tied together appropriately.

Yes, in Global_context::run_iterator_on_me, the next moment to be
processed is calculated, by a (recursive) call of

  Music_iterator::pending_moment().

Then the events are delivered done

  Music_iterator::process(next_moment)

finally

  Global_context::one_time_step()

sets off all the work of creating grobs, etc.

> @node Engravers
> @section Engravers
> @cindex Engravers
> Engravers are used to convert music events to grobs and place them on
> the page.
> 
> Each unique kind of grob should have its own engraver.

(there are also engravers that don't create grobs, see
swallow-engraver.cc and grob-pq-engraver.cc)
> 
> Engravers are C++ classes (see @file{lily/note-heads-engraver.cc}).
> 
> To add an engraver, simply create a file for the class and add it to
> the lily/ directory.  Make will then include the file when LilyPond is 
> rebuilt.

Yes, you have to take an existing engraver as a template, since there
are a number of subtleties that you have to get right. The work of
adding the class to LilyPond is done in the ENTER_DESCRIPTION macro.

> Grob properties are currently used as elements of an
> alist chain that are used in Stencil creation. Stencil creators use the props
> alist to control the characteristics of the created Stencil.

In the end, that's all what matters (the created stencil), but of
course, grob properties contain a lot of things. Stencil Creation
usually is in

        Class::print_function() ,

(Which is exported to Scheme using the macro MAKE_SCHEME_CALLBACK).
However, properties also contain functions, eg.

         (print-function . ,Class::print_function)

or other grobs (used in the  C++  side ), eg. for beam,

         Grob * beam
         SCM stems = beam->get-property ("stems")

stems contains a list of grobs. 

> @node Stencils
> @section Stencils
> @cindex Stencils
> 
> Stencils are the output specifications created by LilyPond grobs. They
> are smobs (scheme objects) containing a specification of how to print the
> object, along with the horizontal and vertical extents.
> 
> The specification is a scheme expression that is processed by the various
> output backends, such as @file{scm/output-tex.scm}.  When a new stencil
> specification is added to LilyPond, the appropriate code for handling the 
> specification must be added to the relevant backends.
> 
> The horizontal and vertical extents are pairs.  The first element of the pair 

this is correct, but I would take the C++ class as definition.  The
extent is a Box, which has an X_AXIS and Y_AXIS extent. Both are
intervals, where interval[LEFT] < interval[RIGHT] (typically, or it is
empty).

The reference point is in Stencil::origin_ , extracted with ly:stencil-origin

> stencils in scheme.
> 
> Internal documentation of the scheme accessors is found at 
> @internalsref{ly:stencil-add}.

Yup, but that documentation should be moved to this document.

> Smobs are C++ objects in Scheme. Scheme objects (lists, functions) are
> manipulated from C++ as well using the GUILE C function interface
> (prefixes: gh_ and scm_).

the gh_ interface is deprecated from guile and isn't used in lily 2.3
anymore.

> Smobs are the primary interface (sometimes called 'lubrication') between the 

(glue is actually the common term, but lubrication visualizes  the
concept better, imo).

> Music_iterators are created during the interpreting phase.

yes, they are created in

     Music_iterators::get_static_get_iterator()

according to the

     iterator-ctor

property of music types (see define-music-types.scm)


-- 

 Han-Wen Nienhuys   |   address@hidden   |   http://www.xs4all.nl/~hanwen 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]