Great job!
Really appreciate it!

\r

On Mon, May 4, 2009 at 9:47 AM, Marc Hohl <marc@hohlart.de> wrote:
Hello tablature users,

after sending my first version of a tablature.ly-file, I got a lot of positive resonse,
and a lot more of corrections/improvements. Thank you all!

Now, there is a (hopefully) better file which includes the following features/changes:

1) the palmmute/deadnote stuff is the same, only the code has been simplified, thanks to Neil's proposals

2) the \tabNumbersOnly settings are now the default, so when tablature.ly is included, the stems etc. are gone
 (as proposed by Grammostola Rosea)

3) the modern tab clef is now available as any other clef by typing \clef "moderntab"

To implement (3), there is another function necessary, which will be in future releases of lilypond, but
for now, you have to insert the following lines into scm/parser-clef.scm:

;; a function to add new clefs at runtime
(define-public (add-new-clef clef-name clef-glyph clef-position octavation 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 octavation) supported-clefs))
 (set! c0-pitch-alist
      (acons clef-glyph c0-position c0-pitch-alist)))

Otherwise the new clef definition won't work.

Thanks again to Carl and Neil for their help!

There is one problem now with the settings in tablature.ly: I simply made ties transparent, but
then, the fret number appears as it were a note to be played. Hopefully somewhere in the future,
I will find a possibility to let the fret number disappear, but as David Stocerk pointed out,
some cases had to be  distinguished (the following is a quote from a former posting from David):

(quote...)

It should be noted that a publishing standard is when there is a Note Staff + Tab Staff, tied notes (that is, the notes that are 'held') in the Tab Staff are indicated by parenthesizing the tab number(s). There are several conventions that are related to tied notes in a Notes+Tab situation:

 * Tab numbers that are 'tied to' are sometimes parenthesized,
   sometimes hidden.
 * In the case that 'tied to' notes are hidden, a parenthesized tab
   number is usually forced if the 'tied to' note is at the beginning
   of a line (i.e., the note is tied over a system break).
 * Likewise, parenthesized tab numbers are forced when a 'tied to'
   note begins a 2nd ending or Coda section.
 * A parenthesized chord in the Tab Staff are indicated with a single
   pair of parentheses surrounding all of the notes in the chord (as
   opposed to as single pair of parentheses around each individual
   note in the chord).

(...quote)

So this seems to be a difficult task, but somehow to manage.

Marc




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


% 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
  #})

% 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")))))

% 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
}
% 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 defaults for tablature:
% the clef handler will be included and the tablature
% is displayed \tabNumbersOnly-style:
\layout {
  \context {
     \TabStaff
     % the clef handler
     \override Clef #'stencil = #clef::print-modern-tab-if-set
     \override TimeSignature #'stencil = ##f
  }
  \context {
     \TabVoice
     \override Stem #'stencil = ##f
     \override Beam #'stencil = ##f
     \override Dots #'stencil = ##f
     \override Tie  #'stencil = ##f
     \override Slur #'stencil = ##f
     \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 Rest #'stencil = ##f
     \override MultiMeasureRest #'stencil = ##f
     \override Script #'stencil = ##f
     \override TextScript #'stencil = ##f
  }
}

\version "2.12.2"
\include "tablature.ly"

% for testing purposes only; in newer versions of lilypond, they will be
% already defined:
#(define-public guitar-seven-string-tuning '(4 -1 -5 -10 -15 -20 -25))
#(define-public guitar-drop-d-tuning       '(4 -1 -5 -10 -15 -22))
#(define-public bass-four-string-tuning    '(-17 -22 -27 -32))
#(define-public bass-drop-d-tuning         '(-17 -22 -27 -34))
#(define-public bass-five-string-tuning    '(-17 -22 -27 -32 -37))
#(define-public bass-six-string-tuning     '(-12 -17 -22 -27 -32 -37))

\markup{tablature.ly - second attempt.}

alotofstuff = {
  \time 3/4
  c4^"test" d( e)
  f4\f g a^\fermata
  c8\< c16 c ~ c2\!
  c'2.
  \mark \default
  R2.
  r4 d4 r8 r
  \times 3/4 { b4 c d c }
  c4. d-_( e\varcoda)
  ->f g~ a\prall g\thumb e-. f-. g-.
  \times 3/4 { b4 c d c }
  \bar "|."
}

\score {
  <<
     \new Staff { \clef "G_8"  \alotofstuff }
     \new TabStaff { \clef "tab" \alotofstuff }
  >>
}

\markup{When we invoke tabNumbersOnly, it looks better.}

\score {
  <<
     \new Staff { \clef "G_8" \alotofstuff }
     \new TabStaff   { \tabNumbersOnly \alotofstuff }
  >>
}

\markup{ tablature.ly supports an easy way to mark notes as played palm mute-style...}

palmmute = \relative c, {
   \time 4/4
   e8^\markup { \musicglyph #"noteheads.u2do"  = palm mute } \palmMuteOn e e \palmMuteOff  e e  \palmMute e e e
   e8 \palmMute { e e e } e e e e
   \palmMuteOn
   < e b' e>8 e e e <e b' e>2
   \bar "|."
}

\score {
  <<
     \new Staff { \clef "G_8" \palmmute }
     \new TabStaff  { \clef "moderntab"
                      \palmmute }
  >>
}

\markup {... or dead notes:}

deadnotes = \relative c,, {
  e8. \deadNotesOn e16 \deadNotesOff g4 a b
  e8. \deadNotes e16 g4 a b
  e,4. \deadNotes { e8 e e } e4
  \bar "|."
}

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

\markup { The new sansSerifTab-Clef supports tablatures from 4 to 7 strings.}
% some stuff
bass = \relative c,, {
  e4 g a b
  b4 f g d'
  \bar "|."
}

\score {
  <<
     \new Staff { \mark \markup{4 strings}
                  \clef "bass_8" \bass }
     \new TabStaff   { \set TabStaff.stringTunings =   #bass-four-string-tuning
                       \bass }
  >>
}

% five strings, calculated clef
\score {
  <<
     \new Staff { \mark \markup{5 strings}
                  \clef "bass_8" \bass }
     \new TabStaff   { \set TabStaff.stringTunings =  #bass-five-string-tuning
                       \bass }
  >>
}

guitar = \relative c {
  c4 d e f
  g4 a b c
  \bar "|."
}

% six strings, calculated clef
\score {
  <<
     \new Staff { \mark \markup{6 strings}
                  \clef "G_8" \guitar }
     \new TabStaff   { \set TabStaff.stringTunings = #guitar-tuning
                       \guitar }
  >>
}

% seven strings, calculated clef
\score {
  <<
     \new Staff { \mark \markup{7 strings}
                  \clef "G_8" \guitar }
     \new TabStaff   { \clef "moderntab"
                       \set TabStaff.stringTunings = #guitar-seven-string-tuning
                       \guitar }
  >>
}

% seven strings, calculated clef
\score {
  <<
     \new Staff { \mark \markup{7 strings, staff space 1.2}
                  \clef "G_8" \guitar }
     \new TabStaff   { \clef "moderntab" \override TabStaff.StaffSymbol #'staff-space = #1.2
                       \set TabStaff.stringTunings =  #guitar-seven-string-tuning
                       \guitar }
  >>
}