# \def taking rest of the line as argument

I know how to define a macro that will take the rest of the paragraph as parameter. Simply write \def\a#1\par{\textbf{#1}}.

But, how do I write a macro whose argument will extend to the end of the line?

This answer builds upon Martin Scharrer's updated solution (which was based on mine, based on his... ;-p).

\documentclass{article}
\begin{document}
\newcommand*{\newlinecommand}[2]{%
\newcommand*{#1}{%
\begingroup%
\escapechar=\\%
\catcode\endlinechar=\active%
\csname\string#1\endcsname%
}%
\begingroup%
\escapechar=\\%
\lccode\~=\endlinechar%
\lowercase{%
\expandafter\endgroup
\expandafter\def\csname\string#1\endcsname##1~%
}{\endgroup#2\space}%
}

%%% USAGE:
\newlinecommand{\emphline}{\emph{#1}}

First words \emphline rest of line
some more text

\end{document}


\emphline sets up the catcode of the end-line character to be active (we could have used a few other choices, as long as it is consistent). It then calls \\emphline, which takes care of grabbing the argument until the end of the line, and applies \emph{ } to it (this is #2 in the definition of \newlinecommand).

We use \begingroup and \endgroup to limit the scope of our change in catcode of \endlinechar to the inside of \emphline.

In order to grab the end of the line, we use a delimited argument, but for this, we need to have an active end-of-line character. Two possibilities:

• change the catcode locally and then use this active end-of-line in the definition, but this fails in our case, because we are already inside a definition (of \newlinecommand), and catcodes cannot change anymore

• use \lowercase{~} after defining a lowercase ~ to be the end-of-line character.

Finally, the construction \csname\string#1\endcsname makes the control sequence \\emphline in our case (because #1 is \emphline). We make sure that \string produces \emphline by setting the escape character (that TeX uses for \string) to actually be \.

• Absolutely brilliant! Maybe this should go into a small package? Feb 7, 2011 at 6:33
• @Bruno: Nice solution. Yes, you can modify it to avoid the doubling of #. See my updated example. Also @Yossi. Feb 7, 2011 at 7:21
• @Bruno: Very nice answer! Could you edit it so that the best updated solution is shown first? There is no need to keep a (visible) record of how the answer was improved over time. Editing history is always available by clicking on the link next to “edited”. Feb 7, 2011 at 10:14
• @Juan: since it was accepted, I assumed that I shouldn't change it without some form of consent from someone. I guess a moderator is enough ;). Feb 7, 2011 at 10:19
• @Bruno: Nice adaption again. I don't like the name newlinecommand very much because its reads more like a command for newline s. I don't think the code is used so often by many people to justify an own package. Maybe it could be added to an existing package which provides new command definition macros. Feb 7, 2011 at 10:22

The end-of-line character in TeX is the ASCII 13 Carriage Return character which can be represented by ^^M (M=13th character in the alphabet). This is independent of the actual input file format (i.e. DOS/Windows vs. Unix vs. Mac end-of-line characters).

However you cannot simply write \def\a#1^^M{\textbf{#1}} because TeX doesn't like this. One way is to redefine the catcode (see The TeXBook) of it:

\def\restofline{%
\begingroup
\catcode\^^M=\active
\irestofline
}
\begingroup
\catcode\^^M=\active %
\gdef\irestofline#1^^M{%
\iirestofline{#1}%
\endgroup %
\space % Readd effective space from removed end-of-line
}%
\endgroup %

\def\iirestofline#1{\textbf{#1}}

%%% USAGE:
First words \restofline rest of line


This worked in my tests, but might be flawed somehow and there might be better/more efficient ways to do it.

Please note that the end-of-line can be commented out using % in which case this macro will also read the next line.

Here a variation of the solution of Bruno Le Floch (which is based on my solution above) where # in #1 doesn't have to be doubled. The trick is to use a second macro for this. Note that \csname\string#1\endcsname generates a command sequence \\foo from \foo.

\documentclass{article}
\begin{document}
\makeatletter
\newcommand*{\newlinecommand}[1]{%
\newcommand*{#1}{%
\begingroup%
\lccode\~=\endlinechar%
\lowercase{\def\restofline@aux####1~}{\endgroup\csname\string#1\endcsname{####1}\space}%
\catcode\endlinechar=\active%
\restofline@aux%
}%
\expandafter\def\csname\string#1\endcsname##1%
}
\makeatother

%%% USAGE:
\newlinecommand{\emphline}{\emph{#1}}

First words \emphline rest of line
some more text

\end{document}


Please also note that there is a parselines package which might be used. Its code might be a good read for people interested in this kind of parsing.

• it is even possible to get rid of the \def\restofline@aux (see my updated answer). Do you think that this is useful enough that we should package it? Feb 7, 2011 at 10:11
• Is it possible to make it work if the line ends with \\  or \par? Jun 3, 2020 at 16:28
• How would you make it work with parselines? Doesn't seem possible to me.... Apr 19 at 8:18

Here is a crude solution that relies on changing catcodes:

\def\TEST
{\begingroup
\catcode\^^M=13
\doTEST}

\begingroup
\catcode\^^M=13
\gdef\doTEST#1^^M%
{\endgroup The line argument is :#1:}
\endgroup

\TEST this is a command that takes on line
as an argument

some more text

\bye

• Is it possible to make it work if the line ends with \\  or \par? Jun 3, 2020 at 16:28