\gtab [歌曲包] 使用 \pgfkeys 属性作为第二个参数

\gtab [歌曲包] 使用 \pgfkeys 属性作为第二个参数

songs 包中的 \gtabs 部分根据两个参数打印吉他和弦

\gtab{chord name}{guitar frets and strings}

第二个参数不接受 \pgfkeys 作为第二个参数

以下是说明该示例的代码:

\documentclass{article}
\RequirePackage{filecontents}% write the data file
\usepackage{pgfkeys}
\usepackage{xparse}
\usepackage{songs}

\begin{filecontents}{chords.csv}
    A   = { A,0022200}
    A01 = { A,5:133211:143211}
    B = { B,X24442} 
    C = { C,032010}
\end{filecontents}

% BEGIN Read Chord Definitions
\pgfkeys{/chords/.is family, chords,
.unknown/.code args={#1,#2}{ % Format is <name>,<capital>,<population>
    \pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname/c_name}{#1}
    \pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname/c_def}{#2}},
}

\newcommand\printchordnm[1]{% print the key if it is defined and ???Otherwise
    \pgfkeysifdefined{/chords/#1/c_name}{\pgfkeysvalueof{/chords/#1/c_name}}{???}%
}

\newcommand\printchordef[1]{% print the key if it is defined and ???Otherwise
    \pgfkeysifdefined{/chords/#1/c_def}{\pgfkeysvalueof{/chords/#1/c_def}}{???}%
}

\newcommand\AddState[1]{\expandafter\pgfkeys\expandafter{/chords, #1}}
\newread\statefile% file handler
\def\apar{\par}% \ifx\par won't work but \ifx\apar will
\newcommand\ReadStates[1]{% read file into [\pgfkeys{/state}
    \openin\statefile=#1% open file for reading
    \loop\unless\ifeof\statefile% loop until end of file
    \read\statefile to \stateline% read line from file
    \ifx\stateline\apar% test for \par
    \else%
    \ifx\stateline\empty\relax% skip over empty lines/comments
    \else\expandafter\AddState\expandafter{\stateline}%
    \fi%
    \fi%
    \repeat% end of file reading loop
    \closein\statefile% close input file
}
\ReadStates{chords.csv}% read the file


\begin{document}
    \def\hpvardef{\printchordef{A01}}
    Hi \printchordnm{A01} and definition is \printchordef{A01}\par 

    the chord is represented as \gtab{A}{5:133211:143211}\par 
    Using macro as first parameter OK \gtab{\printchordnm{A01}}{5:133211:143211}\par 
    Now I want to use macro as second parameter \gtab{A02}{\printchordef{A01}}\par 
    which generates an error\par 
    What about local macro def hpvardef: \hpvardef\par 
    Let's try it \gtab{A02}{\hpvardef}
\begin{songs}{}
\end{songs}
\end{document}

enter image description here

答案1

根据 Elrich 提供的解释\gtab [歌曲包] 使用宏变量作为第二个参数 我修改了他的两个宏命令如下

\documentclass{article}
\RequirePackage{filecontents}% write the data file
\usepackage{pgfkeys}
\usepackage{xparse}
\usepackage{songs}

\begin{filecontents}{chords.csv}
    A   = { A,0022200}
    A01 = { A,5:133211:143211}
    B = { B,X24442} 
    C = { C,032010}
\end{filecontents}

% BEGIN Read US Chords Definitions
\pgfkeys{/chords/.is family, chords,
    .unknown/.code args={#1,#2}{ % Format is <name>,<capital>,<population>
        \pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname/c_name}{#1}
        \pgfkeyssetvalue{\pgfkeyscurrentpath/\pgfkeyscurrentname/c_def}{#2}},
}

\newcommand\AddChord[1]{\expandafter\pgfkeys\expandafter{/chords, #1}}
\newread\Chordfile% file handler
\def\apar{\par}% \ifx\par won't work but \ifx\apar will
\newcommand\ReadChords[1]{% read file into [\pgfkeys{/Chord}
    \openin\Chordfile=#1% open file for reading
    \loop\unless\ifeof\Chordfile% loop until end of file
    \read\Chordfile to \Chordline% read line from file
    \ifx\Chordline\apar% test for \par
    \else%
    \ifx\Chordline\empty\relax% skip over empty lines/comments
    \else\expandafter\AddChord\expandafter{\Chordline}%
    \fi%
    \fi%
    \repeat% end of file reading loop
    \closein\Chordfile% close input file
}
\ReadChords{chords.csv}% read the file


\makeatletter

\newcommand\hpvarC[2]{\TotalExpandSecondFirst{\expandafter\gtab\@firstofone}{{#1}{#2}}}%

\newcommand\TotalExpandSecondFirst[2]{%
    \begingroup
    \protected@edef\mytempa{{#2}}%
    \expandafter\PassFirstToSecond\mytempa{\endgroup#1}%
}%
\makeatother

\newcommand\PassFirstToSecond[2]{#2{#1}}%

\newcommand\hptab[1]{% print the key if it is defined and ???Otherwise
    \pgfkeysgetvalue{/chords/#1/c_name}\hpdeni
    \pgfkeysgetvalue{/chords/#1/c_def}\hpdeff 

    Variant    is: #1\par 
    Chord      is: \hpdeni\par 
    Definition is: \hpdeff\par

    Hello ``\hpvarC{\hpdeni}{\hpdeff}''

}

\begin{document}

    My music book prints chords using macro definitions.\par
    All I do is send the variant chord I want to hptab\par 
    Let's try it\par 
    \bigskip
    Print First Variant of Chord A\par 
    \par 
    Let's call first hptab\{A01\} but take a look at hpvarC
    \hptab{A01}
\end{document}

enter image description here

相关内容