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.

  • 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. – Andrew Swann Apr 25 at 14:38
  • Good point! Confirmed. – sgmoye Apr 25 at 15:23
6

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

  • 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

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.