PostScript is used to generate graphical output. A brief PostScript tutorial
is @uref{http://local.wasp.uwa.edu.au/~pbourke/dataformats/postscript/,
available online}. The
-@uref{http://www.adobe.com/devnet/postscript/pdfs/PLRM.pdf, PostScript Language
+@uref{http://www.adobe.com/products/postscript/pdfs/PLRM.pdf, PostScript Language
Reference} is available online in PDF format.
@subsection Python
(ps), grobs (pgrob), and parsed music expressions (pmusic).
@example
-file lily/out/lilypond
+file $LILYPOND_GIT/build/out/bin/lilypond
b programming_error
b Grob::programming_error
short, single-issue regression tests are preferred to a single, long,
multiple-issue regression test.
+If the change in the output is small or easy to overlook, use bigger
+staff size -- 40 or more (up to 100 in extreme cases). Size 30 means
+"pay extra attention to details in general".
+
Use existing regression tests as templates to demonstrate the type of
header information that should be included in a regression test.
can write relevant material for inclusion in the Notation
Reference. If the developer does not feel qualified to write
the documentation, a documentation editor will be able to
-write it from the regression tests. The text that is added to
-or removed from the documentation should be changed only in
-the English version.
+write it from the regression tests. In this case the developer
+should raise a new issue with the Type=Documentation tag containing
+a reference to the original issue number and/or the committish of
+the pushed patch so that the need for new documention is not
+overlooked.
+
+Any text that is added to or removed from the documentation should
+be changed only in the English version.
@node Edit changes.tely
considered to function successfully.
Developers on Windows who are unable to build LilyPond should
-get help from a Linux or OSX developer to do the make tests.
+get help from a GNU/Linux or OSX developer to do the make tests.
@node Verify regression tests
@subheading Typical developer's edit/compile/test cycle
-TODO: is @code{[-j@var{X} CPU_COUNT=@var{X}]} useful for
-@code{test-baseline}, @code{check}, @code{clean},
-@code{test-redo}? Neil Puttock says it is useful for
-everything but @code{clean}, which is disk-limited.
-Need to check formally.
-
@itemize
@item
Initial test:
@example
make [-j@var{X}]
-make test-baseline
+make [-j@var{X} CPU_COUNT=@var{X}] test-baseline
make [-j@var{X} CPU_COUNT=@var{X}] check
@end example
@example
@emph{## edit source files, then...}
-make clean @emph{## only if needed (see below)}
-make [-j@var{X}] @emph{## only if needed (see below)}
-make test-redo @emph{## redo files differing from baseline}
-make [-j@var{X} CPU_COUNT=@var{X}] check @emph{## CPU_COUNT here?}
+make clean @emph{## only if needed (see below)}
+make [-j@var{X}] @emph{## only if needed (see below)}
+make [-j@var{X} CPU_COUNT=@var{X}] test-redo @emph{## redo files differing from baseline}
+make [-j@var{X} CPU_COUNT=@var{X}] check
@end example
@item
like those in the @file{scm/} and @file{ly/} directories, then
@command{make} is not needed before @command{make test-redo}.
-TODO: Fix the following paragraph. You can do @command{rm mf/out/*}
-instead of make clean, and you can probably do
-@command{make -C mf/ clean} as well, but I haven't checked it -- cds
-
Also, if you modify any font definitions in the @file{mf/}
directory then you must run @command{make clean} and
@command{make} before running @command{make test-redo}. This will
important differences that your change introduced, whether in the
layout, MIDI, performance or error reporting.
+You only need to use @command{make test-clean} to start from
+scratch, prior to running @command{make@tie{}test-baseline}. To
+check new modifications, all that is needed is to repeat
+@command{make@tie{}test-redo} and @command{make@tie{}test-check}
+(not forgetting @command{make} if needed).
+
during line breaking, for example, when we want to estimate the Y-extent
of a spanner broken at given starting and ending columns.
-If the pure function you're writing takes more than three arguments
-(say, for example, a chained offset callback), this is not a problem:
-just make sure that the grob is the first argument and that start and
-end are the last two arguments.
-
@node How purity is defined and stored
@subsection How purity is defined and stored
-Purity can currently be defined two different ways in LilyPond that
-correspond to two types of scenarios. In one scenario, we know that a
-callback is pure, but we are not necessarily certain what properties
-will use this callback. In another, we want a property to be pure, but
-we don't want to guarantee that its callback function will be pure in
-all circumstances.
-
-In the first scenario, we register the callback in define-grobs.scm in
-one of four places depending on what the function does.
-
-@itemize
-@item @code{pure-print-functions}: If finding a print function's vertical
-extent does not have any @q{side effects} we register it here. We then
-don't have to set the pure Y-extent property, which will be taken from the
-stencil.
-
-@item @code{pure-print-to-height-conversions}: If a stencil can
-eventually be used to glean a grob's Y-extent but is not pure (meaning
-it will have a different height at different stages of the compilation
-process), we add it to this list along with a function for the pure
-Y-extent.
-
-@item @code{pure-conversions-alist}: This list contains pairs of
-functions and their pure equivalents. It is onto but not one-to-one.
-
-@item @code{pure-functions}: Like pure-print-functions in that they work
-for both pure and impure values, but they do not return a stencil.
-@end itemize
-
-At all stages of the compilation process, when LilyPond wants the pure
-version of a property, it will consult these lists and see if it can get
-this property for a given Grob. Note that you do @emph{not} need to
-register the pure property in the grob itself. For example, there is no
-property @q{pure-Y-extent}. Rather, by registering these functions as
-defined above, every time LilyPond needs a pure property, it will check
-to see if a Grob contains one of these functions and, if so, will use
-its value. If LilyPond cannot get a pure function, it will return a
-value of @code{##f} for the property.
-
-LilyPond is smart enough to know if a series of chained functions are
-pure. For example, if a Y-offset property has four chained functions
-and all of them have pure equivalents, LilyPond will read the four pure
-equivalents when calculating the pure property. However, if even one is
-impure, LilyPond will not return a pure property for the offset (instead
-returning something like @code{#f} or @code{'()}) and will likely wreak
-havoc on your score.
-
-In the second scenario, we create an unpure-pure-container (unpure is
-not a word, but hey, neither was Lilypond until the 90s). For example:
+Purity is defined in LilyPond with the creation of an unpure-pure container
+(unpure is not a word, but hey, neither was Lilypond until the 90s). For example:
@example
#(define (foo grob)
\override Stem #'length = #(ly:make-unpure-pure-container foo bar)
@end example
-This is useful if we want to:
-
-@itemize
-@item create overrides that have pure alternatives (should not be used
-in development, but useful for users)
-
-@item use return values that are not functions (i.e. pairs or booleans)
-for either pure or unpure values.
-
-@item allow a function to be considered pure in a limited amount of
-circumstances. This is useful if we are sure that, when associated with
-one grob a function will be pure but not necessarily with another grob
-that has different callbacks.
-@end itemize
-
-Items can only ever have two pure heights: their actual pure height if
-they are between @q{start} and @q{end}, or an empty interval if they are
+Note that items can only ever have two pure heights: their actual pure height
+if they are between @q{start} and @q{end}, or an empty interval if they are
not. Thus, their pure property is cached to speed LilyPond up. Pure
heights for spanners are generally not cached as they change depending
on the start and end values. They are only cached in certain particular
often than not, the code checks Lilypond specific C++-implemented
types using
-@subsubheading [type *] unsmob_[type] (SCM s)
+@subsubheading [Type *] Type::unsmob (SCM s)
This tries converting a Scheme object to a pointer of the desired
kind. If the Scheme object is of the wrong type, a pointer value
A C(++) object that is encapsulated so it can be used as a Scheme
object. See GUILE info, "19.3 Defining New Types (Smobs)"
-@@subheading When is each C++ class constructed and used
+@subheading When is each C++ class constructed and used?
@itemize