How to combine cgloss4e, colouring and pinyin?

This is a follow-up to this question.

In this new question, I would like to be able to combine the colour-altering commands provided in the previous question with the automatic pinyin encoding of the text placed at line two.

Example.

In this example, part (1) shows how the colouring commands break automatic pinyin translation for the text on line two, which works correctly when colouring is not use, as in part (2). Part (3) shows the desired output.

\documentclass{report}

\usepackage{xcolor}
\usepackage{polyglossia}
\usepackage[AutoFallBack=true]{xeCJK}[2018/02/27]
\setCJKmainfont[FallBack=NotoSansCJKtc-Regular]{NotoSerifCJKtc-Regular}
\usepackage{xpinyin}
\usepackage{gb4e}

\let\eachwordtwo=\pinyin

\makeatletter
\newcommand*\glosscolor[1]{\gdef\@glcolor{#1}}
\glosscolor{red}
\AtBeginDocument{\colorlet{savedcol}{.}}
\def\@glosscolor{savedcol}

\newcommand{\clt}{\gdef\@glosscolor{\@glcolor}\color{\@glosscolor}}
\newcommand{\clf}{\gdef\@glosscolor{savedcol}\color{\@glosscolor}}

\gdef\getwords(#1,#2)#3 #4\\% #1=linebox, #2=\each, #3=1st word, #4=remainder
\unvbox#1%
}%
\def\more{#4}%
\ifx\more\empty\let\more=\donewords
\else\let\more=\getwords
\fi
\more(#1,#2)#4\\%
}
\gdef\donewords(#1,#2)\\{\gdef\@glosscolor{savedcol}}
\makeatother

\begin{document}

Present Situation:

\begin{exe}
\ex \glll
我  \clt {没有}        \clf {问题} \\
wo3 \clt {mei2 you3}  \clf {wen4 ti2} \\
I   \clt {don't have} \clf questions \\

\ex \glll
我   {没有}       {问题} \\
wo3 {mei2 you3}  {wen4 ti2} \\
I   {don't have} questions \\
\end{exe}

Desired Output:

\begin{exe}
\ex \glll
我           \clt {没有}              \clf {问题} \\
\pinyin{wo3} \clt \pinyin{mei2 you3} \clf \pinyin{wen4 ti2} \\
I            \clt {don't have}       \clf questions \\
\end{exe}

\end{document}


output:

Goal.

Ideally, I would like to maintain the best of the two worlds:

• being able to change the text colour with \clt/\clf
• not being forced to explicitly write \pinyin{} (as I did in part (3), which displays the desired output)

Is there a way to combine the automatic pinyin encoding for the text in line two, which is now performed with the following command:

\let\eachwordtwo=\pinyin


with the new \clt / \clf commands, so that they don't break each other?

• I found out that I can pretty much write wo3 \clt mei2you3 \clf wen4ti2 to get the desired output without any need to repeat \pinyin over and over.. the reason why it works it is not entirely clear to me, so I'll leave the question open. – Patrick Trentin May 27 '18 at 14:50
• The reason is that \pinyin is not a switch, but a macro that takes an argument. – Alan Munn May 27 '18 at 15:18
• You're welcome. I've added your no spaces option to my answer too, as it might be useful for others, and not everybody reads the comments. – Alan Munn May 27 '18 at 15:28

The xpinyin command \pinyin appears to take an argument (the documentation is all in Mandarin, which I can't read). Since the way I added the colour code was to the cgloss4e parsing macro, there's no way with that code to distinguish which line of the three line gloss you are in.

The best solution therefore would be to have a separate command for turning on the colouring in the pinyin line. So I've just added \plt and \plf commands to do that. Use them in the second line of the gloss.

Alternatively, as you discovered, you can leave the original commands intact and instead remove all the spaces in the pinyin elements. This works equally well since the \pinyin command takes an argument and I assume parses on the tone numbers.

\documentclass{report}

\usepackage{xcolor}
\usepackage{polyglossia}
\usepackage[AutoFallBack=true]{xeCJK}[2018/02/27]
\setCJKmainfont[FallBack=SimSun-ExtB]{SimSun}
%       and place it into ~/.fonts directory on linux
\usepackage{xpinyin}
\usepackage{gb4e}
\newif\ifpy
\renewcommand{\eachwordtwo}{\pytrue\pinyin}

\makeatletter
\newcommand*\glosscolor[1]{\gdef\@glcolor{#1}}
\glosscolor{red}
\AtBeginDocument{\colorlet{savedcol}{.}}
\def\@glosscolor{savedcol}

\newcommand{\clt}{\gdef\@glosscolor{\@glcolor}\color{\@glosscolor}}
\newcommand{\plt}{\gdef\@glosscolor{\@glcolor}\color{\@glosscolor}\eachwordtwo}
\newcommand{\clf}{\gdef\@glosscolor{savedcol}\color{\@glosscolor}}
\newcommand{\plf}{\gdef\@glosscolor{savedcol}\color{\@glosscolor}\eachwordtwo}

\gdef\getwords(#1,#2)#3 #4\\% #1=linebox, #2=\each, #3=1st word, #4=remainder
\unvbox#1%
}%
\def\more{#4}%
\ifx\more\empty\let\more=\donewords
\else\let\more=\getwords
\fi
\more(#1,#2)#4\\%
}
\gdef\donewords(#1,#2)\\{\gdef\@glosscolor{savedcol}}

\makeatother

\begin{document}

Present Situation:

\begin{exe} % works if you remove spaces from pinyin
\ex \glll
我  \clt {没有}        \clf {问题} \\
wo3 \clt mei2you3  \clf wen4ti2 \\
I   \clt {don't have} \clf questions \\

% alternatively use a separate command for the second line colouring
\ex \glll
我   \clt{没有}       \clf{问题} \\
wo3 \plt{mei2 you3}  \plf{wen4 ti2} \\
I   \clt{don't have} \clf questions \\
\end{exe}

Desired Output:

\begin{exe}
\ex \glll
我           \clt {没有}              \clf {问题} \\
\pinyin{wo3} \clt \pinyin{mei2 you3} \clf \pinyin{wen4 ti2} \\
I            \clt {don't have}       \clf questions \\
\end{exe}

\end{document}