]> git.donarmstrong.com Git - lilypond.git/commitdiff
This commit was manufactured by cvs2svn to create tag 'lilypond_2_1_17'. release/2.1.17
authorjanneke <janneke>
Mon, 2 Feb 2004 17:11:47 +0000 (17:11 +0000)
committerjanneke <janneke>
Mon, 2 Feb 2004 17:11:47 +0000 (17:11 +0000)
31 files changed:
ChangeLog
Documentation/topdocs/NEWS.texi
Documentation/user/invoking.itexi
Documentation/user/refman.itely
VERSION
input/bugs/rhytmicstaff-tie.ly [deleted file]
input/regression/grace-part-combine.ly
input/regression/lyric-combine-new.ly
input/regression/new-markup-scheme.ly [new file with mode: 0644]
input/regression/new-part-combine-text.ly [new file with mode: 0644]
input/regression/new-part-combine.ly
input/regression/pc-mmrest.ly [deleted file]
input/regression/pc-switch-slur.ly [deleted file]
input/test/lyrics-skip-notes.ly [new file with mode: 0644]
input/test/part-combine-moments.ly [deleted file]
input/test/part-combine-staff.ly [deleted file]
input/test/text-rotate.ly [new file with mode: 0644]
input/test/transposition.ly
lily/hyphen-engraver.cc
lily/new-lyric-combine-music-iterator.cc
lily/new-part-combine-iterator.cc
lily/parser.yy
lily/part-combine-engraver.cc [new file with mode: 0644]
lily/tie-performer.cc
lily/tuplet-bracket.cc
ly/engraver-init.ly
scm/define-grobs.scm
scm/define-music-properties.scm
scm/define-music-types.scm
scm/music-functions.scm
scm/new-markup.scm

index a04fcb0f12fa06214a312b91e3fa051e7e91fe32..ac27236f5cf8c0c1778d037b8cf4e9c818587c0e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+2004-02-02  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * VERSION: release 2.1.17
+       
+       * Documentation/user/refman.itely (Automatic part combining):
+       revise documentation of the part-combiner.
+
+       * input/regression/pc-switch-slur.ly (texidoc): remove file.
+       
+       * input/test/part-combine-{moment,staff}.ly: remove file.
+
+       * input/regression/pc-mmrest.ly (two): remove file.
+
+       * scm/define-music-types.scm (music-descriptions): add
+       Solo{One,Two}Event and UnisonoEvent
+
+       * lily/new-part-combine-iterator.cc (unisono): add state_
+       variable, signal changes with part-combine-event.
+
+       * input/regression/new-part-combine-text.ly: new file.
+
+       * lily/part-combine-engraver.cc: new file.
+
+2004-02-02  Jan Nieuwenhuizen  <janneke@gnu.org>
+
+       * scripts/filter-lilypond-book.py: Handle snippet options.
+
+2004-02-02  Han-Wen Nienhuys   <hanwen@xs4all.nl>
+
+       * scm/music-functions.scm (determine-split-list): detect solo1/2
+       and unisono.
+
+       * lily/new-lyric-combine-music-iterator.cc (construct_children):
+       revert fix, document why.
+
+       * lily/tie-performer.cc (process_music): new function. Set melisma
+       property.
+
+       * lily/tuplet-bracket.cc (make_bracket): make sure that gap is
+       always smaller than bracket size.
+       (make_bracket): oops. Size of the gap was off by factor 2
+
+       * input/test/text-rotate.ly: new file.
+
+       * scm/new-markup.scm (markup): a macro that provides a
+       LilyPond-like syntax in scheme for building markups, in order to
+       help markup command definition. (Nicolas Sceaux)
+
+       * input/test/lyrics-skip-notes.ly: new example.
+
+       * lily/parser.yy (post_event): make HYPHEN into postfix event.
+
+       * lily/new-lyric-combine-music-iterator.cc (find_context_below):
+       use is_alias() iso. == . This fixes lyrics on
+       GregorianTranscriptions. 
+
+2004-02-02  Mats Bengtsson  <mabe@drongo.s3.kth.se>
+
+       * scripts/lilypond.py (ly_paper_to_latexpaper): Add newline before 
+       \thispagestyle{lastpage} to avoid that it's printed on the second
+       last page when there's only a single score line on the last page.
+       (The page breaking mechanism in TeX played some ugly tricks to us.)
+
 2004-02-01  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * scripts/filter-lilypond-book.py: Further development.
 
 2004-01-28  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * VERSION: release 2.1.16
+       
        * scm/music-functions.scm (determine-split-list): bugfix: only use
        new-active for both voices if both indexes advance. This fixes the
        biggest outstanding problem with new-pc. 
 
 2004-01-26  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * VERSION: release 2.1.15
+       
        * lily/lyric-phrasing-engraver.cc (stop_translation_timestep):
        align all stanza numbers.
 
index 8207622508e2fbf5f0fcd589ecf171822d462da8..95ea4ad53266b562f0df9e144d56963029198d2c 100644 (file)
@@ -17,6 +17,17 @@ Version 2.1.13
 @end ignore
 
 @itemize @bullet
+@item The ergonomic syntax of @code{\markup} now has an equivalent in
+Scheme. The @code{markup*} macro creates such objects; the following
+two markup commands are equivalent:
+@example
+ f4^#(markup* #:raise 0.2 #:bold "hi")
+ f4^\markup @{ \raise #0.2 \bold hi  @}
+@end example
+
+@item Voice names, for vocal lines, have been added. They are similar
+to instrument names.   They can be set by defining @code{vocalName}
+and @code{vocNam}.
 
 @item Safe mode has been reinstated for lilypond.
 When lilypond is invoked with @code{--safe-mode}, @TeX{} and
index 2f9424b47aa62cacaf75617bb0ab538f433902f6..72ca9ddaa2b6a2221110691b014fb3977c9612c4 100644 (file)
@@ -132,7 +132,8 @@ to generate titling; an example demonstrating all these fields is in
 @item footer
     A text to print in the footer of all but the last page.
 @item tagline
-    Line to print at the bottom of last page. The default text is ``Engraved by LilyPond @var{version-number}''.
+    Line to print at the bottom of last page. The default text is ``Engraved
+by LilyPond @var{version-number}''.
 @end table
 
 
index 88f621bd4e1b8c39cfd209a7e1fce2ca12cc31e7..ccae49f6d6328fa64cdc9ec06f00dcdeaf3a09f2 100644 (file)
@@ -3536,15 +3536,16 @@ A complete example of a SATB score setup is in the file
 
 @seealso
 
-Internals: @internalsref{LyricCombineMusic}, @internalsref{Lyrics},
-@internalsref{Melisma_engraver}.
+Internals: Music expressions: @internalsref{LyricCombineMusic},
+Contexts: @internalsref{LyricsVoice}, @internalsref{Melisma_engraver}.
 
 Examples: @inputfileref{input/template,satb.ly},
 @inputfileref{input/regression,lyric-combine-new.ly}.
  
 @refbugs
 
-Melismata are not detected automatically, and must be inserted by hand.
+Melismata are not detected automatically, and extender lines must be
+inserted by hand.
 
 
 @node More stanzas
@@ -3607,12 +3608,17 @@ prevent @code{LyricsVoice.stanza} being interpreted as a single
 string.
 
 Names of the singers should be added using @code{LyricsVoice
-. instrument} and @code{LyricsVoice . instr}, analogous to instrument
+. vocalName} and @code{LyricsVoice . vocNam}, analogous to instrument
 annotations for staves.
  
 To make empty spaces in lyrics, use @code{\skip}.
 
 
+@seealso
+
+Internals: Layout objects @internalsref{LyricText}
+@internalsref{VocalName}.  Music expressions:
+@internalsref{LyricEvent}.
 
 @refbugs
 
@@ -3634,6 +3640,8 @@ making or a music identifier @code{\foo} containing the syllable
 @end example
 
 
+
+
 @node Ambitus
 @subsection Ambitus
 @cindex ambitus
@@ -4348,15 +4356,31 @@ is
   \transpose @var{from} @var{to} @var{musicexpr}
 @end example
 
-This means that @var{musicexpr} is transposed by the interval
-between the pitches @var{from} and @var{to}.
-Since @var{from} and @var{to} are pitches, @code{\transpose} must be
-inside a @code{\notes} section.
+This means that @var{musicexpr} is transposed by the interval between
+the pitches @var{from} and @var{to}: any note with pitch @code{from}
+is changed to @code{to}.
+
+
+For example, consider  a piece written in the key of  D major.  If
+this piece is a  little too low for its performer, it can be
+transposed up to E major with
+@example
+ \tranpose d e @dots{}
+@end example
 
-@code{\transpose} distinguishes between enharmonic pitches: both
-@code{\transpose c cis} or @code{\transpose c des} will transpose up
-half a tone.  The first version will print sharps and the second
-version will print flats:
+Consider a part  written for violin (a C instrument). If
+this part is to be played on the A clarinet, the following
+transposition will produce the appropriate part
+
+@example
+  \transpose a c @dots{}
+@end example   
+
+Since @var{from} and @var{to} are pitches, @code{\transpose} must be
+inside a @code{\notes} section.  @code{\transpose} distinguishes
+between enharmonic pitches: both @code{\transpose c cis} or
+@code{\transpose c des} will transpose up half a tone.  The first
+version will print sharps and the second version will print flats:
 
 @lilypond[singleline, verbatim]
 mus =\notes { \key d \major cis d fis g }
@@ -4495,27 +4519,24 @@ voices, and stem directions are set automatically.  Also, solo and
 The syntax for part combining is
 
 @example
-  \partcombine @var{context} @var{musicexpr1} @var{musicexpr2}
+  \newpartcombine @var{musicexpr1} @var{musicexpr2}
 @end example
-where the pieces of music @var{musicexpr1} and @var{musicexpr2} will be
-combined into one context of type @var{context}.  The music expressions
-must be interpreted by contexts whose names should start with @code{one}
-and @code{two}.
+
+The music expressions will be interpreted as @internalsref{Voice}
+contexts.
 
 The following example demonstrates the basic functionality of the part
 combiner: putting parts on one staff, and setting stem directions and
 polyphony:
 
-@lilypond[verbatim,singleline,fragment]
-  \context Staff <<
-    \context Voice=one \partcombine Voice
-      \context Thread=one \relative c'' {
+@lilypond[verbatim,singleline,fragment,relative 1]
+  \new Staff \newpartcombine 
+      {
         g a( b) r
       }
-      \context Thread=two \relative c'' {
+      {
         g r4 r f
       }
-  >>
 @end lilypond
 
 The first @code{g} appears only once, although it was
@@ -4529,51 +4550,31 @@ If you just want the merging parts, and not the textual markings, you
 may set the property @var{soloADue} to false:
 
 @lilypond[verbatim,singleline,fragment]
-  \context Staff <<
+   \new Staff <<
     \property Staff.soloADue = ##f
-    \context Voice=one \partcombine Voice
-      \context Thread=one \relative c'' {
-        b4 a c g
-      }
-      \context Thread=two \relative c'' {
-        d,2 a4 g'
+    \newpartcombine 
+      {
+        g a( b) r
       }
-  >>
+      {
+        g r4 r f
+      } >>
 @end lilypond
 
 @seealso
 
 Internals: @internalsref{PartCombineMusic},
-@internalsref{Thread_devnull_engraver}, and
-@internalsref{Voice_devnull_engraver} and @internalsref{A2_engraver}.
+@internalsref{SoloOneEvent}, and
+@internalsref{SoloTwoEvent}, and
+@internalsref{UnisonoEvent}.
 
 @refbugs
 
-The syntax for naming contexts in inconsistent with the syntax for
-combining stanzas.
-
 In @code{soloADue} mode, when the two voices play the same notes on and
 off, the part combiner may typeset @code{a2} more than once in a
 measure:
 
-@lilypond[fragment,singleline]
-  \context Staff <<
-    \context Voice=one \partcombine Voice
-      \context Thread=one \relative c'' {
-        c b c b c a c a
-      }
-      \context Thread=two \relative c'' {
-        b b b b f a f a
-      }
-  >>
-@end lilypond
-
-The part combiner is rather buggy, and it will be replaced by a better
-mechanism in the near future.
 
-@cindex @code{Thread_devnull_engraver}
-@cindex @code{Voice_engraver}
-@cindex @code{A2_engraver}
 
 @node Hiding staves
 @subsection Hiding staves
@@ -8783,6 +8784,9 @@ setting @code{instrumentEqualizer}.
 Many musically interesting effects, such as swing, articulation,
 slurring, etc., are not translated to MIDI.
 
+Since slurs are not interpreted, @code{\lyricsto} and
+@code{\addlyrics} sections will be interpreted wrongly.
+
 
 @menu
 * MIDI block::                  
diff --git a/VERSION b/VERSION
index c0480ca46d65dd75a8874460a4044fa355b289d1..126932f63d24c368b55cf4ce80836b0a7fb28008 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,6 +1,6 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=1
-PATCH_LEVEL=16
+PATCH_LEVEL=17
 MY_PATCH_LEVEL=
 
diff --git a/input/bugs/rhytmicstaff-tie.ly b/input/bugs/rhytmicstaff-tie.ly
deleted file mode 100644 (file)
index 197e3ac..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-% from José Luis Cruz <joseluis AT jazzartistas.com>
-\version "2.1.0"
-
-\header { 
-  texidoc="@cindex A tie in RhythmicStaff fails to compile."
-}
-
-\score { 
-  \context RhythmicStaff {
-    \notes { 
-        c1 ~ c1
-    }
-  }
-}
index 01a8818805f2a8c1c58e6a9ac6e95e53c2a68236..8bf714bb543621f9f95f4b5123e6926da461a94b 100644 (file)
@@ -3,19 +3,19 @@
 \header {
     texidoc = "Partcombiner and grace notes can go together."
 }
-    \paper { raggedright= ##t }
+
+\paper { raggedright= ##t }
 
 \score {
-    \new StaffGroup <<
-       \new Staff <<
-           \context Voice=one \partcombine Voice
-           \context Thread=one \notes \relative c'' {
+    \new Staff
+           \newpartcombine 
+            \notes \relative c'' {
                c4 d e f  \grace f16 g1
            }
-           \context Thread=two \notes \relative c' {
+            \notes \relative c' {
                c4 d e2  g1
            }
-       >>
-    >>
+       
+    
 }
 
index fffacd9c7daf72b9ca6b6a65dd7c358e273e6dec..41a9ccfe6eeb32bdfb14065ed1a9b832bdca4dc3 100644 (file)
@@ -1,9 +1,9 @@
 \version "2.1.10"
 \header {
 
-    texidoc = "With the newaddlyrics mechanism, individual lyric lines
-    can be associated with one melody line. For each lyric line, can
-    be tuned whether to follow melismata or not."
+    texidoc = "With the @code{\\lyricsto} mechanism, individual lyric
+    lines can be associated with one melody line. For each lyric line,
+    can be tuned whether to follow melismata or not."
     
 }
 
diff --git a/input/regression/new-markup-scheme.ly b/input/regression/new-markup-scheme.ly
new file mode 100644 (file)
index 0000000..81eb14f
--- /dev/null
@@ -0,0 +1,64 @@
+
+\header {
+
+    texidoc = "There is a Scheme macro @code{markup} to produce markup
+    texts using a similar syntax as @code{\\markup}."
+
+    }
+\version "2.1.16"
+\score {
+    \notes {
+        \fatText
+        f'1-\markup {
+            foo
+            \raise #0.2 \hbracket \bold bar
+            \override #'(baseline-skip . 4)
+
+            \bracket \column < baz bazr bla >
+            \hspace #2.0
+            \override #'(font-family . music) {
+                \lookup #"noteheads-0"
+                \char #53
+            }
+            \musicglyph #"accidentals--1"
+            \combine "X" "+"   
+            \combine "o" "/"
+            \box \column < { "string 1" } { "string 2" } >
+            "$\\emptyset$"
+            \italic Norsk
+            \super "2"
+            \dynamic sfzp
+            \huge { "A" \smaller "A" \smaller \smaller "A"
+                    \smaller \smaller \smaller "A" }
+            \sub "alike"
+        }      
+        \break
+        f'1-#(markup* 
+              "foo"
+              #:raise 0.2 #:hbracket #:bold "bar"
+              #:override '(baseline-skip . 4) 
+              #:bracket #:column ( "baz" "bazr" "bla" )
+              #:hspace 2.0
+              #:override '(font-family . music) #:line (#:lookup "noteheads-0" 
+                                                        #:char 53)
+              #:musicglyph "accidentals--1"
+              #:combine "X" "+"   
+              #:combine "o" "/"
+              #:box #:column ("string 1" "string 2")
+              "$\\emptyset$"
+              #:italic "Norsk"
+              #:super "2"
+              #:dynamic "sfzp"
+              #:huge #:line ("A" #:smaller "A" #:smaller #:smaller "A" 
+                             #:smaller #:smaller #:smaller "A")
+              #:sub "alike")
+    }
+    \paper { 
+        raggedright = ##t
+        indent = #0
+        \translator {
+            \StaffContext
+            \remove Time_signature_engraver 
+        }
+    }
+}
diff --git a/input/regression/new-part-combine-text.ly b/input/regression/new-part-combine-text.ly
new file mode 100644 (file)
index 0000000..89a6530
--- /dev/null
@@ -0,0 +1,18 @@
+
+\header {
+    texidoc ="The new part combiner:
+
+Detect a2, solo1, solo2  and print texts accordingly.
+"
+
+    
+    }
+
+
+vone = \notes \relative a' { R1 a4 r4 r r a a a a }
+vtwo = \notes \relative a' { R1 f4 f4 f4 f f f a a  }
+
+\score {
+   \newpartcombine \vone \vtwo
+}
index e83d6bdde30ff59ccd7b10231bd6f957ab48d41f..dfc3cb5d873238639a4d444ffd4bfb45a2caa5f2 100644 (file)
@@ -10,10 +10,6 @@ Apart for:
 "
     }
 
-theMusic = \context Staff \notes { c4 d8-. }
-
-
-
 vone = \notes \relative a' { g2 g    g  g4 g f' c c( c) c c  c ~ c
                             c2. c4   c
                         }
diff --git a/input/regression/pc-mmrest.ly b/input/regression/pc-mmrest.ly
deleted file mode 100644 (file)
index a4cb9d5..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-
-\version "2.1.7"
-\header {
-texidoc="Multi measure rests of second voice should not disappear."
-}
-
-
-%{
-
-TODO:  what does this test? The contexts are tweaked too much.
-
-%}
-
-#(ly:set-point-and-click 'line-column)
-one = \notes\relative c'' {
-
-       f4 e\!-.\f r2|
-       R1|
-       f2\p(es )|
-       d1\<|
-       d1|
-       d2 d2|
-       d2 d2|
-       f1\!\ff  |
-       f1
-}
-
-two = \notes \relative c'' {
-       r4 c r2|
-       R1*6|
-       c1 ~|
-       c1
-}
-       
-\score {
-  \notes <<
-    \context Staff = Viole <<
-       \context Voice=one \partcombine Voice
-               \context Thread=one \one
-               \context Thread=two \two
-    >>
-  >>
-  \paper {
-    \translator {
-      \ThreadContext
-      \consists "Rest_engraver"
-    }
-    \translator {
-      \VoiceContext
-      \remove "Rest_engraver"
-      \consists Multi_measure_rest_engraver
-      \consists Bar_engraver
-    }
-    \translator {
-      \RemoveEmptyStaffContext
-      \remove Multi_measure_rest_engraver
-      \remove Bar_engraver
-    }
-    \translator {
-      \OrchestralScoreContext
-      RestCollision \override #'maximum-rest-count = #1
-    }
-  }
-}
diff --git a/input/regression/pc-switch-slur.ly b/input/regression/pc-switch-slur.ly
deleted file mode 100644 (file)
index 5614ee4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-
-\version "2.1.7"
-\header{
-texidoc="The partcombiner should not combine two small slurs into a big one."
-}
-
-\score{
-       \context Staff <<
-               \context Voice=one\skip 1
-               \context Voice=two\skip 1
-               \context Voice=one \partcombine Voice
-                       \context Thread=one \notes\relative c'' {
-                               c4( c b  a) 
-                               a( b c  d)
-                       }
-                       \context Thread=two \notes\relative c'' {
-                               a4( c b  a)
-                               a( b c  a)
-                               
-                       }
-       >>
-       \paper{
-               linewidth=140.\mm
-       }
-}
-
-
-
diff --git a/input/test/lyrics-skip-notes.ly b/input/test/lyrics-skip-notes.ly
new file mode 100644 (file)
index 0000000..4673ea5
--- /dev/null
@@ -0,0 +1,23 @@
+
+\header
+{
+texidoc ="
+
+By inserting @code{\\skip} statements into lyric lines, one can put less lyric syllables to a melody. 
+
+"
+}
+
+
+% shorthand for Skip Lyric
+sl = \notes { \skip 4 }
+
+\version "2.1.16"
+\score {
+  <<
+  \context Voice = "A"  \notes  {c4 c c c}
+  \lyricsto "A" \context LyricsVoice=A \lyrics { foo __ \sl \sl bar }
+  \lyricsto "A" \context LyricsVoice=B \lyrics { foo -- \sl baz bar }
+  \lyricsto "A" \context LyricsVoice=C \lyrics { foo -- baz -- baaz bar }
+  >>
+}
diff --git a/input/test/part-combine-moments.ly b/input/test/part-combine-moments.ly
deleted file mode 100644 (file)
index fa0ac90..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-
-\version "2.1.7"
-% TODO: this example has a ton of text for very little output.
-% Is it all needed?  -gp
-% should this go to regression or be delete'd?   -gp
-\header{ texidoc="@cindex Part Combine Moments
-When you combine two voices with the same notes, you should
-only have one stem. "
-}
-
-\score{
-       \context PianoStaff <<
-               \context StaffCombineStaff=one \skip 1*2
-               \context StaffCombineStaff=two \skip 1*2
-               \context StaffCombineStaff=one \partcombine StaffCombineStaff
-                       \context StaffCombineVoice=one \notes\relative c''
-                               {
-                                       c4 d e f\break
-                                       c2 e4 f\break
-                               }
-                       \context StaffCombineVoice=two \notes\relative c''
-                               {
-                                       c4 d e f
-                                       c2 e2
-                               }
-               >>
-       \paper {
-               raggedright= ##t
-               textheight = 295.0\mm
-               linewidth = 180.0\mm
-
-               \translator{ \RemoveEmptyStaffContext }
-               %
-               % The Voice combine hierarchy
-               %
-               \translator{
-                       \ThreadContext
-                       \name "VoiceCombineThread"
-                       \consists "Rest_engraver"
-               }
-               \translator{
-                       \VoiceContext
-                       \name "VoiceCombineVoice"
-                       soloText = #"I."
-                       soloIIText = #"II."
-                       \remove "Rest_engraver"
-                       \accepts "VoiceCombineThread"
-               }
-               \translator{
-                       \RemoveEmptyStaffContext
-                       \consists "Mark_engraver"
-                       \name "VoiceCombineStaff"
-                       \accepts "VoiceCombineVoice"
-               }
-
-               %
-               % The Staff combine hierarchy
-               %
-               \translator{
-                       \ThreadContext
-                       \name "StaffCombineThread"
-               }
-               \translator{
-                       \VoiceContext
-                       \name "StaffCombineVoice"
-                       \accepts "StaffCombineThread"
-                       \consists "Thread_devnull_engraver"
-               }
-               \translator {
-                       \RemoveEmptyStaffContext
-                       \name "StaffCombineStaff"
-                       \accepts "StaffCombineVoice"
-
-                       soloADue = ##t
-                       soloText = #""
-                       soloIIText = #""
-                       aDueText = #""
-                       splitInterval = #'(1 . 0)
-                       changeMoment = #`(,(ly:make-moment 1 1) . ,(ly:make-moment 1 1))
-
-               }
-               \translator {
-                       \StaffGroupContext
-                       \accepts "VoiceCombineStaff"
-                       \accepts "StaffCombineStaff"
-               }
-               \translator{ \RemoveEmptyStaffContext }
-
-               \translator {
-                       \ScoreContext
-                       \accepts "VoiceCombineStaff"
-                       \accepts "StaffCombineStaff"
-                       skipBars = ##t 
-
-                       RehearsalMark \override #'padding = #4
-                       BarNumber \override #'padding = #3
-                       TimeSignature \override #'style = #'C
-                       RestCollision \set #'maximum-rest-count = #1
-               }
-       }
-}
-
diff --git a/input/test/part-combine-staff.ly b/input/test/part-combine-staff.ly
deleted file mode 100644 (file)
index 3b6226f..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-
-\version "2.1.7"
-\header { texidoc = "@cindex Part Combine Staff
-You can combine parts on two staffs, as well as two voices. "
-}
-
-\score{
-       \context PianoStaff <<
-               \context StaffCombineStaff=one \skip 1*7
-               \context StaffCombineStaff=two \skip 1*7
-               \context StaffCombineStaff=one \partcombine StaffCombineStaff
-                       \context StaffCombineVoice=one \notes\relative c''
-                               {
-                                       c4 d e f\break
-                                       c d e f\break
-                                       c d e f
-                                       c4 d e f\break
-                                       a8 a a a b b b b
-                                       a,4 a a a\break
-                                       c2 e4 f\break
-                               }
-                       \context StaffCombineVoice=two \notes\relative c''
-                               {
-                                       c2 e2
-                                       c4 d e f
-                                       c2 e2
-                                       c,4 d e f
-                                       a8 a a a b b b b
-                                       a4 a a a
-                                       c2 e2
-                               }
-               >>
-       \paper {
-               textheight = 295.0\mm
-               linewidth = 180.0\mm
-
-               \translator{ \RemoveEmptyStaffContext }
-               %
-               % The Voice combine hierarchy
-               %
-               \translator{
-                       \ThreadContext
-                       \name "VoiceCombineThread"
-                       \consists "Rest_engraver"
-               }
-               \translator{
-                       \VoiceContext
-                       \name "VoiceCombineVoice"
-                       soloText = #"I."
-                       soloIIText = #"II."
-                       \remove "Rest_engraver"
-                       \accepts "VoiceCombineThread"
-               }
-               \translator{
-                       \RemoveEmptyStaffContext
-                       \consists "Mark_engraver"
-                       \name "VoiceCombineStaff"
-                       \accepts "VoiceCombineVoice"
-               }
-
-               %
-               % The Staff combine hierarchy
-               %
-               \translator{
-                       \ThreadContext
-                       \name "StaffCombineThread"
-               }
-               \translator{
-                       \VoiceContext
-                       \name "StaffCombineVoice"
-                       \accepts "StaffCombineThread"
-                       \consists "Thread_devnull_engraver"
-               }
-               \translator {
-                       \RemoveEmptyStaffContext
-                       \name "StaffCombineStaff"
-                       \accepts "StaffCombineVoice"
-
-                       soloADue = ##t
-                       soloText = #""
-                       soloIIText = #""
-                       aDueText = #""
-                       splitInterval = #'(1 . 0)
-                       changeMoment = #`(,(ly:make-moment 1 1) . ,(ly:make-moment 1 1))
-
-               }
-               \translator {
-                       \StaffGroupContext
-                       \accepts "VoiceCombineStaff"
-                       \accepts "StaffCombineStaff"
-               }
-               \translator{ \RemoveEmptyStaffContext }
-
-               \translator {
-                       \ScoreContext
-                       \accepts "VoiceCombineStaff"
-                       \accepts "StaffCombineStaff"
-                       skipBars = ##t 
-
-                       %%% FIXME barScriptPadding = #2.0 % dimension \pt
-                       RehearsalMark \override #'padding = #4
-                       BarNumber \override #'padding = #3
-                       
-                       %% URG: this changes dynamics too
-                       %%textStyle = #"italic"
-                       TimeSignature \override #'style = #'C
-
-                       RestCollision \set #'maximum-rest-count = #1
-
-               }
-       }
-}
-
diff --git a/input/test/text-rotate.ly b/input/test/text-rotate.ly
new file mode 100644 (file)
index 0000000..bb750a9
--- /dev/null
@@ -0,0 +1,30 @@
+\header {
+    latexpackages = "graphicx"
+    
+    texidoc = "
+@cindex rotated text
+@cindex choir, rotated text
+
+Rotated text may be faked using inline TeX (or inline
+postscript). To see the result, this files must be processed with
+the lilypond.py script, and a line must be uncommented.
+
+"
+
+    %% fixme.
+    
+
+    }
+\score {
+\new Staff \notes \relative c'' {
+    \property Staff.instrument = #"rotatebox{90}{Chor}"
+
+%%  uncomment this for rotation
+%    \property Staff.instrument        = #"\\rotatebox{90}{Chor}"
+
+    c4 c4 }
+
+\paper { raggedright = ##t }
+}
+
+
index 79007d0df9569e44e69cd8196b9adb74a648c78d..1667e5a7b707dc922f89bcec19a83423a248ee2c 100644 (file)
@@ -6,30 +6,6 @@ Transposition test file."
 }
 
 
-%{
-Hi all,
-
-I have extend Mats' patches to allow accidental transposition:
-        \keysignature bes es fis
-               = \transpose c' d =>>
-        \keysignature gis
-
-As you can see in output =  the example file "test.ly" there are a few problems left:
-- key undo (already in the Todo)
-- "wrong" transposition: e.g. \transpose c' d of fis-major = gis-major (better as-major?).
-       The solution gis=as etc. would concern both note and key transposistion
-
-Eric
-
-- Note that transpose eses of fis-major = as-major 
-- Note also that key signatures specified with \property keySignature 
-  are not transposed!
-
-  /Mats B, March 21, 2001
-%}
-
-
-
 
 vOne =  \notes \relative c''{
         \clef"violin"
@@ -46,18 +22,19 @@ vTwo =  \notes \transpose c d { \vOne }
 
 vThree =  \notes \relative c''{
         \clef"violin"
-%        \keysignature fis cis
+%        keysignature fis cis
        \property Staff.keySignature = #'((0 . 2)(3 . 2))
         \time 2/4 
         d4 d |       
-%        \keysignature bes es fis
+%        keysignature bes es fis
        \property Staff.keySignature = #'((3 . 2)(2 . -2)(6 . -2))
         fis4 fis |         
-%        \keysignature fis cis gis dis ais eis
+%        keysignature fis cis gis dis ais eis
        \property Staff.keySignature = #'((2 . -2)(5 . -2)(1 . 2)(4 . 2)(0 . 2)(3 . 2))
         cis4 ais4 |
 }
 
+
 vFour =  \notes \transpose c d \vThree
 
 \score {
index 8e14ca48e366ee4bf659c604e80744dece21c122..fb83dc407fbe809c412ba69a9c567b38ed30a023 100644 (file)
@@ -2,32 +2,22 @@
   hyphen-engraver.cc -- implement Hyphen_engraver
 
   source file of the GNU LilyPond music typesetter
-
-  (c)  1999--2003 Glen Prideaux <glenprideaux@iname.com>
+  
+  (c)  1999--2003 Glen Prideaux <glenprideaux@iname.com>,
+                  Han-Wen Nienhuys <hanwen@cs.uu.nl>,
+                  Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
-#include "flower-proto.hh"
-#include "event.hh"
+#include "warn.hh"
 #include "hyphen-spanner.hh"
-#include "paper-column.hh"
 #include "item.hh"
 #include "engraver.hh"
 
-/**
-  Generate an centred hyphen.  Should make a Hyphen_spanner that
-  typesets a nice centred hyphen of varying length depending on the
-  gap between syllables.
-
-  We remember the last Item that come across. When we get a
-  event, we create the spanner, and attach the left point to the
-  last lyrics, and the right point to any lyrics we receive by
-  then.  */
 class Hyphen_engraver : public Engraver
 {
-  Grob *last_lyric_;
-  Grob *current_lyric_;
-  Music* req_;
+  Music* ev_;
   Spanner* hyphen_;
+  Spanner * finished_hyphen_;  
 public:
   TRANSLATOR_DECLARATIONS(Hyphen_engraver);
 
@@ -36,33 +26,33 @@ protected:
   virtual void finalize ();
   virtual bool try_music (Music*);
   virtual void stop_translation_timestep ();
-  virtual void process_acknowledged_grobs ();
+  virtual void process_music ();
 private:
 
 };
 
 
 
+
 Hyphen_engraver::Hyphen_engraver ()
 {
-  current_lyric_ = 0;
-  last_lyric_ = 0;
   hyphen_ = 0;
-  req_ = 0;
+  finished_hyphen_ = 0;
+  ev_ = 0;
 }
 
 void
 Hyphen_engraver::acknowledge_grob (Grob_info i)
 {
-  // -> text-item
-  if (i.grob_->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
+  Item * item =  dynamic_cast<Item*> (i.grob_);
+  // -> text_item
+  if (item && item->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
     {
-      current_lyric_ = i.grob_;
-      if (hyphen_
-         && !hyphen_->get_bound (RIGHT))
-         {
-           hyphen_->set_bound (RIGHT, i.grob_);
-         }
+      if (hyphen_)
+       hyphen_->set_bound (LEFT, item);
+
+      if (finished_hyphen_)
+       finished_hyphen_->set_bound (RIGHT, item);
     }
 }
 
@@ -70,38 +60,61 @@ Hyphen_engraver::acknowledge_grob (Grob_info i)
 bool
 Hyphen_engraver::try_music (Music* r)
 {
-  if (req_)
-       return false;
+  if (ev_)
+    return false;
 
-      req_ = r;
-      return true;
+  ev_ = r;
+  return true;
+}
+
+void
+completize_hyphen (Spanner* sp)
+{
+  if (!sp->get_bound (RIGHT))
+    {
+      SCM heads = sp->get_grob_property ("heads");
+      if (gh_pair_p (heads))
+       {
+         Item* it = dynamic_cast<Item*> (unsmob_grob (gh_car (heads)));
+         if (it)
+           sp->set_bound (RIGHT, it);
+       }
+    }
 }
 
+  
+
 void
 Hyphen_engraver::finalize ()
 {
   if (hyphen_)
     {
-      req_->origin ()->warning (_ ("unterminated hyphen"));
-      hyphen_->set_bound (RIGHT, unsmob_grob (get_property ("currentCommandColumn")));
+      completize_hyphen (hyphen_);
+
+      if (!hyphen_->get_bound (RIGHT))
+       hyphen_->warning (_ ("unterminated hyphen"));
+      typeset_grob (hyphen_);
+      hyphen_ = 0;
+    }
+
+  if (finished_hyphen_)
+    {
+      completize_hyphen (finished_hyphen_);
+
+      if (!finished_hyphen_->get_bound (RIGHT))
+         finished_hyphen_->warning (_("unterminated hyphen"));
+      typeset_grob (finished_hyphen_);
+      finished_hyphen_ =0;
     }
 }
 
 void
-Hyphen_engraver::process_acknowledged_grobs ()
+Hyphen_engraver::process_music ()
 {
-  if (req_ &&! hyphen_)
+  if (ev_)
     {
-      if (!last_lyric_)
-       {
-         req_->origin ()->warning (_ ("Nothing to connect hyphen to on the left.  Ignoring hyphen event."));
-         return;
-       }
-      
       hyphen_ = make_spanner ("LyricHyphen");
-
-      hyphen_->set_bound (LEFT, last_lyric_);
-      announce_grob(hyphen_, req_->self_scm());
+      announce_grob (hyphen_, ev_->self_scm());
     }
 }
 
@@ -109,21 +122,29 @@ Hyphen_engraver::process_acknowledged_grobs ()
 void
 Hyphen_engraver::stop_translation_timestep ()
 {
-  if (hyphen_)
+  if (finished_hyphen_ && finished_hyphen_->get_bound (RIGHT))
     {
-      typeset_grob (hyphen_);
-      hyphen_ = 0;
+      typeset_grob (finished_hyphen_);
+      finished_hyphen_ = 0;
     }
 
-  if (current_lyric_)
+  if (finished_hyphen_ && hyphen_)
     {
-      last_lyric_ = current_lyric_;
-      current_lyric_ =0;
+      programming_error ("Haven't finished hyphen yet.");
+      typeset_grob (finished_hyphen_);
+      finished_hyphen_ =0;
     }
-  req_ = 0;
+  
+  if (hyphen_)
+    finished_hyphen_ = hyphen_;
+  hyphen_ = 0;
+
+  ev_ = 0;
 }
 
 
+
+
 ENTER_DESCRIPTION(Hyphen_engraver,
 /* descr */       "Create lyric hyphens",
 /* creats*/       "LyricHyphen",
index b5d0729108c5381cb2cef56b4bda519aa1546380..e7c2e84696ca45fcfc8b69fca5a09b902a518554 100644 (file)
@@ -72,7 +72,7 @@ New_lyric_combine_music_iterator::start_new_syllable ()
     return false;
 
   if (!lyrics_context_)
-    construct_children ();
+    return false;
   
   if (!to_boolean (lyrics_context_->get_property ("ignoreMelismata")))
     {
@@ -135,7 +135,7 @@ Translator_group *
 find_context_below (Translator_group * where,
                    String type, String id)
 {
-  if (where->context_name () == type)
+  if (where->is_alias (ly_symbol2scm (type.to_str0 ())))
     {
       if (id == "" || where->id_string_ == id)
        return where;
@@ -147,7 +147,6 @@ find_context_below (Translator_group * where,
     {
       Translator_group * tr = dynamic_cast<Translator_group*> (unsmob_translator (gh_car (s)));
 
-      
       found = find_context_below (tr, type, id);
     }
 
@@ -167,10 +166,12 @@ New_lyric_combine_music_iterator::construct_children ()
   if (lyric_iter_)
     lyrics_context_ = find_context_below (lyric_iter_->report_to (),
                                          "LyricsVoice", "");
-  
-  if (music_context_ && !lyrics_context_)
-    lyrics_context_ = music_context_
-      ->find_create_translator (ly_symbol2scm ("LyricsVoice"), "", SCM_EOL);
+
+  /*
+    We do not create a LyricsVoice context, because the user might
+    create one with a different name, and then we will not find that
+    one.
+   */
 }
 
 void
index ecb4534c17445cdd1306391171c195e9707f7c9b..c98761aa9d7f49fe34a64359219f30ff4d893acd 100644 (file)
@@ -43,6 +43,12 @@ private:
   bool is_shared_ ;
   SCM split_list_;
 
+  enum  {
+    APART, TOGETHER,
+    SOLO1, SOLO2,
+    UNISONO,
+  } state_;
+
   Interpretation_context_handle one_;
   Interpretation_context_handle two_;
   Interpretation_context_handle null_;
@@ -62,6 +68,7 @@ New_pc_iterator::New_pc_iterator ()
   first_iter_ = 0;
   second_iter_ = 0;
   split_list_ = SCM_EOL;
+  state_ = APART;
 }
 
 void
@@ -137,59 +144,102 @@ New_pc_iterator::ok () const
 void
 New_pc_iterator::chords_together ()
 {
-  first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
-  first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
-  second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+  if (state_ == TOGETHER)
+    return;
+  else
+    {
+      state_ = TOGETHER;
+      first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+      first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+      second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+      second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+    }
 }
 
 
 void
 New_pc_iterator::solo1 ()
 {
-  first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+  if (state_ == SOLO1)
+    return;
+  else
+    {
+      state_ = SOLO1;
+      first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+      first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
 
-  second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
-  second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
-}
+      second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
+      second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
+
+      static Music* event;
+      if (!event)
+       event = make_music_by_name (ly_symbol2scm ("SoloOneEvent"));
 
+    first_iter_-> try_music_in_children (event);
+    }
+}
 void
 New_pc_iterator::unisono ()
 {
-  /*
-    like solo1, but should set a2 string.
-   */
-  first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
-
-  second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
-  second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
-}
+  if (state_ == UNISONO)
+    return;
+  else
+    {
+      state_ = UNISONO;
+
+      first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+      first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+
+      second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
+      second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
 
 
+      static Music* event;
+      if (!event)
+       event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
+
+      first_iter_-> try_music_in_children (event);      
+    }
+}
+
 void
 New_pc_iterator::solo2 ()
 {
-  second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+  if (state_ == SOLO2)
+    return;
+  else
+    {
+      state_ = SOLO2;
+      second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+      second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
 
-  first_iter_->substitute_outlet (one_.report_to (), null_.report_to ());
-  first_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
-}
+      first_iter_->substitute_outlet (one_.report_to (), null_.report_to ());
+      first_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
 
+      static Music* event;
+      if (!event)
+       event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent"));
+
+      second_iter_-> try_music_in_children (event);
+    }
+}
 
 void
 New_pc_iterator::apart ()
 {
-  first_iter_->substitute_outlet (null_.report_to (), one_.report_to ());
-  first_iter_->substitute_outlet (shared_.report_to (), one_.report_to ());
+  if (state_ == APART)
+    return;
+  else
+    {
+      state_ = APART;
+  
+      first_iter_->substitute_outlet (null_.report_to (), one_.report_to ());
+      first_iter_->substitute_outlet (shared_.report_to (), one_.report_to ());
   
-  second_iter_->substitute_outlet (null_.report_to (), two_.report_to ());
-  second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ());
+      second_iter_->substitute_outlet (null_.report_to (), two_.report_to ());
+      second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ());    }
 }
 
-
 void
 New_pc_iterator::construct_children ()
 {
index c22c66a42575b989c01ced4da9862181e139751e..277365e90f129bb802b8f3068480533d3ec4f2bf 100644 (file)
@@ -390,7 +390,6 @@ yylex (YYSTYPE *s,  void * v)
 %type <music> shorthand_command_req
 %type <music>  post_event tagged_post_event
 %type <music> command_req verbose_command_req
-%type <music> hyphen_req
 %type <music> string_number_event
 %type <scm>    string bare_number number_expression number_term number_factor 
 %type <score>  score_block score_body
@@ -1425,10 +1424,7 @@ command_req:
        ;
 
 shorthand_command_req:
-       hyphen_req {
-               $$ = $1;
-       }
-       | BREATHE {
+       BREATHE {
                $$ = MY_MAKE_MUSIC("BreathingSignEvent");
        }
        | E_TILDE {
@@ -1499,6 +1495,11 @@ post_event:
        direction_less_event {
                $$ = $1;
        }
+       | HYPHEN {
+               if (!THIS->lexer_->lyric_state_b ())
+                       THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
+               $$ = MY_MAKE_MUSIC("HyphenEvent");
+       }
        | EXTENDER {
                if (!THIS->lexer_->lyric_state_b ())
                        THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
@@ -1664,14 +1665,6 @@ pitch_also_in_chords:
        | steno_tonic_pitch
        ;
 
-hyphen_req:
-       HYPHEN {
-               if (!THIS->lexer_->lyric_state_b ())
-                       THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
-               $$ = MY_MAKE_MUSIC("HyphenEvent");
-       }
-       ;
-
 close_event:
        '('     {
                Music * s= MY_MAKE_MUSIC("SlurEvent");
diff --git a/lily/part-combine-engraver.cc b/lily/part-combine-engraver.cc
new file mode 100644 (file)
index 0000000..1952395
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+  part-combine-engraver.cc -- implement PC-engraver
+
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2000--2003 Jan Nieuwenhuizen <janneke@gnu.org>
+
+  Han-Wen Nienhuys <hanwen@xs4all.nl>
+  
+*/
+
+#include "engraver.hh"
+#include "item.hh"
+#include "text-item.hh"
+#include "note-head.hh"
+#include "stem.hh"
+#include "side-position-interface.hh"
+#include "multi-measure-rest.hh"
+
+class Part_combine_engraver : public Engraver
+{
+  TRANSLATOR_DECLARATIONS(Part_combine_engraver);
+
+protected:
+  virtual void acknowledge_grob (Grob_info);
+  virtual void process_music ();
+  virtual void stop_translation_timestep ();
+  virtual bool try_music (Music *);
+private:
+  Item *text_;
+  Music *event_;
+};
+
+bool
+Part_combine_engraver::try_music (Music*m)
+{
+  event_ = m;
+  return true;
+}
+
+Part_combine_engraver::Part_combine_engraver ()
+{
+  text_ = 0;
+  event_  =0;
+}
+
+void
+Part_combine_engraver::process_music ()
+{
+  if (event_
+      && to_boolean (get_property ("soloADue")))
+    {
+      SCM what = event_->get_mus_property ("part-combine-status");
+      SCM text = SCM_EOL;
+      if (what == ly_symbol2scm ("solo1"))
+       text = get_property ("soloText");
+      else if (what== ly_symbol2scm ("solo2"))
+       text = get_property ("soloIIText");
+      else if (what == ly_symbol2scm ("unisono"))
+       text = get_property ("aDueText");
+
+      if (Text_item::markup_p (text))
+       {
+         text_ =  make_item ("CombineTextScript");
+         text_->set_grob_property ("text", text);
+         announce_grob (text_, event_->self_scm ());
+       }
+    }
+}
+
+void
+Part_combine_engraver::acknowledge_grob (Grob_info i)
+{
+  if (text_)
+    {
+      if (Note_head::has_interface (i.grob_))
+       {
+         Grob*t = text_;
+         Side_position_interface::add_support (t, i.grob_);
+         if (Side_position_interface::get_axis (t) == X_AXIS
+             && !t->get_parent (Y_AXIS))
+           t->set_parent (i.grob_, Y_AXIS);
+       }
+      if (Stem::has_interface (i.grob_))
+       {
+         Side_position_interface::add_support (text_, i.grob_);
+       }
+    }
+}
+
+void 
+Part_combine_engraver::stop_translation_timestep ()
+{
+  if (text_)
+    {
+      typeset_grob (text_);
+      text_ = 0;
+    }
+  event_ = 0;
+}
+
+ENTER_DESCRIPTION(Part_combine_engraver,
+/* descr */       "Part combine engraver for orchestral scores:                "
+                 "Print markings a2, Solo, Solo II, and unisono ",
+/* creats*/       "CombineTextScript",
+/* accepts */     "part-combine-event",
+/* acks  */       "multi-measure-rest-interface "
+"slur-interface stem-interface note-head-interface"
+,/* reads */       "soloADue",
+/* write */       "");
index 12ea01c52ee8517b8b2eb1c5ef09b5e5647fb650..6e767ef2dd1a696c879d37f31a8ad52ae421f13d 100644 (file)
@@ -7,7 +7,7 @@
   
  */
 
-
+#include "translator-group.hh"
 #include "audio-item.hh"
 #include "event.hh"
 #include "pqueue.hh"
@@ -52,6 +52,7 @@ private:
   Link_array<Audio_tie> ties_;
   
 protected:
+  virtual void process_music ();
   virtual void start_translation_timestep ();
   virtual void stop_translation_timestep ();
   virtual void acknowledge_audio_element (Audio_element_info);
@@ -59,6 +60,13 @@ protected:
   virtual void create_audio_elements ();
 };
 
+void
+Tie_performer::process_music ()
+{
+  if (event_)
+    daddy_trans_->set_property ("tieMelismaBusy", SCM_BOOL_T);
+}
+
 
 Tie_performer::Tie_performer ()
 {
index 351eed8fef81070122bef1aec3c34ea7945effa0..352331c630840a6b648f5a210a144f0407e826f8 100644 (file)
@@ -258,7 +258,16 @@ Tuplet_bracket::make_bracket (Grob *me,    // for line properties.
   Direction d = LEFT;
   do {
     straight_corners[d] += - d * shorten[d] /length * dz;
-    gap_corners[d] = (dz * 0.5) + d * gap / length * dz;
+  } while (flip (&d) != LEFT);
+
+  /*
+    UGH: the shortening factor is magic.
+   */
+  gap = gap <?
+    (0.66 * (straight_corners[RIGHT] - straight_corners[LEFT]).length ());
+  
+  do {
+    gap_corners[d] = (dz * 0.5) + d * 0.5 * gap / length * dz;
   } while (flip (&d) != LEFT);
 
   Drul_array<Offset> flare_corners = straight_corners;
index 193dd3ea47665f58f3cadb6fe6bae6c2837d1f1d..b664bd8578e4abb3fde587ba208b24111cca9d31 100644 (file)
        \consists "Percent_repeat_engraver"
        \consists "Slash_repeat_engraver"
        \consists "Melisma_engraver"
+       \consists "Part_combine_engraver"
 
 %{
  Must come before text_engraver, but after note_column engraver.
index 6d83c4278f02f338db9a1bb9357082113dec9a08..435adc0378d8306810dea1d88095522ddb22b198 100644 (file)
@@ -21,6 +21,7 @@
        (cautionary-style . parentheses)
        (after-line-breaking-callback . ,Accidental_interface::after_line_breaking)             (meta . ((interfaces . (item-interface accidental-interface font-interface))))
        ))
+    
     (AccidentalPlacement
      . (
        (X-extent-callback . ,Axis_group_interface::group_extent_callback)
@@ -28,7 +29,7 @@
 
        ;; this is quite small, but it is very ugly to have
        ;; accs closer to the previous note than to the next one.
-       (right-padding . 0.2)
+       (right-padding . 0.25)
        (meta . ((interfaces . (item-interface accidental-placement-interface))))
        ))
 
        (font-family . roman)
        (meta . ((interfaces . (text-script-interface text-interface side-position-interface font-interface item-interface ))))
        ))
-
+    (CombineTextScript
+     . (
+       (molecule-callback . ,Text_item::brew_molecule)
+       (no-spacing-rods . #t)
+       (Y-offset-callbacks . (,Side_position_interface::aligned_side))
+       (X-offset-callbacks . (,Self_alignment_interface::aligned_on_self))
+       (direction . 1)
+       (padding . 0.5)
+       (staff-padding . 0.5)
+       (script-priority . 200)
+       ;; todo: add X self alignment?
+       (baseline-skip . 2)
+       (font-family . roman)
+       (font-series . bold)
+       (meta . ((interfaces . (text-script-interface text-interface  side-position-interface font-interface item-interface ))))
+       ))
     (TextSpanner
      . (
        (molecule-callback . ,Text_spanner::brew_molecule)
 
     (TupletBracket
      . (
-       (gap . 2.0)
+       (gap . 1.0)
        (padding . 1.1)
        (thickness . 1.6)
        (edge-height . (0.7 . 0.7))
index 6731047090cb1a64ca84ceb4955933b9c8d46cf0..a118419f74fc0ad3e52d5b22981cbce030a0c7db 100644 (file)
@@ -79,7 +79,10 @@ For chord inversions, this is negative.")
                            "Do these operations for instantiating the context.")
 (music-property-description 'predicate procedure? "the predicate of a \\outputproperty")
 (music-property-description 'type symbol? "The type of this music object. Determines iteration in some cases.")
-(music-property-description 'types list? "The types of this music object. Determines iteration in some cases.")
+(music-property-description 'types list? "The types of this music
+object; determines by what engraver this music expression is
+processed.")
+
 (music-property-description 'repeat-count  integer? "do a @code{\repeat} how ofen?")
 (music-property-description 'span-direction ly:dir? "Does this start or stop a spanner?")
 (music-property-description 'split-list list? "splitting moments for part combiner.")
@@ -94,6 +97,9 @@ starting grace notes.")
 (music-property-description 'value scheme? "Assignment value for a
 translation property")
 (music-property-description 'what symbol? "What to change for auto-change. FIXME, naming")
+(music-property-description 'part-combine-status symbol?
+                           "Change to what kind of state? Options are
+solo1, solo2 and unisono")
 
 (music-property-description 'figure string? "a `figure' (which may be
 a string) for figured bass")
index 58ff4e01217fc700acee7782783f64941bf324f0..c845f602cb7f157466c09ca5e1c2407f64fc605c 100644 (file)
@@ -139,7 +139,7 @@ c8-[ c c-] c8")
     
     (CrescendoEvent
      . (
-   (description .  "Begins or ends a crescendo.  Syntax: @var{note}\\cr
+       (description .  "Begins or ends a crescendo.  Syntax: @var{note}\\cr
 ... @var{note}\\rc (you can also use \\<, \\!, \\cresc, and
 \\endcresc.  See the user manual for details.).")
 
@@ -405,6 +405,26 @@ to group start-mmrest, skip, stop-mmrest sequence. Syntax @code{R2.*5} for 5 mea
        (iterator-ctor . ,Sequential_music_iterator::constructor)
        (types . (general-music sequential-music))
        ))
+
+    (SoloOneEvent
+     . (
+       (description . "Print Solo.1")
+       (internal-class-name . "Event")
+       (part-combine-status . solo1)
+       (types . (general-music event part-combine-event))
+       ))
+    (SoloTwoEvent
+     . (
+       (description . "Print Solo.2")
+       (internal-class-name . "Event")
+       (part-combine-status . solo2)
+       (types . (general-music event part-combine-event))
+       ))
+    (UnisonoEvent
+     . ((description . "Print a2")
+       (internal-class-name .  "Event")
+       (part-combine-status . unisono)
+       (types . (general-music event part-combine-event))))
     
     (SimultaneousMusic
      . (
index 081163c8af0ec0a6088c8512e3c872b32f359b67..1b9297509f8eb77eeb7c53d53173e9027356c20f 100644 (file)
@@ -844,6 +844,10 @@ Rest can contain a list of beat groupings
     (cdr (vector-ref v i)))
 
   (define chord-threshold 8)
+  (define (get-note-evs v i)
+    (define (f? x)
+      (equal? (ly:get-mus-property  x 'name) 'NoteEvent))
+    (filter f? (map car (what v i))))
   
   (define result
     (list->vector
@@ -907,11 +911,7 @@ Rest can contain a list of beat groupings
                       (helper analyse-tie-end active evs) evs) evs)
        active<?))
     
-    (define (get-note-evs v i)
-      (define (f? x)
-       (equal? (ly:get-mus-property  x 'name) 'NoteEvent))
-      (filter f? (map car (what v i))))
-    
+
     (define (put x . index)
       "Put the result to X, starting from INDEX backwards."
       (let
@@ -981,6 +981,8 @@ Rest can contain a list of beat groupings
                (cond
                 ((> (length notes1) 1) (put 'apart))
                 ((> (length notes2) 1) (put 'apart))
+                ((not (= (length notes1) (length notes2)))
+                 (put 'apart))
                 ((and
                   (= (length durs1) 1)
                   (= (length durs2) 1)
@@ -988,36 +990,81 @@ Rest can contain a list of beat groupings
 
                  (put 'apart))
                 (else
-                 (if
-                  (and (= (length pitches1) 1) (= (length pitches2) 1) 
-                   (< chord-threshold (ly:pitch-steps
-                                       (ly:pitch-diff (car pitches1) (car pitches2)))))
-                       (put 'apart)
-
-
-                       ;; copy previous split state from spanner state
-                       (begin
-                         (map (lambda (key-idx)
-                                (let*
-                                    ((idx (cdr key-idx))
-                                     (prev (what result  idx))
-                                     )
-                                  (if (symbol? prev)
-                                      (put prev))
-                                  )) (append active1 active2))
-                         (if (and (null? new-active1) (null? new-active2))
-                             (put 'chords ri)))
-                   
-                   ))) )
+                 (if (and (= (length pitches1) (length pitches2)))
+                     (if
+                      (and (pair?  pitches1) (pair? pitches2)
+                      (< chord-threshold (ly:pitch-steps
+                                          (ly:pitch-diff (car pitches1) (car pitches2)))))
+                      (put 'apart)
+
+
+                      ;; copy previous split state from spanner state
+                      (begin
+                        (map (lambda (key-idx)
+                               (let*
+                                   ((idx (cdr key-idx))
+                                    (prev (what result  idx))
+                                    )
+                                 (if (symbol? prev)
+                                     (put prev))
+                                 )) (append active1 active2))
+                        (if (and (null? new-active1) (null? new-active2))
+                            (put 'chords ri))))
+                 
+                 ))))
+             
              ;; active states different: 
-             (put 'apart) )
-         (analyse-time-step (1+ i1) (1+ i2) (1+ ri) new-active1 new-active2))
-        )))))
+             (put 'apart))
+         (analyse-time-step (1+ i1) (1+ i2) (1+ ri) new-active1 new-active2)))
+        ))))
 
 ;; 
-  
-  
+   (define (analyse-solo12 i1 i2 ri)
+     (cond
+      ((= ri (vector-length result)) '())
+      ((= i1 (vector-length ev1)) '())
+      ((= i2 (vector-length ev2)) '())
+      (else
+       (let*
+         (
+          (m1 (when ev1 i1))
+          (m2 (when ev2 i2))
+          (notes1 (get-note-evs ev1 i1))
+          (durs1 (sort (map (lambda (x) (ly:get-mus-property x 'duration)) notes1) ly:duration<?))
+          (pitches1 (sort
+                     (map (lambda (x) (ly:get-mus-property x 'pitch)) notes1) ly:pitch<?))
+          (notes2 (get-note-evs ev2 i2))
+          (durs2 (sort (map (lambda (x) (ly:get-mus-property x 'duration)) notes2) ly:duration<?))
+          (pitches2 (sort
+                     (map (lambda (x) (ly:get-mus-property x 'pitch)) notes2) ly:pitch<?))
+          )
+
+        (if (equal? (what result ri) 'apart)
+            (cond
+             ((and (= 0 (length notes1))
+                  (< 0 (length notes2)))
+              (set-cdr! (vector-ref result ri) 'solo2))
+             ((and (< 0 (length notes1))
+                   (= 0 (length notes2)))
+              (set-cdr! (vector-ref result ri) 'solo1))
+             ))
+
+        (if (and
+             (equal? (what result ri) 'chords)
+             (pair? pitches1)
+             (equal? pitches1 pitches2))
+            (set-cdr! (vector-ref result ri) 'unisono) )
+        
+        (cond
+         ((ly:moment<? m1 m2)
+          (analyse-solo12 (1+ i1) i2 (1+ ri) ))
+         ((ly:moment<? m2 m1)
+          (analyse-solo12 i1 (1+ i2) (1+ ri) ))
+         (else
+          (analyse-solo12 (1+ i1) (1+ i2) (1+ ri)))
+         )))))
 
    (analyse-time-step 0 0  0 '() '())
+   (analyse-solo12 0 0 0)
 ;   (display result)
    (vector->list result))
index 06356aa9854cc4c0999fc9d87926b68ff44f63b7..4aa774a692202bb84f3ff08ca51a82dc556dc3b6 100644 (file)
@@ -82,6 +82,126 @@ against SIGNATURE, reporting MAKE-NAME as the user-invoked function.
                    error-msg #f)
         (cons markup-function args))))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; markup constructors
+;;; lilypond-like syntax for markup construction in scheme.
+
+(use-modules (ice-9 optargs)
+             (ice-9 receive))
+
+(defmacro*-public markup (#:rest body)
+  "The `markup' macro provides a lilypond-like syntax for building markups.
+
+ - #:COMMAND is used instead of \\COMMAND
+ - #:lines ( ... ) is used instead of { ... }
+ - #:center ( ... ) is used instead of \\center < ... >
+ - etc.
+
+Example:
+  \\markup { foo
+            \\raise #0.2 \\hbracket \\bold bar
+            \\override #'(baseline-skip . 4)
+            \\bracket \\column < baz bazr bla >
+  }
+         <==>
+  (markup \"foo\"
+          #:raise 0.2 #:hbracket #:bold \"bar\"
+          #:override '(baseline-skip . 4) 
+          #:bracket #:column (\"baz\" \"bazr\" \"bla\"))
+Use `markup*' in a \\notes block."
+  
+  (car (compile-all-markup-expressions `(#:line ,body))))
+
+(defmacro*-public markup* (#:rest body)
+  "Same as `markup', for use in a \\notes block."
+  `(ly:export (markup ,@body)))
+  
+  
+(define (compile-all-markup-expressions expr)
+  "Return a list of canonical markups expressions, eg:
+  (#:COMMAND1 arg11 arg12 #:COMMAND2 arg21 arg22 arg23)
+  ===>
+  ((make-COMMAND1-markup arg11 arg12)
+   (make-COMMAND2-markup arg21 arg22 arg23) ...)"
+  (do ((rest expr rest)
+       (markps '() markps))
+      ((null? rest) (reverse markps))
+    (receive (m r) (compile-markup-expression rest)
+             (set! markps (cons m markps))
+             (set! rest r))))
+
+(define (keyword->make-markup key)
+  "Transform a keyword, eg. #:COMMAND, in a make-COMMAND-markup symbol."
+  (string->symbol (string-append "make-" (symbol->string (keyword->symbol key)) "-markup")))
+
+(define (compile-markup-expression expr)
+  "Return two values: the first complete canonical markup expression found in `expr',
+eg (make-COMMAND-markup arg1 arg2 ...), and the rest expression."
+  (cond ((and (pair? expr)
+              (keyword? (car expr)))
+         ;; expr === (#:COMMAND arg1 ...)
+         (let* ((command (symbol->string (keyword->symbol (car expr))))
+                (sig (markup-command-signature (car (lookup-markup-command command))))
+                (sig-len (length sig)))
+           (do ((i 0 (1+ i))
+                (args '() args)
+                (rest (cdr expr) rest))
+               ((>= i sig-len)
+                (values (cons (keyword->make-markup (car expr)) (reverse args)) rest))
+             (cond ((eqv? (list-ref sig i) markup-list?)
+                    ;; (car rest) is a markup list
+                    (set! args (cons `(list ,@(compile-all-markup-expressions (car rest))) args))
+                    (set! rest (cdr rest)))
+                   (else
+                    ;; pick up one arg in `rest'
+                    (receive (a r) (compile-markup-arg rest)
+                             (set! args (cons a args))
+                             (set! rest r)))))))
+        ((and (pair? expr)
+              (pair? (car expr))
+              (keyword? (caar expr)))
+         ;; expr === ((#:COMMAND arg1 ...) ...)
+         (receive (m r) (compile-markup-expression (car expr))
+                  (values m (cdr expr))))
+        (else
+         ;; expr === (symbol ...) or ("string" ...) or ((funcall ...) ...)
+         (values (car expr)
+                 (cdr expr)))))
+
+(define (compile-all-markup-args expr)
+  "Transform `expr' into markup arguments"
+  (do ((rest expr rest)
+       (args '() args))
+      ((null? rest) (reverse args))
+    (receive (a r) (compile-markup-arg rest)
+             (set! args (cons a args))
+             (set! rest r))))
+
+(define (compile-markup-arg expr)
+  "Return two values: the desired markup argument, and the rest arguments"
+  (cond ((null? expr)
+         ;; no more args
+         (values '() '()))
+        ((keyword? (car expr))
+         ;; expr === (#:COMMAND ...)
+         ;; ==> build and return the whole markup expression
+         (compile-markup-expression expr))
+        ((and (pair? (car expr))
+              (keyword? (caar expr)))
+         ;; expr === ((#:COMMAND ...) ...)
+         ;; ==> build and return the whole markup expression(s)
+         ;; found in (car expr)
+         (receive (markup-expr rest-expr) (compile-markup-expression (car expr))
+                  (if (null? rest-expr)
+                      (values markup-expr (cdr expr))
+                      (values `(list ,markup-expr ,@(compile-all-markup-args rest-expr))
+                              (cdr expr)))))
+        ((and (pair? (car expr))
+              (pair? (caar expr)))
+         ;; expr === (((foo ...) ...) ...)
+         (values (cons 'list (compile-all-markup-args (car expr))) (cdr expr)))
+        (else (values (car expr) (cdr expr)))))
+
 ;;;;;;;;;;;;;;;
 ;;; Utilities for storing and accessing markup commands signature
 ;;; and keyword.