Hi all, I'm trying to add hammer-on and pull-off to a tablature.These are not supported by tablature.ly, so I was told to use an .eps file and \markup to get what I want.
I need your help to understand how to do it actually. Please direct me to a place of the manual where this issue is discussed. So far, I've seen this example but I don't know how to implement it: http://lists.gnu.org/archive/html/lilypond-user/2005-02/msg00208.htmlI attach the .eps file, a simple example and the file tablature.ly (which is needed...for those who don't have and want to try..).
Could you give me some hint? I don't know hot to go on.. Thanks in advance, Federico
%%%% tablature.ly %%%% %%%% source file of the GNU LilyPond music typesetter %%%% %%%% (c) 2009 Marc Hohl <m...@hohlart.de> % some publications use the triangle-shaped note head % for palm mute, so here we go: palmMuteOn = { \override NoteHead #'style = #'do } palmMuteOff = { \revert NoteHead #'style } % for single notes (even in chord constructs <...>), % or grouped notes in {...} palmMute = #(define-music-function (parser location note) (ly:music?) ;; are we inside a <...>? (if (eq? (ly:music-property note 'name) 'NoteEvent) ;; yes -> add a tweak (begin (set! (ly:music-property note 'tweaks) (acons 'style 'do (ly:music-property note 'tweaks))) note) ;; no -> use predefined commands to switch to triangle-shaped note heads #{ \palmMuteOn $note \palmMuteOff #})) % x-tab-format uses a "x" instead of the fret number: #(define (x-tab-format str context event) (make-whiteout-markup (make-vcenter-markup (markup #:musicglyph "noteheads.s2cross")))) % dead notes are marked with a cross-shape note head, % both in normal notation and in tablature: deadNotesOn = { \set tablatureFormat = #x-tab-format \override NoteHead #'style = #'cross } deadNotesOff = { \unset tablatureFormat \revert NoteHead #'style } % for single notes (even in chord constructs <...>), % or grouped notes in {...} deadNote = #(define-music-function (parser location note) (ly:music?) ;; are we inside a <...>? (if (eq? (ly:music-property note 'name) 'NoteEvent) ;; yes -> add a tweak (begin (set! (ly:music-property note 'tweaks) (acons 'glyph-name "2cross" (acons 'style 'special (ly:music-property note 'tweaks)))) note) ;; no -> use predefined commmands for changing ;; note head and tablature fret signs #{ \deadNotesOn $note \deadNotesOff #})) % To distinguish between palm mute and dead notes, we have to % check whether the grob-property 'style is set; if it is, % then we want to draw a "whiteout" cross for the tab note head: #(define (tab-note-head::whiteout-if-style-set grob) (let ((style (ly:grob-property grob 'style))) (if (and (symbol? style) (string=? (symbol->string style) "special")) (stencil-whiteout (ly:note-head::print grob)) (ly:text-interface::print grob)))) % definitions for the "moderntab" clef: % the "moderntab" clef will be added to the list of known clefs, % so it can be used as any other clef: % % \clef "moderntab" % #(add-new-clef "moderntab" "markup.moderntab" 0 0 0) % this function decides which clef to take #(define (clef::print-modern-tab-if-set grob) (let ((glyph (ly:grob-property grob 'glyph))) ;; which clef is wanted? (if (string=? glyph "markup.moderntab") ;; if it is "moderntab", we'll draw it (let* ((staff-symbol (ly:grob-object grob 'staff-symbol)) (line-count (ly:grob-property staff-symbol 'line-count)) (staff-space (ly:grob-property staff-symbol 'staff-space 1))) (grob-interpret-markup grob (make-customTabClef-markup line-count staff-space))) ;; otherwise, we simply use the default printing routine (ly:clef::print grob)))) % define sans serif-style tab-Clefs as a markup: #(define-markup-command (customTabClef layout props num-strings staff-space) (integer? number?) (define (square x) (* x x)) (let* ((scale-factor (/ staff-space 1.5)) (font-size (- (* num-strings 1.5 scale-factor) 7)) (base-skip (* (square (+ (* num-strings 0.195) 0.4)) scale-factor))) (interpret-markup layout props (markup #:vcenter #:bold #:override (cons 'font-family 'sans) #:fontsize font-size #:override (cons 'baseline-skip base-skip) #:left-align #:center-column ("T" "A" "B"))))) % if the stems are drawn, it is nice to have a double stem for % (dotted) half notes to distinguish them from quarter notes: #(define-public (tabvoice::draw-double-stem-for-half-notes grob) (let ((stem (ly:stem::print grob))) ;; is the note a (dotted) half note? (if (= 1 (ly:grob-property grob 'duration-log)) ;; yes -> draw double stem (ly:stencil-combine-at-edge stem X RIGHT stem 0.5) ;; no -> draw simple stem stem))) % as default, the glissando line between fret numbers goes % upwards, here we have a function to correct this behavior: #(define-public (glissando::calc-tab-extra-dy grob) (let* ((original (ly:grob-original grob)) (left-bound (ly:spanner-bound original LEFT)) (right-bound (ly:spanner-bound original RIGHT)) (left-pitch (ly:event-property (event-cause left-bound) 'pitch)) (right-pitch (ly:event-property (event-cause right-bound) 'pitch))) (if (< (ly:pitch-semitones right-pitch) (ly:pitch-semitones left-pitch)) -0.75 0.75))) % for ties in tablature, fret numbers that are tied to should be invisible, % except for 'tied to' numbers after a line break; these will be parenthesized % (thanks to Neil for his solution): #(define (parenthesize-fret-nr grob) ;; Helper function to parenthesize tab noteheads, ;; since we can't use ParenthesesItem at this stage ;; This is basically the same as the C++ function ;; in accidental.cc, converted to Scheme (let* ((font (ly:grob-default-font grob)) (open (stencil-whiteout (ly:font-get-glyph font "accidentals.leftparen"))) (close (stencil-whiteout (ly:font-get-glyph font "accidentals.rightparen"))) (me (ly:text-interface::print grob))) (ly:stencil-combine-at-edge (ly:stencil-combine-at-edge me X LEFT open) X RIGHT close))) % ParenthesesItem doesn't work very well for TabNoteHead, since % the parentheses are too small and clash with the staff-lines % Define a callback for the 'stencils property which will tweak % the parentheses' appearance for TabNoteHead #(define (parentheses-item::calc-tabstaff-parenthesis-stencils grob) ;; the grob we want to parenthesize (let ((victim (ly:grob-array-ref (ly:grob-object grob 'elements) 0))) ;; check whether it's a notehead (if (grob::has-interface victim 'note-head-interface) (begin ;; tweak appearance before retrieving list of stencils '(left-paren right-paren) (ly:grob-set-property! grob 'font-size -2) (ly:grob-set-property! grob 'padding 0) ;; apply whiteout to each element of the list (map stencil-whiteout (parentheses-item::calc-parenthesis-stencils grob))) (parentheses-item::calc-parenthesis-stencils grob)))) % the handler for ties in tablature; split ties yield in a parenthesized % fret number, otherwise the fret number will be invisible. #(define (tie::handle-tab-tie grob) (let* ((original (ly:grob-original grob)) (tied-tabnotehead (ly:spanner-bound grob RIGHT)) (siblings (if (ly:grob? original) (ly:spanner-broken-into original) '()))) (if (and (>= (length siblings) 2) (eq? (car (last-pair siblings)) grob)) ;; tie is split -> parenthesize (ly:grob-set-property! tied-tabnotehead 'stencil (lambda (grob) (parenthesize-fret-nr grob))) ;; tie is not split -> make fret number invisible (ly:grob-set-property! tied-tabnotehead 'transparent #t)))) % repeat ties occur within alternatives in a repeat construct; % the correspondig fret numbers are shown in parentheses: #(define (repeat-tie::parenthesize-tab grob) (let ((tied-tabnotehead (ly:grob-object grob 'note-head))) (ly:grob-set-property! tied-tabnotehead 'stencil (lambda (grob) (parenthesize-fret-nr grob))))) % This allows to hide the fret numbers also in a RepeatTie. % It can be called using this line: % \override RepeatTie #'after-line-breaking = #repeat-tie::erase-tab #(define (repeat-tie::erase-tab grob) (let ((tied-tabnotehead (ly:grob-object grob 'note-head))) (ly:grob-set-property! tied-tabnotehead 'transparent #t))) % a command for switching to the (improved) full notation tabFullNotation = { % time signature \revert TabStaff.TimeSignature #'stencil % stems (the half note gets a double stem) \override TabVoice.Stem #'stencil = #tabvoice::draw-double-stem-for-half-notes % beams, dots \revert TabVoice.Beam #'stencil \revert TabVoice.Dots #'stencil \revert TabVoice.Tie #'stencil \revert TabVoice.Tie #'after-line-breaking \revert TabVoice.RepeatTie #'stencil \revert TabVoice.RepeatTie #'after-line-braking \revert TabVoice.LaissezVibrerTie #'stencil \revert TabVoice.Slur #'stencil \revert PhrasingSlur #'stencil % tuplet stuff \revert TabVoice.TupletBracket #'stencil \revert TabVoice.TupletNumber #'stencil % dynamic signs \revert DynamicText #'transparent \override DynamicTextSpanner #'stencil = ##f \revert TabVoice.DynamicTextSpanner #'stencil \revert TabVoice.Hairpin #'transparent % rests \revert TabVoice.Rest #'stencil \revert TabVoice.MultiMeasureRest #'stencil % markups \revert TabVoice.Script #'stencil \revert TabVoice.TextScript #'stencil } % the defaults for tablature: \layout { \context { \TabStaff % the clef handler \override Clef #'stencil = #clef::print-modern-tab-if-set % no time signature \override TimeSignature #'stencil = ##f % better parentheses in a TabStaff \override ParenthesesItem #'stencils = #parentheses-item::calc-tabstaff-parenthesis-stencils } \context { \TabVoice % remove stems, beams, dots and rests ... \override Stem #'stencil = ##f \override Beam #'stencil = ##f \override Dots #'stencil = ##f \override Rest #'stencil = ##f \override MultiMeasureRest #'stencil = ##f % ... all kinds of ties/slurs \override Tie #'stencil = ##f \override RepeatTie #'stencil = ##f \override LaissezVibrerTie #'stencil = ##f \override Slur #'stencil = ##f \override PhrasingSlur #'stencil = ##f % 'tied to' fret numbers become invisible or parenthesized, respectively) \override Tie #'after-line-breaking = #tie::handle-tab-tie \override RepeatTie #'after-line-breaking = #repeat-tie::parenthesize-tab % ... and all kinds of markups, spanners etc. \override TupletBracket #'stencil = ##f \override TupletNumber #'stencil = ##f \override DynamicText #'transparent = ##t \override DynamicTextSpanner #'stencil = ##f \override TextSpanner #'stencil = ##f \override Hairpin #'transparent = ##t \override Script #'stencil = ##f \override TextScript #'stencil = ##f % the direction for glissando lines will be automatically corrected \override Glissando #'extra-dy = #glissando::calc-tab-extra-dy % dead notes in tablature and within chord constructs %\override TabNoteHead #'glyph-name = #note-head::calc-glyph-name \override TabNoteHead #'stencil = #tab-note-head::whiteout-if-style-set } }
\version "2.12.1" \include "tablature.ly" \include "english.ly" upper = \relative c { \time 4/4 \key g \major g'8( a) b( c b) ~ b4. } lower = \relative c { \time 4/4 \key g \major g4 d'2. } \score { \new StaffGroup << \new Staff = "guitar" << \context Voice = "upper guitar" { \clef "G_8" \voiceOne \upper } \context Voice = "lower guitar" { \clef "G_8" \voiceTwo \lower } >> \new TabStaff = "tab" << \context TabVoice = "upper tab" { \clef "moderntab" \voiceOne \upper } \context TabVoice = "lower tab" { \clef "moderntab" \voiceTwo \lower } >> >> }
<<inline: hammer-pull.eps>>
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user