5

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.

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

1 Answer 1

5

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}

enter image description here

3
  • However, an input such as a 1 u\\ would be much easier to manage and less fragile.
    – egreg
    Apr 25, 2019 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, 2019 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, 2019 at 13:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .