# Preserve tab and newline characters in command argument

Following the question Tab not as extra alignment tab I managed to use the tab character as column divider '&' and the newline character as line break '\\' in an array (or tabular) environment, which works as expected.

Now I'd like to wrap this environment in a command, but it seems that all tab and newline characters are stripped from the table body. Is there a way to preserve those control characters?

MWE:

\documentclass{article}

\makeatletter%
\begingroup%
\gdef\activateCtrlChars{%
\catcode\^^I=\active%
\catcode\^^M=\active%
}%
\activateCtrlChars%
\gdef^^I{\@ifnextchar^^I{}{&}}%
\gdef^^M{\@ifnextchar\end {}{\\}}%
\gdef\gobbleLineBreak{\@ifnextchar^^M {\@gobble}{}}%
\endgroup%
\makeatother%

\newenvironment{myArray}
{% before
\activateCtrlChars%
\array[t]{ccc}%
\gobbleLineBreak%
}
{% after
\endarray%
\par%
}

\newcommand{\myArrayAsCmd}[1]{\begin{myArray}#1\end{myArray}}

\begin{document}

Environment:
\begin{myArray}
a   b   c
aa  bb  cc
\end{myArray}

Command:
\myArrayAsCmd{
a   b   c
aa  bb  cc
}

\end{document}


Output:

A global redefinition of active ^^M is not a good idea. Here's code that avoids it. About your problem: you need to change the category code before grabbing the argument.

Final comment: this can seem handy. But it's fragile and editor dependent (some normalize TAB characters with spaces, for instance). You gain very little and risk losing much. Don't do it.

\documentclass{article}

\makeatletter
\def\activateCtrlChars{%
\catcode\^^I=\active
\catcode\^^M=\active
\begingroup\lccode~=\^^I\lowercase{\endgroup\def~}{&}%
\begingroup\lccode~=\^^M\lowercase{\endgroup\def~}{\\}%
}
\begingroup
\obeylines
\gdef\gobbleLineBreak{\@ifnextchar^^M{\@gobble}{}}%
\endgroup%
\makeatother

\newenvironment{myArray}
{%before
\activateCtrlChars
\array[t]{ccc}\gobbleLineBreak
}
{% after
\endarray
}

\newcommand{\myArrayAsCmd}{%
\begingroup\activateCtrlChars\begin{myArray}\fetchArg
}
\newcommand\fetchArg[1]{\gobbleLineBreak#1\end{myArray}\endgroup}

\begin{document}

Environment:
\begin{myArray}
a   b   c
aa  bb  cc
\end{myArray}

Command:
\myArrayAsCmd{
a   b   c
aa  bb  cc
}

\end{document}


• It works as advertised, but after extensive testing i can only concur to your warning not to do it. – lujomu Jan 22 '15 at 16:11