2

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
1

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

        return tonumber(fret) - base_fret;
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}
1

Works in pdflatex, using modified syntax:

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

instead of

\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}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.