From 1b5902741e95c7685a817246c42c225f8ed8392e Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 23 Apr 2003 23:17:17 +0000 Subject: [PATCH] more updates. --- ChangeLog | 4 + Documentation/topdocs/AUTHORS.texi | 6 +- Documentation/user/internals.itely | 252 ++++++++++++------------- Documentation/user/invoking.itexi | 4 +- Documentation/user/music-glossary.tely | 1 - Documentation/user/refman.itely | 71 ++++--- input/test/duration-check.ly | 10 + lily/music.cc | 5 +- 8 files changed, 193 insertions(+), 160 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1e3882a27..860bc06dc5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-04-24 Han-Wen Nienhuys + + * Documentation/user/internals.itely: more updates. + 2003-04-23 Han-Wen Nienhuys * Documentation/user/refman.itely: revise diff --git a/Documentation/topdocs/AUTHORS.texi b/Documentation/topdocs/AUTHORS.texi index d379e0c6f7..a911ba18cc 100644 --- a/Documentation/topdocs/AUTHORS.texi +++ b/Documentation/topdocs/AUTHORS.texi @@ -33,6 +33,8 @@ list is alphabetically ordered. @TeX{} titling and lytodvi.sh @item @email{foka@@debian.org, Anthony Fok}, Debian package: debian/* +@item David Gonz@'alez + Spanish glossary translations. @item @email{jlhamm@@pacificnet.net, James Hammons}, American chord names, gnu-windows testing @item @email{bjoern.jacke@@gmx.de, Bjoern Jacke} @@ -78,7 +80,9 @@ list is alphabetically ordered. @item @email{reuter@@ipd.uka.de, Juergen Reuter} Ancient notation support (custos, porrectus, mensural notation, ancient clefs, etc.) -@item @email{august@@infran.ru, August S.Sigov} + + + @item @email{august@@infran.ru, August S.Sigov} Russian translation @item @email{rune@@zedeler.dk, Rune Zedeler} Drum notation, beaming and auto-accidental code. Font diff --git a/Documentation/user/internals.itely b/Documentation/user/internals.itely index b198514e9b..00254c999f 100644 --- a/Documentation/user/internals.itely +++ b/Documentation/user/internals.itely @@ -21,7 +21,6 @@ the embedded Scheme interpreter. * Interpretation context:: * Scheme integration:: * Music storage format:: -* Syntactic details:: * Lexical details:: * Output details:: @end menu @@ -531,7 +530,7 @@ not yet user-accessible. Many functions are defined to manipulate these data structures. They are all listed and documented in @internalsref{All scheme functions}. -@c . {Assignments} + @node Assignments @subsection Assignments @cindex Assignments @@ -581,6 +580,7 @@ first item in a block. @menu * Music expressions:: +* Internal music representation:: * Manipulating music expressions:: @end menu @@ -657,163 +657,153 @@ Other compound music expressions include \times @var{fraction} @var{expr} @end example +@node Internal music representation +@subsection Internal music representation + + + + + -@c . {Manipulating music expressions} @node Manipulating music expressions @subsection Manipulating music expressions -The @code{\apply} mechanism gives you access to the internal -representation of music. You can write Scheme-functions that operate -directly on it. The syntax is +When a music expression is parsed, it is converted into a set of +Scheme music objects. The defining property of a music object is that +it takes up time. Time is a rational number that measures the length +of a piece of music, in whole notes. + +A music object has three kinds of types +@itemize @bullet +@item + Music name: each music expression has a name, for example, a note +leads to a @internalsref{NoteEvent}, and @code{\simultaneous} leads to +a @internalsref{SimultaneousMusic}. A list of all expressions +available is in the internals manual, under @internalsref{Music +expressions}. + +@item + Each music name has several `types' or interface. For example, a + note is an @code{event}, but it is also a @code{note-event}, a + @code{rhythmic-event} and a @code{melodic-event}. + + All classes of music are listed in the internals manual, under + @internalsref{Music classes}. +@item +Each music object is represented by a C++ object. may be represented +by different C++ classes. For technical reasons, different music +objects may be represented by different C++ object types. For example, +a note is @code{Event} object, while @code{\grace} creates a +@code{Grace_music} object. + + The distinctions between different C++ types will disappear in the +future. +@end itemize +The actual information of a music expression is stored in properties. +For example, a @internalsref{NoteEvent} has @code{pitch} and +@code{duration} properties that store the pitch and duration of that +note. A list of all properties available is in the internals manual, +under @internalsref{Music properties}. + +A compound music expresssion is a music object that contains other +music objects in its properties. A list of objects can be stored in +the @code{elements} property of a music object, or a single `child' +music object is stored in the @code{element} object. For example, +@internalsref{SequentialMusic} has its children in @code{elements}, +and @internalsref{GraceMusic} has its single argument in +@code{element}. The body of a repeat is in @code{element} property of +@internalsref{RepeatedMusic}, and the alternatives in @code{elements}. + +These properties and objects can be directly accessed and manipulated, +through the @code{\apply} mechanism. Scheme functions can read and +write properties using the functions @code{ly:get-music-property} and +@code{ly:set-music-property!}. + +The syntax for @code{\apply} @example \apply #@var{func} @var{music} @end example @noindent -This means that @var{func} is applied to @var{music}. The function -@var{func} should return a music expression. +This means that the scheme function @var{func} is called with +@var{music} as its argument. The return value of @var{func} is the +result of the entire expresssion. -This example replaces the text string of a script. It also shows a dump -of the music it processes, which is useful if you want to know more -about how music is stored. - -@lilypond[verbatim,singleline] -#(define (testfunc x) - (if (equal? (ly:get-mus-property x 'text) (make-simple-markup "foo")) - (ly:set-mus-property! x 'text (make-simple-markup "bar"))) - ;; recurse - (ly:set-mus-property! x 'elements - (map testfunc (ly:get-mus-property x 'elements))) - (display x) - x) +An example is a function that reverses the order of elements in +its argument: +@example + #(define (rev-music-1 m) + (ly:set-music-property! 'elements (reverse + (ly:get-music-property mus 'elements))) + ) + \apply #rev-music-1 @{ c4 d4 @} +@end example -\score { - \notes - \apply #testfunc { c'4_"foo" } -} -@end lilypond +The use of such a function is very limited. The effect of this +function is void, when it is applied to an argument which is does not +have multiple children, for example -A final example is a function that reverses a piece of music in time: +@example + \apply #rev-music-1 \grace @{ c4 d4 @} +@end example -@lilypond[verbatim,singleline] +@noindent +does not do anything: @code{\grace} is stored as +@internalsref{GraceMusic}, which has no @code{elements}, only a single +@code{element}. Every generally applicable function for @code{\apply} +must --like music expressions themselves-- be recursive. + +The following example is such a recursive function: it first extracts +the @code{elements} of an expression, reverses them and puts them +back. Then it recurses, both on @code{elements} and @code{element}. +@example #(define (reverse-music music) (let* ((elements (ly:get-mus-property music 'elements)) - (reversed (reverse elements)) - (span-dir (ly:get-mus-property music 'span-direction))) + (child (ly:get-mus-property music 'element)) + (reversed (reverse elements))) + + ; set children (ly:set-mus-property! music 'elements reversed) - (if (ly:dir? span-dir) - (ly:set-mus-property! music 'span-direction (- span-dir))) + + ; recurse + (if (ly:music? child) (reverse-music child)) (map reverse-music reversed) + music)) +@end example -music = \notes { c'4 d'4( e'4 f'4 } - -\score { - \context Voice { - \music - \apply #reverse-music \music - } -} -@end lilypond - -@seealso - -More examples are given in the distributed example files in -@code{input/test/}. - - -@refbugs - -Directly accessing internal representations is dangerous: The -implementation is subject to changes, so you should avoid this feature -if possible. - - -@node Syntactic details -@section Syntactic details -@cindex Syntactic details - -This section describes details that were too boring to be put elsewhere. - -@menu -* Lexical modes:: -* Ambiguities:: -@end menu - - -@c . {Lexical modes} -@node Lexical modes -@subsection Lexical modes -@cindex Lexical modes -@cindex input mode -@cindex mode, input -@cindex @code{\notes} -@cindex @code{\chords} -@cindex @code{\lyrics} - -To simplify entering notes, lyrics, and chords, LilyPond has three -special input modes in addition to the default mode: note, lyrics, and -chords mode. These input modes change the way that normal, unquoted -words are interpreted: For example, the word @code{cis} may be -interpreted as a C-sharp, as a lyric syllable `cis' or as a C-sharp -major triad respectively. - -A mode switch is entered as a compound music expression +A slightly more elaborate example is in +@inputfileref{input/test,reverse-music.ly}. +Some of the input syntax is also implemented as recursive music +functions. For example, the syntax for polyphony @example -@code{\notes} @var{musicexpr} -@code{\chords} @var{musicexpr} -@code{\lyrics} @var{musicexpr} -@code{\figures} @var{musicexpr} -@code{\markup} @var{markupexpr} + < a \\ b> @end example @noindent -In each of these cases, these expressions do not add anything to the -meaning of their arguments. They just instruct the parser in what mode -to parse their arguments. - -Different input modes for music expressions may be nested. - - -@c . {Ambiguities} -@node Ambiguities -@subsection Ambiguities -@cindex ambiguities -@cindex grammar - -The grammar contains two ambiguities. - -@itemize @bullet -@item The assignment - -@example -foo = bar -@end example - -@noindent -is interpreted as the string identifier assignment. However, -it can also be interpreted as making a string identifier @code{\foo} -containing @code{"bar"}, or a music identifier @code{\foo} containing -the syllable `bar'. The former interpretation is chosen. - -@item If you do a nested repeat like +is actually implemented as a recursive function that replaces the +above by the internal equivalent of +@example + < \context Voice = "1" @{ \voiceOne a @} + \context Voice = "2" @{ \voiceTwo a @} > +@end example -@example -\repeat @dots{} -\repeat @dots{} -\alternative -@end example +Other applications of @code{\apply} are writing out repeats +automatically (@inputfileref{input/test,unfold-all-repeats.ly}), +saving keystrokes (@inputfileref{input/test,music-box.ly}) and +exporting +LilyPond input to other formats (@inputfileref{input/test,to-xml.ly}) -@noindent -then it is ambiguous to which @code{\repeat} the -@code{\alternative} belongs. This is the classic if-then-else -dilemma. It may be solved by using braces. -@end itemize +@seealso +@file{scm/music-functions.scm}, @file{scm/music-types.scm}, +@inputfileref{input/test,add-staccato.ly}, +@inputfileref{input/test,duration-check.ly}. +@inputfileref{input/test,unfold-all-repeats.ly}, +@inputfileref{input/test,music-box.ly}. -@c . {Lexical details} @node Lexical details @section Lexical details @@ -833,7 +823,7 @@ that contains no spaces can be written without the quotes. Strings can be concatenated with the @code{+} operator. -@c . {Output details} + @node Output details @section Output details diff --git a/Documentation/user/invoking.itexi b/Documentation/user/invoking.itexi index 13dec9da45..01eadcd672 100644 --- a/Documentation/user/invoking.itexi +++ b/Documentation/user/invoking.itexi @@ -470,8 +470,8 @@ generate titling. An example demonstrating all these fields is in Name of the arranger, right flushed below the opus. @item instrument Name of the instrument, centered below the arranger -@item dedication - [docme] +@item dedication + To whom the piece is dedicated. @item piece Name of the piece, left flushed below the instrument @item head diff --git a/Documentation/user/music-glossary.tely b/Documentation/user/music-glossary.tely index 45a4b1ff73..a0c4541fca 100644 --- a/Documentation/user/music-glossary.tely +++ b/Documentation/user/music-glossary.tely @@ -14,7 +14,6 @@ PostScript} and @uref{music-glossary.pdf,PDF}. @titlepage @title Music Glossary @author Christian Mondrup -@author spanish by David Gonz@'alez @c License PD, BSD-ish, GNU GPL, GNU FDL? Copyright @copyright{} 1999--2002 by the authors diff --git a/Documentation/user/refman.itely b/Documentation/user/refman.itely index 631fbbe915..938e564a5f 100644 --- a/Documentation/user/refman.itely +++ b/Documentation/user/refman.itely @@ -16,11 +16,11 @@ This document describes GNU LilyPond and its input format. The last -revision of this document was made for LilyPond 1.7.10. It assumes -that you already know a little bit about LilyPond input (how to -make an input file, how to create sheet music from that input file, -etc). New users are encouraged to study the tutorial before reading -this manual. +revision of this document was made for LilyPond 1.7.11. It assumes +that you already know a little bit about LilyPond input (how to make +an input file, how to create sheet music from that input file, etc). +New users are encouraged to study the tutorial before reading this +manual. @menu * Note entry:: @@ -939,11 +939,7 @@ You are encouraged to use @code{\repeat} for repetitions. See @seealso -@ref{Repeats}, @internalsref{RepeatedMusic}, -@internalsref{VoltaRepeatedMusic}, -@internalsref{UnfoldedRepeatedMusic} -@internalsref{TremoloRepeteadMusic}, -@internalsref{FoldedRepeatedMusic}. +@ref{Repeats}. The bar line objects that are created at @internalsref{Staff} level @@ -2175,18 +2171,6 @@ With alternative endings: \alternative { {d'2 d'} {f' f} } @end lilypond -@ignore -Folded repeats look like this: - - -@li lypond[fragment,verbatim] - c'1 - \repeat fold 2 {c'4 d' e' f'} - \alternative { {d'2 d'} {f' f} } - -@end lilypond -@end ignore - @lilypond[fragment,verbatim] \context Staff { @@ -2198,6 +2182,23 @@ Folded repeats look like this: } @end lilypond +@refbugs + + If you do a nested repeat like + +@example +\repeat @dots{} +\repeat @dots{} +\alternative +@end example + +@noindent +then it is ambiguous to which @code{\repeat} the @code{\alternative} +belongs. This ambiguity is resolved by always having the +@code{\alternative} belong to the inner @code{\repeat}. This +ambiguity may also be resolved by using braces. +@cindex ambiguity + @node Repeats and MIDI @subsection Repeats and MIDI @@ -2249,7 +2250,10 @@ alphabetic characters. @seealso -@internalsref{VoltaBracket} +@internalsref{VoltaBracket}, @internalsref{RepeatedMusic}, +@internalsref{VoltaRepeatedMusic}, +@internalsref{UnfoldedRepeatedMusic} +@internalsref{FoldedRepeatedMusic}. @node Tremolo repeats @subsection Tremolo repeats @@ -2907,6 +2911,27 @@ lyrics. This can confuse the LilyPond -- for example, this might put (empty) lyrics under rests. To remedy this, use @code{\skip}. +@refbugs + +@cindex ambiguity + +Input for lyrics introduces a syntactical ambiguity: + +@example +foo = bar +@end example + +@noindent +is interpreted as the string identifier assignment. However, +it can also be interpreted as making a string identifier @code{\foo} +containing @code{"bar"}, or a music identifier @code{\foo} containing +the syllable `bar'. The former interpretation is chosen. The latter +can be specified using +@example + foo = \lyrics bar +@end example + + @menu * Ambitus:: @end menu diff --git a/input/test/duration-check.ly b/input/test/duration-check.ly index 20f19c727e..3079d6c6d6 100644 --- a/input/test/duration-check.ly +++ b/input/test/duration-check.ly @@ -1,4 +1,14 @@ \version "1.7.16" +\header { + + texidoc = "Check whether all @code{duration} properties can +be printed. This once helped track down an obscure memory corruption +bug. " + +} + + + #(define (duration-check music) "Check all rest durations in MUSIC" diff --git a/lily/music.cc b/lily/music.cc index 085af801d3..1866be33f4 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -65,7 +65,6 @@ Music::compress (Moment) { } - Music::Music (Music const &m) { immutable_property_alist_ = m.immutable_property_alist_; @@ -244,7 +243,9 @@ LY_DEFINE(ly_get_music_length, LY_DEFINE(ly_get_mus_property, "ly:get-mus-property", 2, 0, 0, (SCM mus, SCM sym), - "Get the property @var{sym} of music expression @var{mus}.") + "Get the property @var{sym} of music expression @var{mus}.\n" + "If @var{sym} is undefined, return @code{'()}.\n" + ) { Music * sc = unsmob_music (mus); SCM_ASSERT_TYPE(sc, mus, SCM_ARG1, __FUNCTION__, "music"); -- 2.39.5