-1.3.118.jcn3
-============
-
-* More feature examples.
-
-* Renamed some scm files.
-
-1.3.118.jcn2
-============
+1.3.119
+=======
* Added some feature examples.
* Bugfix for \partial and auto-beamer.
-1.3.118.jcn1
-============
-
* Bugfixes: warnings.
+* More feature examples.
+
+* Renamed some scm files.
+
+* Some more documentation fixes (move hacking.texi into normal
+documentation.)
+
+* Bugfix: header protection in parser.yy
+
1.3.117.mb1
===========
@settitle LilyPond internals
-@node Top, LilyPond internals, (dir), (dir)
+@node Top, , (dir), (dir)
@top
-@menu
-* LilyPond internals::
-* Overview::
-* Request_engraver::
-* Coding standards::
-* Making patches::
-* Localisation::
-@end menu
-
-@node LilyPond internals, , Top, Top
-
-@menu
-* Overview:: Overview
-* Request_engraver:: Request_engraver
-@end menu
-
@chapter Getting involved
@chapter LilyPond internals
-
-@node Overview, , , Top
-@section Overview
-
-GNU LilyPond is a "multi-pass" system.
-
-@table @samp
-
-@item Parsing:
-
-No difficult algorithms. 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
-
-The music is walked through in time-order. The iterators which do the
-walking report Music to Translators which use this information to
-create elements, either MIDI or "visual" elements. The translators
-form a hierarchy; the ones for paper output are Engravers, for MIDI
-Performers.
-
-The translators swallow Music (mostly atomic gobs called Requests),
-create elements, broadcast them to other translators on higher or same
-level in the hierarchy:
-
-The stem of a voice A is broadcast to the staff which contains A, but
-not to the stems, beams and noteheads of a different voice (say B) or
-a different staff. The stem and noteheads of A are coupled, because
-the the Note_heads_engraver broadcasts its heads, and the Stem_engraver catches
-these.
-
-The engraver which agrees to handle a request decides whether to to
-honor the request, ignore it, or merge it with other requests. Merging
-of requests is preferably done with other requests done by members of
-the same voicegroups (beams, brackets, stems). In this way you can put
-the voices of 2 instruments in a conductor's score so they make chords
-(the Beam requests of both instruments will be merged).
-
-@item Prebreaking
-
-Breakable stuff (eg. clefs and bars) are copied into pre and
-postbreaks.
-
-@item Preprocessing
-
-Some dependencies are resolved, such as the direction of stems, beams,
-and "horizontal" placement issues (the order of clefs, keys etc,
-placement of chords in multi-voice music),
-
-@item Break calculation:
-
-The lines and horizontal positions of the columns are determined.
-
-@item Breaking
-
-Through some magical interactions with Line_of_score and Super_elem
-(check out the source) the "lines" are produced.
-
-All other spanners can figure across which lines they are spread. If
-applicable, they break themselves into pieces. After this, each piece
-(or, if there are no pieces, the original spanner itself) throws out
-any dependencies which are in the wrong line.
-
-@item Postprocesing:
-
-Some items and all spanners need computation after the Paper_column
-positions are determined. Examples: slurs, vertical positions of
-staffs.
-
-@item Output paper
-
-@end table
-
-
-@node Request_engraver, , , Top
-@section Request_engraver
-
-In the previous section the idea of Request has been explained, but
-this only solves one half of the problem. The other half is deciding
-which requests should be honored, which should merged with other
-requests, and which should be ignored. Consider this input
-
-@example
-
- \type Staff < % chord
- @{ \meter 2/4; [c8 c8] @}
- @{\meter 2/4; [e8 e8] @}
- >
-
-@end example
-
-Both the cs and es are part of a staff (they are in the same
-Voice_group), so they should share meters, but the two [ ] pairs
-should be merged.
-
-The judge in this "allocation" problem a set of brokers: the requests
-are transmitted to so-called engravers which respond if they want to
-accept a request eg, the @code{Notehead_engraver} will accept
-@code{Note_req}s, and turn down @code{Slur_req}s. If the Music_iterator
-cannot find a engraver that wants the request, it is junked (with a
-warning message).
-
-After all requests have been either assigned, or junked, the Engraver
-will process the requests (which usually means creating an @code{Item}
-or @code{Spanner}). If a @code{Request_engraver} creates something, it
-tells the enclosing context. If all items/spanners have been created,
-then each Engraver is notified of any created Score_element, via a
-broadcasting system.
-
-@unnumberedsubsec example:
-
-@example
-
- c4
-
-@end example
-
-produces:
-
-@example
-
- Note_request (duration 1/4)
- Stem_request (duration 1/4)
-
-@end example
-
-Note_request will be taken by a @code{Notehead_engraver}, stem_request
-will be taken by a @code{Stem_beam_engraver}. @code{Notehead_engraver}
-creates a @code{Notehead}, @code{Stem_beam_engraver} creates a
-@code{Stem}. Both announce this to the Staff_engraver. Staff_engraver
-will tell @code{Stem_beam_engraver} about the @code{Notehead}, which
-will add the @code{Notehead} to the @code{Stem} it just created.
-
-To decide on merging, several engravers have been grouped. Please
-check @file{init/engraver.ly}.
-
-@node Coding standards, , , Top
-
-@chapter CodingStyle - standards while programming for GNU LilyPond
-
-Functions and methods do not return errorcodes: they never crash, but
-report a programming_error and try to carry on.q
-
-
-@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_abbreviation is coded in @file{class-name-abbr.*}
-
-@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
-
-Macros should be written completely in uppercase
-
-@unnumberedsubsec Broken code
-
-Broken code (hardwired dependencies, hardwired constants, slow
-algorithms and obvious limitations) should be marked as such: either
-with a verbose TODO, or with a short "ugh" comment.
-
-@unnumberedsec Hungarian notation naming convention
-
-Proposed is 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.
- (slur)
- */
- 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{array}
- user built array.
-@item @code{c}
- const. Note that the proper order is @code{Type const}
- i.s.o. @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
- pl 0.1.73.jcn1
- - added PATCHES.texi
-@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
-
-(Some scripts also assume this lives in @file{$HOME/usr/src}).
-
-
-@unnumberedsec Applying patches
-
-
-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 for LilyPond@footnote{
-In addition to the C++ coding standards that come with Lily
-}. 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)@footnote{
-This may seem ridiculously obvious, however, makeinfo-3.12s localises
-output strings. Sending bug report now ---jcn
-}
-@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's 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
-
-@bye
-
-
-
-@bye
-
-
--- /dev/null
+@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
@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
@include convert-ly.itexi
+@include development.itexi
+
@node Index, , , Top
@unnumbered Index
* 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.
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
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
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
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
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
music notation. The syntax is
@example
-
@code{\paper @{} [@var{paperidentifier}] @var{items} @code{@}}
@end example
@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
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
@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}
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
@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.
@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
@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.
PACKAGE_NAME=LilyPond
MAJOR_VERSION=1
MINOR_VERSION=3
-PATCH_LEVEL=118
-MY_PATCH_LEVEL=jcn3
+PATCH_LEVEL=119
+MY_PATCH_LEVEL=
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
\header{
-texidoc="
-The number of stafflines of a staff can be set with the property
-numberOfStaffLines. Ledger lines both on note heads and rests are
-adjusted. Barlines also are adjusted.
-";
+
+texidoc=" The number of stafflines of a staff can be set. Ledger
+lines both on note heads and rests are adjusted. Barlines also are
+adjusted. ";
+
}
\score {
- \context Voice \notes\relative c {
-
- c' c c c | g' g g g \property Staff . numberOfStaffLines = 3
-
+\context Voice \notes\relative c {
+ c' c c c | g' g g g
}
- \paper { }
+ \paper {
+
+\translator { \StaffContext
+StaffSymbol \override #'line-count = #3
+} }
\midi { }
}
if (verbose_global_b)
progress_indication ("[" + path);
val = read_afm_file (path);
-
+ unsmob_metrics (val)->path_ = path;
+
unsmob_metrics (val)->description_ = gh_cons (name_str, gh_double2scm (1.0));
if (verbose_global_b)
if (tfm->info_.checksum != afm->checksum_)
{
String s = _f ("checksum mismatch for font file: `%s'", path.ch_C ());
- s+= "\n";
+ s += _f ("does not match: `%s'", tfm->path_.ch_C()); // FIXME
+ s += "\n";
s += " TFM: " + to_str ((int) tfm->info_.checksum);
s += " AFM: " + to_str ((int) afm->checksum_);
s += "\n";
if (path.empty_b())
return 0;
+
if (verbose_global_b)
progress_indication ("[" + path);
val = Tex_font_metric::make_tfm (path);
+
if (verbose_global_b)
progress_indication ("]");
+ unsmob_metrics (val)->path_ = path;
unsmob_metrics (val)->description_ = gh_cons (name_str, gh_double2scm (1.0));
tfm_p_dict_->set (sname, val);
smobify_self ();
}
-Font_metric::Font_metric (Font_metric const &)
+Font_metric::Font_metric (Font_metric const &s)
{
}
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);
/*
#include "lily-guile.hh"
#include "smobs.hh"
#include "lily-proto.hh"
+#include "string.hh"
struct Font_metric
{
public:
SCM description_;
-
+ String path_;
virtual Box get_char (int ascii) const;
virtual Box text_dimension (String) const;
virtual Molecule find_by_name (String) const;
Tfm_header header_;
Array<Tex_font_char_metric> char_metrics_;
Array<int> ascii_to_metric_idx_;
+
+ String path_;
private:
Tex_font_metric ();
};
$$->set_spot (THIS->here_input ());
}
| score_body lilypond_header {
- scm_unprotect_object ( $1->self_scm ());
+ scm_unprotect_object ($2->self_scm ());
$$->header_p_ = $2;
}
| score_body output_def {
SCM s = $$;
SCM c = gh_cons ($2->self_scm (), SCM_EOL);
scm_unprotect_object ($2->self_scm ()); /* UGH */
-
-
if (gh_pair_p (gh_cdr (s)))
gh_set_cdr_x (gh_cdr (s), c); /* append */
else
*/
if (val != SCM_EOL)
{ // not the right type: error message.
+ SCM errport = scm_current_error_port ();
SCM typefunc = scm_eval2 (ly_symbol2scm ("type-name"), SCM_EOL);
SCM type_name = gh_call1 (typefunc, type_p);
+#if 0
warning (_f ("Wrong type for property: %s, type: %s, value found: %s, type: %s",
ly_symbol2string (prop_sym).ch_C (),
ly_scm2string (type_name).ch_C (),
ly_scm2string (ly_write2scm (val)).ch_C (),
ly_scm2string (ly_type (val)).ch_C ()));
+#endif
+ scm_puts ("\n", errport);
}
}
}
: Input (s)
{
music_ = SCM_EOL;
-
+ header_p_ = 0;
smobify_self ();
Music * m =unsmob_music (s.music_);
music_ = m?m->clone()->self_scm () : SCM_EOL;
+ scm_unprotect_object (music_);
for (int i=0; i < s.def_p_arr_.size (); i++)
def_p_arr_.push(s.def_p_arr_[i]->clone());
errorlevel_i_ = s.errorlevel_i_;
- header_p_ = (s.header_p_) ? new Scheme_hash_table (*s.header_p_): 0;
+ if (s.header_p_)
+ {
+ header_p_ = (s.header_p_) ? new Scheme_hash_table (*s.header_p_): 0;
+
+ scm_unprotect_object(header_p_->self_scm ());
+ }
+
}
Score::~Score()
&& gh_procedure_p (type_p)
&& gh_call1 (type_p, val) == SCM_BOOL_F)
{
+ SCM errport = scm_current_error_port ();
ok = false;
SCM typefunc = scm_eval2 (ly_symbol2scm ("type-name"), SCM_EOL);
SCM type_name = gh_call1 (typefunc, type_p);
- warning (_f ("Failed typecheck for `%s', value `%s' must be of type `%s'",
- ly_symbol2string (sym).ch_C (),
- ly_scm2string (ly_write2scm( val)).ch_C (),
- ly_scm2string (type_name).ch_C ()));
+
+ scm_puts (_f ("Failed typecheck for `%s', value `%s' must be of type `%s'",
+ ly_symbol2string (sym).ch_C (),
+ ly_scm2string (ly_write2scm( val)).ch_C (),
+ ly_scm2string (type_name).ch_C ()).ch_C (),
+ errport);
+ scm_puts ("\n", errport);
}
}
return ok;
Begin3
Title: LilyPond
-Version: 1.3.118
-Entered-date: 17DEC00
+Version: 1.3.119
+Entered-date: 20DEC00
Description:
Keywords: music notation typesetting midi fonts engraving
Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
janneke@gnu.org (Jan Nieuwenhuizen)
Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
- 1000k lilypond-1.3.118.tar.gz
+ 1000k lilypond-1.3.119.tar.gz
Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
- 1000k lilypond-1.3.118.tar.gz
+ 1000k lilypond-1.3.119.tar.gz
Copying-policy: GPL
End
%define info yes
Name: lilypond
-Version: 1.3.118
+Version: 1.3.119
Release: 1
License: GPL
Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.118.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.119.tar.gz
Summary: A program for printing sheet music.
URL: http://www.cs.uu.nl/~hanwen/lilypond
# Icon: lilypond-icon.gif
msgid ""
"Can't find property type-check for `%s'. Perhaps you made a typing error?"
msgstr ""
-"Kan geen type-controle vinden voor property `%s'. Misschien een tiepfout?"
+"Kan geen type-controle vinden voor property `%s'. Misschien een tikfout?"
#. warning () ?
#: translator-group.cc:420
(translator-property-description 'voltaSpannerDuration moment? "maximum duration of the volta bracket.
Set to a duration to control the size of the brackets printed by
-@code{\alternative}. It specifies the number of whole notes duration
+@code{\\alternative}. It specifies the number of whole notes duration
to use for the brackets. This can be used to shrink the length of
brackets in the situation where one alternative is very large. It may
have odd effects if the specified duration is longer than the music
-given in an @code{\alternative}.
+given in an @code{\\alternative}.
")
(translator-property-description 'weAreGraceContext boolean? "")
(translator-property-description 'whichBar string? "This property is read to determine what type of barline to create.
for c in chunks:
if c[0] == 'lilypond' and 'eps' in c[2]:
body = re.sub (r"""\\lilypondepswidth{(.*?)}""", find_eps_dims, c[1])
- newchunks.append(('lilypond', body, c[2], c[3], c[4]))
- else:
- newchunks.append (c)
+ # why do we junk opts, todo, basename?
+ new_chunk = (('lilypond', body))
+ newchunks.append (c)
return newchunks