diff -uNr ./lilypond.orig/input/test/tablature.ly ./lilypond.patched/input/test/tablature.ly
--- ./lilypond.orig/input/test/tablature.ly	Sat Jun  1 13:59:06 2002
+++ ./lilypond.patched/input/test/tablature.ly	Tue Jun  4 18:54:57 2002
@@ -2,7 +2,7 @@
 
 %{
 
-A sample tablature.
+A sample tablature, with both normal staff and tab.
 
 Tablature is done by overriding the note-head formatting function, and
 putting it on a 6-line staff. A special engraver takes care of going
@@ -10,7 +10,18 @@
 
 %}
 
+partition = \notes { ces'16^2 d'^2 e'8^2 g'2.^3  \times 2/3 { c'8^2 e'8^3 d'8^3 } e'4^2 }
+
 \score {
-  \notes  \context TabStaff { ces'16-2 d'-2 e'8-2 g'2.-3  c'4-1 c''8-5 b'-5 }
-  
- }
+  \context StaffGroup <
+    \context Staff <
+      % Hide fingering number (used for string number) for the "normal" staff
+      \property Staff.Fingering \override #'transparent = ##t
+      
+      \partition
+    >
+    \context TabStaff <
+      \partition
+    >
+  >
+}
diff -uNr ./lilypond.orig/lily/stem.cc ./lilypond.patched/lily/stem.cc
--- ./lilypond.orig/lily/stem.cc	Thu May 30 19:02:53 2002
+++ ./lilypond.patched/lily/stem.cc	Tue Jun  4 13:50:55 2002
@@ -274,6 +274,16 @@
 Real
 Stem::get_default_stem_end_position (Grob*me) 
 {
+  SCM up_to_staff = me->get_grob_property ("up-to-staff");
+  if (gh_scm2bool(up_to_staff)) {
+    int line_count = Staff_symbol_referencer::line_count (me);
+    
+    Direction dir = get_direction (me);
+    
+    if (dir == UP) return  ((double) line_count) + 1.5;
+    else           return -((double) line_count) - 1.5;
+  }
+  
   bool grace_b = to_boolean (me->get_grob_property ("grace"));
   SCM s;
   Array<Real> a;
@@ -750,6 +760,25 @@
 Stem_info
 Stem::calc_stem_info (Grob*me) 
 {
+  SCM up_to_staff = me->get_grob_property ("up-to-staff");
+  if (gh_scm2bool(up_to_staff)) {
+    
+    // Up-to-staff : the stem end out of the staff.
+    
+    int line_count = Staff_symbol_referencer::line_count (me);
+    
+    Stem_info si ;
+    
+    Direction dir = get_direction (me);
+    if (dir == UP) si.ideal_y_ =  ((double) line_count) + 1.5;
+    else           si.ideal_y_ = -((double) line_count) - 1.5;
+    
+    si.dir_ = Directional_element_interface::get(me); 
+    si.shortest_y_ = si.ideal_y_; 
+    
+    return si;
+  }
+  
   SCM scm_info = me->get_grob_property ("stem-info");
 
   if (gh_pair_p (scm_info ))
@@ -863,5 +892,5 @@
 
 ADD_INTERFACE (Stem,"stem-interface",
   "A stem",
-  "avoid-note-head adjust-if-on-staffline thickness stem-info beamed-lengths beamed-minimum-lengths lengths beam stem-shorten duration-log beaming neutral-direction stem-end-position support-head note-heads direction length style no-stem-extend flag-style dir-forced");
+  "up-to-staff avoid-note-head adjust-if-on-staffline thickness stem-info beamed-lengths beamed-minimum-lengths lengths beam stem-shorten duration-log beaming neutral-direction stem-end-position support-head note-heads direction length style no-stem-extend flag-style dir-forced");
 
diff -uNr ./lilypond.orig/lily/tab-note-heads-engraver.cc ./lilypond.patched/lily/tab-note-heads-engraver.cc
--- ./lilypond.orig/lily/tab-note-heads-engraver.cc	Wed May 29 01:10:42 2002
+++ ./lilypond.patched/lily/tab-note-heads-engraver.cc	Mon Jun  3 13:49:38 2002
@@ -114,7 +114,10 @@
       SCM c0 = get_property ("centralCPosition");
       if (gh_number_p (c0)) pos += gh_scm2int (c0);
       
-      note_p->set_grob_property ("tab-string", gh_int2scm (tab_string));
+      SCM scm_pitch = req->get_mus_property ("pitch");
+      SCM proc      = get_property ("tablatureFormat");
+      SCM text      = gh_call3 (proc, gh_int2scm (tab_string), get_property ("stringTunings"), scm_pitch);
+      note_p->set_grob_property ("text", text);
       
       note_p->set_grob_property ("staff-position", gh_int2scm (pos));
       announce_grob (note_p, req->self_scm());
diff -uNr ./lilypond.orig/ly/engraver-init.ly ./lilypond.patched/ly/engraver-init.ly
--- ./lilypond.orig/ly/engraver-init.ly	Sat Jun  1 13:58:16 2002
+++ ./lilypond.patched/ly/engraver-init.ly	Tue Jun  4 13:51:20 2002
@@ -449,6 +449,10 @@
       \name "TabVoice"
       \denies "Thread"
       \consists "Tab_note_heads_engraver"
+      
+      % Draws all stems/beams out of the staff (and not in the middle of the staff !)
+      Beam \override #'damping = #100000
+      Stem \override #'up-to-staff = ##t
 }
 
 TabStaffContext = \translator {
@@ -475,5 +479,8 @@
       
       % No accidental in tablature !
       Accidental  = \turnOff 
+      
+      stringTunings = #'(-8 -3 2 7 11 16)
+      tablatureFormat = #fret-number-tablature-format
 }
    
diff -uNr ./lilypond.orig/scm/grob-description.scm ./lilypond.patched/scm/grob-description.scm
--- ./lilypond.orig/scm/grob-description.scm	Wed May 29 01:04:46 2002
+++ ./lilypond.patched/scm/grob-description.scm	Mon Jun  3 13:52:01 2002
@@ -512,7 +512,6 @@
 	(molecule-callback . ,tablature-molecule-callback)
 	(Y-offset-callbacks  . (,Staff_symbol_referencer::callback))
 	(stem-attachment-function . ,tablature-stem-attachment-function)
-  (string-tunings . (-8 -3 2 7 11 16))
 	(meta . ((interfaces . (rhythmic-head-interface font-interface note-head-interface staff-symbol-referencer-interface))))
 	))
 
@@ -811,6 +810,7 @@
 	(adjust-if-on-staffline . #t)
 	(font-family . music)	   
 	(avoid-note-head . #f)
+	(up-to-staff . #f)
 	(meta . ((interfaces . (stem-interface  font-interface))))
 	))
 
diff -uNr ./lilypond.orig/scm/grob-property-description.scm ./lilypond.patched/scm/grob-property-description.scm
--- ./lilypond.orig/scm/grob-property-description.scm	Wed May 29 01:04:46 2002
+++ ./lilypond.patched/scm/grob-property-description.scm	Tue Jun  4 13:49:53 2002
@@ -467,4 +467,4 @@
 
 (grob-property-description 'tab-string number?       "The tablature string of a TabNoteHead.")
 (grob-property-description 'avoid-note-head boolean? "if set, the stem of a chord does not pass through all note head, but start at the last note head. Used by tablature.")
-(grob-property-description 'string-tunings list?     "The strings tuning, in semi-tons from the middle C. Used by tablature.")
+(grob-property-description 'up-to-staff boolean? "if set, stems' lengths are set so as stems end out of the staff. Used by tablature.")
diff -uNr ./lilypond.orig/scm/output-lib.scm ./lilypond.patched/scm/output-lib.scm
--- ./lilypond.orig/scm/output-lib.scm	Wed May 29 01:04:46 2002
+++ ./lilypond.patched/scm/output-lib.scm	Mon Jun  3 13:51:01 2002
@@ -17,20 +17,22 @@
 (define (tablature-molecule-callback grob)
   (let ((molecule (fontify-text
                    (ly-get-default-font grob)
-                   (string-append
-                    (number->string
-                     (- (pitch-semitones (ly-get-mus-property (ly-get-grob-property grob 'cause) 'pitch))
-                        (list-ref
-                         (ly-get-grob-property grob 'string-tunings)
-                         (- (ly-get-grob-property grob 'tab-string)
-                            1 ; remove 1 because list index starts at 0 and guitar string at 1.
-                            ))
-                        )
-                     )
-                    )
+                   (ly-get-grob-property grob 'text)
                    )))
     molecule ; return the molecule.
     )
+  )
+
+; The TabNoteHead tablatureFormat callback.
+; Compute the text grob-property
+(define (fret-number-tablature-format string tuning pitch)
+  (number->string
+   (- (pitch-semitones pitch)
+      (list-ref tuning
+                (- string 1) ; remove 1 because list index starts at 0 and guitar string at 1.
+                )
+      )
+   )
   )
 
 ; end of tablature functions
