]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' into lilypond/translation
authorFrancisco Vila <francisco.vila@hispalinux.es>
Wed, 1 Feb 2012 14:37:48 +0000 (15:37 +0100)
committerFrancisco Vila <francisco.vila@hispalinux.es>
Wed, 1 Feb 2012 14:37:48 +0000 (15:37 +0100)
44 files changed:
Documentation/changes.tely
Documentation/extending/programming-interface.itely
Documentation/extending/scheme-tutorial.itely
Documentation/hu/macros.itexi
Documentation/included/authors.itexi
Documentation/learning/tweaks.itely
Documentation/music-glossary.tely
Documentation/notation/rhythms.itely
Documentation/po/cs.po
Documentation/po/de.po
Documentation/snippets/new/strict-beat-beaming.ly [new file with mode: 0644]
Documentation/snippets/strict-beat-beaming.ly [new file with mode: 0644]
configure.in
input/regression/beamlet-point-toward-beat.ly
input/regression/display-lily-tests.ly
input/regression/tablature-open-string-chord.ly [new file with mode: 0644]
lily/beaming-pattern.cc
lily/include/beaming-pattern.hh
lily/include/lily-proto.hh
lily/include/rhythmic-music-iterator.hh [new file with mode: 0644]
lily/music-scheme.cc
lily/music.cc
lily/parser.yy
lily/rhythmic-music-iterator.cc [new file with mode: 0644]
ly/declarations-init.ly
ly/music-functions-init.ly
python/GNUmakefile
python/book_texinfo.py
python/convertrules.py
scm/define-context-properties.scm
scm/define-music-display-methods.scm
scm/define-music-types.scm
scm/lily.scm
scm/modal-transforms.scm
scm/music-functions.scm
scm/output-lib.scm
scm/song-util.scm
scm/song.scm
scm/translation-functions.scm
scripts/abc2ly.py
scripts/build/help2man.pl
tex/texinfo.tex
tex/txi-de.tex
tex/txi-hu.tex

index 50f2022cb29c087161107d3d1c074a52f692e37e..8281811608c63ac3b6cf840898e44f43e5c0b298 100644 (file)
@@ -61,6 +61,13 @@ which scares away people.
 
 @end ignore
 
+@item
+Flags are now treated as separate objects rather than as stem parts.
+@lilypond[fragment,quote,relative=2]
+\override Flag #'color = #red
+g8
+@end lilypond
+
 @item
 Two alternative methods for bar numbering can be set, especially for
 when using repeated music;
@@ -86,6 +93,31 @@ when using repeated music;
 }
 @end lilypond
 
+@item
+The following is a fundamental change in LilyPond's music
+representation: Rhythmic events like @code{LyricEvent} and
+@code{NoteEvent} are no longer wrapped in @code{EventChord} unless they
+have been actually entered as part of a chord in the input.  If you
+manipulate music expressions in Scheme, the new behavior may require
+changes in your code.  The advantages of making input and music match
+more closely are numerous: music functions previously worked differently
+when used inside or outside of chords.  Now they are the same, including
+all the possibilities of argument parsing.  You can now use music
+variables inside of chords: a construct like
+@lilypond[quote,ragged-right]
+tonic=fis'
+{ <\tonic \transpose c g \tonic> }
+@end lilypond
+@noindent
+would have been unthinkable previously.  You can use
+@code{#@{@dots{}#@}} for constructing chord constituents.  Music
+functions inside of chords are no longer specially treated and thus
+accept the same arguments as outside of chords.  @code{\tweak} now works
+on single notes without needing to wrap them in a chord.  String number
+indications like @code{\1} can be used on single notes.  If you need to
+suppress them in some context, override their @code{stencil} with
+@code{##f}.
+
 @item
 Scheme expressions inside of embedded Lilypond (@code{#@{@dots{}#@}})
 are now executed in lexical closure of the surrounding Scheme code.
@@ -210,7 +242,7 @@ c4_\< c c^\> c c1_\p
 @item
 Appoggiaturas and acciaccaturas now also work inside a slur, not only inside
 a phrasing slur. Also, a function @code{\slashedGrace} was added that does
-does not use a slur from the acciaccatura note.
+not use a slur from the acciaccatura note.
 @lilypond[fragment,quote,relative=2]
 c4( \appoggiatura e8 d4 \acciaccatura e8 d4 \slashedGrace e8 c4)
 @end lilypond
index 518f11b3eacd7843762fa05a99725d1c0fd2ba08..46d7fd512fa08490edcbfe5b993aa960a07c49ad 100644 (file)
@@ -123,8 +123,8 @@ arg2)}}).  Where normal Scheme expressions using @code{#} don't do the
 trick, you might need to revert to immediate Scheme expressions using
 @code{$}, for example as @samp{$music}.
 
-If your function returns a music expression, it is cloned and given the
-correct @code{origin}.
+If your function returns a music expression, it is given a useful value
+of @code{origin}.
 @end multitable
 
 @noindent
@@ -154,8 +154,9 @@ ambiguities that Lilypond sorts out by checking with predicate
 functions: is @samp{-3} a fingering postevent or a negative number?  Is
 @code{"a" 4} in lyric mode a string followed by a number, or a lyric
 event of duration @code{4}?  Lilypond decides by asking the predicates.
-That means that a lenient predicate like @code{scheme?} might be good
-for surprising interpretations.
+That means that you should avoid permissive predicates like
+@code{scheme?} if you have a particular use in mind instead of a general
+purpose function.
 
 For a list of available predefined type predicates, see
 @ruser{Predefined type predicates}.
@@ -299,33 +300,31 @@ Installed Files:
 
 @node Music function usage
 @subsection Music function usage
-Music functions may currently be used in three places.  Depending on
+Music functions may currently be used in several places.  Depending on
 where they are used, restrictions apply in order to be able to parse
 them unambiguously.  The result a music function returns must be
 compatible with the context in which it is called.
 
 @itemize
 @item
-At top level in a music expression.  There are no special restrictions
-on the argument list.
+At top level in a music expression.  No restriction apply here.
 
 @item
 As a post-event, explicitly started with a direction indicator (one of
-@code{-}, @code{^}, @w{and @code{_}}).  All trailing arguments of the
-music function with the predicate @code{ly:music?} will get parsed also
-as post-events (if the last argument is a scheme function, this will
-hold for trailing @code{ly:music?} arguments of the scheme function
-instead).  Note that returning a post-event will be acceptable for music
-functions called as normal music, leading to a result roughly equivalent
-to
+@code{-}, @code{^}, @w{and @code{_}}).  Note that returning a post-event
+will be acceptable for music functions called as normal music, leading
+to a result roughly equivalent to
 @example
 s 1*0-\fun
 @end example
 
+In this case, you can't use an @emph{open} music expression as the last
+argument, one that would end with a music expression able to accept
+additional postevents.
+
 @item
-As a chord constituent.  All trailing arguments of the music function
-with the predicate @code{ly:music?} will get parsed also as chord
-constituents.
+As a chord constituent.  The returned expression must be of
+@code{rhythmic-event} type, most likely a @code{NoteEvent}.
 @end itemize
 
 @noindent
@@ -1152,6 +1151,14 @@ my-callback = #(lambda (grob)
 @node Inline Scheme code
 @section Inline Scheme code
 
+TODO: the example for this section is ill-chosen since
+@example
+F = -\tweak #'font-size #-3 -\flageolet
+@end example
+(note the @samp{-} marking it as a post event) will actually work fine
+for the stated purpose.  Until this section gets a rewrite, let's
+pretend we don't know.
+
 The main disadvantage of @code{\tweak} is its syntactical
 inflexibility.  For example, the following produces a syntax error.
 
@@ -1164,10 +1171,6 @@ F = \tweak #'font-size #-3 -\flageolet
 @end example
 
 @noindent
-In other words, @code{\tweak} doesn't behave like an articulation
-regarding the syntax; in particular, it can't be attached with
-@code{^} and @code{_}.
-
 Using Scheme, this problem can be avoided.  The route to the
 result is given in @ref{Adding articulation to notes (example)},
 especially how to use @code{\displayMusic} as a helping guide.
index d8492d0032bfed71cef0e3090f379200899dcb95..db3f09db05aa9fac04326e3aa3760b735b1928e6 100644 (file)
@@ -889,7 +889,7 @@ while @code{twentyFour} is a variable.
 
 @subheading Offsets
 
-Two-dimensional offsets (X and Y coordinates) are stored as @code{pairs}.
+Two-dimensional offsets (X and Y coordinates) are stored as @emph{pairs}.
 The @code{car} of the offset is the X coordinate, and the @code{cdr} is
 the Y coordinate.
 
@@ -904,6 +904,16 @@ this command moves the object 1 staff space to the right, and 2 spaces up.
 
 Procedures for working with offsets are found in @file{scm/lily-library.scm}.
 
+@subheading Fractions
+
+Fractions as used by LilyPond are again stored as @emph{pairs}, this
+time of unsigned integers.  While Scheme can represent rational numbers
+as a native type, musically @samp{2/4} and @samp{1/2} are not the same,
+and we need to be able to distinguish between them.  Similarly there are
+no negative @q{fractions} in LilyPond's mind.  So @code{2/4} in LilyPond
+means @code{(2 . 4)} in Scheme, and @code{#2/4} in LilyPond means
+@code{1/2} in Scheme.
+
 @subheading Extents
 
 Pairs are also used to store intervals, which represent a range of numbers
@@ -1030,18 +1040,16 @@ will display
   'SequentialMusic
   'elements
   (list (make-music
-          'EventChord
-          'elements
+          'NoteEvent
+          'articulations
           (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 0 0))
-                (make-music
                   'AbsoluteDynamicEvent
                   'text
-                  "f")))))
+                  "f"))
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch 0 0 0))))
 @end example
 
 By default, LilyPond will print these messages to the console along
@@ -1068,20 +1076,22 @@ A bit of reformatting makes the above information easier to read:
 
 @example
 (make-music 'SequentialMusic
-  'elements (list (make-music 'EventChord
-                    'elements (list (make-music 'NoteEvent
-                                      'duration (ly:make-duration 2 0 1 1)
-                                      'pitch (ly:make-pitch 0 0 0))
-                                    (make-music 'AbsoluteDynamicEvent
-                                      'text "f")))))
+  'elements (list
+            (make-music 'NoteEvent
+               'articulations (list
+                              (make-music 'AbsoluteDynamicEvent
+                                'text
+                                "f"))
+              'duration (ly:make-duration 2 0 1 1)
+              'pitch    (ly:make-pitch 0 0 0))))
 @end example
 
 A @code{@{ ... @}} music sequence has the name @code{SequentialMusic},
 and its inner expressions are stored as a list in its @code{'elements}
-property.  A note is represented as an @code{EventChord} expression,
-containing a @code{NoteEvent} object (storing the duration and
-pitch properties) and any extra information (in this case, an
-@code{AbsoluteDynamicEvent} with a @code{"f"} text property.
+property.  A note is represented as a @code{NoteEvent} object (storing
+the duration and pitch properties) with attached information (in this
+case, an @code{AbsoluteDynamicEvent} with a @code{"f"} text property)
+stored in its @code{articulations} property.
 
 @funindex{\void}
 @code{\displayMusic} returns the music it displays, so it will get
@@ -1095,13 +1105,27 @@ TODO -- make sure we delineate between @emph{music} properties,
 @emph{context} properties, and @emph{layout} properties.  These
 are potentially confusing.
 
-The @code{NoteEvent} object is the first object of the
-@code{'elements} property of @code{someNote}.
+Let's look at an example:
 
 @example
 someNote = c'
 \displayMusic \someNote
 ===>
+(make-music
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch 0 0 0))
+@end example
+
+The @code{NoteEvent} object is the representation of @code{someNote}.
+Straightforward.  How about putting c' in a chord?
+
+@example
+someNote = <c'>
+\displayMusic \someNote
+===>
 (make-music
   'EventChord
   'elements
@@ -1113,6 +1137,9 @@ someNote = c'
           (ly:make-pitch 0 0 0))))
 @end example
 
+Now the @code{NoteEvent} object is the first object of the
+@code{'elements} property of @code{someNote}.
+
 The @code{display-scheme-music} function is the function used by
 @code{\displayMusic} to display the Scheme representation of a music
 expression.
@@ -1157,7 +1184,7 @@ d'
 @subsection Doubling a note with slurs (example)
 
 Suppose we want to create a function that translates input like
-@code{a} into @code{a( a)}.  We begin by examining the internal
+@code{a} into @code{@{ a( a) @}}.  We begin by examining the internal
 representation of the desired result.
 
 @example
@@ -1167,70 +1194,65 @@ representation of the desired result.
   'SequentialMusic
   'elements
   (list (make-music
-          'EventChord
-          'elements
+          'NoteEvent
+          'articulations
           (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))
-                (make-music
                   'SlurEvent
                   'span-direction
-                  -1)))
+                  -1))
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch 0 5 0))
         (make-music
-          'EventChord
-          'elements
+          'NoteEvent
+          'articulations
           (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))
-                (make-music
                   'SlurEvent
                   'span-direction
-                  1)))))
+                  1))
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch 0 5 0))))
 @end example
 
 The bad news is that the @code{SlurEvent} expressions
-must be added @q{inside} the note (or more precisely,
-inside the @code{EventChord} expression).
+must be added @q{inside} the note (in its @code{articulations}
+property).
 
 Now we examine the input,
 
 @example
+\displayMusic a'
+===>
 (make-music
-  'SequentialMusic
-  'elements
-  (list (make-music
-          'EventChord
-          'elements
-          (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))))))
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch 0 5 0))))
 @end example
 
-So in our function, we need to clone this expression (so that we
-have two notes to build the sequence), add a @code{SlurEvent} to the
-@code{'elements} property of each one, and finally make a
-@code{SequentialMusic} with the two @code{EventChords}.
+So in our function, we need to clone this expression (so that we have
+two notes to build the sequence), add a @code{SlurEvent} to the
+@code{'articulations} property of each one, and finally make a
+@code{SequentialMusic} with the two @code{EventChords}.  For adding to a
+property, it is useful to know that an unset property is read out as
+@code{'()}, the empty list, so no special checks are required before we
+put another element at the front of the @code{articulations} property.
 
 @example
 doubleSlur = #(define-music-function (parser location note) (ly:music?)
          "Return: @{ note ( note ) @}.
-         `note' is supposed to be an EventChord."
+         `note' is supposed to be a single note."
          (let ((note2 (ly:music-deep-copy note)))
-           (set! (ly:music-property note 'elements)
+           (set! (ly:music-property note 'articulations)
                  (cons (make-music 'SlurEvent 'span-direction -1)
-                       (ly:music-property note 'elements)))
-           (set! (ly:music-property note2 'elements)
+                       (ly:music-property note 'articulations)))
+           (set! (ly:music-property note2 'articulations)
                  (cons (make-music 'SlurEvent 'span-direction 1)
-                       (ly:music-property note2 'elements)))
+                       (ly:music-property note2 'articulations)))
            (make-music 'SequentialMusic 'elements (list note note2))))
 @end example
 
@@ -1239,9 +1261,12 @@ doubleSlur = #(define-music-function (parser location note) (ly:music?)
 @subsection Adding articulation to notes (example)
 
 The easy way to add articulation to notes is to merge two music
-expressions into one context, as explained in
-@ruser{Creating contexts}.  However, suppose that we want to write
-a music function that does this.
+expressions into one context, as explained in @ruser{Creating contexts}.
+However, suppose that we want to write a music function that does this.
+This will have the additional advantage that we can use that music
+function to add an articulation (like a fingering instruction) to a
+single note inside of a chord which is not possible if we just merge
+independent music.
 
 A @code{$variable} inside the @code{#@{...#@}} notation is like
 a regular @code{\variable} in classical LilyPond notation.  We
@@ -1268,140 +1293,147 @@ Scheme.  We begin by examining our input and desired output,
 \displayMusic c4
 ===>
 (make-music
-  'EventChord
-  'elements
-  (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch -1 0 0))))
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch -1 0 0))))
 =====
 %  desired output
 \displayMusic c4->
 ===>
 (make-music
-  'EventChord
-  'elements
+  'NoteEvent
+  'articulations
   (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch -1 0 0))
-        (make-music
           'ArticulationEvent
           'articulation-type
-          "marcato")))
+          "accent"))
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch -1 0 0))
 @end example
 
-We see that a note (@code{c4}) is represented as an @code{EventChord}
-expression, with a @code{NoteEvent} expression in its elements list.  To
-add a marcato articulation, an @code{ArticulationEvent} expression must
-be added to the elements property of the @code{EventChord}
-expression.
+We see that a note (@code{c4}) is represented as an @code{NoteEvent}
+expression.  To add an accent articulation, an @code{ArticulationEvent}
+expression must be added to the @code{articulations} property of the
+@code{NoteEvent} expression.
 
 To build this function, we begin with
 
 @example
-(define (add-marcato event-chord)
-  "Add a marcato ArticulationEvent to the elements of `event-chord',
-  which is supposed to be an EventChord expression."
-  (let ((result-event-chord (ly:music-deep-copy event-chord)))
-    (set! (ly:music-property result-event-chord 'elements)
-          (cons (make-music 'ArticulationEvent
-                  'articulation-type "marcato")
-                (ly:music-property result-event-chord 'elements)))
-    result-event-chord))
+(define (add-accent note-event)
+  "Add an accent ArticulationEvent to the articulations of `note-event',
+  which is supposed to be a NoteEvent expression."
+  (set! (ly:music-property note-event 'articulations)
+        (cons (make-music 'ArticulationEvent
+                'articulation-type "accent")
+              (ly:music-property note-event 'articulations)))
+  note-event)
 @end example
 
 The first line is the way to define a function in Scheme: the function
-name is @code{add-marcato}, and has one variable called
-@code{event-chord}.  In Scheme, the type of variable is often clear
+name is @code{add-accent}, and has one variable called
+@code{note-event}.  In Scheme, the type of variable is often clear
 from its name.  (this is good practice in other programming languages,
 too!)
 
 @example
-"Add a marcato..."
+"Add an accent..."
 @end example
 
 @noindent
 is a description of what the function does.  This is not strictly
 necessary, but just like clear variable names, it is good practice.
 
-@example
-(let ((result-event-chord (ly:music-deep-copy event-chord)))
-@end example
-
-@code{let} is used to declare local variables.  Here we use one local
-variable, named @code{result-event-chord}, to which we give the value
-@code{(ly:music-deep-copy event-chord)}.  @code{ly:music-deep-copy} is
-a function specific to LilyPond, like all functions prefixed by
-@code{ly:}.  It is use to make a copy of a music
-expression.  Here we copy @code{event-chord} (the parameter of the
-function).  Recall that our purpose is to add a marcato to an
-@code{EventChord} expression.  It is better to not modify the
-@code{EventChord} which was given as an argument, because it may be
-used elsewhere.
-
-Now we have a @code{result-event-chord}, which is a
-@code{NoteEventChord} expression and is a copy of
-@code{event-chord}.  We add the marcato to its @code{'elements}
-list property.
+You may wonder why we modify the note event directly instead of working
+on a copy (@code{ly:music-deep-copy} can be used for that).  The reason
+is a silent contract: music functions are allowed to modify their
+arguments: they are either generated from scratch (like user input) or
+are already copied (referencing a music variable with @samp{\name} or
+music from immediate Scheme expressions @samp{$(@dots{})} provides a
+copy).  Since it would be inefficient to create unnecessary copies, the
+return value from a music function is @emph{not} copied.  So to heed
+that contract, you must not use any arguments more than once, and
+returning it counts as one use.
+
+In an earlier example, we constructed music by repeating a given music
+argument.  In that case, at least one repetition had to be a copy of its
+own.  If it weren't, strange things may happen.  For example, if you use
+@code{\relative} or @code{\transpose} on the resulting music containing
+the same elements multiple times, those will be subjected to
+relativation or transposition multiple times.  If you assign them to a
+music variable, the curse is broken since referencing @samp{\name} will
+again create a copy which does not retain the identity of the repeated
+elements.
+
+Now while the above function is not a music function, it will normally
+be used within music functions.  So it makes sense to heed the same
+contract we use for music functions: the input may be modified for
+producing the output, and the caller is responsible for creating copies
+if it still needs the unchanged argument itself.  If you take a look at
+LilyPond's own functions like @code{music-map}, you'll find that they
+stick with the same principles.
+
+Where were we?  Now we have a @code{note-event} we may modify, not
+because of using @code{ly:music-deep-copy} but because of a long-winded
+explanation.  We add the accent to its @code{'articulations} list
+property.
 
 @example
 (set! place new-value)
 @end example
 
-Here, what we want to set (the @q{place}) is the @code{'elements}
-property of @code{result-event-chord} expression.
+Here, what we want to set (the @q{place}) is the @code{'articulations}
+property of @code{note-event} expression.
 
 @example
-(ly:music-property result-event-chord 'elements)
+(ly:music-property note-event 'articulations)
 @end example
 
 @code{ly:music-property} is the function used to access music properties
-(the @code{'elements}, @code{'duration}, @code{'pitch}, etc, that we
+(the @code{'articulations}, @code{'duration}, @code{'pitch}, etc, that we
 see in the @code{\displayMusic} output above).  The new value is the
-former @code{'elements} property, with an extra item: the
+former @code{'articulations} property, with an extra item: the
 @code{ArticulationEvent} expression, which we copy from the
 @code{\displayMusic} output,
 
 @example
 (cons (make-music 'ArticulationEvent
-        'articulation-type "marcato")
-      (ly:music-property result-event-chord 'elements))
+        'articulation-type "accent")
+      (ly:music-property result-event-chord 'articulations))
 @end example
 
-@code{cons} is used to add an element to a list without modifying
-the original list.  This is what we want: the same list as before,
-plus the new @code{ArticulationEvent} expression.  The order
-inside the @code{'elements} property is not important here.
+@code{cons} is used to add an element to the front of a list without
+modifying the original list.  This is what we want: the same list as
+before, plus the new @code{ArticulationEvent} expression.  The order
+inside the @code{'articulations} property is not important here.
 
-Finally, once we have added the marcato articulation to its @code{elements}
-property, we can return @code{result-event-chord}, hence the last line of
-the function.
+Finally, once we have added the accent articulation to its
+@code{articulations} property, we can return @code{note-event}, hence
+the last line of the function.
 
-Now we transform the @code{add-marcato} function into a music
-function,
+Now we transform the @code{add-accent} function into a music
+function (a matter of some syntactic sugar and a declaration of the type
+of its sole @q{real} argument).
 
 @example
-addMarcato = #(define-music-function (parser location event-chord)
+addAccent = #(define-music-function (parser location note-event)
                                      (ly:music?)
-    "Add a marcato ArticulationEvent to the elements of `event-chord',
-    which is supposed to be an EventChord expression."
-    (let ((result-event-chord (ly:music-deep-copy event-chord)))
-      (set! (ly:music-property result-event-chord 'elements)
-            (cons (make-music 'ArticulationEvent
-                    'articulation-type "marcato")
-                  (ly:music-property result-event-chord 'elements)))
-      result-event-chord))
+  "Add an accent ArticulationEvent to the articulations of `note-event',
+  which is supposed to be a NoteEvent expression."
+  (set! (ly:music-property note-event 'articulations)
+        (cons (make-music 'ArticulationEvent
+                'articulation-type "accent")
+              (ly:music-property note-event 'articulations)))
+  note-event)
 @end example
 
 We may verify that this music function works correctly,
 
 @example
-\displayMusic \addMarcato c4
+\displayMusic \addAccent c4
 @end example
 
 
index f57c34f67e126c2ce5e5d5b7c60c208156682f2a..78cf9a3fa70f6c53292483e79982112dc74d889f 100644 (file)
@@ -16,7 +16,7 @@
 MACRO DEFINITIONS GUIDELINES
 ****************************
 
-This file should contain macro defintions which are common to all
+This file should contain macro definitions which are common to all
 languages, i.e. all macro definitions which do not contain text that
 should be translated (namely text visible in the output).
 
index eb52a4b45740c307d9c06cb58b8ffb7705e7594d..041f843900dc7c9fd2f25b64e5ae975323b33693 100644 (file)
@@ -164,10 +164,13 @@ Core developer, Schemer extraordinaire
 
 @c use commas not colons
 
+Sven Axelsson,
 Karin Hoethker,
 Mark Hohl,
+Justin Ohmie,
 Julien Rioux,
 Patrick Schmidt,
+Adam Spiers,
 Heikki Taurainen,
 Piers Titus van der Torren
 
@@ -191,7 +194,10 @@ Piers Titus van der Torren
 
 @c use commas not colons
 
-James Lowe
+James Lowe,
+Pavel Roskin,
+Alberto Simoes,
+Stefan Weil
 
 @c no comma for last entry
 
index 753f00a68599e54cef2d58c599bbd2d5b736b56a..361b14b3e80822ba72c287a77aab0c827f59a236 100644 (file)
@@ -319,11 +319,11 @@ We mention it here for completeness, but for details see
 @funindex \tweak
 @funindex tweak
 
-The final tweaking command which is available is @code{\tweak}.
-This should be used to change the properties of objects which
-occur at the same musical moment, such as the notes within a
-chord.  Using @code{\override} would affect all the notes
-within a chord, whereas @code{\tweak} affects just the following
+The final tweaking command which is available is @code{\tweak}.  This
+should be used when several objects occur at the same musical moment,
+but you only want to change the properties of selected ones, such as a
+single note within a chord.  Using @code{\override} would affect all the
+notes within a chord, whereas @code{\tweak} affects just the following
 item in the input stream.
 
 Here's an example.  Suppose we wish to change the size of the
@@ -352,11 +352,7 @@ on the immediately following item in the input stream.  However,
 it is effective only on objects which are created directly from
 the input stream, essentially note heads and articulations;
 objects such as stems and accidentals are created later and
-cannot be tweaked in this way.  Furthermore, when it is applied
-to note heads these @emph{must} be within a chord, i.e., within
-single angle brackets, so to tweak a single note the @code{\tweak}
-command must be placed inside single angle brackets with the
-note.
+cannot be tweaked in this way.
 
 So to return to our example, the size of the middle note of
 a chord would be changed in this way:
@@ -394,8 +390,10 @@ a4^"Black"
 @end lilypond
 
 @noindent
-Note that the @code{\tweak} command must be preceded by an
-articulation mark as if it were an articulation itself.
+Note that the @code{\tweak} command must be preceded by an articulation
+mark since the tweaked expression needs to be applied as an articulation
+itself.  In case of multiple direction overrides (@code{^} or @code{_}),
+the leftmost override wins since it is applied last.
 
 @cindex tuplets, nested
 @cindex triplets, nested
@@ -3638,7 +3636,7 @@ VerseOne = \lyrics {
 }
 
 VerseTwo = \lyricmode {
-  O | \emphasize Christ, \normal whose voice the | wa -- ters heard,
+  O | \once \emphasize Christ, whose voice the | wa -- ters heard,
 }
 
 VerseThree = \lyricmode {
@@ -3686,19 +3684,17 @@ the parts with all the @code{#()}.  This is explained in
 @lilypond[quote,verbatim,ragged-right]
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #{ \markup { \hspace #0
+               \translate #'(5 . 0)
+               \line { \dynamic "mp"
+                       \text \italic "dolce" } }
+  #})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #{ ^\markup \bold \box #string #})
 
 \relative c'' {
   \tempo 4=50
@@ -3723,19 +3719,17 @@ the @code{#()} somewhat ugly.  Let's hide them in another file:
 %%% save this to a file called "definitions.ily"
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #@{ \markup @{ \hspace #0
+               \translate #'(5 . 0)
+               \line @{ \dynamic "mp"
+                       \text \italic "dolce" @} @}
+  #@})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #@{ ^\markup \bold \box #string #@})
 @end example
 
 We will refer to this file using the @code{\include} command near
@@ -3763,19 +3757,17 @@ Now let's modify our music (let's save this file as @file{music.ly}).
 @lilypond[quote,ragged-right]
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #{ \markup { \hspace #0
+               \translate #'(5 . 0)
+               \line { \dynamic "mp"
+                       \text \italic "dolce" } }
+  #})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #{ ^\markup \bold \box #string #})
 
 \relative c'' {
   \tempo 4=50
@@ -3800,19 +3792,17 @@ with this:
 %%%  definitions.ily
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #@{ \markup @{ \hspace #0
+               \translate #'(5 . 0)
+               \line @{ \dynamic "mp"
+                       \text \italic "dolce" @} @}
+  #@})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #@{ ^\markup \bold \box #string #@})
 
 \layout@{
   \context @{
@@ -3835,19 +3825,17 @@ inst =
 @lilypond[quote,ragged-right]
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #{ \markup { \hspace #0
+               \translate #'(5 . 0)
+               \line { \dynamic "mp"
+                       \text \italic "dolce" } }
+  #})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #{ ^\markup \bold \box #string #})
 
 \layout{
   \context {
@@ -3888,19 +3876,17 @@ overall size of the output.
 %%%  definitions.ily
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #@{ \markup @{ \hspace #0
+               \translate #'(5 . 0)
+               \line @{ \dynamic "mp"
+                       \text \italic "dolce" @} @}
+  #@})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #@{ ^\markup \bold \box #string #@})
 
 #(set-global-staff-size 23)
 
@@ -3924,19 +3910,17 @@ inst =
 @lilypond[quote,ragged-right]
 mpdolce =
 #(make-dynamic-script
-  (markup #:hspace 0
-          #:translate '(5 . 0)
-          #:line (#:dynamic "mp"
-                  #:text #:italic "dolce")))
+  #{ \markup { \hspace #0
+               \translate #'(5 . 0)
+               \line { \dynamic "mp"
+                       \text \italic "dolce" } }
+  #})
 
 inst =
 #(define-music-function
      (parser location string)
      (string?)
-   (make-music
-    'TextScriptEvent
-    'direction UP
-    'text (markup #:bold (#:box string))))
+   #{ ^\markup \bold \box #string #})
 
 #(set-global-staff-size 23)
 
index 5f113dda908f83874e7e4ff89ba346948dde190d..b2df038dc722d5ec91047f054db0d7c9e0ccfe1f 100644 (file)
@@ -6644,7 +6644,10 @@ DK: rallentando,
 S: rallentando,
 FI: rallerdando, hidastuen.
 
-[Italian] A performance indication, abbreviated @notation{rall.}
+[Italian: @q{slowing down}]
+
+Slackening in speed, more gradual than @ref{ritardando}.  Abbreviated
+to @notation{rall.}
 
 @seealso
 @ref{ritardando}.
@@ -6770,11 +6773,13 @@ DK: ritardando,
 S: ritardando,
 FI: ritardando, hidastuen,
 
-Gradually slackening in speed.  Mostly abbreviated to @notation{rit.} or
-@notation{ritard}.
+[Italian: @q{lagging}]
+
+Gradual slowing down, more pronounced than @ref{rallentando}.  Mostly
+abbreviated to @notation{rit.} or @notation{ritard}.
 
 @seealso
-No cross-references.
+@ref{rallentando}.
 
 
 @node ritenuto
index 624ebacdf10ce9811d440162b5f9e3045aabe04e..c22f55fb52356cc7c0133af219eb2a3c0ce6fb86 100644 (file)
@@ -2189,6 +2189,11 @@ The default beaming rules can be found in
 @lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
 {subdividing-beams.ly}
 
+@cindex beamlets, orienting
+
+@lilypondfile[verbatim,quote,ragged-right,texidoc,doctitle]
+{strict-beat-beaming.ly}
+
 @cindex measure groupings
 @cindex beats, grouping
 @cindex grouping beats
index 4d8b02f0f6a2e4558742ea9a1c2c863cb76f2bbd..3c73e6ba6a54439ced7d8253c1b5df14ea955a89 100644 (file)
@@ -12968,7 +12968,7 @@ msgstr "Obsah"
 #~ msgstr "Dudelsack"
 
 #~ msgid "Bagpipe definitions"
-#~ msgstr "Dudelsack-Defintionen"
+#~ msgstr "Dudelsack-Definitionen"
 
 #~ msgid "Bagpipe example"
 #~ msgstr "Dudelsack-Beispiele"
index cee7d8b3001357ecbdacb94ea717eae37917c25f..ecfafd1067aff68facc5dc1d4c0683b413effb6a 100644 (file)
@@ -12871,7 +12871,7 @@ msgstr "Inhaltsverzeichnis"
 #~ msgstr "Dudelsack"
 
 #~ msgid "Bagpipe definitions"
-#~ msgstr "Dudelsack-Defintionen"
+#~ msgstr "Dudelsack-Definitionen"
 
 #~ msgid "Bagpipe example"
 #~ msgstr "Dudelsack-Beispiele"
diff --git a/Documentation/snippets/new/strict-beat-beaming.ly b/Documentation/snippets/new/strict-beat-beaming.ly
new file mode 100644 (file)
index 0000000..bc1c970
--- /dev/null
@@ -0,0 +1,21 @@
+\version "2.15.28"
+
+\header {
+  texidoc = "
+Beamlets can be set to point in the direction of the beat to which they
+belong.  The first beam avoids sticking out flags (the default);
+the second beam strictly follows the beat.
+"
+
+  doctitle = "Strict beat beaming"
+
+  lsrtags = "rhythms"
+}
+
+
+\relative c'' {
+  \time 6/8
+  a8. a16 a a
+  \set strictBeatBeaming = ##t
+  a8. a16 a a
+}
diff --git a/Documentation/snippets/strict-beat-beaming.ly b/Documentation/snippets/strict-beat-beaming.ly
new file mode 100644 (file)
index 0000000..b06c1aa
--- /dev/null
@@ -0,0 +1,29 @@
+% DO NOT EDIT this file manually; it is automatically
+% generated from Documentation/snippets/new
+% Make any changes in Documentation/snippets/new/
+% and then run scripts/auxiliar/makelsr.py
+%
+% This file is in the public domain.
+%% Note: this file works from version 2.15.28
+\version "2.15.28"
+
+\header {
+  texidoc = "
+Beamlets can be set to point in the direction of the beat to which they
+belong.  The first beam avoids sticking out flags (the default);
+the second beam strictly follows the beat.
+"
+
+  doctitle = "Strict beat beaming"
+
+  lsrtags = "rhythms"
+} % begin verbatim
+
+
+
+\relative c'' {
+  \time 6/8
+  a8. a16 a a
+  \set strictBeatBeaming = ##t
+  a8. a16 a a
+}
index 7a020d6e097fdef22e04ad16af6cc935f2da19a4..b2fc7f4be7cfa6b7e845e56e8e901cef327d4155 100644 (file)
@@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.60)
 
-# Bootstrap the init proces.
+# Bootstrap the init process.
 AC_INIT
 
 # Bootstrap StepMake configure
index b1a761fdbbb035fc54de6a95ba2bc14da0b33c06..fa0c15a360fe16ad26b26c64efb0ea0146670fe0 100644 (file)
@@ -1,14 +1,17 @@
-\version "2.15.20"
+\version "2.15.27"
 
 \header {
   texidoc = "
-Beamlets should point in the direction of the beat to which they
-belong.
+Beamlets can be set to point in the direction of the beat to which they
+belong.  The first beam avoids sticking out flags (the default);
+the second beam strictly follows the beat.
 "
 }
 
 
-\relative c' {
-b16. b32 b32 b16.
-b16.[ b32 b   b b b16.]
+\relative c'' {
+  \time 6/8
+  a8. a16 a a
+  \set strictBeatBeaming = ##t
+  a8. a16 a a
 }
index 998627b716b3664c835a6e6147326418d1e60084..76bfc420c629a0eef4cca54e48818fedcb8934da 100644 (file)
@@ -74,7 +74,7 @@ stderr of this run."
 
 %% tags
 \test ##[ { \tag #'foo { c4 d } } #]
-\test ##[ c-\tag #'foo -\tag #'baz -^ -. #]
+\test ##[ c-\tag #'foo -\tag #'baz -^-. #]
 
 %% Graces
 \test ##[ { \grace c8 d2 } #]                          % GraceMusic
diff --git a/input/regression/tablature-open-string-chord.ly b/input/regression/tablature-open-string-chord.ly
new file mode 100644 (file)
index 0000000..36bd309
--- /dev/null
@@ -0,0 +1,17 @@
+\version "2.15.28"
+
+\header {
+
+  texidoc = "
+Open strings can always be part of a chord in tablature, even when frets
+above 4 have been used in the chord.  In this case, both chords should show
+an open fourth string."
+
+}  
+
+\score {
+  \new TabStaff { 
+    \set TabStaff.stringTunings = \stringTuning <c g d' a'>
+    <c g'> 1 <c\4 g'> 1
+  }
+}
index 2db441ef690d347f4436efeec704e0a6e2cdc2a5..cc569c7c73b696aad614dd2d7344f182803e3dac 100644 (file)
@@ -99,6 +99,15 @@ Beaming_pattern::flag_direction (Beaming_options const &options, vsize i) const
 
   if (count <= left_count && count <= right_count)
     return CENTER;
+  else if (!options.strict_beat_beaming_)
+    {
+      // Try to avoid sticking-out flags as much as possible by pointing
+      // my flags at the neighbor with the most flags.
+      if (right_count > left_count)
+        return RIGHT;
+      else if (left_count > right_count)
+        return LEFT;
+    }
 
   // If all else fails, point the beamlet away from the important moment.
   return (infos_[i].rhythmic_importance_ < infos_[i + 1].rhythmic_importance_)
@@ -174,8 +183,8 @@ update_tuplet (Moment start_moment, Rational factor, Moment *tuplet_start_moment
   int tuplet_number = (int) factor.den ();
   if ((tuplet_number > 1) && (tuplet_start_moment->num () < 0))
     *tuplet_start_moment = start_moment;
-  else if (tuplet_number == 1) 
-    *tuplet_start_moment = Moment (-1, 1); 
+  else if (tuplet_number == 1)
+    *tuplet_start_moment = Moment (-1, 1);
 }
 
 
@@ -270,8 +279,8 @@ Beaming_pattern::find_rhythmic_importance (Beaming_options const &options)
           // important.  For tuplets, we need to make sure that we use
           // the fraction of the tuplet, instead of the fraction of
           // a beat.
-          Moment ratio = (tuplet_number == 1) 
-                           ? dt / options.base_moment_ 
+          Moment ratio = (tuplet_number == 1)
+                           ? dt / options.base_moment_
                            : tuplet_dt / Moment (1, 8)  / tuplet_moment;
           if (infos_[i].rhythmic_importance_ >= 0)
             infos_[i].rhythmic_importance_ = (int) ratio.den ();
@@ -389,6 +398,7 @@ Beaming_options::from_context (Context *context)
 {
   grouping_ = context->get_property ("beatStructure");
   subdivide_beams_ = to_boolean (context->get_property ("subdivideBeams"));
+  strict_beat_beaming_ = to_boolean (context->get_property ("strictBeatBeaming"));
   base_moment_ = robust_scm2moment (context->get_property ("baseMoment"),
                                     Moment (1, 4));
   measure_length_ = robust_scm2moment (context->get_property ("measureLength"),
@@ -399,4 +409,5 @@ Beaming_options::Beaming_options ()
 {
   grouping_ = SCM_EOL;
   subdivide_beams_ = false;
+  strict_beat_beaming_ = false;
 }
index 11265e973657bcfb0ba57d83195c3d9551db2129..704c8f070c71a0417eefd71d52903c452370772e 100644 (file)
@@ -28,6 +28,7 @@ struct Beaming_options
 {
   SCM grouping_;
   bool subdivide_beams_;
+  bool strict_beat_beaming_;
   Moment base_moment_;
   Moment measure_length_;
 
index a1b566ddfe531a69d9cc714a940dd723f2f15bae..9ecb1b44aaf377c089302ca7e870251f6ba25b60 100644 (file)
@@ -151,6 +151,7 @@ class Property_iterator;
 class Rational;
 class Relative_octave_music;
 class Repeated_music;
+class Rhythmic_music_iterator;
 class Scale;
 class Scheme_hash_table;
 class Scheme_engraver;
diff --git a/lily/include/rhythmic-music-iterator.hh b/lily/include/rhythmic-music-iterator.hh
new file mode 100644 (file)
index 0000000..f639a1c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2012 Mike Solomon <mike@apollinemike.com>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef RHYTHMIC_MUSIC_ITERATOR_HH
+#define RHYTHMIC_MUSIC_ITERATOR_HH
+
+#include "simple-music-iterator.hh"
+
+/*
+  Iterator for rhythmic music events that are not enclosed by EventChord
+*/
+class Rhythmic_music_iterator : public Simple_music_iterator
+{
+protected:
+  DECLARE_CLASSNAME (Rhythmic_music_iterator);
+
+public:
+  DECLARE_SCHEME_CALLBACK (constructor, ());
+  Rhythmic_music_iterator ();
+  Rhythmic_music_iterator (Rhythmic_music_iterator const &);
+
+protected:
+  virtual void process (Moment);
+  virtual void construct_children ();
+};
+
+#endif /* RHYTHMIC_MUSIC_ITERATOR_HH */
+
index 943199ce08b97d4b4e418feeec7f965f57b57254..ffa903b4ebedc5d6ead2b34eb08679747f3ab30e 100644 (file)
@@ -76,11 +76,11 @@ LY_DEFINE (ly_music_p, "ly:music?",
 
 LY_DEFINE (ly_event_p, "ly:event?",
            1, 0, 0, (SCM obj),
-           "Is @var{obj} an event object?")
+           "Is @var{obj} a proper (non-rhythmic) event object?")
 {
   if (Music *m = unsmob_music (obj))
     {
-      return scm_from_bool (m->is_mus_type ("event"));
+      return scm_from_bool (m->is_mus_type ("post-event"));
     }
   return SCM_BOOL_F;
 }
index 02dbe41499e644d184c356254933e4c1397fddfa..45944511359fb3fe9f0f2137feb7fe76f4188ad9 100644 (file)
@@ -161,6 +161,7 @@ Music::generic_to_relative_octave (Pitch last)
   if (Music *m = unsmob_music (elt))
     last = m->to_relative_octave (last);
 
+  (void) music_list_to_relative (get_property ("articulations"), last, true);
   last = music_list_to_relative (get_property ("elements"), last, false);
   return last;
 }
index ba6650acd08cab4b30aa3256384394aa7d5c4386..22a45b279786e62e8fc0d5156d4b5647634fcc2e 100644 (file)
@@ -46,7 +46,7 @@
 %lex-param {Lily_parser *parser}
 
 /* We use SCMs to do strings, because it saves us the trouble of
-deleting them.  Let's hope that a stack overflow doesnt trigger a move
+deleting them.  Let's hope that a stack overflow doesn't trigger a move
 of the parse stack onto the heap. */
 
 %left PREC_BOT
@@ -201,7 +201,7 @@ while (0)
   scm_apply_0 (proc, args)
 /* Syntactic Sugar. */
 #define MAKE_SYNTAX(name, location, ...)       \
-  LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (location) , ##__VA_ARGS__, SCM_UNDEFINED));
+  LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (parser->self_scm (), make_input (location) , ##__VA_ARGS__, SCM_UNDEFINED))
 #define START_MAKE_SYNTAX(name, ...)                                   \
        scm_list_n (ly_lily_module_constant (name) , ##__VA_ARGS__, SCM_UNDEFINED)
 #define FINISH_MAKE_SYNTAX(start, location, ...)                       \
@@ -468,7 +468,6 @@ If we give names, Bison complains.
 %type <scm> embedded_scm_bare
 %type <scm> embedded_scm_bare_arg
 %type <scm> embedded_scm_closed
-%type <scm> embedded_scm_chord_body
 %type <scm> event_function_event
 %type <scm> figure_list
 %type <scm> figure_spec
@@ -513,7 +512,6 @@ If we give names, Bison complains.
 %type <scm> multiplied_duration
 %type <scm> music_function_event
 %type <scm> music_function_chord_body
-%type <scm> music_function_chord_body_arglist
 %type <scm> new_chord
 %type <scm> new_lyrics
 %type <scm> number_expression
@@ -776,16 +774,7 @@ identifier_init:
                $$ = $1;
        }
        | music  {
-               /* Hack: Create event-chord around standalone events.
-                  Prevents the identifier from being interpreted as a post-event. */
-               Music *mus = unsmob_music ($1);
-               bool is_event = mus &&
-                       (scm_memq (ly_symbol2scm ("event"), mus->get_property ("types"))
-                               != SCM_BOOL_F);
-               if (!is_event)
-                       $$ = $1;
-               else
-                       $$ = MAKE_SYNTAX ("event-chord", @$, scm_list_1 ($1));
+               $$ = $1;
        }
        | post_event_nofinger {
                $$ = $1;
@@ -2046,10 +2035,13 @@ scalar_closed:
 
 
 event_chord:
-       /* TODO: Create a special case that avoids the creation of
-          EventChords around simple_elements that have no post_events?
-        */
-       simple_chord_elements post_events       {
+       simple_element post_events {
+               // Let the rhythmic music iterator sort this mess out.
+               if (scm_is_pair ($2))
+                       unsmob_music ($1)->set_property ("articulations",
+                                                        scm_reverse_x ($2, SCM_EOL));
+       }
+       | simple_chord_elements post_events     {
                SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
 
                Input i;
@@ -2111,7 +2103,8 @@ chord_body:
 chord_body_elements:
        /* empty */             { $$ = SCM_EOL; }
        | chord_body_elements chord_body_element {
-               $$ = scm_cons ($2, $1);
+               if (!SCM_UNBNDP ($2))
+                       $$ = scm_cons ($2, $1);
        }
        ;
 
@@ -2153,43 +2146,24 @@ chord_body_element:
                $$ = n->unprotect ();
        }
        | music_function_chord_body
-       ;
-
-/* We can't accept a music argument, not even a closed one,
- * immediately before chord_body_elements, otherwise a function \fun
- * with a signature of two music arguments can't be sorted out
- * properly in a construct like
- * <\fun { c } \fun { c } c>
- * The second call could be interpreted either as a chord constituent
- * or a music expression.
- */
-
-music_function_chord_body_arglist:
-       function_arglist_bare
-       | EXPECT_SCM music_function_chord_body_arglist embedded_scm_chord_body
        {
-               $$ = check_scheme_arg (parser, @3,
-                                      $3, $2, $1);
-       }
-       ;
+               Music *m = unsmob_music ($1);
 
-embedded_scm_chord_body:
-       embedded_scm_bare_arg
-       | SCM_FUNCTION music_function_chord_body_arglist {
-               $$ = MAKE_SYNTAX ("music-function", @$,
-                                        $1, $2);
+               while (m && m->is_mus_type ("music-wrapper-music")) {
+                       $$ = m->get_property ("element");
+                       m = unsmob_music ($$);
+               }
+
+               if (!(m && m->is_mus_type ("rhythmic-event"))) {
+                       parser->parser_error (@$, _ ("not a rhythmic event"));
+                       $$ = SCM_UNDEFINED;
+               }
        }
-       | bare_number
-       | fraction
-       | lyric_element
-       | chord_body_element
        ;
 
 music_function_chord_body:
-       MUSIC_FUNCTION music_function_chord_body_arglist {
-               $$ = MAKE_SYNTAX ("music-function", @$,
-                                        $1, $2);
-       }
+       music_function_call
+       | MUSIC_IDENTIFIER
        ;
 
 // Event functions may only take closed arglists, otherwise it would
@@ -2766,10 +2740,7 @@ simple_element:
        ;
 
 simple_chord_elements:
-       simple_element  {
-               $$ = scm_list_1 ($1);
-       }
-       | new_chord {
+       new_chord {
                 if (!parser->lexer_->is_chord_state ())
                         parser->parser_error (@1, _ ("have to be in Chord mode for chords"));
                 $$ = $1;
@@ -2795,35 +2766,32 @@ lyric_element:
 lyric_element_arg:
        lyric_element
        | lyric_element multiplied_duration post_events {
-               SCM lyric_event = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
-               $$ = MAKE_SYNTAX ("event-chord", @$,
-                                 scm_cons (lyric_event,
-                                           scm_reverse_x ($3, SCM_EOL)));
+               $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
+               if (scm_is_pair ($3))
+                       unsmob_music ($$)->set_property
+                               ("articulations", scm_reverse_x ($3, SCM_EOL));
        }
        | lyric_element post_event post_events {
-               SCM lyric_event =
-                       MAKE_SYNTAX ("lyric-event", @$, $1,
-                                    parser->default_duration_.smobbed_copy ());
-               $$ = MAKE_SYNTAX ("event-chord", @$,
-                                 scm_cons2 (lyric_event, $2,
-                                            scm_reverse_x ($3, SCM_EOL)));
-                                            
+               $$ = MAKE_SYNTAX ("lyric-event", @$, $1,
+                                 parser->default_duration_.smobbed_copy ());
+               unsmob_music ($$)->set_property
+                       ("articulations", scm_cons ($2, scm_reverse_x ($3, SCM_EOL)));
        }
        | LYRIC_ELEMENT optional_notemode_duration post_events {
-               SCM lyric_event = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
-               $$ = MAKE_SYNTAX ("event-chord", @$,
-                                 scm_cons (lyric_event,
-                                           scm_reverse_x ($3, SCM_EOL)));
+               $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
+               if (scm_is_pair ($3))
+                       unsmob_music ($$)->set_property
+                               ("articulations", scm_reverse_x ($3, SCM_EOL));
        }
        ;
 
 
 lyric_element_music:
        lyric_element optional_notemode_duration post_events {
-               SCM lyric_event = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
-               $$ = MAKE_SYNTAX ("event-chord", @$,
-                                 scm_cons (lyric_event,
-                                           scm_reverse_x ($3, SCM_EOL)));
+               $$ = MAKE_SYNTAX ("lyric-event", @$, $1, $2);
+               if (scm_is_pair ($3))
+                       unsmob_music ($$)->set_property
+                               ("articulations", scm_reverse_x ($3, SCM_EOL));
        }
        ;
 
@@ -3226,9 +3194,7 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid)
                unsmob_music (*destination)->
                        set_property ("origin", make_input (last_input_));
 
-               bool is_event = scm_memq (ly_symbol2scm ("event"), mus->get_property ("types"))
-                       != SCM_BOOL_F;
-
+               bool is_event = mus->is_mus_type ("post-event");
                mus->unprotect ();
                return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
        } else if (unsmob_pitch (sid)) {
diff --git a/lily/rhythmic-music-iterator.cc b/lily/rhythmic-music-iterator.cc
new file mode 100644 (file)
index 0000000..8d9e75a
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2012 Mike Solomon <mike@apollinemike.com>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "rhythmic-music-iterator.hh"
+
+#include "context.hh"
+#include "dispatcher.hh"
+#include "duration.hh"
+#include "input.hh"
+#include "international.hh"
+#include "music.hh"
+#include "warn.hh"
+
+Rhythmic_music_iterator::Rhythmic_music_iterator ()
+{
+}
+
+void
+Rhythmic_music_iterator::construct_children ()
+{
+  Simple_music_iterator::construct_children ();
+  descend_to_bottom_context ();
+}
+
+void
+Rhythmic_music_iterator::process (Moment m)
+{
+  if (last_processed_mom_ < Moment (0))
+    {
+
+      descend_to_bottom_context ();
+
+      Context *c = get_outlet ();
+      Stream_event *ev = get_music ()->to_event ();
+      SCM arts = ev->get_property ("articulations");
+      
+      if (scm_is_pair (arts))
+       {
+         // There is no point in broadcasting articulations like
+         // harmonic events that nobody listens to.  Those work
+         // exclusively as articulations.
+         SCM listened = SCM_EOL;
+         SCM unlistened = SCM_EOL;
+         for (; scm_is_pair (arts); arts = scm_cdr (arts))
+           {
+             if (scm_is_true
+                 (scm_call_2
+                  (ly_lily_module_constant ("any"),
+                   ly_lily_module_constant ("ly:is-listened-event-class"),
+                   scm_call_1
+                   (ly_lily_module_constant ("ly:make-event-class"),
+                    unsmob_stream_event (scm_car (arts))
+                    ->get_property ("class")))))
+               listened = scm_cons (scm_car (arts), listened);
+             else
+               unlistened = scm_cons (scm_car (arts), unlistened);
+           }
+         ev->set_property ("articulations", scm_reverse_x (unlistened, SCM_EOL));
+         c->event_source ()->broadcast (ev);
+         arts = scm_reverse_x (listened, SCM_EOL);
+         for (; scm_is_pair (arts); arts = scm_cdr (arts))
+           c->event_source ()->broadcast (unsmob_stream_event (scm_car (arts)));
+       }
+      else
+       c->event_source ()->broadcast (ev);
+
+      ev->unprotect ();
+    }
+  Simple_music_iterator::process (m);
+}
+
+IMPLEMENT_CTOR_CALLBACK (Rhythmic_music_iterator);
index 6024d1dc03542dcfa62569678ab754db3c9ac869..2419940c0b52b5f28d69b9ce750ba1983ea1b40a 100644 (file)
@@ -60,13 +60,13 @@ center = #0
 %% try \once \override Score.Beam #'breakable = ##t
 
 %% rather name \newline, \pageBreak ?
-break = #(make-event-chord (list (make-music 'LineBreakEvent 'break-permission 'force)))
-noBreak = #(make-event-chord (list (make-music 'LineBreakEvent 'break-permission '())))
+break = #(make-music 'LineBreakEvent 'break-permission 'force)
+noBreak = #(make-music 'LineBreakEvent 'break-permission '())
 %% \pageBreak, \noPageBreak, \pageTurn, \noPageTurn, \allowPageTurn are defined
 %% as music functions
 
-stopStaff = #(make-event-chord (list (make-span-event 'StaffSpanEvent STOP)))
-startStaff = #(make-event-chord (list (make-span-event 'StaffSpanEvent START)))
+stopStaff = #(make-span-event 'StaffSpanEvent STOP)
+startStaff = #(make-span-event 'StaffSpanEvent START)
 
 
 %
index 933712736233eaee870adf5ced267ad05d93f781..59c452065c3a03cc33fda0e489908c5f15faff69 100644 (file)
@@ -293,13 +293,11 @@ endSpanners =
 #(define-music-function (parser location music) (ly:music?)
    (_i "Terminate the next spanner prematurely after exactly one note
 without the need of a specific end spanner.")
-   (if (eq? (ly:music-property music 'name) 'EventChord)
-       (let* ((elts (ly:music-property music 'elements))
-             (start-span-evs (filter (lambda (ev)
-                                       (and (music-has-type ev 'span-event)
-                                            (equal? (ly:music-property ev 'span-direction)
-                                                    START)))
-                                     elts))
+   (if (memq (ly:music-property music 'name) '(EventChord NoteEvent))
+       (let* ((start-span-evs (filter (lambda (ev)
+                                       (equal? (ly:music-property ev 'span-direction)
+                                               START))
+                                     (extract-typed-music music 'span-event)))
              (stop-span-evs
               (map (lambda (m)
                      (let ((c (music-clone m)))
@@ -314,7 +312,7 @@ without the need of a specific end spanner.")
         total)
 
        (begin
-        (ly:input-message location (_ "argument endSpanners is not an EventChord: ~a" music))
+        (ly:input-message location (_ "argument endSpanners is not an EventChord: ~a") music)
         music)))
 
 
@@ -325,16 +323,13 @@ featherDurations=
    (let ((orig-duration (ly:music-length argument))
         (multiplier (ly:make-moment 1 1)))
 
-     (music-map
+     (for-each
       (lambda (mus)
-       (if (and (eq? (ly:music-property mus 'name) 'EventChord)
-                (< 0 (ly:moment-main-denominator (ly:music-length mus))))
+       (if (< 0 (ly:moment-main-denominator (ly:music-length mus)))
            (begin
              (ly:music-compress mus multiplier)
-             (set! multiplier (ly:moment-mul factor multiplier))))
-       mus)
-      argument)
-
+             (set! multiplier (ly:moment-mul factor multiplier)))))
+      (extract-named-music argument '(EventChord NoteEvent RestEvent SkipEvent)))
      (ly:music-compress
       argument
       (ly:moment-div orig-duration (ly:music-length argument)))
@@ -846,13 +841,9 @@ pitchedTrill =
    (_i "Print a trill with @var{main-note} as the main note of the trill and
 print @var{secondary-note} as a stemless note head in parentheses.")
    (let* ((get-notes (lambda (ev-chord)
-                       (filter
-                        (lambda (m) (eq? 'NoteEvent (ly:music-property m 'name)))
-                        (ly:music-property ev-chord 'elements))))
+                      (extract-named-music ev-chord 'NoteEvent)))
           (sec-note-events (get-notes secondary-note))
-          (trill-events (filter (lambda (m) (music-has-type m 'trill-span-event))
-                                (ly:music-property main-note 'elements))))
-
+          (trill-events (extract-named-music main-note 'TrillSpanEvent)))
      (if (pair? sec-note-events)
          (begin
            (let* ((trill-pitch (ly:music-property (car sec-note-events) 'pitch))
index 14060aed61dc35bbf482c003fbfbb06b527e54dc..87fa7660893539f84d11b823ec9d56a7adc60002 100644 (file)
@@ -21,3 +21,5 @@ INSTALLATION_OUT_FILES1=$(OUT_PY_MODULES) $(OUT_PYC_MODULES)
 $(outdir)/midi.lo: $(outdir)/config.hh
 
 default: $(outdir)/relocate-preamble.py
+
+$(outdir)/relocate-preamble.py: $(depth)/VERSION
index c5ed56471778e54e98973f979cbcfff5b95b8932..226ec8eb6f787b0bf8569d0dc51e6f2b99f51e92 100644 (file)
@@ -201,7 +201,7 @@ def get_texinfo_width_indent (source, global_options):
     tmp_handle.close ()
 
     # Work around a texi2pdf bug: if LANG=C is not given, a broken regexp is
-    # used to detect relative/absolute pathes, so the absolute path is not
+    # used to detect relative/absolute paths, so the absolute path is not
     # detected as such and this command fails:
     progress (_ ("Running texi2pdf on file %s to detect default page settings.\n") % tmpfile);
 
index b7d845f765bc3162c75696d127a780e511f8654f..3ed1d18e00d3ab4756620aab7d43d3b3189a9bc5 100644 (file)
@@ -9,9 +9,9 @@ import lilylib
 _ = lilylib._
 
 
-NOT_SMART = "\n" + _ ("Not smart enough to convert %s")
-UPDATE_MANUALLY = _ ("Please refer to the manual for details, and update manually.")
-FROM_TO = _ ( "%s has been replaced by %s")
+NOT_SMART = "\n" + _ ("Not smart enough to convert %s.") + "\n"
+UPDATE_MANUALLY = _ ("Please refer to the manual for details, and update manually.") + "\n"
+FROM_TO = _ ("%s has been replaced by %s") + "\n"
 
 
 class FatalConversionError:
@@ -49,20 +49,15 @@ def rule (version, message):
 @rule ((0, 1, 9), _ ('\\header { key = concat + with + operator }'))
 def conv(str):
     if re.search ('\\\\multi', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "\\multi")
-        stderr_write ('\n')
     return str
 
 
 @rule ((0, 1, 19), _ ('deprecated %s') % '\\octave')
 def conv (str):
     if re.search ('\\\\octave', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "\\octave")
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
     #   raise FatalConversionError ()
     return str
 
@@ -99,9 +94,7 @@ def conv (str):
 @rule ((1, 0, 2), _ ('\\header { key = concat + with + operator }'))
 def conv(str):
     if re.search ('\\\\header', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("new \\header format"))
-        stderr_write ('\n')
     return str
 
 
@@ -128,9 +121,7 @@ def conv(str):
 @rule ((1, 0, 6), 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }')
 def conv(str):
     if re.search ('[a-zA-Z]+ = *\\translator',str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("\\translator syntax"))
-        stderr_write ('\n')
     #   raise FatalConversionError ()
     return str
 
@@ -184,9 +175,7 @@ def conv(str):
 @rule ((1, 0, 18), _ ('\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative'))
 def conv(str):
     if re.search ('\\\\repeat',str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "\\repeat")
-        stderr_write ('\n')
     #   raise FatalConversionError ()
     return str
 
@@ -290,9 +279,7 @@ def conv (str):
 @rule ((1, 3, 23), _ ('deprecate %s ') % '\\repetitions')
 def conv(str):
     if re.search ('\\\\repetitions',str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "\\repetitions")
-        stderr_write ('\n')
     #   raise FatalConversionError ()
     return str
 
@@ -315,9 +302,7 @@ def conv (str):
     str = re.sub ("\\\\musicalpitch *{([0-9 -]+)}",
                   "\\\\musicalpitch #'(\\1)", str)
     if re.search ('\\\\notenames',str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("new \\notenames format"))
-        stderr_write ('\n')
     return str
 
 
@@ -333,9 +318,7 @@ def conv (str):
 @rule ((1, 3, 41), '[:16 c4 d4 ] -> \\repeat "tremolo" 2 { c16 d16 }')
 def conv (str):
     if re.search ('\\[:',str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("new tremolo format"))
-        stderr_write ('\n')
     return str
 
 
@@ -354,9 +337,7 @@ def conv (str):
 @rule ((1, 3, 58), 'noteHeadStyle value: string -> symbol')
 def conv (str):
     if re.search ('\\\\keysignature', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % '\\keysignature')
-        stderr_write ('\n')
     return str
 
 
@@ -453,9 +434,7 @@ def conv (str):
 def conv (str):
     str = re.sub ('ChordNames*', 'ChordNames', str)
     if re.search ('\\\\textscript "[^"]* *"[^"]*"', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("new \\textscript markup text"))
-        stderr_write ('\n')
 
     str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str)
     return str
@@ -725,8 +704,8 @@ def conv (str):
 def conv (str):
     if re.search (r'\addlyrics',str) \
            and re.search ('automaticMelismata', str)  == None:
-        stderr_write ('\n')
-        stderr_write (NOT_SMART % "automaticMelismata; turned on by default since 1.5.67.")
+        stderr_write (NOT_SMART % "automaticMelismata")
+        stderr_write (_ ("automaticMelismata is turned on by default since 1.5.67."))
         stderr_write ('\n')
         raise FatalConversionError ()
     return str
@@ -963,13 +942,10 @@ def conv(str):
 @rule ((1, 7, 19), _ ("remove %s") % "GraceContext")
 def conv(str):
     if re.search( r'\\GraceContext', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "GraceContext")
         stderr_write (FROM_TO \
                           % ("GraceContext", "#(add-to-grace-init .. )"))
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
         raise FatalConversionError ()
 
     str = re.sub ('HaraKiriStaffContext', 'RemoveEmptyStaffContext', str)
@@ -1001,11 +977,8 @@ def conv(str):
 @rule ((1, 7, 24), _ ("cluster syntax"))
 def conv(str):
     if re.search( r'-(start|stop)Cluster', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("cluster syntax"))
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
 
         raise FatalConversionError ()
     return str
@@ -1286,11 +1259,8 @@ def conv (str):
 @rule ((1, 9, 1), _ ("Remove - before articulation"))
 def conv (str):
     if re.search ("font-style",str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "font-style")
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
 
         raise FatalConversionError ()
 
@@ -1328,11 +1298,8 @@ def conv (str):
                   'acciaccatura', str)
 
     if re.search ("context-spec-music", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "context-spec-music")
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
 
         raise FatalConversionError ()
 
@@ -1383,20 +1350,15 @@ def conv (str):
 @rule ((1, 9, 6), _ ('deprecate %s') % 'ly:get-font')
 def conv (str):
     if re.search ("ly:get-font", str) :
-        stderr_write ('\n')
-        stderr_write (NOT_SMART % "(ly:-get-font")
-        stderr_write ('\n')
+        stderr_write (NOT_SMART % "ly:get-font")
         stderr_write (FROM_TO \
                           % ("(ly:paper-get-font (ly:grob-get-paper foo) .. )",
                              "(ly:paper-get-font (ly:grob-get-paper foo) .. )"))
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
         raise FatalConversionError ()
 
     if re.search ("\\pitch *#", str) :
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "\\pitch")
-        stderr_write ('\n')
         stderr_write (_ ("Use Scheme code to construct arbitrary note events."))
         stderr_write ('\n')
 
@@ -1439,9 +1401,7 @@ as a substitution text.""") % (m.group (1), m.group (2)) )
 
     if re.search ("ly:(make-pitch|pitch-alteration)", str) \
            or re.search ("keySignature", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "pitches")
-        stderr_write ('\n')
         stderr_write (
             _ ("""The alteration field of Scheme pitches was multiplied by 2
 to support quarter tone accidentals.  You must update the following constructs manually:
@@ -1456,13 +1416,9 @@ to support quarter tone accidentals.  You must update the following constructs m
 @rule ((1, 9, 8), "dash-length -> dash-fraction")
 def conv (str):
     if re.search ("dash-length",str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "dash-length")
-        stderr_write ('\n')
         stderr_write (FROM_TO % ("dash-length", "dash-fraction"))
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
         raise FatalConversionError ()
     return str
 
@@ -1601,11 +1557,8 @@ def conv (str):
 def conv (str):
 
     if re.search (r'\\partcombine', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "\\partcombine")
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
         raise FatalConversionError ()
 
     # this rule doesn't really work,
@@ -1774,11 +1727,8 @@ def conv (str):
     str = re.sub (r'ly:get-broken-into', 'ly:spanner-broken-into', str)
     str = re.sub (r'Melisma_engraver', 'Melisma_translator', str)
     if re.search ("ly:get-paper-variable", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "ly:paper-get-variable")
-        stderr_write ('\n')
-        stderr_write (_ ('use %s') % '(ly:paper-lookup (ly:grob-paper ))')
-        stderr_write ('\n')
+        stderr_write (_ ('Use %s\n') % '(ly:paper-lookup (ly:grob-paper ))')
         raise FatalConversionError ()
 
     str = re.sub (r'\\defaultAccidentals', "#(set-accidental-style 'default)", str)
@@ -1915,11 +1865,8 @@ def conv (str):
 @rule ((2, 3, 2), '\\FooContext -> \\Foo')
 def conv (str):
     if re.search ('textheight', str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "textheight")
-        stderr_write ('\n')
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
         stderr_write (
 _ ("""Page layout has been changed, using paper size and margins.
 textheight is no longer used.
@@ -2143,9 +2090,7 @@ def conv (str):
         if encoding == 'latin1':
             return match.group (2)
 
-        stderr_write ('\n')
         stderr_write (NOT_SMART % ("\\encoding: %s" % encoding))
-        stderr_write ('\n')
         stderr_write (_ ("LilyPond source must be UTF-8"))
         stderr_write ('\n')
         if encoding == 'TeX':
@@ -2189,16 +2134,12 @@ def conv (str):
 @rule ((2, 5, 17), _ ('remove %s') % 'ly:stencil-set-extent!')
 def conv (str):
     if re.search ("ly:stencil-set-extent!", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "ly:stencil-set-extent!")
-        stderr_write ('\n')
-        stderr_write ('use (set! VAR (ly:make-stencil (ly:stencil-expr VAR) X-EXT Y-EXT))\n')
+        stderr_write (_ ('Use %s\n') % '(set! VAR (ly:make-stencil (ly:stencil-expr VAR) X-EXT Y-EXT))')
         raise FatalConversionError ()
     if re.search ("ly:stencil-align-to!", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "ly:stencil-align-to!")
-        stderr_write ('\n')
-        stderr_write ('use (set! VAR (ly:stencil-aligned-to VAR AXIS DIR))\n')
+        stderr_write (_ ('Use %s\n') % '(set! VAR (ly:stencil-aligned-to VAR AXIS DIR))')
         raise FatalConversionError ()
     return str
 
@@ -2213,15 +2154,12 @@ def conv (str):
 def conv (str):
     if re.search ("(override-|revert-)auto-beam-setting", str)\
        or re.search ("autoBeamSettings", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % _ ("auto beam settings"))
-        stderr_write ('\n')
         stderr_write (_ ('''
 Auto beam settings must now specify each interesting moment in a measure
 explicitly; 1/4 is no longer multiplied to cover moments 1/2 and 3/4 too.
 '''))
         stderr_write (UPDATE_MANUALLY)
-        stderr_write ('\n')
         raise FatalConversionError ()
     return str
 
@@ -2331,6 +2269,7 @@ def conv (str):
         stderr_write (NOT_SMART % "space-function")
     if re.search ('verticalAlignmentChildCallback', str):
         stderr_write (_ ('verticalAlignmentChildCallback has been deprecated'))
+        stderr_write ('\n')
     return str
 
 
@@ -2648,7 +2587,7 @@ def conv (str):
                   str)
 
     if re.search ('edge-text', str):
-        stderr_write (NOT_SMART % _ ("edge-text settings for TextSpanner."))
+        stderr_write (NOT_SMART % _ ("edge-text settings for TextSpanner"))
         stderr_write (_ ("Use\n\n%s") %
                           "\t\\override TextSpanner #'bound-details #'right #'text = <right-text>\n"
                           "\t\\override TextSpanner #'bound-details #'left #'text = <left-text>\n")
@@ -2681,7 +2620,7 @@ def conv (str):
 
     str = re.sub (r"(\\once)?\s*\\override\s*([a-zA-Z]+\s*[.]\s*)?TextSpanner\s*#'edge-height\s*=\s*#'\(\s*([0-9.-]+)\s+[.]\s+([0-9.-]+)\s*\)", sub_edge_height, str)
     if re.search (r"#'forced-distance", str):
-        stderr_write (NOT_SMART % ("VerticalAlignment #'forced-distance.\n"))
+        stderr_write (NOT_SMART % "VerticalAlignment #'forced-distance")
         stderr_write (_ ("Use the `alignment-offsets' sub-property of\n"))
         stderr_write (_ ("NonMusicalPaperColumn #'line-break-system-details\n"))
         stderr_write (_ ("to set fixed distances between staves.\n"))
@@ -2702,7 +2641,7 @@ def conv (str):
                   r"scripts.caesura.curved", str)
 
     if re.search ('dash-fraction', str):
-        stderr_write (NOT_SMART % _ ("all settings related to dashed lines.\n"))
+        stderr_write (NOT_SMART % _ ("all settings related to dashed lines"))
         stderr_write (_ ("Use \\override ... #'style = #'line for solid lines and\n"))
         stderr_write (_ ("\t\\override ... #'style = #'dashed-line for dashed lines."))
     return str
@@ -2745,7 +2684,8 @@ fret diagram properties moved to fret-diagram-details."))
 def conv (str):
     ## warning 1/2: metronomeMarkFormatter uses text markup as second argument
     if re.search ('metronomeMarkFormatter', str):
-        stderr_write (NOT_SMART % _ ("metronomeMarkFormatter got an additional text argument.\n"))
+        stderr_write (NOT_SMART % "metronomeMarkFormatter")
+        stderr_write (_ ("metronomeMarkFormatter got an additional text argument.\n"))
         stderr_write (_ ("The function assigned to Score.metronomeMarkFunction now uses the signature\n%s") %
                           "\t(format-metronome-markup text dur count context)\n")
 
@@ -2764,9 +2704,8 @@ def conv (str):
                 'orientation']
     for prop in fret_props:
       if re.search (prop, str):
-          stderr_write (NOT_SMART %
-            prop + " in fret-diagram properties. Use fret-diagram-details.")
-          stderr_write ('\n')
+          stderr_write (NOT_SMART % (_ ("%s in fret-diagram properties") % prop))
+          stderr_write (_ ('Use %s\n') % "fret-diagram-details")
     return str
 
 @rule ((2, 11, 51), "\\octave -> \\octaveCheck, \\arpeggioUp -> \\arpeggioArrowUp,\n\
@@ -2809,9 +2748,10 @@ def conv (str):
 def conv (str):
     str = re.sub (r"#\(set-octavation (-*[0-9]+)\)", r"\\ottava #\1", str)
     if re.search ('put-adjacent', str):
-        stderr_write (NOT_SMART % _ ("\\put-adjacent argument order.\n"))
+        stderr_write (NOT_SMART % _ ("\\put-adjacent argument order"))
         stderr_write (_ ("Axis and direction now come before markups:\n"))
         stderr_write (_ ("\\put-adjacent axis dir markup markup."))
+        stderr_write ("\n")
     return str
 
 @rule ((2, 11, 57), "\\center-align -> \\center-column, \\hcenter -> \\center-align")
@@ -2841,15 +2781,13 @@ InnerStaffGroup -> StaffGroup, InnerChoirStaff -> ChoirStaff")
 def conv (str):
     str = re.sub (r'systemSeparatorMarkup', r'system-separator-markup', str)
     if re.search (r'\\InnerStaffGroup', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("re-definition of InnerStaffGroup.\n"))
-        stderr_write (FROM_TO % ("InnerStaffGroup", "StaffGroup.\n"))
+        stderr_write (NOT_SMART % _("re-definition of InnerStaffGroup"))
+        stderr_write (FROM_TO % ("InnerStaffGroup", "StaffGroup"))
         stderr_write (UPDATE_MANUALLY)
         raise FatalConversionError ()
     if re.search (r'\\InnerChoirStaff', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("re-definition of InnerChoirStaff.\n"))
-        stderr_write (FROM_TO % ("InnerChoirStaff", "ChoirStaff.\n"))
+        stderr_write (NOT_SMART % _("re-definition of InnerChoirStaff"))
+        stderr_write (FROM_TO % ("InnerChoirStaff", "ChoirStaff"))
         stderr_write (UPDATE_MANUALLY)
         raise FatalConversionError ()
     else:
@@ -2862,15 +2800,13 @@ def conv (str):
        _ ("bump version for release"))
 def conv(str):
     if re.search(r'\\addChordShape', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("stringTuning must be added to \
-addChordShape call.\n"))
+        stderr_write (NOT_SMART % "addChordShape")
+        stderr_write (_ ("stringTuning must be added to addChordShape call.\n"))
         stderr_write (UPDATE_MANUALLY)
         raise FatalConversionError ()
     if re.search (r'\\chord-shape', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("stringTuning must be added to \
-chord-shape call.\n"))
+        stderr_write (NOT_SMART % "chord-shape")
+        stderr_write (_ ("stringTuning must be added to chord-shape call.\n"))
         stderr_write (UPDATE_MANUALLY)
         raise FatalConversionError ()
     return str
@@ -2879,8 +2815,8 @@ chord-shape call.\n"))
     _ ("Remove oldaddlyrics"))
 def conv(str):
     if re.search(r'\\oldaddlyrics', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("oldaddlyrics is no longer supported. \n \
+        stderr_write (NOT_SMART % "oldaddlyrics")
+        stderr_write (("oldaddlyrics is no longer supported. \n \
         Use addlyrics or lyrsicsto instead.\n"))
         stderr_write (UPDATE_MANUALLY)
         raise FatalConversionError ()
@@ -2890,8 +2826,8 @@ def conv(str):
 MIDI 47: orchestral strings -> orchestral harp"))
 def conv(str):
     if re.search(r'\set Staff.keySignature', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("The alist for Staff.keySignature is no \
+        stderr_write (NOT_SMART % "Staff.keySignature")
+        stderr_write (("The alist for Staff.keySignature is no \
 longer in reversed order.\n"))
     str = str.replace('"orchestral strings"', '"orchestral harp"')
     return str
@@ -2902,14 +2838,14 @@ ly:hairpin::after-line-breaking -> ly:spanner::kill-zero-spanned-time\n\
 Dash parameters for slurs and ties are now in dash-definition"))
 def conv(str):
     if re.search(r'\\bar\s*"\."', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("\\bar \".\" now produces a thick barline.\n"))
+        stderr_write (NOT_SMART % "\\bar \".\"")
+        stderr_write (("\\bar \".\" now produces a thick barline.\n"))
         stderr_write (UPDATE_MANUALLY)
     str = re.sub (r'ly:hairpin::after-line-breaking', r'ly:spanner::kill-zero-spanned-time', str)
     if re.search("(Slur|Tie)\w+#\'dash-fraction", str) \
         or re.search("(Slur|Tie)\w+#\'dash-period", str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("Dash parameters for slurs and ties are now in \'dash-details.\n"))
+        stderr_write (NOT_SMART % "dash-fraction, dash-period")
+        stderr_write (("Dash parameters for slurs and ties are now in \'dash-details.\n"))
         stderr_write (UPDATE_MANUALLY)
     return str
 
@@ -2927,26 +2863,27 @@ Explicit dynamics context definition from `Piano centered dynamics'\n\
 template replaced by new `Dynamics' context."))
 def conv(str):
     if re.search("override-auto-beam-setting", str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("override-auto-beam-setting.\n\
+        stderr_write (NOT_SMART % "override-auto-beam-setting")
+        stderr_write (_ (" \
    Autobeam settings are now overriden with \\overrideBeamSettings.\n"))
         stderr_write (UPDATE_MANUALLY)
     if re.search("revert-auto-beam-setting", str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("override-auto-beam-setting.\n\
+        stderr_write (NOT_SMART % "override-auto-beam-setting")
+        stderr_write (_ (" \
    Autobeam settings are now reverted with \\revertBeamSettings.\n"))
         stderr_write (UPDATE_MANUALLY)
     str = re.sub(r"\\set\s+beatGrouping", r"\\setBeatGrouping", str)
     if re.search(r"\w+\s*.\s*beatGrouping", str):
-        stderr_write (NOT_SMART % _("beatGrouping. \n\
+        stderr_write (NOT_SMART % "beatGrouping")
+        stderr_write (_ (" \
    beatGrouping with a specified context must now be accomplished with\n\
    \\overrideBeamSettings.\n"))
         stderr_write (UPDATE_MANUALLY)
     if re.search(r'alignment-offsets', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("alignment-offsets has been changed to alignment-distances: \
+        stderr_write (NOT_SMART % "alignment-offsets")
+        stderr_write (_ ("alignment-offsets has been changed to alignment-distances: \
 you must now specify the distances between staves rather than the offset of staves.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (UPDATE_MANUALLY)
     str = re.sub ('ly:(system-start-text::print|note-head::brew-ez-stencil|ambitus::print)',
                   '\\1', str)
     str = re.sub ('(\\bBeam\\s+#\')(?=thickness\\b)', '\\1beam-', str)
@@ -2985,9 +2922,9 @@ def conv(str):
                   str)
 
     if re.search(r"VerticalAxisGroup\s*#\s*'minimum-Y-extent", str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("minimum-Y-extent; vertical spacing no longer depends on the Y-extent of a VerticalAxisGroup.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "minimum-Y-extent")
+        stderr_write (_ ("Vertical spacing no longer depends on the Y-extent of a VerticalAxisGroup.\n"))
+        stderr_write (UPDATE_MANUALLY)
 
     return str
 
@@ -3037,25 +2974,25 @@ def conv(str):
     str = re.sub (r'"accordion\.acc([a-zA-Z]+)"',
                   sub_acc, str)
     if re.search(r'overrideBeamSettings', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("\\overrideBeamSettings.  Use \\set beamExceptions or \\overrideTimeSignatureSettings.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "\\overrideBeamSettings")
+        stderr_write (_ ("Use \\set beamExceptions or \\overrideTimeSignatureSettings.\n"))
+        stderr_write (UPDATE_MANUALLY)
     if re.search(r'revertBeamSettings', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("\\revertBeamSettings. Use \\set beamExceptions or \\revertTimeSignatureSettings.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "\\revertBeamSettings")
+        stderr_write (_ ("Use \\set beamExceptions or \\revertTimeSignatureSettings.\n"))
+        stderr_write (UPDATE_MANUALLY)
     if re.search(r'beamSettings', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("beamSettings. Use baseMoment, beatStructure, and beamExceptions.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "beamSettings")
+        stderr_write (_ ("Use baseMoment, beatStructure, and beamExceptions.\n"))
+        stderr_write (UPDATE_MANUALLY)
     if re.search(r'beatLength', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("beatLength. Use baseMoment and beatStructure.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "beatLength")
+        stderr_write (_ ("Use baseMoment and beatStructure.\n"))
+        stderr_write (UPDATE_MANUALLY)
     if re.search(r'setBeatGrouping', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("setbeatGrouping. Use baseMoment and beatStructure.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "setbeatGrouping")
+        stderr_write (_ ("Use baseMoment and beatStructure.\n"))
+        stderr_write (UPDATE_MANUALLY)
     return str
 
 @rule ((2, 13, 31),
@@ -3063,9 +3000,9 @@ def conv(str):
 Deprecate negative dash-period for hidden lines: use #'style = #'none instead."))
 def conv(str):
     if re.search(r'woodwind-diagram', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % _("woodwind-diagrams.  Move size, thickness, and graphic to properties.  Argument should be just the key list.\n"))
-        stderr_write(UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "woodwind-diagrams")
+        stderr_write (_ ("Move size, thickness, and graphic to properties.  Argument should be just the key list.\n"))
+        stderr_write (UPDATE_MANUALLY)
     str = re.sub (r"dash-period\s+=\s*#\s*-[0-9.]+",
                   r"style = #'none",
                   str);
@@ -3109,15 +3046,13 @@ def conv(str):
     _ ("Remove \\paper variables head-separation and foot-separation."))
 def conv(str):
     if re.search (r'head-separation', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % ("head-separation.\n"))
-        stderr_write(_ ("Adjust settings for top-system-spacing instead.\n"))
+        stderr_write (NOT_SMART % "head-separation")
+        stderr_write (_ ("Adjust settings for top-system-spacing instead.\n"))
         stderr_write (UPDATE_MANUALLY)
     if re.search (r'foot-separation', str):
-        stderr_write("\n")
-        stderr_write(NOT_SMART % ("foot-separation.\n"))
-        stderr_write(_ ("Adjust settings for last-bottom-spacing instead.\n"))
-        stderr_write(UPDATE_MANUALLY);
+        stderr_write (NOT_SMART % "foot-separation")
+        stderr_write (_ ("Adjust settings for last-bottom-spacing instead.\n"))
+        stderr_write (UPDATE_MANUALLY);
 
     return str
 
@@ -3128,8 +3063,7 @@ def conv(str):
     str = re.sub (r'\(space\s+\.\s+([0-9]*\.?[0-9]*)\)', r'(basic-distance . \1)', str)
     str = re.sub (r"#'space\s+=\s+#?([0-9]*\.?[0-9]*)", r"#'basic-distance = #\1", str)
     if re.search (r'HarmonicParenthesesItem', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % ("HarmonicParenthesesItem.\n"))
+        stderr_write (NOT_SMART % "HarmonicParenthesesItem")
         stderr_write (_ ("HarmonicParenthesesItem has been eliminated.\n"))
         stderr_write (_ ("Harmonic parentheses are part of the TabNoteHead grob.\n"))
         stderr_write (UPDATE_MANUALLY);
@@ -3177,13 +3111,17 @@ def conv(str):
     str = re.sub (r"ukulele-(tenor|baritone)-tuning", r"\1-ukulele-tuning", str)
 
     if re.search (r"[^-]page-top-space", str):
-        stderr_write (NOT_SMART % "page-top-space.  " + UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "page-top-space")
+        stderr_write (UPDATE_MANUALLY)
     if re.search (r"[^-]between-system-(space|padding)", str):
-        stderr_write (NOT_SMART % "between-system-space, -padding.  " + UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "between-system-space, -padding")
+        stderr_write (UPDATE_MANUALLY)
     if re.search (r"[^-](before|between|after)-title-space", str):
-        stderr_write (NOT_SMART % "-title-space.  " + UPDATE_MANUALLY)
+        stderr_write (NOT_SMART % "before-, between-, after-title-space")
+        stderr_write (UPDATE_MANUALLY)
     if re.search (r"\\name\s", str):
-        stderr_write("\n" + _("Vertical spacing changes might affect user-defined contexts.  ") + UPDATE_MANUALLY)
+        stderr_write ("\n" + _("Vertical spacing changes might affect user-defined contexts.") + "\n")
+        stderr_write (UPDATE_MANUALLY)
 
     return str
 
@@ -3203,8 +3141,8 @@ def conv(str):
     _ ("Woodwind diagrams: Changes to the clarinet diagram."))
 def conv(str):
     if re.search (r'\\woodwind-diagram\s*#[^#]*clarinet\s', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("woodwind-diagrams.  Clarinet fingering changed to reflect actual anatomy of instrument.\n"))
+        stderr_write (NOT_SMART % "woodwind-diagrams")
+        stderr_write (_ ("Clarinet fingering changed to reflect actual anatomy of instrument.\n"))
         stderr_write (UPDATE_MANUALLY)
     return str
 
@@ -3217,8 +3155,8 @@ def conv (str):
     _ ("Handling of non-automatic footnotes."))
 def conv(str):
     if re.search (r'\\footnote', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("If you are using non-automatic footnotes, make sure to set footnote-auto-numbering = ##f in the paper block.\n"))
+        stderr_write (NOT_SMART % "\\footnote")
+        stderr_write (("If you are using non-automatic footnotes, make sure to set footnote-auto-numbering = ##f in the paper block.\n"))
         stderr_write (UPDATE_MANUALLY)
     return str
 
@@ -3226,8 +3164,7 @@ def conv(str):
        _ ("Change in internal property for MultiMeasureRest"))
 def conv (str):
     if re.search (r'use-breve-rest',str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % "use-breve-rest.\n")
+        stderr_write (NOT_SMART % "use-breve-rest")
         stderr_write (_ ("This internal property has been replaced by round-up-to-longer-rest, round-up-exceptions and usable-duration-logs.\n"))
         stderr_write (UPDATE_MANUALLY)
     return str
@@ -3268,8 +3205,8 @@ def conv (str):
     str = re.sub (r"\\markuplines", r"\\markuplist", str)
     str = re.sub (r"@funindex markuplines", r"@funindex markuplist", str)
     if re.search (r'consistent-broken-slope', str):
-        stderr_write ("\n")
-        stderr_write (NOT_SMART % _("consistent-broken-slope, which is now handled through the positions callback.\n"))
+        stderr_write (NOT_SMART % "consistent-broken-slope")
+        stderr_write (_ ("consistent-broken-slope is now handled through the positions callback.\n"))
         stderr_write (_ ("input/regression/beam-broken-classic.ly shows how broken beams are now handled.\n"))
         stderr_write (UPDATE_MANUALLY)
     return str
@@ -3329,9 +3266,7 @@ def conv (str):
     str = re.sub (r"#\(markup\*(?=\s)", r"$(markup", str)
     str = re.sub ("#\("+paren_matcher (25)+"\)", export_puller, str)
     if re.search (r"\(ly:export\s+", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "ly:export")
-        stderr_write ('\n')
     return str
 
 @rule ((2, 15, 19), r"$(set-time-signature ...) -> \time")
@@ -3341,9 +3276,7 @@ def conv (str):
     str = re.sub (r"\$\(set-time-signature\s+([0-9]+)\s+([0-9]+)\s+(" +
                   paren_matcher (5) + r")\)", r"\\time #\3 \1/\2", str)
     if re.search (r"\(set-time-signature\s+", str):
-        stderr_write ('\n')
         stderr_write (NOT_SMART % "set-time-signature")
-        stderr_write ('\n')
     return str
 
 @rule ((2, 15, 20), r"$(set-accidental-style ...) -> \accidentalStyle")
index 835539ef5b2b08bf10631a0809bfe7f10dcc9bf4..43079859c638b83acba705060a6eba9413a85d2f 100644 (file)
@@ -476,6 +476,8 @@ verse.  Use in @code{Lyrics} context.")
 on the left side of the next note.  Overrides automatic beaming.  The
 value is only used once, and then it is erased.")
      (stemRightBeamCount ,integer? "See @code{stemLeftBeamCount}.")
+     (strictBeatBeaming ,boolean? "Should partial beams reflect the
+beat structure even if it causes flags to hang out?")
      (stringNumberOrientations ,list? "See
 @code{fingeringOrientations}.")
      (stringOneTopmost ,boolean? "Whether the first string is
index 259c0ccaaebbb42e2c8eaeec3051ddedd7512249..db21afda90aacfb9aa62b0f45e169582c9762213 100644 (file)
@@ -108,7 +108,9 @@ expression."
 (define*-public (duration->lily-string ly-duration #:key (prev-duration (*previous-duration*))
                        (force-duration (*force-duration*))
                        (time-factor-numerator (*time-factor-numerator*))
-                       (time-factor-denominator (*time-factor-denominator*)))
+                       (time-factor-denominator (*time-factor-denominator*))
+                       remember)
+  (if remember (*previous-duration* ly-duration))
   (let ((log2   (ly:duration-log ly-duration))
        (dots    (ly:duration-dot-count ly-duration))
        (num+den (ly:duration-factor ly-duration)))
@@ -136,37 +138,8 @@ expression."
 ;;; post events
 ;;;
 
-(define post-event?
-  (make-music-type-predicate
-    'AbsoluteDynamicEvent
-    'ArpeggioEvent
-    'ArticulationEvent
-    'BeamEvent
-    'BeamForbidEvent
-    'BendAfterEvent
-    'CrescendoEvent
-    'DecrescendoEvent
-    'EpisemaEvent
-    'ExtenderEvent
-    'FingeringEvent
-    'GlissandoEvent
-    'HarmonicEvent
-    'HyphenEvent
-    'MultiMeasureTextEvent
-    'NoteGroupingEvent
-    'PhrasingSlurEvent
-    'SlurEvent
-    'SostenutoEvent
-    'StringNumberEvent
-    'StrokeFingerEvent
-    'SustainEvent
-    'TextScriptEvent
-    'TextSpanEvent
-    'TieEvent
-    'TremoloEvent
-    'TrillSpanEvent
-    'TupletSpanEvent
-    'UnaCordaEvent))
+(define (post-event? m)
+  (music-is-of-type? m 'post-event))
 
 (define* (event-direction->lily-string event #:optional (required #t))
   (let ((direction (ly:music-property event 'direction)))
@@ -281,24 +254,22 @@ expression."
     (and (with-music-match (?start (music
                                    'SequentialMusic
                                    elements ((music
-                                              'EventChord
-                                              elements ((music
-                                                         'SkipEvent
-                                                         duration (ly:make-duration 0 0 0 1))
-                                                        (music
-                                                         'SlurEvent
-                                                         span-direction START))))))
-          #t)
-         (with-music-match (?stop (music
-                                   'SequentialMusic
-                                   elements ((music
-                                              'EventChord
-                                              elements ((music
-                                                         'SkipEvent
-                                                         duration (ly:make-duration 0 0 0 1))
-                                                        (music
-                                                         'SlurEvent
-                                                         span-direction STOP))))))
+                                              'SkipEvent
+                                              duration (ly:make-duration 0 0 0 1)
+                                              articulations
+                                              ((music
+                                                'SlurEvent
+                                                span-direction START))))))
+           #t)
+        (with-music-match (?stop (music
+                                  'SequentialMusic
+                                  elements ((music
+                                             'SkipEvent
+                                             duration (ly:make-duration 0 0 0 1)
+                                             articulations
+                                             ((music
+                                               'SlurEvent
+                                               span-direction STOP))))))
            (format #f "\\appoggiatura ~a" (music->lily-string ?music parser))))))
 
 
@@ -316,13 +287,12 @@ expression."
     (and (with-music-match (?start (music
                                    'SequentialMusic
                                    elements ((music
-                                              'EventChord
-                                              elements ((music
-                                                         'SkipEvent
-                                                         duration (ly:make-duration 0 0 0 1))
-                                                        (music
-                                                         'SlurEvent
-                                                         span-direction START)))
+                                              'SkipEvent
+                                              duration (ly:make-duration 0 0 0 1)
+                                              articulations
+                                              ((music
+                                                'SlurEvent
+                                                span-direction START)))
                                              (music
                                               'ContextSpeccedMusic
                                               element (music
@@ -339,14 +309,14 @@ expression."
                                                       'RevertProperty
                                                       grob-property-path '(stroke-style)
                                                       symbol 'Flag))
+
                                             (music
-                                             'EventChord
-                                             elements ((music
-                                                        'SkipEvent
-                                                        duration (ly:make-duration 0 0 0 1))
-                                                       (music
-                                                        'SlurEvent
-                                                        span-direction STOP))))))
+                                             'SkipEvent
+                                             duration (ly:make-duration 0 0 0 1)
+                                             articulations
+                                             ((music
+                                               'SlurEvent
+                                               span-direction STOP))))))
           (format #f "\\acciaccatura ~a" (music->lily-string ?music parser))))))
 
 (define-extra-display-method GraceMusic (expr parser)
@@ -375,12 +345,16 @@ expression."
                                  (*max-element-number-before-break*))))
        (elements (ly:music-property seq 'elements))
        (chord? (make-music-type-predicate 'EventChord))
+       (note-or-chord? (make-music-type-predicate 'EventChord 'NoteEvent
+                                                  'LyricEvent 'RestEvent
+                                                  'ClusterNoteEvent))
        (cluster? (make-music-type-predicate 'ClusterNoteEvent))
        (note? (make-music-type-predicate 'NoteEvent)))
     (format #f "~a~a{~v%~v_~{~a~^ ~}~v%~v_}"
            (if (any (lambda (e)
-                      (and (chord? e)
-                           (any cluster? (ly:music-property e 'elements))))
+                      (or (cluster? e)
+                          (and (chord? e)
+                               (any cluster? (ly:music-property e 'elements)))))
                     elements)
                "\\makeClusters "
                "")
@@ -395,15 +369,17 @@ expression."
                       "\\figuremode ")
                      ((any (lambda (chord)
                              (any (make-music-type-predicate 'LyricEvent)
-                                  (ly:music-property chord 'elements)))
-                           (filter chord? elements))
+                                  (cons chord
+                                        (ly:music-property chord 'elements))))
+                           (filter note-or-chord? elements))
                       "\\lyricmode ")
                      ((any (lambda (chord)
                              (any (lambda (event)
                                     (and (note? event)
                                          (not (null? (ly:music-property event 'drum-type)))))
-                                  (ly:music-property chord 'elements)))
-                           (filter chord? elements))
+                                  (cons chord
+                                        (ly:music-property chord 'elements))))
+                           (filter note-or-chord? elements))
                       "\\drummode ")
                      (else ;; TODO: other modes?
                       ""))
@@ -454,58 +430,29 @@ Otherwise, return #f."
   (let* ((elements (ly:music-property chord 'elements))
         (simple-elements (filter (make-music-type-predicate
                                   'NoteEvent 'ClusterNoteEvent 'RestEvent
-                                  'MultiMeasureRestEvent 'SkipEvent 'LyricEvent)
+                                  'SkipEvent 'LyricEvent)
                                  elements)))
-    (if ((make-music-type-predicate 'StaffSpanEvent 'BreathingEvent) (car elements))
-       ;; first, a special case: StaffSpanEvent (\startStaff, \stopStaff)
-       ;; and BreathingEvent (\breathe)
-       (music->lily-string (car elements) parser)
-       (if (and (not (null? simple-elements))
-                (null? (cdr simple-elements))
-                ;; special case: if this simple_element has any post_events in
-                ;; its 'articulations list, it should be interpreted instead
-                ;; as a note_chord_element to prevent spurious output, e.g.,
-                ;; \displayLilyMusic < c-1\4 >8 -> c-1\48
-                (null? (filter post-event?
-                               (ly:music-property (car simple-elements) 'articulations)))
-                ;; same for simple_element with \tweak
-                (null? (ly:music-property (car simple-elements) 'tweaks)))
-           ;; simple_element : note | figure | rest | mmrest | lyric_element | skip
-           (let* ((simple-element (car simple-elements))
-                  (duration (ly:music-property simple-element 'duration))
-                  (lily-string (format #f "~a~a~a~{~a~^ ~}"
-                                       (music->lily-string simple-element parser)
-                                       (duration->lily-string duration)
-                                       (if (and ((make-music-type-predicate 'RestEvent) simple-element)
-                                                (ly:pitch? (ly:music-property simple-element 'pitch)))
-                                           "\\rest"
-                                           "")
-                                       (map-in-order (lambda (music)
-                                                       (music->lily-string music parser))
-                                                     (filter post-event? elements)))))
-             (*previous-duration* duration)
-             lily-string)
            (let ((chord-elements (filter (make-music-type-predicate
                                           'NoteEvent 'ClusterNoteEvent 'BassFigureEvent)
                                          elements))
                  (post-events (filter post-event? elements)))
              (if (not (null? chord-elements))
                  ;; note_chord_element : '<' (notepitch | drumpitch)* '>" duration post_events
-                 (let ((lily-string (format #f "< ~{~a ~}>~a~{~a~^ ~}"
-                                            (map-in-order (lambda (music)
-                                                            (music->lily-string music parser))
-                                                          chord-elements)
-                                            (duration->lily-string (ly:music-property (car chord-elements)
-                                                                                      'duration))
-                                            (map-in-order (lambda (music)
-                                                            (music->lily-string music parser))
-                                                          post-events))))
-                   (*previous-duration* (ly:music-property (car chord-elements) 'duration))
-                   lily-string)
+                 (let* ((duration (duration->lily-string
+                                   (ly:music-property (car chord-elements) 'duration)
+                                   #:remember #t)))
+                   (format #f "< ~{~a ~}>~a~{~a~^ ~}"
+                           (map-in-order (lambda (music)
+                                           (music->lily-string music parser))
+                                         chord-elements)
+                           duration
+                           (map-in-order (lambda (music)
+                                           (music->lily-string music parser))
+                                         post-events)))
                  ;; command_element
                  (format #f "~{~a~^ ~}" (map-in-order (lambda (music)
                                                       (music->lily-string music parser))
-                                                    elements))))))))
+                                                    elements))))))
 
 (define-display-method MultiMeasureRestMusic (mmrest parser)
   (let* ((dur (ly:music-property mmrest 'duration))
@@ -528,7 +475,7 @@ Otherwise, return #f."
 ;;;
 
 (define (simple-note->lily-string event parser)
-  (format #f "~a~a~a~a~{~a~}" ; pitchname octave !? octave-check articulations
+  (format #f "~a~a~a~a~a~a~{~a~}" ; pitchname octave !? octave-check duration optional_rest articulations
          (note-name->lily-string (ly:music-property event 'pitch) parser)
          (octave->lily-string (ly:music-property event 'pitch))
          (let ((forced (ly:music-property event 'force-accidental))
@@ -548,6 +495,10 @@ Otherwise, return #f."
                                        (make-string (1- (* -1 octave-check)) #\,))
                                       (else "")))
                ""))
+         (duration->lily-string (ly:music-property event 'duration)
+                                #:remember #t)
+         (if ((make-music-type-predicate 'RestEvent) event)
+             "\\rest" "")
          (map-in-order (lambda (event)
                          (music->lily-string event parser))
                        (ly:music-property event 'articulations))))
@@ -556,7 +507,9 @@ Otherwise, return #f."
   (cond ((not (null? (ly:music-property note 'pitch))) ;; note
         (simple-note->lily-string note parser))
        ((not (null? (ly:music-property note 'drum-type))) ;; drum
-        (format #f "~a" (ly:music-property note 'drum-type)))
+        (format #f "~a~a" (ly:music-property note 'drum-type)
+                (duration->lily-string (ly:music-property note 'duration)
+                                       #:remember #t)))
        (else ;; unknown?
         "")))
 
@@ -566,13 +519,16 @@ Otherwise, return #f."
 (define-display-method RestEvent (rest parser)
   (if (not (null? (ly:music-property rest 'pitch)))
       (simple-note->lily-string rest parser)
-      "r"))
+      (string-append "r" (duration->lily-string (ly:music-property rest 'duration)
+                                               #:remember #t))))
 
 (define-display-method MultiMeasureRestEvent (rest parser)
-  "R")
+  (string-append "R" (duration->lily-string (ly:music-property rest 'duration)
+                                           #:remember #t)))
 
 (define-display-method SkipEvent (rest parser)
-  "s")
+  (string-append "s" (duration->lily-string (ly:music-property rest 'duration)
+                                           #:remember #t)))
 
 (define-display-method RepeatedChord (chord parser)
   (music->lily-string (ly:music-property chord 'element) parser))
@@ -644,18 +600,21 @@ Otherwise, return #f."
            (if (null? bracket-stop) "" "]"))))
 
 (define-display-method LyricEvent (lyric parser)
-  (let ((text (ly:music-property lyric 'text)))
-    (if (or (string? text)
-           (eqv? (first text) simple-markup))
-       ;; a string or a simple markup
-       (let ((string (if (string? text)
-                         text
-                         (second text))))
-         (if (string-match "(\"| |[0-9])" string)
-             ;; TODO check exactly in which cases double quotes should be used
-             (format #f "~s" string)
-             string))
-       (markup->lily-string text))))
+  (format "~a~{~a~^ ~}"
+         (let ((text (ly:music-property lyric 'text)))
+           (if (or (string? text)
+                   (eqv? (first text) simple-markup))
+               ;; a string or a simple markup
+               (let ((string (if (string? text)
+                                 text
+                                 (second text))))
+                 (if (string-match "(\"| |[0-9])" string)
+                     ;; TODO check exactly in which cases double quotes should be used
+                     (format #f "~s" string)
+                     string))
+               (markup->lily-string text)))
+         (map-in-order (lambda (m) (music->lily-string m parser))
+                       (ly:music-property lyric 'articulations))))
 
 (define-display-method BreathingEvent (event parser)
   "\\breathe")
index b5b64b08c858953b11e91a162ec806664912510f..7b60887bd698a8de035b0d73751fb1218c093d41 100644 (file)
@@ -29,7 +29,7 @@
 Syntax: @var{note}@code{\\x}, where @code{\\x} is a dynamic mark like
 @code{\\ppp} or @code{\\sfz}.  A complete list is in file
 @file{ly/@/dynamic-scripts-init.ly}.")
-       (types . (general-music event dynamic-event absolute-dynamic-event))
+       (types . (general-music post-event event dynamic-event absolute-dynamic-event))
        ))
 
     (AlternativeEvent
@@ -64,7 +64,7 @@ context, and 3.@tie{}the context where @var{func} is called.")
      . ((description . "Make an arpeggio on this note.
 
 Syntax: @w{@var{note}@code{-\\arpeggio}}")
-       (types . (general-music arpeggio-event event))
+       (types . (general-music post-event arpeggio-event event))
        ))
 
     ;; todo: use articulation-event for slur as well.
@@ -77,7 +77,7 @@ Syntax: @var{note}@code{x}@code{y}, where @code{x} is a direction
 (no direction specified), and where @code{y} is an articulation
 (such as @w{@code{-.}}, @w{@code{->}}, @code{\\tenuto}, @code{\\downbow}).
 See the Notation Reference for details.")
-       (types . (general-music event articulation-event script-event))
+       (types . (general-music post-event event articulation-event script-event))
        ))
 
     (AutoChangeMusic
@@ -105,22 +105,22 @@ the start of the measure.")
      . ((description . "Start or stop a beam.
 
 Syntax for manual control: @code{c8-[ c c-] c8}")
-       (types . (general-music event beam-event span-event))
+       (types . (general-music post-event event beam-event span-event))
        ))
 
     (BeamForbidEvent
      . ((description . "Specify that a note may not auto-beamed.")
-       (types . (general-music event beam-forbid-event))
+       (types . (general-music post-event event beam-forbid-event))
        ))
 
     (BreakDynamicSpanEvent
      . ((description . "End an alignment spanner for dynamics here.")
-       (types . (general-music break-span-event break-dynamic-span-event event))
+       (types . (general-music post-event break-span-event break-dynamic-span-event event))
        ))
 
     (BendAfterEvent
      . ((description . "A drop/@/fall/@/doit jazz articulation.")
-       (types . (general-music bend-after-event event))))
+       (types . (general-music post-event bend-after-event event))))
 
     (BreathingEvent
      . ((description . "Create a @q{breath mark} or @q{comma}.
@@ -133,6 +133,7 @@ Syntax: @var{note}@code{\\breathe}")
     (ClusterNoteEvent
      . ((description . "A note that is part of a cluster.")
        ;; not a note-event, to ensure that Note_heads_engraver doesn't eat it.
+       (iterator-ctor . ,ly:rhythmic-music-iterator::constructor)
        (types . (general-music cluster-note-event melodic-event
                  rhythmic-event event))
        ))
@@ -168,7 +169,7 @@ Syntax: @var{note}@code{\\<} @dots{} @var{note}@code{\\!}
 
 An alternative syntax is @var{note}@code{\\cr} @dots{}
 @var{note}@code{\\endcr}.")
-       (types . (general-music span-event span-dynamic-event crescendo-event
+       (types . (general-music post-event span-event span-dynamic-event crescendo-event
                  event))
        ))
 
@@ -179,7 +180,7 @@ Syntax: @var{note}@code{\\>} @dots{} @var{note}@code{\\!}
 
 An alternative syntax is @var{note}@code{\\decr} @dots{}
 @var{note}@code{\\enddecr}.")
-       (types . (general-music span-event span-dynamic-event decrescendo-event
+       (types . (general-music post-event span-event span-dynamic-event decrescendo-event
                  event))
        ))
 
@@ -190,7 +191,7 @@ An alternative syntax is @var{note}@code{\\decr} @dots{}
 
     (EpisemaEvent
      . ((description . "Begin or end an episema.")
-       (types . (general-music span-event event episema-event))
+       (types . (general-music post-event span-event event episema-event))
        ))
 
     (Event
@@ -209,12 +210,12 @@ An alternative syntax is @var{note}@code{\\decr} @dots{}
 
     (ExtenderEvent
      . ((description . "Extend lyrics.")
-       (types . (general-music extender-event event))
+       (types . (general-music post-event extender-event event))
        ))
 
     (FingeringEvent
      . ((description . "Specify what finger to use for this note.")
-       (types . (general-music fingering-event event))
+       (types . (general-music post-event fingering-event event))
        ))
 
     (FootnoteEvent
@@ -224,7 +225,7 @@ An alternative syntax is @var{note}@code{\\decr} @dots{}
 
     (GlissandoEvent
      . ((description . "Start a glissando on this note.")
-       (types . (general-music glissando-event event))
+       (types . (general-music post-event glissando-event event))
        ))
 
     (GraceMusic
@@ -237,12 +238,12 @@ An alternative syntax is @var{note}@code{\\decr} @dots{}
 
     (HarmonicEvent
      . ((description . "Mark a note as harmonic.")
-       (types . (general-music event harmonic-event))
+       (types . (general-music post-event event harmonic-event))
        ))
 
     (HyphenEvent
      . ((description . "A hyphen between lyric syllables.")
-       (types . (general-music hyphen-event event))
+       (types . (general-music post-event hyphen-event event))
        ))
 
     (KeyChangeEvent
@@ -262,7 +263,7 @@ Syntax: @code{\\key} @var{name} @var{scale}")
      . ((description . "Don't damp this chord.
 
 Syntax: @var{note}@code{\\laissezVibrer}")
-       (types . (general-music event laissez-vibrer-event))
+       (types . (general-music post-event event laissez-vibrer-event))
        ))
 
     (LigatureEvent
@@ -287,6 +288,7 @@ Syntax: @code{\\lyricsto} @var{voicename} @var{lyrics}")
     (LyricEvent
      . ((description . "A lyric syllable.  Must be entered in lyrics mode,
 i.e., @code{\\lyrics @{ twinkle4 twinkle4 @} }.")
+       (iterator-ctor . ,ly:rhythmic-music-iterator::constructor)
        (types . (general-music rhythmic-event lyric-event event))
        ))
 
@@ -321,7 +323,7 @@ Syntax: @code{R2.*4} for 4 measures in 3/4 time.")
 Syntax: @code{R-\\markup @{ \\roman \"bla\" @}}
 
 Note the explicit font switch.")
-       (types . (general-music event multi-measure-text-event))
+       (types . (general-music post-event event multi-measure-text-event))
        ))
 
     (Music
@@ -331,13 +333,14 @@ Note the explicit font switch.")
 
     (NoteEvent
      . ((description . "A note.")
+       (iterator-ctor . ,ly:rhythmic-music-iterator::constructor)
        (types . (general-music event note-event rhythmic-event
                  melodic-event))
        ))
 
     (NoteGroupingEvent
      . ((description . "Start or stop grouping brackets.")
-       (types . (general-music event note-grouping-event))
+       (types . (general-music post-event event note-grouping-event))
        ))
 
     (OttavaMusic
@@ -412,7 +415,7 @@ goes down).")
 
 Syntax: @var{note}@code{\\(} and @var{note}@code{\\)}")
         (spanner-id . "")
-       (types . (general-music span-event event phrasing-slur-event))
+       (types . (general-music post-event span-event event phrasing-slur-event))
        ))
 
     (PropertySet
@@ -476,13 +479,14 @@ Syntax: @code{\\unset @var{context}.@var{prop}}")
 
     (RepeatTieEvent
      . ((description . "Ties for starting a second volta bracket.")
-       (types . (general-music event repeat-tie-event))
+       (types . (general-music post-event event repeat-tie-event))
        ))
 
     (RestEvent
      . ((description . "A Rest.
 
 Syntax: @code{r4} for a quarter rest.")
+       (iterator-ctor . ,ly:rhythmic-music-iterator::constructor)
        (types . (general-music event rhythmic-event rest-event))
        ))
 
@@ -526,6 +530,7 @@ Syntax: @code{\\simultaneous @{ @dots{} @}} or @code{<< @dots{} >>}")
 print anything.
 
 Syntax: @code{s4} for a skip equivalent to a quarter rest.")
+       (iterator-ctor . ,ly:rhythmic-music-iterator::constructor)
        (types . (general-music event rhythmic-event skip-event))
        ))
 
@@ -544,7 +549,7 @@ Syntax: @code{\\skip} @var{duration}")
 
 Syntax: @var{note}@code{(} and @var{note}@code{)}")
         (spanner-id . "")
-       (types . (general-music span-event event slur-event))
+       (types . (general-music post-event span-event event slur-event))
        ))
 
     (SoloOneEvent
@@ -561,7 +566,7 @@ Syntax: @var{note}@code{(} and @var{note}@code{)}")
 
     (SostenutoEvent
      . ((description . "Depress or release sostenuto pedal.")
-       (types . (general-music event pedal-event sostenuto-event))
+       (types . (general-music post-event event pedal-event sostenuto-event))
        ))
 
     (SpacingSectionEvent
@@ -583,19 +588,19 @@ different time than stopped.")
      . ((description . "Specify on which string to play this note.
 
 Syntax: @code{\\@var{number}}")
-       (types . (general-music string-number-event event))
+       (types . (general-music post-event string-number-event event))
        ))
 
     (StrokeFingerEvent
      . ((description . "Specify with which finger to pluck a string.
 
 Syntax: @code{\\rightHandFinger @var{text}}")
-       (types . (general-music stroke-finger-event event))
+       (types . (general-music post-event stroke-finger-event event))
        ))
 
     (SustainEvent
      . ((description . "Depress or release sustain pedal.")
-       (types . (general-music event pedal-event sustain-event))
+       (types . (general-music post-event event pedal-event sustain-event))
        ))
 
     (TempoChangeEvent
@@ -605,20 +610,20 @@ Syntax: @code{\\rightHandFinger @var{text}}")
 
     (TextScriptEvent
      . ((description . "Print text.")
-       (types . (general-music script-event text-script-event event))
+       (types . (general-music post-event script-event text-script-event event))
        ))
 
     (TextSpanEvent
      . ((description . "Start a text spanner, for example, an
 octavation.")
-       (types . (general-music span-event event text-span-event))
+       (types . (general-music post-event span-event event text-span-event))
        ))
 
     (TieEvent
      . ((description . "A tie.
 
 Syntax: @w{@var{note}@code{-~}}")
-       (types . (general-music tie-event event))
+       (types . (general-music post-event tie-event event))
        ))
 
     (TimeScaledMusic
@@ -651,7 +656,7 @@ Syntax: @code{\\times @var{fraction} @var{music}}, e.g.,
 
     (TremoloEvent
      . ((description . "Unmeasured tremolo.")
-       (types . (general-music event tremolo-event))
+       (types . (general-music post-event event tremolo-event))
        ))
 
     (TremoloRepeatedMusic
@@ -670,18 +675,18 @@ Syntax: @code{\\times @var{fraction} @var{music}}, e.g.,
 
     (TrillSpanEvent
      . ((description . "Start a trill spanner.")
-       (types . (general-music span-event event trill-span-event))
+       (types . (general-music post-event span-event event trill-span-event))
        ))
 
     (TupletSpanEvent
      . ((description . "Used internally to signal where tuplet
 brackets start and stop.")
-       (types . (tuplet-span-event span-event event general-music))
+       (types . (tuplet-span-event span-event event general-music post-event))
        ))
 
     (UnaCordaEvent
      . ((description . "Depress or release una-corda pedal.")
-       (types . (general-music event pedal-event una-corda-event))
+       (types . (general-music post-event event pedal-event una-corda-event))
        ))
 
     (UnfoldedRepeatedMusic
index 5c2c846275ed121a5eeeadd7d852a647db4312b3..21c9599b66170838d0ac7b961a9b6a5e574fa451 100644 (file)
@@ -516,7 +516,7 @@ messages into errors.")
     (,ly:dir? . "direction")
     (,ly:dispatcher? . "dispatcher")
     (,ly:duration? . "duration")
-    (,ly:event? . "event")
+    (,ly:event? . "post event")
     (,ly:font-metric? . "font metric")
     (,ly:grob? . "graphical (layout) object")
     (,ly:grob-array? . "array of grobs")
index 737d7e2a9f37dc8c9bf8a957678e902fe13b3656..9617329d77843a4e13777046cc86908be1edd44a 100644 (file)
@@ -126,7 +126,7 @@ LilyPond scheme pitches, e.g. @code{(ly:make-pitch 0 2 0)}
       (change-pitches element converter)))))
 
 
-(define (extract-pitch-sequence music)
+(define (make-scale music)
   "Recurse through @var{music}, extracting pitches.
 Returns a list of pitch objects, e.g
 @code{'((ly:make-pitch 0 2 0) (ly:make-pitch 0 4 0) ... )}
@@ -140,20 +140,15 @@ Typically used to construct a scale for input to transposer-factory
 
     (cond
      ((ly:pitch? pitch)
-      pitch)
+      (list pitch))
 
      ((pair? elements)
-      (map
-       (lambda (x) (extract-pitch-sequence x))
+      (append-map
+       (lambda (x) (make-scale x))
        elements))
 
      ((ly:music? element)
-      (extract-pitch-sequence element)))))
-
-(define (make-scale music)
-  "Convenience wrapper for extract-pitch-sequence."
-  (map car (extract-pitch-sequence music)))
-
+      (make-scale element)))))
 
 (define (make-extended-scale music)
   "Extend scale given by @var{music} by 5 octaves up and down."
index 1b1d07c490fefefbcaeaadfff19f7eec604283fd..6114e144d6bc8e6b5d8400fd7b5b2d3bd04ed132 100644 (file)
@@ -276,12 +276,12 @@ through MUSIC."
     (set! (ly:music-property r 'repeat-count) (max times 1))
     (set! (ly:music-property r 'elements) talts)
     (if (and (equal? name "tremolo")
-            (or (pair? (ly:music-property main 'elements))
-                (ly:music? (ly:music-property main 'element))))
+            (pair? (extract-named-music main 'NoteEvent)))
        ;; This works for single-note and multi-note tremolos!
        (let* ((children (if (music-is-of-type? main 'sequential-music)
                             ;; \repeat tremolo n { ... }
-                            (length (extract-named-music main 'EventChord))
+                            (length (extract-named-music main '(EventChord
+                                                                NoteEvent)))
                             ;; \repeat tremolo n c4
                             1))
               ;; # of dots is equal to the 1 in bitwise representation (minus 1)!
@@ -311,7 +311,7 @@ if durations in @var{music} vary, allowing slash beats and double-percent
 beats to be distinguished."
   (let* ((durs (map (lambda (elt)
                      (duration-of-note elt))
-                   (extract-named-music music 'EventChord)))
+                   (extract-named-music music '(EventChord NoteEvent))))
         (first-dur (car durs)))
 
     (if (every (lambda (d) (equal? d first-dur)) durs)
@@ -1517,7 +1517,8 @@ Entries that conform with the current key signature are not invalidated."
 (define-public (duration-of-note event-chord)
   (let ((evs (filter (lambda (x)
                       (music-has-type x 'rhythmic-event))
-                    (ly:music-property event-chord 'elements))))
+                    (cons event-chord
+                          (ly:music-property event-chord 'elements)))))
 
     (and (pair? evs)
         (ly:music-property (car evs) 'duration))))
@@ -1526,21 +1527,33 @@ Entries that conform with the current key signature are not invalidated."
 
 (define-public (extract-named-music music music-name)
   "Return a flat list of all music named @var{music-name} from @var{music}."
-   (let ((extracted-list
-          (if (ly:music? music)
-              (if (eq? (ly:music-property music 'name) music-name)
-                  (list music)
-                  (let ((elt (ly:music-property music 'element))
-                        (elts (ly:music-property music 'elements)))
-                    (if (ly:music? elt)
-                        (extract-named-music elt music-name)
-                        (if (null? elts)
-                            '()
-                            (map (lambda(x)
-                                    (extract-named-music x music-name ))
-                             elts)))))
-              '())))
-     (flatten-list extracted-list)))
+  (if (not (list? music-name))
+      (set! music-name (list music-name)))
+  (if (ly:music? music)
+      (if (memq (ly:music-property music 'name) music-name)
+         (list music)
+         (let ((arts (ly:music-property music 'articulations)))
+           (append-map!
+            (lambda (x) (extract-named-music x music-name))
+            (if (pair? arts)
+                arts
+                (cons (ly:music-property music 'element)
+                      (ly:music-property music 'elements))))))
+      '()))
+
+(define-public (extract-typed-music music type)
+  "Return a flat list of all music with @var{type} from @var{music}."
+  (if (ly:music? music)
+      (if (music-is-of-type? music type)
+         (list music)
+         (let ((arts (ly:music-property music 'articulations)))
+           (append-map!
+            (lambda (x) (extract-typed-music x type))
+            (if (pair? arts)
+                arts
+                (cons (ly:music-property music 'element)
+                      (ly:music-property music 'elements))))))
+      '()))
 
 (define-public (event-chord-notes event-chord)
   "Return a list of all notes from @var{event-chord}."
index a38a49da49880e5fb7306cb2aa082c25afab0be2..7a43a7bb54978e4f314b948ebe389e59664c14eb 100644 (file)
@@ -864,11 +864,6 @@ and duration-log @var{log}."
   (let* ((event (event-cause grob))
         (digit (ly:event-property event 'digit)))
 
-    (if (> digit 5)
-       (ly:input-message (ly:event-property event 'origin)
-                         "Warning: Fingering notation for finger number ~a"
-                         digit))
-
     (number->string digit 10)))
 
 (define-public (string-number::calc-text grob)
index 9a65d44c8eea934ca42b0248fc4031aea257110d..568b967ba6d16ef891b691c87774c81d2e6268a7 100644 (file)
@@ -159,7 +159,9 @@ If it unsets the property, return @code{#f}."
 (define-public (music-elements music)
   "Return list of all @var{music}'s top-level children."
   (let ((elt (ly:music-property music 'element))
-        (elts (ly:music-property music 'elements)))
+        (elts (append
+              (ly:music-property music 'articulations)
+              (ly:music-property music 'elements))))
     (if (not (null? elt))
         (cons elt elts)
         elts)))
@@ -182,12 +184,17 @@ If it unsets the property, return @code{#f}."
 (define-public (process-music music function)
   "Process all nodes of @var{music} (including @var{music}) in the DFS order.
 Apply @var{function} on each of the nodes.  If @var{function} applied on a
-node returns @code{#t}, don't process the node's subtree."
+node returns @code{#t}, don't process the node's subtree.
+
+If a non-boolean is returned, it is considered the material to recurse."
   (define (process-music queue)
     (if (not (null? queue))
         (let* ((elt (car queue))
                (stop (function elt)))
-          (process-music (if stop
-                             (cdr queue)
-                             (append (music-elements elt) (cdr queue)))))))
+          (process-music (if (boolean? stop)
+                            (if stop
+                                (cdr queue)
+                                (append (music-elements elt) (cdr queue)))
+                            ((if (cheap-list? stop) append cons)
+                             stop (cdr queue)))))))
   (process-music (list music)))
index ffa53816c22293af75ab27f862bd4c137313fc5b..71eb03d72f4b5aa17ed5f5902c98798fdac5f2fb 100644 (file)
      (lambda (music)
        (cond
         ;; true lyrics
-        ((music-name? music 'EventChord)
+        ((music-name? music '(EventChord LyricEvent))
          (let ((lyric-event (find-child-named music 'LyricEvent)))
            (push! (make-lyrics
                         #:text (ly:music-property lyric-event 'text)
                                                          (append (score-notes-note/rest-list last-result)
                                                                  (list rest-spec)))
                    (add! (make-score-notes #:note/rest-list (list rest-spec)) result-list))))))
-         #f)
+        (filter
+         (lambda (m)
+           (not (music-name? m '(RestEvent
+                                 NoteEvent
+                                 LyricEvent
+                                 MultiMeasureRestEvent))))
+         (ly:music-property music 'elements)))
+       ((music-name? music '(RestEvent
+                             NoteEvent
+                             LyricEvent
+                             MultiMeasureRestEvent))
+        (make-music 'EventChord
+                    'elements
+                    (cons music
+                          (ly:music-property music 'articulations))))
         ;; autobeaming change
         ((music-property? music 'autoBeaming)
          (set! autobeaming (property-value music))
          (let ((change (if (property-value music) 1 -1)))
            (set! in-slur (+ in-slur change))
            (if last-note-spec
-               (set-note-joined! last-note-spec (+ (note-joined last-note-spec) change)))))
+               (set-note-joined! last-note-spec (+ (note-joined last-note-spec) change))))
+        #t)
         ;; tempo change
         ((music-property? music 'tempoWholesPerMinute)
-         (set! *tempo-compression* (ly:moment-div *default-tempo* (property-value music))))
+         (set! *tempo-compression* (ly:moment-div *default-tempo* (property-value music)))
+        #t)
         ;; breathe
         ((music-name? music 'BreathingEvent)
          (if last-note-spec
                                                #:origin (ly:music-property music 'origin))))
                (set-note-duration! last-note-spec (* note-duration (*breathe-shortage*)))
                (add! (make-score-notes #:note/rest-list (list rest-spec)) result-list))
-             (warning music "\\\\breathe without previous note known")))
+             (warning music "\\\\breathe without previous note known"))
+        #t)
         ;; anything else
         (else
          #f))))
index 6f7d0524938969c5ba26a5b903917df321f4858a..d373da0eebcc0079c2e0c8d0e76a747ceba38742 100644 (file)
@@ -326,6 +326,7 @@ if no string-number is present."
          #t
          (map (lambda (specced-fret)
                 (or (eq? 0 specced-fret)
+                     (eq? 0 fret)
                     (>= maximum-stretch (abs (- fret specced-fret)))))
               specified-frets))))
 
@@ -333,7 +334,7 @@ if no string-number is present."
       "Can @var{pitch} be played on @var{string}, given already placed
 notes?"
       (let* ((fret (calc-fret pitch string tuning)))
-       (and (>= fret minimum-fret)
+       (and (or (eq? fret 0) (>= fret minimum-fret))
             (close-enough fret))))
 
     (define (open-string string pitch)
index ac99b292b5b23fa8aa19ad05757ecec1739c9b62..3a0aeaedabe7776a610acbc087b358a80bab3e90 100644 (file)
@@ -695,7 +695,7 @@ def try_parse_header_line (ln, state):
         if g == 'K': # KEY
             a = check_clef(a)
             if a:
-                m = re.match ('^([^ \t]*) *([^ ]*)( *)(.*)$', a) # seperate clef info
+                m = re.match ('^([^ \t]*) *([^ ]*)( *)(.*)$', a) # separate clef info
                 if m:
                     # there may or may not be a space
                     # between the key letter and the mode
@@ -929,7 +929,7 @@ def try_parse_articulation (str, state):
 
 
 
-    # s7m2 input doesnt care about spaces
+    # s7m2 input doesn't care about spaces
     if re.match('[ \t]*\(', str):
         str = str.lstrip ()
 
index 9349010964f191c7bd5a09558689597b6a4debf6..4c618520240a43e33c3b7e52181c0e97e4a0d00d 100644 (file)
@@ -218,7 +218,7 @@ if ($opt_output)
 #   <program> ({GNU,Free} <package>) <version>
 #   <program> - {GNU,Free} <package> <version>
 #
-# and seperated from any copyright/author details by a blank line.
+# and separated from any copyright/author details by a blank line.
 
 ($_, $version_text) = split /\n+/, $version_text, 2;
 
index caab907e0ed808d5acee717a06bce3579d98e8a1..23e896c8726b4261089e8dfc25893defb591c4a5 100644 (file)
@@ -5046,7 +5046,7 @@ end
 \chardef\maxseclevel = 3
 %
 % A numbered section within an unnumbered changes to unnumbered too.
-% To achive this, remember the "biggest" unnum. sec. we are currently in:
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
 \chardef\unmlevel = \maxseclevel
 %
 % Trace whether the current chapter is an appendix or not:
index 6f399da2d9d1830fb8487d6894c753371bfbdba0..3745ebbe5b55212c07e00e6a68e9bb74f724cc94 100644 (file)
@@ -43,7 +43,7 @@
 %%
 \gdef\putwordNoTitle{Kein Titel}
 %%
-%% New defintion for the output of months.
+%% New definition for the output of months.
 \gdef\putwordMJan{Januar}
 \gdef\putwordMFeb{Februar}
 \gdef\putwordMMar{M\"arz}
index 2366ee7432895d2bf87c72ecd6c5f284cf50f5e9..bf5f05929a21d3dd0ef33df8f136803874569742 100644 (file)
@@ -37,7 +37,7 @@
 %%
 \gdef\putwordNoTitle{Nincs cím}
 %%
-%% New defintion for the output of months.
+%% New definition for the output of months.
 \gdef\putwordMJan{Január}
 \gdef\putwordMFeb{Február}
 \gdef\putwordMMar{Március}