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?
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 \.
#. See my updated example. Also @Yossi.
– Martin Scharrer
Feb 07 '11 at 07:21
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.
– Martin Scharrer
Feb 07 '11 at 10:22
\newlinecommand is a bad name. Any better alternative? About packaging, I agree as well. Do you know which packages do this kind of thing?
– Bruno Le Floch
Feb 07 '11 at 10:40
\newlinecommand to also take arguments?
– Joachim Breitner
Feb 05 '17 at 22:30
\rowswitch in the first cell and define either \newlinecommand{\emphline}{#1} or \newlinecommand{\emphline}{} but I keep getting Forbidden control sequence found while scanning use of \\rowswitch. Is there a way to still achieve this using your method?
– sheß
Mar 08 '18 at 20:09
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.
\def\restofline@aux (see my updated answer). Do you think that this is useful enough that we should package it?
– Bruno Le Floch
Feb 07 '11 at 10:11
parselines? Doesn't seem possible to me....
– user32882
Apr 19 '22 at 08: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