[Top][All Lists]
[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