lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: tablature.ly


From: Marc Hohl
Subject: Re: tablature.ly
Date: Sat, 02 May 2009 10:25:00 +0200
User-agent: Thunderbird 2.0.0.21 (X11/20090318)

Thank you, Carl and Neil, for your answers.

Neil Puttock schrieb:
2009/4/30 Carl D. Sorensen <address@hidden>:
On 4/30/09 1:36 AM, "Marc Hohl" <address@hidden> wrote:

I tried to cons these values, and I succeded (or at least it seemed to
me) for the
supported-clefs list, but not with the c0-pitch-alist
(see attached files and lilypond's error messages).
Is this list only locally defined, or am I missing something?
You are correct.  c0-pitch-alist is not public.  So it's currently not
possible to cons a value in with the tablature.ly file.

Oops. :)

Sorry Marc, I didn't notice that.  I ran a quick test by amending
parser-clef.scm, so I hadn't actually tried consing values.
Never mind. It is kind of reassuring to see that making mistakes is not
completely my domain ;-)
My recommendation is that you pursue option c.  The disadvantage of pursuing
option c is that it won't be available to others until a new release of
LilyPond is issued.

I agree, that seems the best option for the moment.

Ok, so I inserted the following lines in my scm/parser-clef.scm:

;; a function to add new clefs at runtime
(define-public (add-new-clef clef-name clef-glyph clef-position octaviation c0-position) "Append the entries for a clef symbol to supported clefs and c0-pitch-alist"
 (set! supported-clefs
(acons clef-name (list clef-glyph clef-position octaviation) supported-clefs))
 (set! c0-pitch-alist
       (acons clef-glyph c0-position c0-pitch-alist)))

[ I don't know if everything is correct, see below, but when everything works, I'll send patches.]
At a later date, we might consider moving the clef callbacks in
clef.cc to scheme completely, so you'd be able to incorporate the
conditional code for modern tabs directly into the clef::print
callback.

Define a new Scheme function to be used as the Clef 'stencil property

(define (newClefPrint grob) ....)

I suggest something like `clef::print-modern-tab-if-set' to follow
LilyPond coding style.

It should check for the 'glyph property of the grob, and if it's
markup.moderntab, it will call the new tab markup function.  Otherwise, it
will call (ly:clef::print grob).
I tried to follow your suggestions, and after some trial and error, I have
rearranged my tablature.ly as follows (see attachment):

#(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)))
         (if (eq? glyph "markup.moderntab")
             (ly:modern-tab-clef::print grob)
             (ly:clef::print grob))))


#(define (ly:modern-tab-clef::print grob)
  (ly:grob-property grob 'staff-space 1)
  (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)))
(grob-interpret-markup grob (make-customTabClef-markup line-count staff-space))))


Two further points:

Just to be on the safe side, when retrieving 'staff-space, a default
value should be given, since it's not normally set:

(ly:grob-property grob 'staff-space 1)
Is this line placed properly? I don't understand this quite right, does this line define the default value if 'staff-space is not set at all and doesn't override 'staff-space
if it s set before?
As I mentioned previously, unless you want to code a smaller clef for
changes, you'll want to set 'full-size-change = ##t.  This will shut
up any complaints about missing a glyph for "markup.moderntab_change".
 You can set it within the new stencil callback using
ly:grob-set-property!:

(ly:grob-set-property! grob 'full-size-change #t)
Where have I to put this? I surely want changes to be enabled for the standard clefs, so I have to put it after the comparison for "markup.moderntab". On the other hand, when it's put too late, then 'glyph has the value "markup.moderntab_change", so the test for
"markup.moderntab" will fail.

And a final question:
I put the override for the TabStaff.Clef #'stencil into \tabNumbersOnly resp. \tabFullNotation, so if the user doesn't call one of these commands, the clef
selection mechanism won't work. Is there a workaround, or - even better -
can \tabNumbersOnly be invoked automatically when tablature.ly is included?
This doesn't alter the defaults for older files but would give the desired functionality
(i.e. numbers only) for tablature users.

Anyway, when I put all the pieces together, lilypond still complains about not finding
"markup.moderntab", so I have made some mistakes.
Sorry to occupy your time so much, it is hard for me to learn basic scheme and lilypond's internal mechanisms at the same time, but in every mail, everything gets a bit clearer ;-)

Thank you.

Marc

Regards,
Neil


%%%% tablature.ly
%%%%
%%%% source file of the GNU LilyPond music typesetter
%%%%
%%%% (c) 2009 Marc Hohl <address@hidden>


% some publications use the triangled note head 
% for palm mute, so here we go:
palmMuteOn = { \set shapeNoteStyles = #(make-vector 7 do) }
palmMuteOff = { \unset shapeNoteStyles }
% for single notes (or groups of notes within { ...} :
palmMute =  #(define-music-function (parser location notes) (ly:music?)
      #{
         \palmMuteOn $notes \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 = {
   \override NoteHead #'style = #'cross
   \set tablatureFormat = #x-tab-format
}
deadNotesOff = {
   \unset tablatureFormat
   \revert NoteHead #'style
}
% for single notes or groups of notes within {...}:
deadNotes = #(define-music-function (parser location notes) (ly:music?)
   #{
      \deadNotesOn  $notes \deadNotesOff
   #})
%
% the "moderntab" clef will be added to the list of known clefs:
#(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)))
          (if (eq? glyph "markup.moderntab")
              (ly:modern-tab-clef::print grob)
              (ly:clef::print grob))))


#(define (ly:modern-tab-clef::print grob)
   (ly:grob-property grob 'staff-space 1)
   (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)))
             (grob-interpret-markup grob (make-customTabClef-markup line-count 
staff-space))))
% 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")))))

% commands for switching between tablature with numbers only...
tabNumbersOnly = {
   % no time signature
   \override TabStaff.TimeSignature #'stencil = ##f
   % no stems, beams, dots, ties and slurs
   \override TabVoice.Stem #'stencil = ##f
   \override TabVoice.Beam #'stencil = ##f
   \override TabVoice.Dots #'stencil = ##f
   \override TabVoice.Tie  #'stencil = ##f
   \override TabVoice.Slur #'stencil = ##f
   % no tuplet stuff
   \override TabVoice.TupletBracket #'stencil = ##f
   \override TabVoice.TupletNumber #'stencil = ##f
   % no dynamic signs, text spanners etc.
   \override DynamicText #'transparent = ##t 
   \override DynamicTextSpanner #'stencil = ##f
   \override TextSpanner #'stencil = ##f
   \override Hairpin #'transparent = ##t
   % no rests
   \override TabVoice.Rest #'stencil = ##f
   \override TabVoice.MultiMeasureRest #'stencil = ##f
   % no markups
   \override TabVoice.Script #'stencil = ##f
   \override TabVoice.TextScript #'stencil = ##f
   % the clef handler
   \override TabStaff.Clef #'stencil = #clef::print-modern-tab-if-set
}
% and the full notation
tabFullNotation = {
   % time signature
   \revert TabStaff.TimeSignature #'stencil
   % stems, beams, dots
   \revert TabVoice.Stem #'stencil
   \revert TabVoice.Beam #'stencil
   \revert TabVoice.Dots #'stencil
   \revert TabVoice.Tie #'stencil
   \revert TabVoice.Slur #'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 clef handler
   \override TabStaff.Clef #'stencil = #clef::print-modern-tab-if-set
}
\version "2.12.2"
\include "tablature.ly"

% some stuff 
bass = \relative c,, {
   e4 g a b
   b4 f g d'
   \bar "|."
}

% four strings, calculated clef
\score {
   <<
      \new Staff      { \clef "bass_8" \bass }
      \new TabStaff   { %\tabNumbersOnly
                        \set TabStaff.stringTunings = #bass-tuning
                        \clef tab
                        \bass }
   >>
}

\score {
   <<
      \new Staff      { \clef "bass_8" \bass }
      \new TabStaff   { \tabNumbersOnly
                        \set TabStaff.stringTunings = #bass-tuning
                        \clef moderntab
                        \bass }
   >>
}

%

reply via email to

[Prev in Thread] Current Thread [Next in Thread]