18

How is it possible to use the end-of-line character as a macro parameter ? I would like something along the lines of :

\def\mymacro#1\endlinechar{Content:#1}
\mymacro First content
\mymacro Second content

Giving the following output :

Content: First content
Content: Second content

I have tried \endlinechar and \^^M but it does not work that easily.

  • 2
    Welcome to TeX.SX! I would recommend against doing this. It requires changing the category code of ^^M and this opens more problems than it can solve. – egreg Jul 26 '13 at 13:05
  • Thanks. Is that why there are delimiters like \begin{} and \end{} ? – alex_reader Jul 26 '13 at 13:10
  • 1
    LaTeX uses a different model than Plain TeX which is more “liberal”. While delimited arguments are useful, using them in documents forces to use a very rigid typing style (you can check the source of the TeXbook to see what I mean). Delimiting by end-of-line should be reserved to special situations such as verbatim modes. – egreg Jul 26 '13 at 13:16
22

The end-of-line character is not available to be used in the main input stream, under the standard setting which is

\endlinechar=`\^^M
\catcode`\^^M=5

(see The ^^ notation in various engines for information about the ^^ notation).

When TeX sees a character with category code 5, it immediately converts it either to a space or to a \par token if another follows (possibly after the “skipping blanks” phase). When it sees the (operating system defined) end-of-record, it throws it away together with anything that can be on the line past it, removes all trailing blank spaces and inserts the \endlinechar.

Usually the \endlinechar has category code 5, but this is not mandatory and different effects can be obtained by changing the category code. For instance, \obeylines makes \^^M into an active character and assign it the same meaning as \par.

For your application you can look at section 11.9.4 of TeX by Topic; basically you do

\def\mymacro{\begingroup\catcode`\^^M=12 \xmymacro}
{\catcode`\^^M=12 %
 \gdef\xmymacro#1^^M{Content: #1\endgroup}%
}

Changing the category code of ^^M must be done in a group or otherwise you end up painting yourself into a corner.

However, I can't recommend doing this: editors might have different ideas about you with respect to when lines should end and hitting a key by mistake can spoil your work. Moreover, using \mymacro inside an argument to another macro will definitely not work.

Important note

The end-of-line character mentioned above is not the system dependent record terminator. When TeX (any engine implementing it) reads a line, is informed by the operating system what the record terminator is; upon finding it, it throws it away together with everything after it on the same line; then it removes trailing blank spaces (character code 32) and tabs (character code 9); finally it inserts the character having the code equal to the current value of \endlinechar.

So it's immaterial whether the record terminator is CR (ASCII 13), LF (ASCII 10) or CR+LF, or nothing at all (like for legacy IBM mainframes).

The TeX Live implementation allows any of the combinations above (CR, LF or CR+LF): it examines the first lines of the file and decides upon the line terminator to inform TeX of.

  • Regarding your 'Important note'. You wrote: "upon finding it [=the operating system record terminator], it [=the TeX engine] throws it away together with everything after it on the same line". How can there be anything else on the same line following a record terminator? Isn't anything following a record terminator on the next line by definition? – Evan Aad Jun 20 '17 at 17:54
  • @EvanAad Older operating systems might behave strangely. – egreg Jun 20 '17 at 19:13
  • You wrote: "When TeX (any engine implementing it) reads a line, is informed by the operating system what the record terminator is". How is TeX informed what the record terminator is? Is there a macro or register similar to \endlinechar, which contains this information? – Evan Aad Jun 21 '17 at 15:45
  • @EvanAad No, this happens at the OS level. – egreg Jun 21 '17 at 15:48
  • @egreg What do you mean this happens at the OS level? I was under the impression that TeX read input byte by byte. Then, how could it know when an OS-dependent record terminator appeared? It would just see the code point of the character. – extremeaxe5 Oct 10 '18 at 19:12
6

OPmac defines:

\def\eoldef#1{\def#1{\begingroup \catcode`\^^M=12 \eoldefA#1}%
   \expandafter\def\csname\string#1:M\endcsname}
{\catcode`\^^M=12\gdef\eoldefA#1#2^^M{\endgroup\csname\string#1:M\endcsname{#2}}}

Then you can define your macro:

\eoldef\foo#1{\message{param: "#1"}}

And you can use it:

\foo this is parameter
and this is next text.  

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.