# Obeylines and \gappto from etoolbox

In order to simplify data entry with as little markup of the data as possible, I am attempting the following:

\documentclass{article}

\usepackage{etoolbox}

\begingroup
\obeylines
\gdef\ing#1 #2 #3{\gappto{\tabbody}{% Collect rows of tabular[x] in \tabbody
%% Ignore #1 and/or #2 if empty (= . )
\if.#2
\if.#1
&&#3\\
\else
#1&&#3\\
\fi
\else
\if.#1
&#2&#3\\
\else
#1&#2&#3\\
\fi
\fi
}%
}
\endgroup

%%%%%% This, without the \if's works, though it does not do what I need:

\begingroup
\obeylines
\gdef\iing#1 #2 #3{\gappto{\tabbody}{% Collect rows of tabular[x] in \tabbody
#1&#2&#3\\
}%
}
\endgroup

\begin{document}

\begingroup
\obeylines
\everypar={\ing} %<<<--- change to \iing and there is no error
a 1 u
b 2 v
. 3 w
d 4 x
e 5 y
f 6 z
\endgroup

\begin{tabular}{ccc}
\tabbody
\end{tabular}

\end{document}


I'm getting an unexpected error:

ERROR: Incomplete \if; all text was ignored after line 39.

--- TeX said ---
<inserted text>
\fi
l.39 ^^I^^I\tabbody


I have looked at past queries, but have not thus far found an answer. If I remove all of the \if statements from the definition of \ing (=\iing) the problem goes a way. Quite sure I'm missing something really basic -- something to do with the timing of the expansion of the \ifs, but I'm stuck for the moment.

• Why do you need \obeylines so many places? Dropping \obeylines before the definition of \ing allows the file to compile and produces reasonable output. – Andrew Swann Apr 25 at 14:38
• Good point! Confirmed. – sgmoye Apr 25 at 15:23

You don't want to define \ing under the scope of \obeylines, but just use the active ^^M as delimiter (reinserting it at the end so a \par will be issued.

You also want to expand the conditionals before appending the result to \tabbody.

\documentclass{article}
\usepackage{etoolbox}

\begingroup\lccode~=\^^M\lowercase{\endgroup\def\ing#1 #2 #3~{%
\xappto{\tabbody}{% Collect rows of tabular[x] in \tabbody
%% Ignore #1 and/or #2 if empty (= . )
\if.#2%
\if.#1%
\unexpanded{&&#3\\}%
\else
\unexpanded{#1&&#3\\}%
\fi
\else
\if.#1%
\unexpanded{&#2&#3\\}%
\else
\unexpanded{#1&#2&#3\\}%
\fi
\fi
}~% we want a \par
}}

\begin{document}

\begingroup
\obeylines
\everypar={\ing} %<<<--- change to \iing and there is no error
a 1 u
b 2 v
. 3 w
d 4 x
e 5 y
f 6 z
\endgroup

%\show\tabbody % for debugging

\begin{tabular}{ccc}
\tabbody
\end{tabular}

\end{document}


• However, an input such as a 1 u\\ would be much easier to manage and less fragile. – egreg Apr 25 at 14:58
• Very nice. Thanks! I don't entirely understand how this works. The \lccode of ~ is being set equal to that of ^^M. Good so far--that ends up being used at the end. But the \begingroup...\lowercase{\endgroup construction eludes me. – sgmoye Apr 26 at 12:07
• Ah. The penny dropped. The \lccode bit is done just prior to \lowercase (which assignment \lowercase will then use) but it is put into a group so that the effect is localized. Sorry for the noise. – sgmoye Apr 26 at 13:07