diff -urN ./lilypond-1.5.55.orig/input/test/tablature.ly ./lilypond-1.5.55/input/test/tablature.ly
--- ./lilypond-1.5.55.orig/input/test/tablature.ly	Thu Jan  1 01:00:00 1970
+++ ./lilypond-1.5.55/input/test/tablature.ly	Wed May 15 12:42:03 2002
@@ -0,0 +1,36 @@
+\version "1.3.146"
+
+\score {
+  \notes  { c'8^1 d'^2 f''^5  < d'8^2 d'^3 g'^4> d'16^1 c'^1 g'8^2 f''4^5 } 
+  
+  \paper {
+    \translator {
+      \ThreadContext
+      
+      \remove   "Note_heads_engraver"
+      \remove   "Fingering_engraver"
+      \consists "Tab_note_heads_engraver"
+    }
+    \translator {
+      \StaffContext
+      
+      % 6 strings
+      StaffSymbol \override #'line-count  = #6
+	    StaffSymbol \override #'staff-space = #1.5
+      
+      % Special "TAB" clef
+    	clefGlyph = #"clefs-tab"
+	    clefPosition = #0
+      
+      % Use a special stem molecule callback, to avoid that the stem pass
+      % through chords
+      Stem \override #'molecule-callback = #tablature-stem-molecule-callback
+      
+      % Force stem up, since the other direction look weird :-(
+      Stem \override #'direction  = #1
+      
+      % Hide Dots
+      Dots \override #'transparent = ##t
+    }
+  }
+}
diff -urN ./lilypond-1.5.55.orig/lily/note-head.cc ./lilypond-1.5.55/lily/note-head.cc
--- ./lilypond-1.5.55.orig/lily/note-head.cc	Tue May 14 21:28:14 2002
+++ ./lilypond-1.5.55/lily/note-head.cc	Wed May 15 12:22:27 2002
@@ -177,7 +177,16 @@
 Interval
 Note_head::head_extent (Grob *me, Axis a)
 {
-  return internal_brew_molecule (me, false).extent (a);
+  Molecule * mol = unsmob_molecule (gh_call1 (me->get_grob_property ("molecule-callback"), me->self_scm ()));
+  return mol->extent (a);
+  
+  // The previous was :
+  // 
+  //return internal_brew_molecule (me, false).extent (a);
+  // 
+  // That's silly, since the molecule-callback may be overriden (in Guile) !
+  // And it is overriden for Tablature.
+  //                                        Jiba
 }
 
 
diff -urN ./lilypond-1.5.55.orig/lily/tab-note-heads-engraver.cc ./lilypond-1.5.55/lily/tab-note-heads-engraver.cc
--- ./lilypond-1.5.55.orig/lily/tab-note-heads-engraver.cc	Thu Jan  1 01:00:00 1970
+++ ./lilypond-1.5.55/lily/tab-note-heads-engraver.cc	Tue May 14 21:52:06 2002
@@ -0,0 +1,143 @@
+/*
+  head-grav.cc -- part of GNU LilyPond
+
+  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+#include <ctype.h>
+#include <stdio.h>
+
+#include "rhythmic-head.hh"
+#include "paper-def.hh"
+#include "musical-request.hh"
+#include "dots.hh"
+#include "dot-column.hh"
+#include "staff-symbol-referencer.hh"
+#include "item.hh"
+#include "score-engraver.hh"
+#include "warn.hh"
+
+/**
+  make (guitar-like) tablature note
+ */
+class Tab_note_heads_engraver : public Engraver
+{
+  Link_array<Item> note_p_arr_;
+  
+  Link_array<Note_req> note_req_l_arr_;
+  
+  Link_array<Text_script_req> tabstring_req_arr_;
+
+public:
+  TRANSLATOR_DECLARATIONS(Tab_note_heads_engraver);
+
+protected:
+  virtual void start_translation_timestep ();
+  virtual bool try_music (Music *req_l) ;
+  virtual void process_music ();
+
+  virtual void stop_translation_timestep ();
+};
+
+
+Tab_note_heads_engraver::Tab_note_heads_engraver()
+{
+}
+
+bool
+Tab_note_heads_engraver::try_music (Music *m) 
+{
+  if (Note_req * n =dynamic_cast <Note_req *> (m))
+    {
+      note_req_l_arr_.push (n);
+      return true;
+    }
+  else if (Text_script_req * ts = dynamic_cast<Text_script_req*> (m))
+    {
+      if (m->get_mus_property ("text-type") != ly_symbol2scm ("finger")) return false;
+      
+      //if (tabstring_req_arr_.size () < note_req_l_arr_.size ()) {
+        tabstring_req_arr_.push (ts);
+      //}
+      return true;
+    }
+  else if (dynamic_cast<Busy_playing_req*> (m))
+    {
+      return note_req_l_arr_.size ();
+    }
+  
+  return false;
+}
+
+
+void
+Tab_note_heads_engraver::process_music ()
+{
+  //printf("\ntabstrings.size = %i\n", tabstring_req_arr_.size ());
+  //printf("\nnotes     .size = %i\n", note_req_l_arr_.size ());
+  
+  for (int i=0; i < tabstring_req_arr_.size (); i++) {
+      Music * tabstring_req = tabstring_req_arr_[i];
+      
+      size_t lenp;
+      char* tab_string_as_str = gh_scm2newstr(tabstring_req->get_mus_property ("text"), &lenp);
+  }
+  
+  for (int i=0; i < note_req_l_arr_.size (); i++)
+    {
+      Item * note_p  = new Item (get_property ("TabNoteHead"));
+      //Item * note_p  = new Item (get_property ("NoteHead"));
+      
+      Music * req = note_req_l_arr_[i];
+      
+      Music * tabstring_req = tabstring_req_arr_[i];
+      
+      size_t lenp;
+      char* tab_string_as_str = gh_scm2newstr(tabstring_req->get_mus_property ("text"), &lenp);
+      int tab_string = atoi(tab_string_as_str);
+      
+      Duration dur = *unsmob_duration (req->get_mus_property ("duration"));
+      
+      note_p->set_grob_property ("duration-log", gh_int2scm (dur.duration_log ()));
+      
+      Pitch *pit =unsmob_pitch (req->get_mus_property ("pitch"));
+      
+      int pos = 2 * tab_string; // No tab-note between the string !!!
+      SCM c0 = get_property ("centralCPosition");
+      if (gh_number_p (c0)) pos += gh_scm2int (c0);
+      
+      note_p->set_grob_property ("semitone-pitch", gh_int2scm (pit->semitone_pitch()));
+      
+      note_p->set_grob_property ("tab-string", gh_int2scm (tab_string));
+      
+      note_p->set_grob_property ("staff-position", gh_int2scm (pos));
+      announce_grob (note_p, req->self_scm());
+      note_p_arr_.push (note_p);
+    }
+}
+
+void
+Tab_note_heads_engraver::stop_translation_timestep ()
+{
+  for (int i=0; i < note_p_arr_.size (); i++)
+    {
+      typeset_grob (note_p_arr_[i]);
+    }
+  note_p_arr_.clear ();
+  
+  note_req_l_arr_.clear ();
+  
+  tabstring_req_arr_.clear ();
+}
+
+void
+Tab_note_heads_engraver::start_translation_timestep ()
+{
+}
+
+
+ENTER_DESCRIPTION(Tab_note_heads_engraver,
+/* descr */       "Generate one or more tablature noteheads from Music of type Note_req.",
+/* creats*/       "TabNoteHead",
+/* acks  */       "",
+/* reads */       "centralCPosition",
+/* write */       "");
diff -urN ./lilypond-1.5.55.orig/scm/grob-description.scm ./lilypond-1.5.55/scm/grob-description.scm
--- ./lilypond-1.5.55.orig/scm/grob-description.scm	Tue May 14 21:28:14 2002
+++ ./lilypond-1.5.55/scm/grob-description.scm	Tue May 14 21:54:23 2002
@@ -485,6 +485,16 @@
 	(meta . ((interfaces . (rhythmic-head-interface font-interface note-head-interface staff-symbol-referencer-interface))))
 	))
 
+    (TabNoteHead
+     . (
+	(font-family . roman)
+	(style . default)
+	(molecule-callback . ,tablature-molecule-callback)
+	(Y-offset-callbacks  . (,Staff_symbol_referencer::callback))
+	(stem-attachment-function . ,tablature-stem-attachment-function)
+	(meta . ((interfaces . (rhythmic-head-interface font-interface note-head-interface staff-symbol-referencer-interface))))
+	))
+
     (Glissando
      . (
 	(type . line)
diff -urN ./lilypond-1.5.55.orig/scm/grob-property-description.scm ./lilypond-1.5.55/scm/grob-property-description.scm
--- ./lilypond-1.5.55.orig/scm/grob-property-description.scm	Tue May 14 21:28:14 2002
+++ ./lilypond-1.5.55/scm/grob-property-description.scm	Wed May 15 12:34:29 2002
@@ -456,3 +456,4 @@
 (grob-property-description 'chord-name-function procedure? "DOCME")
 (grob-property-description 'minimum-beam-collision-distance number?
 "Minimum distance to beam for a rest collision.")
+(grob-property-description 'tab-string number? "Number of the string for a tab head note, where 1 is the highest string.")
diff -urN ./lilypond-1.5.55.orig/scm/output-lib.scm ./lilypond-1.5.55/scm/output-lib.scm
--- ./lilypond-1.5.55.orig/scm/output-lib.scm	Tue May 14 21:28:14 2002
+++ ./lilypond-1.5.55/scm/output-lib.scm	Tue May 14 21:53:25 2002
@@ -5,6 +5,75 @@
 ;;;; (c) 1998--2001 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
 
+; Tablature functions, by Jiba (jiba@tuxfamily.org)
+
+; The strings' tuning.
+; This should not be hardcoded.
+#(define-public guitartuning '(-8 -3 2 7 11 16))
+
+; The TabNoteHead stem attachment function.
+(define (tablature-stem-attachment-function style)
+  (cons 0.0 1.0)
+  )
+
+; The TabNoteHead molecule callback.
+; Create a text molecule
+(define (tablature-molecule-callback grob)
+  (let ((molecule (fontify-text
+                   (ly-get-default-font grob)
+                   (string-append
+                    (number->string
+                     (- (ly-get-grob-property grob 'semitone-pitch)
+                        (list-ref
+                         '(-8 -3 2 7 11 16)
+                         (- (ly-get-grob-property grob 'tab-string)
+                            1 ; remove 1 because list index starts at 0 and guitar string at 1.
+                            ))
+                        )
+                     )
+                    )
+                   )))
+    molecule ; return the molecule.
+    )
+  )
+
+; Stem molecule callback for tablature.
+; This molecule callback delegates to the default one, but for chords, it
+; draws the shorter possible stem (instead of the longer).
+; Hackish !!!
+(define (tablature-stem-molecule-callback grob)
+  (let ((note-heads (ly-get-grob-property grob 'note-heads)))
+    ; HACK !!!
+    ; (Temporarilly) remove all note-heads in "note-heads" but one (the one
+    ; that will give the shorter stem).
+    ; This is required to avoid stems passing in chords...
+    (ly-set-grob-property grob 'note-heads (list
+      (let loop ((note-heads note-heads)
+                 (best (list-ref note-heads 0)))
+        (if (null? note-heads)
+            best
+            (let ((challenger (car note-heads)))
+              (loop (cdr note-heads) (if ((if (= (ly-get-grob-property grob 'direction) UP) > <)
+                                            (ly-get-grob-property challenger 'tab-string)
+                                            (ly-get-grob-property best       'tab-string))
+                                         challenger
+                                         best))
+              )
+          )
+        )
+      ))
+    
+      ; Create the molecule (delegate to the normal molecule brewer)
+      (let ((molecule (Stem::brew_molecule grob)))
+        ; Re-set "note-heads" to its previous value, to avoid interferring with
+        ; anything else.
+        (ly-set-grob-property grob 'note-heads note-heads)
+        molecule
+        )
+    )
+  )
+
+; end of tablature function
 
 (define (arg->string arg)
   (cond ((number? arg) (inexact->string arg 10))
