\version "2.14.2"

#(set-global-staff-size 18)

%% Does not work in polyphonic situations such as:
%% <<{ } \\ { }>> or
%% << \new Voice { } \new Voice { } >>

#(define (create-skip duration)
 (make-music 'SkipEvent
   'duration duration))

%% from /scm/lily-library.scm
%% Why not public?
#(define (split-at-predicate pred lst)
  "Split LST into two lists at the first element that returns #f for
  (PRED previous_element element).  Return the two parts as a pair.
  Example: (split-at-predicate < '(1 2 3 2 1)) ==> ((1 2 3) . (2 1))"
  (if (null? lst)
      (list lst)
      (let ((i (list-index (lambda (x y) (not (pred x y)))
			   lst
			   (cdr lst))))
        (if i
            (cons (take lst (1+ i)) (drop lst (1+ i)))
            (list lst)))))

#(define (create-lists-of-equals l1 l2)
 "Creates a list of lists. All elements of the
  inner lists are equal.
  l2 is supposed to be an empty list."
  
  (set! l1 (split-at-predicate equal? l1))
  (set! l2 (cons (car l1) l2))
  
  (if (null? (cdr l1))
    (reverse l2)
    (create-lists-of-equals (cdr l1) l2)))
  
#(define (make-equal-list-structure l1 l2 l3)
 "Changes l1 to have the same inner structure as l2.
  l2 is supposed t be a list of lists.
  l3 is supposed to be an empty list.
 "
  (if (null? l2)
    (reverse l3)
    (begin
      (let ((ln1 (length (car l2))))
      (make-equal-list-structure
        (list-tail l1 ln1)
        (cdr l2)
        (cons (list-head l1 ln1) l3))))))
        
#(define (make-new-list l1 l2 l3)
 "Creates a new list, with (car l1) as first element and 
  'SkipEvents being the others.
  The length of the new created list is the same as l2
  l1 is supposed to be a list of events.
  l2 is supposed to be a list of (equal) durations.
  l3 is supposed to be an empty list."
  
  (for-each (lambda (x) (set! l3 (cons (create-skip (car l2)) l3))) (iota (- (length l2) 1)))
  (cons (car l1) l3))
   
#(define (make-new-music-list l1 l2)
 "l1 is supposed to be a list of events.
  l2 is supposed to be a list of durations of the elements of l1.
  make-new-music-list creates a new list of events which replaces all elements
  of l1 with 'SkipEvents if the element has the same duration as before.
  "
  (let* ((dur-lst (create-lists-of-equals l2 '()))
         (ev-lst (make-equal-list-structure l1 dur-lst '())))
;; flatten-list from /scm/lily-library.scm
  (flatten-list 
    (map (lambda (x y) (make-new-list x y '()) ) ev-lst dur-lst))))

skipSomeMusic =
#(define-music-function (parser location music) (ly:music?)
  (let* ((ev-lst '())
         (dur-lst '())) 
         
   (music-map (lambda (m)
               (if (or (eqv? (ly:music-property m 'name) 'NoteEvent)
                       (eqv? (ly:music-property m 'name) 'RestEvent)
                       (eqv? (ly:music-property m 'name) 'MultiMeasureRestMusic)
                       (eqv? (ly:music-property m 'name) 'SkipEvent)
                       )
                 (let* ((dur (ly:music-property m 'duration)))
                          
                 (set! ev-lst (append (list m) ev-lst))
                 (set! dur-lst (append  dur-lst (list (ly:music-property m 'duration))))
               m)))
             music)

   (set! ev-lst (reverse ev-lst))
   (set! ev-lst (make-new-music-list ev-lst dur-lst))
   (make-sequential-music ev-lst)))
 
%% For use with 2.15   
thinout =
#(define-music-function (parser location music) (ly:music?)
   (for-some-music
    (lambda (m)
      (and (music-is-of-type? m 'event-chord)
           (let ((elts (ly:music-property m 'elements)))
             (if (pair? elts)
                 (set-cdr!
                  elts
                  (filter!
                   (lambda (m) (not (ly:music-property m 'duration #f)))
                   (cdr elts))))
             #t)))
    music)
   music)
  
%% For use with 2.14.2
thinoutOld =
#(define-music-function (parser location music) (ly:music?)
   (music-map
    (lambda (m)
      (and (memq 'event-chord (ly:music-property m 'types))
           (let ((elts (ly:music-property m 'elements)))
             (if (pair? elts)
                 (set-cdr!
                  elts
                  (filter!
                   (lambda (m) (not (ly:music-property m 'duration #f)))
                   (cdr elts))))
             #t)) m)
    music))
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
"custom-tuning" = \stringTuning <e, a, d fis b e'>
"custom-tuning-1" = \stringTuning <e' b fis d a, e,>

TabLayout = 
\layout {
  \context {
    \Voice
    \type "Engraver_group"
    \name "TabRhythmicVoice"
    \alias "Voice"
    
    \remove "Script_engraver" 
    \remove "Fingering_engraver" 
    \remove "New_fingering_engraver"
    \remove "Text_engraver"
    autoBeaming = ##f
  }
  \context {
    \RhythmicStaff
    \type "Engraver_group"
    \name "TabRhythmicStaff"
    \alias "RhythmicStaff"

    \description "Handles rhythm part of tablature."
    
    \accepts "TabRhythmicVoice"
    \defaultchild "TabRhythmicVoice"
    
    \remove "Time_signature_engraver"
    \remove "Staff_symbol_engraver"
    \remove "Bar_engraver"

    fontSize = #-3
    \override StaffSymbol #'staff-space = #(magstep -3)
    \override Stem #'length = #5
    \override VerticalAxisGroup #'staff-staff-spacing =
      #'((basic-distance . 1)
         (minimum-distance . 1)
         (padding . 1))
  }
  
  \context {
      \TabStaff
      \type "Engraver_group"
      \name "FrenchTabStaff"
      \alias "TabStaff"
    
      \remove "Clef_engraver"
      tablatureFormat = #fret-letter-tablature-format
      stringTunings = #custom-tuning
      % useful for tablature only scores
      \revert TimeSignature #'stencil
      \override TimeSignature #'style = #'single-digit
      \override VerticalAxisGroup #'staff-staff-spacing =
        #'((basic-distance . 10)
           (minimum-distance . 10)
           (padding . 1))
  }
  
  \context {
      \TabStaff
      \type "Engraver_group"
      \name "MilanTabStaff"
      \alias "TabStaff"
    
      \remove "Clef_engraver"
      
      stringTunings = #custom-tuning
      % useful for tablature only scores
      \revert TimeSignature #'stencil
      \override TimeSignature #'style = #'single-digit
      \override VerticalAxisGroup #'staff-staff-spacing =
        #'((basic-distance . 10)
           (minimum-distance . 10)
           (padding . 1))
  }
  
  \context {
      \TabStaff
      \type "Engraver_group"
      \name "ItalianTabStaff"
      \alias "TabStaff"
    
      \remove "Clef_engraver"
      
      stringTunings = #custom-tuning-1
      % useful for tablature only scores
      \revert TimeSignature #'stencil
      \override TimeSignature #'style = #'single-digit
      \override VerticalAxisGroup #'staff-staff-spacing =
        #'((basic-distance . 10)
           (minimum-distance . 10)
           (padding . 1))
  }

  \context {
    \Score
    \accepts "TabRhythmicStaff"
    \accepts "FrenchTabStaff"
    \accepts "MilanTabStaff"
    \accepts "ItalianTabStaff"
  }
}

\layout { 
        \TabLayout
        \context {
        	\Score
        	fingeringOrientations = #'(left) 
        	\override NonMusicalPaperColumn #'line-break-permission = ##f
        	\override InstrumentName #'self-alignment-X = #CENTER
        }
}

\paper { indent = 40 }
 
tuning = \relative c {
        e'4 b fis d a e \bar "||"
}

tuning² = \relative c { 
          	  \override StringNumber #'stencil = ##f  
          	  e'4\6 b\5 fis\4 d\3 a\2 e\1 \bar "||"
          }

m¹ =
\relative c {
        b2
        ces2.-.-2
        ces2.-.
        ces2
        <cis-3\5 eis-2 gis-1 b-0>1-.
        R1
        d8 e f g a g f e
        d4-"xy"
        d d r d s-"skip!" d~ d
        c2
        cis2
}

m² =
\relative c {
        b2\2
        ces2.-.-2\2
        ces2.-.\2
        ces2\2
        <cis-3\2 eis-2\3 gis-1\4 b\5>1-.
        R1
        d8\3 e\3 f\3 g\4 a\4 g\4 f\3 e\3
        d4\3-"xy"
        d\3 d\3 r d\3 s-"skip!" d\3~ d\3
        c2\2
        cis2\2
}

rythm = { \skipSomeMusic \thinoutOld { \tuning \m¹ } }

       
            
\score {
        << 
          \new Staff \with { instrumentName = " normal Staff " }
          { \clef "G_8"  \tuning \m¹ }
          
          \new TabRhythmicVoice 
          \rythm
           
          \new FrenchTabStaff \with { instrumentName = " FrenchTabStaff " }
          { \tuning \m¹ }
          
          \new TabRhythmicVoice \with { \override NoteHead #'style = #'petrucci }
          \rythm 
          
          \new MilanTabStaff \with { instrumentName = " TabStaff used by L.Milan " }
          { \tuning \m¹ }
          
          \new Staff {  \clef "G_8"  \override StringNumber #'stencil = ##f \tuning² \m² }
          
          \new TabRhythmicVoice \with { \override NoteHead #'style = #'petrucci }
          { \skipSomeMusic \thinoutOld { \tuning² \m² } }
          
          \new ItalianTabStaff \with { instrumentName = " ItalianTabStaff " }
          { \tuning² \m² }
        >>
}

restsAndTies = \relative c' {
        a4^"Problemstellen" r ais b8 c~
        c d c b a gis a4
}

<<
  \new Staff { \clef "G_8" \restsAndTies }
  \new TabRhythmicVoice \with { \override NoteHead #'style = #'petrucci }
          { \skipSomeMusic \thinoutOld \restsAndTies }
          
  \new MilanTabStaff \restsAndTies
>>
