# How can I make a modification to gchords.sty to use actual fret numbers?

I'm using LaTeX to put together a jazz guitar chords book. I've been using gchords.sty (https://kasper.phi-sci.com/gchords/) and it's worked well for me so far except for one thing: you have to specify the fret number relative to the base fret you give for the chord box. For instance, here's an example of a chord I put in:

\chord{2}{x,p{5},p{3},p{1},p{1},p{3}}{{Em11(\ensuremath{\flat}5)}}


This is for a chord that you might write as x75335 -- the p{5} in the macro actually represents the seventh fret (base fret of 2 plus 5 frets up from that). That's terribly unintuitive for me as a guitar player, and it means that I have to do mental math for every chord I write out -- figure out a sane base fret and then subtract that from each string in the chord. I would much prefer that the macro work something like this:

\chord{2}{x,p{7},p{5},p{3},p{3},p{5}}{{Em11(\ensuremath{\flat}5)}}


where the position of each dot within the chord grid is computed as the specified fret minus the base fret.

Unfortunately, my LaTeX-foo is nowhere near the level of something like this. If this were C or Java, I would just create a wrapper function that calls the chord function with each argument being (arg - base) -- is something like that possible in LaTeX? Would anyone have any idea how to do this?

FWIW, I followed up with the author with a feature request, but I didn't hear back.

Thanks!

Edit: here is a complete working example:

\documentclass[12pt,pdftex]{report}

\usepackage{gchords}

\begin{document}

\chords{
\def\numfrets{6}
\chord{2}{x,p{5},p{3},p{1},p{1},p{3}}{{Em11(\ensuremath{\flat}5)}}
\chord{2}{3,x,p{3},p{1},p{2},p{3}}{{A7(\ensuremath{\flat}9)(\ensuremath{\sharp}11)}}
}

\end{document}

• Can you actually provide a working example, not just code snippets? Welcome to the site. – Steven B. Segletes Jun 1 '19 at 2:55
• Not relevant to the problem, but you can simply write $\flat$ instead of using \ensuremath. – Alan Munn Jun 1 '19 at 2:57
• Relevant to the problem: there are a lot more commands than just the p{} that the \chord command knows about. Do these need to be modified too? What are the relevant range of values for the base fret and the specified frets? – Alan Munn Jun 1 '19 at 3:01
• @StevenB.Segletes: I updated my question to include a working example. You need to have gchords.sty in the same directory as the example. – Ben Shelton Jun 2 '19 at 0:37
• @AlanMunn: Thanks for the tip on flats/sharps. As far as the commands, I guess the additional commands are specified in gchords.sty. For base fret, valid values are between 0 and maybe 20. For the specified frets, in the way it works currently, they would go from 0 to n, where n is the length of the chord box (6 frets in the example above). In the way I would like it to work, they would go from base_fret to (n + base_fret), where n is the length of the chord box. – Ben Shelton Jun 2 '19 at 0:42

I figured this out using LuaLaTex to make a wrapper around the chord macro.

\documentclass{report}

\usepackage{gchords}
\usepackage{luacode}

\begin{document}

\begin{luacode*}
function fret_to_str(base_fret, fret)
if (fret == "x") then
return "x";
end

if (fret == "o") then
return "o";
end

end

local function split(str,pat)
local tbl = {}
str:gsub(pat, function(x) tbl[#tbl+1]=x end)
return tbl
end

function print_chord(base_fret, strinfo)
local strarray, outstr
local pat = "[^,]*"

strarray = split(strinfo, pat)

outstr = string.format([[\chord{%d}{]], base_fret);

outstr = outstr .. fret_to_str(base_fret, strarray[1]) .. ",";
outstr = outstr .. fret_to_str(base_fret, strarray[2]) .. ",";
outstr = outstr .. fret_to_str(base_fret, strarray[3]) .. ",";
outstr = outstr .. fret_to_str(base_fret, strarray[4]) .. ",";
outstr = outstr .. fret_to_str(base_fret, strarray[5]) .. ",";
outstr = outstr .. fret_to_str(base_fret, strarray[6]) .. "}";

return outstr;
end
\end{luacode*}

\newcommand*{\testchord}[2]{%
\directlua{tex.print(print_chord(#1, [[#2]]))}%
}%

\def\numfrets{6}

\chords{
\testchord{2}{x,7,5,3,3,5}{{Em11($\flat$5)}}
}

\end{document}


Works in pdflatex, using modified syntax:

\xchord{2}{x 7 5 3 3 5}{...}


\chord{2}{x,p{5},p{3},p{1},p{1},p{3}}{...}


The MWE:

\documentclass[12pt,pdftex]{report}

\usepackage{gchords}
\newcommand\xchord[3]{\edef\z{\xxchord{#1} #2}%
\def\tmp{\chord{#1}}%
\expandafter\tmp\expandafter{\z}{#3}}
\def\xxchord#1 #2 #3 #4 #5 #6 #7{%
\ifx x#2 x,\else\the\numexpr#2-#1\relax,\fi
\ifx x#3 x,\else p{\the\numexpr#3-#1\relax},\fi
\ifx x#4 x,\else p{\the\numexpr#4-#1\relax},\fi
\ifx x#5 x,\else p{\the\numexpr#5-#1\relax},\fi
\ifx x#6 x,\else p{\the\numexpr#6-#1\relax},\fi
\ifx x#7 x\else p{\the\numexpr#7-#1\relax}\fi
}

\begin{document}
Gchords method:
\chords{
\def\numfrets{6}
\chord{2}{x,p{5},p{3},p{1},p{1},p{3}}{{Em11(\ensuremath{\flat}5)}}
\chord{2}{3,x,p{3},p{1},p{2},p{3}}{{A7(\ensuremath{\flat}9)(\ensuremath{\sharp}11)}}
}

Proposed alternative:
\chords{
\def\numfrets{6}
\xchord{2}{x 7 5 3 3 5}{{Em11(\ensuremath{\flat}5)}}
\xchord{2}{5 x 5 3 4 5}{{A7(\ensuremath{\flat}9)(\ensuremath{\sharp}11)}}
}
\end{document}