It was worse than that. I started with the idea I wanted the staff
inverted, because that was the way I thought of it, not flipping
strings, who would ever do that? I am not a programmer, never will be.
I can wade through code and cobble things together or pull things
apart when need be, having the most basic understanding of Basic and
Python. It just doesn't interest me enough to really learn beyond as
an occasional trespasser into that world. .But maybe I might try
figuring out how to make Lilypond deal with German lute tab which I
suspect will require some sort of defined array since the system is
very logical but doesn't follow the same level of simplicity that
underlies the french and italian tab styles which are basical;ly
identical mirrors of each other one labeled with letters and the other
numbers.
  Carl, thank you for the extended explanation of working with
internals. It is something I have tried my best to not dig into over
the many years I have used LilyPond.

On Thu, Nov 13, 2025 at 8:14 PM Carl Sorensen <[email protected]> wrote:
>
> On Thu, Nov 13, 2025 at 5:46 PM Charlie Ma <[email protected]> wrote:
> >
> > This is a very helpful deep dive. As an occasional user, and still a newb, 
> > I greatly benefit from this demonstration of stepping through the docs. 
> > Thank you.
> > But you’d need to be a programmer to understand how to trace through these 
> > functions as you did here. (Fortunately I am one, though not with scheme).
> > This highlights a gap in LilyPond documentation and usability.
> >
> > Also I think you meant to demonstrate this use of Internals as an 
> > alternative, or improvement, over googling (which Shane did to find 
> > “stringOneTopmost”). But your effort started with the answer he already 
> > found.
> > It begs the question how one would have found this, via the docs, if one 
> > only started with the idea: “I want the highest sounding string on the 
> > bottom line.”
> >
>
> There's no question that there is a gap in LilyPond documentation.
> Actually. it's an intentional gap.  If we had every possible variation
> shown in the Notation Reference, the NR would be at least ten times
> the size that it is now.  Of course, with search tools, we could
> easily search the NR.  But somebody would have to write all those NR
> sections, and we don't have anybody to do that.  As I mentioned, this
> particular search is one of the hardest I know of -- because the
> layout object you expect to have a property to change the behaviour
> (the StaffSymbol for the TabStaff context) doesn't actually have the
> property you need.  One needs to think carefully about where the
> changes would need to happen to have what you'd like to see (the
> TabNoteHead shows up on a different line, so the property affects
> TabNoteHead, not StaffSymbol).
>
> Let me try to show you how I would have done it.
>
> The question -- I want to have the string with the highest pitch on
> the bottom of my tablature.  I wonder how I can do that?
>
> Let's see.  I need to change the way a tabulature staff is displayed.I
> wonder what properties I can find about tabulature staffs.  Oh, I
> know, I'll go to the Internals Reference, and  look up all the
> properties of tab staffs.  OK, now I need to decide -- am I looking
> for a context property or a layout object property.  TabStaff is a
> context, so maybe it's a context property.  But TabStaff is not the
> thing on the paper; I don't know what that output object is.  How can
> I figure it out?
>
> Let me go to the think I know about, the TabStaff Context.  That's
> section 2.1 of the Internals Reference:
>
> https://lilypond.org/doc/v2.24/Documentation/internals/contexts
>
> Looking on that page, I see 2.1.36 TabStaff.  Let me go there:
>
> https://lilypond.org/doc/v2.24/Documentation/internals/tabstaff
>
> Look at the context properties set by the context.  Nothing seems
> related to my problem.
>
> Look at the grob properties set by the context.  They are set for a
> number of different grobs.  Do any of them look promising?  Nope, but
> I do see that there is a property that affects a TabNoteHead.  So at
> least the context knows about TabNoteHead.  So far, nothing useful.
>
> Now let me look at the engravers.  Two seem possibly promising:
> Staff_symbol_engraver -- it creates the staff lines;
> Tab_staff_symbol_engraver -- creates a tab staff symbol and looks at
> stringTunings.  Let me jump first into the Tab_staff_symbol engraver,
> because it is tablature specific:
>
> https://lilypond.org/doc/v2.24/Documentation/internals/tab_005fstaff_005fsymbol_005fengraver
>
> Hmm -- only stringTunings there.  Not particularly helpful.   But it
> links to StaffSymbol.  So let me follow it.
>
> https://lilypond.org/doc/v2.24/Documentation/internals/staffsymbol
>
> Lots of properties there.  None looks helpful.  Let me scratch my
> head, and think about it.  How would the tablature staff look
> different if the highest-pitch string were on the bottom?  I guess it
> wouldn't look any different.  Just a certain number of lines.  Oh,
> yeah, the doc on the Tab_staff_symbol_engraver said that it read
> stringTunings to determine the number of lines in a tab staff.  But it
> didn't say anything about pitches.  So maybe the StaffSymbol doesn't
> actually know about pitches.
>
> I'm stuck.  What to do?  Here are two possible cases:
>
> Case 1:
> What changes when we put the highest pitch string on the bottom of the
> TabStaff? The vertical location of the TabNoteHead.  So let's look at
> the TabNoteHead layout object (grob).  IR. 3.1 All Layout Objects:
>
> https://lilypond.org/doc/v2.24/Documentation/internals/all-layout-objects
>
> Oh.  There I see 3.1.11 TabNoteHead
>
> https://lilypond.org/doc/v2.24/Documentation/internals/tabnotehead
>
> Look at the properties.  None of the properties seem to make sense.
> But the object is created by the Tab_note_heads_engraver.  So let me
> follow that link.
>
> https://lilypond.org/doc/v2.24/Documentation/internals/tab_005fnote_005fheads_005fengraver
>
> Now look at the properties.  Lots of potentially-interesting properties:
>
> highStringOne (boolean)stringOneTopmost (boolean)
>
> stringTunings (list)
>
> All of these properties affect automatic tablature calculations.  I
> might be able to figure out from these what I should do.
>
> highStringOne -- tells me if the highest pitch string is string one.
> In this case, it is, so highStringOne should be true.
> stringTunings -- we've already set the stringTunings as we want it.
> stringOneTopmost -- oh, we don't want stringOneTopmost, so we should
> set this to false.
>
> Now, we can't set properties in engravers; we must either do it in
> grobs or contexts.  We might want to set it in the TabNoteHead grob;
> but the TabNoteHead grob doesn't support this property.  So let's look
> for a good context.  We could use the TabVoice context (the
> Tab_note_heads_engraver lives in the TabVoice context), but we
> wouldn't want to have different TabVoice contexts in the same TabStaff
> to have different settings of this property.  So I think we should put
> it in the TabStaff context.  And when we try that, it works.
>
> Case 2:
> I have no idea what to change.  So let me look at all of the layout
> object properties (Internals Reference 3.3 User Backend Properies)
>
> https://lilypond.org/doc/v2.24/Documentation/internals/user-backend-properties
>
> Lots of properties.  How can I search them?  What if I search in this
> page for tab?  One property -- double-stem-separation, which applies
> to tab stems.  Not applicable.
>
> So let's look at all context properties (Internals Reference 2.3
> Tunable Context Properties):
>
> https://lilypond.org/doc/v2.24/Documentation/internals/tunable-context-properties
>
> Again, search in the page for tab. THis is helpful:
>
> highStringOne (boolean)
>
> Whether the first string is the string with highest pitch on the
> instrument. This used by the automatic string selector for tablature
> notation.
>
>
> stringOneTopmost (boolean)
>
> Whether the first string is printed on the top line of the tablature.
>
> stringTunings (list)
>
> The tablature strings tuning. It is a list of the pitches of each
> string (starting with the lowest numbered one).
>
> These properties can now help me to think about what I want.  Is
> string one the highest pitch?  Yes.  So this should be true
>
> Is the first string printed on the top line of the tablature?  No.  So
> this should be false.  And we know it's a context property, so we try
> to decide the context to use, and TabStaff seems to make the most
> sense.  Let's try it.  And it works.
>
> I know this is difficult.  But it's doable.  And as you develop the
> skill to do this, it becomes easier and easier to have LilyPond do
> what you want, no matter how non-standard it is.
>
> It takes practice.  But I think it's worth it.
>
> Thanks,
>
> Carl

Reply via email to