]> git.donarmstrong.com Git - lilypond.git/commitdiff
Enhancement: tabalture chord repetition
authorMarc Hohl <marc@hohlart.de>
Tue, 16 Mar 2010 23:27:56 +0000 (23:27 +0000)
committerNeil Puttock <n.puttock@gmail.com>
Tue, 16 Mar 2010 23:27:56 +0000 (23:27 +0000)
For better use with tablature, a new tab-repeat-chord function
is provided which takes care of the string information
(thanks to Nicolas Sceaux!). A new command \tabChordRepetition
is also included to switch to this new repetition style.

Documentation/notation/fretted-strings.itely
input/regression/tablature-chord-repetition.ly [new file with mode: 0644]
ly/chord-repetition-init.ly
ly/music-functions-init.ly

index e331891507d471206e3aa1774f67581536273156..0ef0d107257795dd97adca495486177303a860ec 100644 (file)
@@ -194,7 +194,7 @@ symbols = {
 
 If all musical symbols used in traditional notation should also show up
 in tablature one has to apply the command @code{\tabFullNotation} in a
-@code{TabStaff}-context. Please bear in mind that half notes are
+@code{TabStaff}-context.  Please bear in mind that half notes are
 double-stemmed in tablature in order to distinguish them from quarter
 notes.
 
@@ -221,13 +221,13 @@ symbols = {
 @funindex minimumFret
 
 By default pitches are assigned to the lowest playing position on the
-fret-board (first position). Open strings are automatically preferred.
+fret-board (first position).  Open strings are automatically preferred.
 If you would like a certain pitch to be played on a specific string
-you can add a string number indication to the pitch name. If you
+you can add a string number indication to the pitch name.  If you
 define pitch names and string numbers without a chord construct
 (@code{<>}) the string number indications do not appear in traditional
 notation. It is much more comfortable to define the playing position
-by using the value of @code{minimumFret}. The default value for
+by using the value of @code{minimumFret}.  The default value for
 minimumFret is 0.
 
 
@@ -249,8 +249,34 @@ minimumFret is 0.
 >>
 @end lilypond
 
+@funindex \tabChordRepetition
 
-Ties over a line break are parenthesized by default. The same holds for
+Chord constructs can be repeated by the chord repetition symbol @code{q}.
+To use this feature in combination with tablature, @code{\tabChordRepetition}
+is provided.  It preserves the string information explicitly given within
+chord constructs so repeated chords get identical tablature representations.
+
+@lilypond[quote,verbatim]
+\tabChordRepetition
+
+guitar = \relative c' {
+  r8 < gis\4 cis\3 b\2 > ~ q4 q8 ~ q q4
+}
+
+\new StaffGroup <<
+  \new Staff {
+    \clef "treble_8"
+    \override Voice.StringNumber #'transparent = ##t
+    \guitar
+  }
+  \new TabStaff {
+    \guitar
+  }
+>>
+@end lilypond
+
+
+Ties over a line break are parenthesized by default.  The same holds for
 the second alternative of a repeat.
 
 @lilypond[quote,ragged-right,verbatim]
diff --git a/input/regression/tablature-chord-repetition.ly b/input/regression/tablature-chord-repetition.ly
new file mode 100644 (file)
index 0000000..4d31770
--- /dev/null
@@ -0,0 +1,30 @@
+\version "2.13.17"
+
+\header {
+  texidoc = "In a TabStaff, the chord repetition function needs
+to save the string information. This is handled by
+@code{\\tabChordRepetition}."
+}
+
+\tabChordRepetition
+
+Guitar = \relative c' {
+  r8 < gis\4 cis\3 b\2 > ~ q4 q8 ~ q q4
+}
+
+\score {
+  \new StaffGroup <<
+    \new Staff {
+      \new Voice {
+        \clef "treble_8"
+        \override Voice.StringNumber #'transparent = ##t
+        \Guitar
+      }
+    }
+    \new TabStaff {
+      \new TabVoice {
+        \Guitar
+      }
+    }
+  >>
+}
index f19e3a10b50d5433168ed4c92bafedf90526599d..1056cdec2feac1bbf83e84be7bfccb5d4ab62b86 100644 (file)
@@ -1,5 +1,5 @@
 %%% -*- Mode: Scheme -*-
-\version "2.13.9"
+\version "2.13.17"
 %{
 
 The following functions define the chord repetition behavior, and may
@@ -16,36 +16,63 @@ ly:parser-set-repetition-function
   (previous-chord, location, duration, list of articulations) which is
   supposed to return a new chord.
   `default-repeat-chord' is the default function set in this file.
+  `tab-repeat-chord' may be used in tablatures to preserve the string information.
 %}
 
-#(define-public (default-repeat-chord previous-chord location duration articulations)
-   "Copy the previous chord, filter out events which are not notes, set
-the chord duration, add articulations."
+#(define-public ((make-repeat-chord-function chord-element-types note-articulation-types)
+                 previous-chord location duration articulations)
+   "Make a chord repetition function.
+The returned functions copies the notes from @var{previous-chord} into a new chord.
+Chord elements, which type is found in @var{chord-element-types}, are copied into
+the new chord. Note articulations, which type is found in @var{note-articulation-types},
+are also copied. All other events are not copied into the new chord."
+   (define (filter-events events event-types)
+     (filter (lambda (event)
+              (and (memq (ly:music-property event 'name) event-types) event))
+            events))
    ;; If previous-chord has an length property, then it means that it
    ;; has been processed by a music iterator.  In other words, the chord
-   ;; has been memorized in an other music block, which is certainly not
-   ;; what the user has intended.  In that case, raise a warning.
+   ;; has been memorized from an other music block, which is certainly not
+   ;; what the user has intended, as anywy the result will be buggy.
+   ;; In that case, raise a warning.
    (if (not (and (ly:music? previous-chord)
-                 (null? (ly:music-property previous-chord 'length))))
+                (null? (ly:music-property previous-chord 'length))))
        (ly:input-message location
-                         (_ "No memorized chord in music block before chord repetition")))
+                        (_ "No memorized chord in music block before chord repetition")))
    ;; Instead of copying the previous chord, then removing the
-   ;; undesired elements (like articulations), a new empty chord is
-   ;; built.  Then, the pitch found in the previous chord are added to
-   ;; the new chord, without any "decoration" (e.g. cautionary
-   ;; accidentals, fingerings, text scripts, articulations).
-   (make-music
-    'EventChord
-    'origin location
-    'elements (append! (filter identity
-                               (map (lambda (event)
-                                      (and (eqv? (ly:music-property event 'name) 'NoteEvent)
-                                           (make-music
-                                            'NoteEvent
-                                            'pitch (ly:music-property event 'pitch)
-                                            'duration duration)))
-                                    (ly:music-property previous-chord 'elements)))
-                       articulations)))
+   ;; undesired elements (like articulations), a new empty chord is built.
+   ;; Then, the pitch found in the previous chord are added to the new
+   ;; chord, without any "decoration" (e.g. cautionary accidentals,
+   ;; fingerings, text scripts, articulations).  Only the events of types
+   ;; given in `chord-elements-types' and `note-articulation-types' are
+   ;; copied from the original chord elements and note articulations,
+   ;; respectively.
+   (let ((elements (ly:music-property (ly:music-deep-copy previous-chord) 'elements)))
+     (make-music
+      'EventChord
+      'origin location
+      'elements (append!
+                 (map (lambda (note)
+                        (let ((new-note (make-music 'NoteEvent
+                                                    'pitch (ly:music-property note 'pitch)
+                                                    'duration duration))
+                              (articulations
+                               (filter-events (ly:music-property note 'articulations)
+                                              note-articulation-types)))
+                          (if (not (null? articulations))
+                              (set! (ly:music-property new-note 'articulations)
+                                    articulations))
+                          new-note))
+                      (filter-events elements '(NoteEvent)))
+                 (filter-events elements chord-element-types)
+                 articulations))))
 
+#(define-public default-repeat-chord
+   (make-repeat-chord-function '() '()))
+
+#(define-public tab-repeat-chord
+   (make-repeat-chord-function '(StringNumberEvent) '(StringNumberEvent)))
+
+% default settings
 #(ly:parser-set-repetition-symbol parser 'q)
 #(ly:parser-set-repetition-function parser default-repeat-chord)
index f49797ec81871c7cf777e5d0352dcae837d7cf21..71a834ba2d718fc1e704cec22fda84fc1aa1f881 100644 (file)
@@ -775,7 +775,11 @@ styledNoteHeads =
    (_i "Set @var{heads} in @var{music} to @var{style}.")
    (style-note-heads heads style music))
 
-
+tabChordRepetition =
+#(define-music-function (parser location) ()
+   (_i "Include the string information in a chord repetition.")
+   (ly:parser-set-repetition-function parser tab-repeat-chord)
+   (make-music 'SequentialMusic 'void #t))
 
 tag =
 #(define-music-function (parser location tag arg)