]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-1.3.119
authorfred <fred>
Wed, 27 Mar 2002 00:35:00 +0000 (00:35 +0000)
committerfred <fred>
Wed, 27 Mar 2002 00:35:00 +0000 (00:35 +0000)
Documentation/user/development.itexi [new file with mode: 0644]
Documentation/user/lilypond.tely
Documentation/user/refman.itely
lily/include/engraver.hh

diff --git a/Documentation/user/development.itexi b/Documentation/user/development.itexi
new file mode 100644 (file)
index 0000000..e01549b
--- /dev/null
@@ -0,0 +1,866 @@
+@node Internals, , , top
+
+@menu
+* Conversion stages::              Lilypond is a multi-pass program.
+
+* Grobs::                          Graphical object  
+* Engraver::
+* Music_iterator::
+* Music::
+* Molecule::                       Molecule are stand-alone descriptions of output
+@end menu
+
+
+@node Conversion stages, , , Internals
+
+When translating the input to notation, there are number of distinct
+phases.  We list them here:
+
+
+@table @samp
+
+@item Parsing:
+
+The .ly file is read, and converted to a list of @code{Scores}, which
+each contain @code{Music} and paper/midi-definitions.
+
+@item 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,
+@cindex engraver
+which use them to build grobs (or MIDI objects, for MIDI output).
+
+@item Prebreaking
+
+At places where line breaks may occur, clefs and bars are prepared for
+a possible line break. 
+
+@item Preprocessing
+
+In this stage, all information that is needed to determine line breaking
+is computed. 
+
+@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. See
+also @ref{Pointer substitution}.
+
+@item Outputting:
+
+All vertical dimensions and spanning objects are computed, and all grobs
+are output, line by line.
+
+@end table
+
+
+@node Grobs, , , Internals
+@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 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.
+
+@menu
+* What is a grob?::
+* Callbacks::
+* Setting grob properties::
+* Items and Spanners::
+* Pointer substitution::
+@end menu
+
+@node What is a grob?, , , Grobs
+
+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}
+@ref{(lilypond-internals)Element 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. On the other hand,
+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 NoteCollision
+@ref{(lilypond-internals)Element 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)Elements}
+
+Grobs are created in the "Interpreting music" phase, by things 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{Molecule})  is extracted from
+the network. These are then dumped into the output file
+
+@node Callbacks, , , Grobs
+
+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-gr-property grob '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: Y-offset-callbacks is also a property) 
+
+
+Offset callbacks can be stacked, ie.
+
+@example
+        \property .... \override #'Y-offset-callbacks = #(list
+                callback1 callback2 callback3)
+
+@end example
+
+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.
+
+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 (value #f)
+means: "empty in this direction". If you fill in a pair, that pair
+hard-codes the extent in that coordinate.
+
+
+@node Setting grob properties, , , Grobs
+
+Grob properties are stored as GUILE association lists, with symbols as
+keys.   From C++, element properties can be accessed using the 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
+
+In GUILE, LilyPond provides
+
+@example
+        ly-get-grob-property GROB SYMBOL
+        ly-set-grob-property GROB SYMBOL VALUE
+@end example
+
+All lookup functions identify undefined properties with 
+end-of-list (ie. @code{'()} in Scheme or @code{SCM_EOL} in C)
+
+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
+
+There are two ways to manually set grob properties.
+
+You can change immutable grob properties. This is done 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/element-description.scm}. This can be undone by 
+
+@example
+        \property Voice.stem \revert #'direction
+@end example
+
+If you use this a lot, this gets old quickly. So we also have a
+shorthand,
+
+@example
+        \property Context.GrobType \set #'prop = #VAL
+@end example
+
+this does a @code{\revert} followed by a @code{\override}
+
+The second way is \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 property
+assignment @var{sym} = @var{val} is done.  For example
+
+@example
+        \outputproperty
+                #(lambda (gr) (string? (ly-get-grob-property gr
+                        'text)))
+                #'extra-offset = #'(-1.0 . 0.0)
+@end example
+
+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, , , Grobs
+@unnumberedsubsec Items and Spanners
+
+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}.
+
+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.
+
+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.
+
+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 invisible.
+
+@node Pointer substitution, , , Grobs
+@unnumberedsubsec Pointer substitution
+
+
+Symbols that cross line-breaks (such as slurs) cause some more
+complications. When a  spanner 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.
+
+@node Engraver, , , Internals
+
+@node Music_iterator, , , Internals
+
+@node Music, , , Internals
+
+@node Molecule, , , Internals
+
+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.}.  A molecule is an object that combines
+dimension information (how large is this glyph ?) with
+what-to-print-where.
+
+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
+
+(refer to the C++ code for more details). All visible,
+ie. 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.
+
+
+
+@node Development, , , top
+@chapter Development
+
+@menu
+* Coding standards::
+* Making patches::
+* Localisation::
+@end menu
+
+@section CodingStyle - standards while programming for GNU LilyPond
+
+As a general rule, you should always try to continue computations, even
+if there is some kind of error. When the program stops, it is often very
+hard for a user to pinpoint what part of the input causes an
+error. Finding the culprit is much easier if there is some viewable
+output.
+
+So functions and methods do not return errorcodes, they never crash, but
+report a programming_error and try to carry on.
+
+@unnumberedsubsec Languages
+
+C++ and Python are preferred.  Python code should use an indent of 8,
+using TAB characters.
+
+@unnumberedsubsec Filenames
+
+Definitions of classes that are only accessed via pointers
+(*) or references (&) shall not be included as include files.
+
+filenames
+
+@example 
+       ".hh"   Include files
+       ".cc"   Implementation files
+       ".icc"  Inline definition files
+       ".tcc"  non inline Template defs
+@end example 
+
+in emacs:
+
+@example 
+       (setq auto-mode-alist
+             (append '(("\\.make$" . makefile-mode)
+                       ("\\.cc$" . c++-mode)
+                       ("\\.icc$" . c++-mode)
+                       ("\\.tcc$" . c++-mode)
+                       ("\\.hh$" . c++-mode)
+                       ("\\.pod$" . text-mode)         
+                       )
+                     auto-mode-alist))
+@end example 
+
+
+The class Class_name is coded in @file{class-name.*}
+
+@unnumberedsubsec Indentation
+
+Standard GNU coding style is used.   In emacs:
+
+@example 
+       (add-hook 'c++-mode-hook
+                 '(lambda() (c-set-style "gnu")
+                    )
+                 )
+@end example 
+
+If you like using font-lock, you can also add this to your @file{.emacs}:
+
+@example 
+       (setq font-lock-maximum-decoration t)
+       (setq c++-font-lock-keywords-3 
+             (append
+              c++-font-lock-keywords-3
+              '(("\\b\\([a-zA-Z_]+_\\)\\b" 1 font-lock-variable-name-face)
+              ("\\b\\([A-Z]+[a-z_]+\\)\\b" 1 font-lock-type-face))
+              ))
+@end example 
+
+@unnumberedsubsec Classes and Types
+
+@example 
+       This_is_a_class
+@end example 
+
+@unnumberedsubsec Members
+
+@example 
+       Class::member ()
+       Type Class::member_type_
+       Type Class::member_type ()
+@end example 
+
+the @code{type} is a Hungarian notation postfix for @code{Type}. See below
+
+@unnumberedsubsec Macros
+
+Macro names should be written in uppercase completely.
+
+@unnumberedsubsec Broken code
+
+Try not to write broken code. This includes hardwired dependencies,
+hardwired constants, slow algorithms and obvious limitations. If you can
+not avoid it, mark the place clearly, and add a comment explaining
+shortcomings of the code.
+
+@unnumberedsec Hungarian notation naming convention
+
+The C++ part of LilyPond uses a naming convention derived from the
+so-called @emph{Hungarian Notation}.  Macros, @code{enum}s and
+@code{const}s are all uppercase, with the parts of the names separated
+by underscores.
+
+The hungarian notation  is to be used when variables are not declared
+near usage (mostly in member variables and functions).
+
+@unnumberedsubsec Types
+
+@table @samp
+@item @code{byte}
+    unsigned char. (The postfix _by is ambiguous)
+@item @code{b}
+    bool
+@item @code{bi}
+    bit
+@item @code{ch}
+    char
+@item @code{f}
+    float
+@item @code{i}
+    signed integer
+@item @code{str}
+    string class
+@item @code{sz}
+    Zero terminated c string
+@item @code{u}
+    unsigned integer
+@end table
+
+@unnumberedsubsec User defined types
+
+@example 
+
+       /*
+                Slur blah. blah.
+       */
+       class Slur @{
+                ...
+        @};
+       Slur* slur_p = new Slur;
+@end example 
+
+@unnumberedsubsec Modifiers
+
+The following types modify the meaning of the prefix. 
+These are preceded by the prefixes:
+
+@table @samp
+@item @code{a}
+    array
+@item @code{arr}
+    user built array.
+@item @code{c}
+    const. Note that the proper order is @code{Type const}
+        and not @code{const Type}
+@item @code{C}
+    A const pointer. This would be equivalent to @code{_c_l}, but since any
+    "const" pointer has to be a link (you can't delete a const pointer),
+    it is superfluous.
+@item @code{l}
+    temporary pointer to object (link)
+@item @code{p}
+    pointer to newed object
+@item @code{r}
+    reference
+@end table
+
+@unnumberedsubsec Adjective
+
+Adjectives such as global and static should be spelled out in full.
+They come before the noun that they refer to, just as in normal english.
+
+@example 
+
+foo_global_i: a global variable of type int commonly called "foo".
+@end example 
+
+static class members do not need the static_ prefix in the name (the
+Class::var notation usually makes it clear that it is static)
+
+@table @samp
+@item @code{loop_i}
+    Variable loop: an integer
+@item @code{u}
+    Temporary variable: an unsigned integer
+@item @code{test_ch}
+    Variable test: a character
+@item @code{first_name_str}
+    Variable first_name: a String class object
+@item @code{last_name_ch_a}
+    Variable last_name: a @code{char} array
+@item @code{foo_i_p}
+    Variable foo: an @code{Int*} that you must delete
+@item @code{bar_i_l}
+    Variable bar: an @code{Int*} that you must not delete
+@end table
+
+Generally default arguments are taboo, except for nil pointers.
+
+The naming convention can be quite conveniently memorised, by
+expressing the type in english, and abbreviating it
+
+@example 
+
+       static Array<int*> foo
+@end example 
+
+@code{foo} can be described as "the static int-pointer user-array", so you get
+
+@example 
+
+       foo_static_l_arr
+@end example 
+
+
+@unnumberedsec Miscellaneous
+    
+For some tasks, some scripts are supplied, notably creating patches, a
+mirror of the website, generating the header to put over cc and hh
+files, doing a release.
+
+Use them.
+
+@node Making patches, , , Top
+
+
+@unnumberedsec  Track and distribute your code changes
+
+This page documents how to distribute your changes to GNU lilypond
+    
+We would like to have unified context diffs with full pathnames.  A
+script automating supplied with Lily.
+
+Distributing a change normally goes like this:
+
+@itemize @bullet
+@item make your fix/add your code 
+@item Add changes to CHANGES, and add yourself to Documentation/topdocs/AUTHORS.texi
+@item generate a patch, 
+@item e-mail your patch to one of the mailing lists
+    gnu-music-discuss@@gnu.org or bug-gnu-music@@gnu.org
+@end itemize
+
+Please do not send entire files, even if the patch is bigger than the
+original.  A patch makes it clear what is changed, and it won't
+overwrite previous (not yet released) changes.
+
+@unnumberedsec Generating a patch
+
+Simple version: run
+
+@example
+        make -C lilypond-x.y.z/ distclean
+        make -C lilypond-x.y.z.NEW/ distclean
+        diff -urN lilypond-x.y.z/ lilypond-x.y.z.NEW/
+@end example
+
+Complicated (but automated) version:
+
+In @file{VERSION}, set MY_PATCH_LEVEL:
+
+@example 
+
+    VERSION:
+       ...
+       MY_PATCH_LEVEL=jcn1
+@end example 
+
+In @file{CHANGES}, enter a summary of changes:
+
+@example 
+       0.1.73.jcn1
+        ===========
+
+        * A concise, yet clearly readable description of what changed.
+
+@end example 
+
+Then, from the top of Lily's source tree, type
+
+@example 
+    make release
+@end example 
+
+These handy python scripts assume a directory structure which looks
+like:
+
+@example 
+
+    lilypond -> lilypond-x.y.z   # symlink to development directory
+    lilypond-x.y.z/              # current development
+    patches/                    # patches between different releases
+    releases/                    # .tar.gz releases
+
+@end example 
+
+@unnumberedsec Applying patches
+
+[outdated: please use xdeltas]
+
+If you're following LilyPond development regularly, you probably want to
+download just the patch for each subsequent release.
+After downloading the patch (into the patches directory, of course), simply 
+apply it:
+
+@example 
+
+    gzip -dc ../patches/lilypond-0.1.74.diff.gz | patch -p1 -E
+@end example 
+
+and don't forget to make automatically generated files:
+
+@example 
+
+    autoconf footnote(patches don't include automatically generated files, 
+    i.e. file(configure) and files generated by file(configure).)
+
+    configure
+@end example 
+
+@node Localisation, , , Top
+
+@chapter Localisation - User messages in LilyPond
+
+@section Introduction
+
+This document provides some guidelines for uniformising user messages.
+In the absence of other standards, we'll be using these rules when coding
+ for LilyPond.  Hopefully, this can be replaced by general GNU
+guidelines in the future.
+
+Not-preferred messages are marked with @code{+}.  By convention,
+agrammatical examples are marked with @code{*}.
+
+@section Guidelines
+
+@itemize @bullet
+
+@item
+Every message to the user should be localised (and thus be marked
+for localisation).  This includes warning and error messages.
+
+@item
+Don't localise/gettextify:
+
+@itemize @minus
+@item @code{programming_error ()}s
+@item @code{programming_warning ()}s
+@item debug strings
+@item output strings (PostScript, TeX)
+@end itemize
+
+@item
+Messages to be localised must be encapsulated in @code{_ (STRING)}
+or @code{_f (FORMAT, ...)}.  Eg:
+
+@example
+warning (_ ("Need music in a score"));
+error (_f ("Can't open file: `%s'", file_name));
+@end example
+
+In some rare cases you may need to call @code{gettext ()} by hand.
+This happens when you pre-define (a list of) string constants for later
+use.  In that case, you'll probably also need to mark these string
+constants for translation, using @code{_i (STRING)}.  The @code{_i}
+macro is a no-op, it only serves as a marker for @file{xgettext}.
+
+@example
+char const* messages[] = @{
+  _i ("enable debugging output"),
+  _i ("ignore lilypond version"),
+  0
+@};
+
+void
+foo (int i)
+@{
+  puts (gettext (messages [i]));
+@}
+@end example
+
+See also
+@file{flower/getopt-long.cc} and @file{lily/main.cc}.
+
+@item
+Don't use leading or trailing whitespace in messages.
+
+@item
+Messages containing a final verb, or a gerund (@code{-ing}-form)
+always start with a capital.  Other (simpler) messages start with
+a lowercase letter:
+
+@example
+The word `foo' is not declared.
+`foo': not declared.
+Not declaring: `foo'.
+@end example
+
+@item
+To avoid having a number of different messages for the same situation,
+we'll use quoting like this @code{"message: `%s'"} for all strings.
+Numbers are not quoted:
+
+@example
+_f ("Can't open file: `%s'", name_str)
+_f ("Can't find charater number: %d", i)
+@end example
+
+@item
+Think about translation issues.  In a lot of cases, it is better to
+translate a whole message.  The english grammar mustn't be imposed on
+the translator.  So, iso
+
+@example
+_ ("Stem at ") + moment.str () + _(" doen't fit in beam")
+@end example
+
+@noindent
+have
+
+@example
+_f ("Stem at %s doen't fit in beam", moment.str ())
+@end example
+
+@item
+Split up multi-sentence messages, whenever possible.  Instead of
+
+@example
+warning (_f ("out of tune!  Can't find: `%s', "Key_engraver"));
+
+warning (_f ("Can't find font `%s', loading default", 
+             font_name));
+@end example
+
+@noindent
+rather say:
+
+@example
+warning (_ ("out of tune:");
+warning (_f ("Can't find: `%s', "Key_engraver"));
+
+warning (_f ("Can't find font: `%s', font_name));
+warning (_f ("Loading default font"));
+@end example
+
+@item
+If you must have multiple-sentence messages, use full punctuation.
+Use two spaces after end of sentence punctuation.
+No punctuation (esp. period) is used at the end of simple messages.
+
+@example
+   _f ("Non-matching braces in text `%s', adding braces", text)
+   _ ("Debug output disabled.  Compiled with NPRINT.")
+   _f ("Huh?  Not a Request: `%s'.  Ignoring.", request)
+@end example
+
+@item
+Don't modularise too much; a lot of words cannot be translated
+without context.
+It's probably safe to treat most occurences of words like
+stem, beam, crescendo as separately translatable words.
+
+@item
+When translating, it is preferrable to put interesting information 
+at the end of the message, rather than embedded in the middle.
+This especially applies to frequently used messages, even if this
+would mean sacrificing a bit of eloquency.  This holds for original
+messages too, of course.
+
+@example
+    en: can't open: `foo.ly'
++   nl: kan `foo.ly' niet openen (1)
+    kan niet openen: `foo.ly'*   (2)
+    niet te openen: `foo.ly'*    (3)
+@end example
+
+The first nl message, although gramatically and stylishly correct,
+is not friendly for parsing by humans (even if they speak dutch).
+I guess we'd prefer something like (2) or (3).
+
+@item
+Please don't run make po/po-update with GNU gettext < 0.10.35
+
+@end itemize
index ccb26410603a2cb825a302e5a34d27aa9e33d766..88b3b59f165ad6952e3c82a70a1bb6c68e2b21fc 100644 (file)
@@ -100,6 +100,8 @@ this and other documentation.
 @c Move to Reference Manual?
 * Internals:(lilypond-internals).  Auto generated detailed documentation.
 * convert-ly::                     Upgrading input files.
+* Internals::
+* Development::                    Some hints on developing for LilyPond.
 * Index::                          Unified index.
 @end menu
 
@@ -126,6 +128,8 @@ this and other documentation.
 
 @include convert-ly.itexi
 
+@include development.itexi
+
 @node Index, , , Top
 @unnumbered Index
 
index 55cd7287c8a693c95e2dacf8da7bd04de149018e..60018dacba3b9abf9500193a4d700c35d066c6a5 100644 (file)
@@ -39,8 +39,6 @@
 * contextdefs::                    contextdefs
 * Sound output::                   Sound output
 * midilist::                       midilist
-* Grobs::                          Graphical objects
-* Molecule::                       Molecules
 * Pre-defined Identifiers::        Pre-defined Identifiers
 @c May be fragile.  Better make single link to generated doco?
 * Interpretation contexts:(lilypond-internals)LilyPond interpretation contexts.
@@ -693,8 +691,8 @@ You can alter the length of duration by writing
 appearance of note heads or rests.
 
 
-Rests are entered like notes, with note name `@code{r}@indexcode{r}',
-or `@code{R}@indexcode{R}'.  There is also a note name
+Rests are entered like notes, with note name `@code{r}@indexcode{r}', or
+`@code{R}@indexcode{R}'.  There is also a note name
 `@code{s}@indexcode{s}', which produces a space of the specified
 duration.  `@code{R}' is specifically meant for entering parts: the
 @code{R} rest can expand to fill a score with rests, or it can be
@@ -705,6 +703,10 @@ You can control the expansion by setting the property
 empty measures, and the multimeasure rests automatically adds the
 appropriate number.
 
+Note that there is currently no way to condense multiple rests into a
+single multimeasure rest.
+
+
 
 @cindex lyrics expressions
 
@@ -2017,10 +2019,10 @@ A context is an object that holds the reading state of the
 expression; it contains information like
 
 @itemize @bullet
-  @item  What notes are playing at this point?
-  @item  What symbols will be printed at this point?
-  @item  In what style will they printed?
-  @item  What is the current key signature, time signature, point within
+  @item What notes are playing at this point?
+  @item What symbols will be printed at this point?
+  @item In what style will they printed?
+  @item What is the current key signature, time signature, point within
        the measure, etc.?
 @end itemize
 
@@ -2136,16 +2138,6 @@ sequential music is also the default @code{Voice} context.
 The @code{d4} gets interpreted in the same context
 as @code{c4}.
 
-
-
-These are the contexts supplied with the package.  They are defined
-in the initialization file @file{ly/engraver.ly}.
-
-@table @samp
-@end table
-
-
-
 Properties that are set in one context are inherited by all of the
 contained contexts.  This means that a property valid for the
 @code{Voice} context can be set in the @code{Score} context (for
@@ -2156,33 +2148,18 @@ corresponding to the appropriate context.  In this case, the syntax
 is
 
 @example
-
   @var{propname} @code{=} @var{value}
 @end example
 
 This assignment happens before interpretation starts, so a
 @code{\property} expression will override any predefined settings.
 
-The @code{\property} expression will create any property you specify.
-There is no guarantee that a property will be used.  So if you spell
-a property name wrong, there will be no error message.
-
 The property settings are used during the interpretation phase.  They
 are read by the LilyPond modules where interpretation contexts are
 built of.  These modules are called @emph{translators}.  Translators for
 notation are called @emph{engravers}, and translators for sound are
 called @emph{performers}.
 
-The precise result of a property is determined by the implementation
-of the translator that reads them.  Therefore, the result of a
-property can vary, since it is implementation and configuration
-dependent.
-
-In order to fully find out what properties are used, you must
-currently search the source code for calls to @code{get_property}. 
-The rest of the section is devoted to an (incomplete) overview of
-available properties.
-
 @mbinclude properties.itely
 
 @node Notation output definitions, , ,  Reference Manual
@@ -2200,7 +2177,6 @@ The most important output definition is the @code{\paper} block, for
 music notation.  The syntax is
 
 @example
-
   @code{\paper @{} [@var{paperidentifier}] @var{items} @code{@}}
 @end example
 
@@ -2213,9 +2189,13 @@ where each of the items is one of
   @item  A context definition.  See section @ref{contextdefs} for
        more information on context definitions.
 
-  @item
-       FIXME now in SCM
+@ignore
+
+                FIXME
+
 
+  @item
+       
        A margin shape declaration.  The syntax is
 
        @example
@@ -2232,15 +2212,15 @@ where each of the items is one of
        the successive pairs of dimensions.  The last pair of
        dimensions will define the characeristics of all lines beyond
        those explicitly specified.
+@end ignore
 
   @item  \stylesheet  declaration.  Its syntax is
 
        @example
-               \stylesheet @var{scm}
+               \stylesheet @var{alist}
        @end example
 
-
-       See font.scm for details of @var{scm} 
+       See @file{font.scm} for details of @var{alist}.
 @end itemize
 
 
@@ -2274,17 +2254,7 @@ select.
 
 @node Paper variables, , ,  Reference Manual
 
-There is a large number of paper variables that are used to control
-details of the layout.  These variables control the defaults for the
-entire score.  Usually, they do not have to be changed; they are by
-default set to values that depend on the font size in use.  The
-values are used by the graphic objects while formatting the score;
-they are therefore implementation dependent.  Most variables are
-accompanied by documentation in the initalization file
-@file{params.ly} or @file{paperSZ.ly}, where @code{SZ} is the staff
-height in points.
-
-Nevertheless, here are some variables you may want to use or change:
+The paper block has some variables you may want to use or change:
 
 @table @samp
   @item @code{indent}@indexcode{indent}  
@@ -2313,7 +2283,8 @@ Nevertheless, here are some variables you may want to use or change:
     Defaults to 0.
 
   @item @code{stafflinethickness}@indexcode{stafflinethickness}  
-    Determines the thickness of staff and bar lines. 
+    Determines the thickness of staff lines, and also acts as a scaling
+parameter for other line thicknesses.
 @end table
 
 
@@ -2393,8 +2364,12 @@ one of
     
   @item  @code{\accepts} @var{contextname} @code{;}  
     Add @var{contextname} to the list of  context this context can
-    contain.  The first listed context the context to create by
+    contain.  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{\remove} @var{engravername} @code{;}  
     Remove a previously added (with @code{\consists}) engraver.
@@ -2487,10 +2462,8 @@ translator:
 @node Sound output, , ,  Reference Manual
 @section Sound output
 
-
-
-The MIDI block is analogous to the paper block, but it is simpler.
-The @code{\midi} block can contain:
+The MIDI block is analogous to the paper block, but it is somewhat
+simpler.  The @code{\midi} block can contain:
 @cindex MIDI block
 
 @itemize @bullet
@@ -2630,284 +2603,3 @@ provide shorthands for some settings.  Most of them are in
 
 @end table
 
-@node  Grobs, , , Reference Manual
-@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 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.
-
-@menu
-* What is a grob?::
-* Callbacks::
-* Setting grob properties::
-* Items and Spanners::
-* Pointer substitution::
-@end menu
-
-@node What is a grob?, , , Grobs
-
-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}
-@ref{(lilypond-internals)Element 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. On the other hand, 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 NoteCollision @ref{(lilypond-internals)Element
-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)Elements}
-
-Grobs are created in the "Interpreting music" phase, by things 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{Molecule})  is extracted from
-the network. These are then dumped into the output file
-
-@node Callbacks, , , Grobs
-
-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-gr-property grob '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: Y-offset-callbacks is also a property) 
-
-
-Offset callbacks can be stacked, ie.
-
-@example
-        \property .... \override #'Y-offset-callbacks = #(list
-                callback1 callback2 callback3)
-
-@end example
-
-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.
-
-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 (value #f)
-means: "empty in this direction". If you fill in a pair, that pair
-hard-codes the extent in that coordinate.
-
-
-@node Setting grob properties, , , Grobs
-
-Grob properties are stored as GUILE association lists, with symbols as
-keys.   From C++, element properties can be accessed using the 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
-
-In GUILE, LilyPond provides
-
-@example
-        ly-get-grob-property GROB SYMBOL
-        ly-set-grob-property GROB SYMBOL VALUE
-@end example
-
-All lookup functions identify undefined properties with 
-end-of-list (ie. @code{'()} in Scheme or @code{SCM_EOL} in C)
-
-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
-
-There are two ways to manually set grob properties.
-
-You can change immutable grob properties. This is done 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/element-description.scm}. This can be undone by 
-
-@example
-        \property Voice.stem \revert #'direction
-@end example
-
-If you use this a lot, this gets old quickly. So we also have a
-shorthand,
-
-@example
-        \property Context.GrobType \set #'prop = #VAL
-@end example
-
-this does a @code{\revert} followed by a @code{\override}
-
-The second way is \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 property
-assignment @var{sym} = @var{val} is done.  For example
-
-@example
-        \outputproperty
-                #(lambda (gr) (string? (ly-get-grob-property gr
-                        'text)))
-                #'extra-offset = #'(-1.0 . 0.0)
-@end example
-
-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, , , Grobs
-@unnumberedsubsec Items and Spanners
-
-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}.
-
-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.
-
-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.
-
-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 invisible.
-
-@node Pointer substitution, , , Grobs
-@unnumberedsubsec Pointer substitution
-
-
-Symbols that cross line-breaks (such as slurs) cause some more
-complications. When a  spanner 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.
-
-@node Molecule, , , Reference Manual
-
-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.}.  A molecule is an object that combines
-dimension information (how large is this glyph ?) with
-what-to-print-where.
-
-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
-
-(refer to the C++ code for more details). All visible,
-ie. 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.
index a87cbbc8111f585ee8307ce27ef9ecd44f269e4a..729c5d7d577902737d76349e3430b2b3a530aeee 100644 (file)
@@ -25,11 +25,8 @@ class Engraver : public virtual Translator {
     
   friend class Engraver_group_engraver;
 protected:
-  /// utility
-  //   Paper_def * paper_l() const;
-
   /*
-    Call this last thing.
+    Call this when you're finished with ELEM_P.
    */
   virtual void typeset_grob (Grob*elem_p);
   /*