# Why is this code not working?

On this post, one answer states that \obeylines is defined as

\def\obeylines{\catcode\^^M\active \let ^^M\par }


However TeX complains when I try to compile the following code

\def\obeylines{\catcode\^^M\active \let ^^M\par }
\def\disobeylines{\catcode\^^M=5 }

\obeylines
We obey, and end up on separate lines.
We obey.
\disobeylines
We disobey, and end up on the same line.
We disobey.

\bye


The situation doesn't get any better when I change the first line to

\def\obeylines{\catcode\^^M=13 \let^^M=\par }


Why is this code not working?

• This question could probably do with a better title. – Werner Apr 5 '18 at 15:56
• You don't need to define \obeylines, do you? – egreg Apr 5 '18 at 16:31

When TeX performs a \def, it just stores tokens with their current category code. In your case you are storing

\catcode12\^^M\active\let ^^M5\par

(bullets separate tokens). So when your \obeylines macro is called, ^^M becomes active, but \let^^M will throw an error of “Missing control sequence”.

Actually, this analysis is not the full truth, because the ^^M with category code 5 in the body of the definition will cause the line to be finished and \par} ignored. So the error you get is different. Doing similar things with other characters would have the same problem described above.

If you look in plain.tex you see

% In \obeylines, we say \let^^M=\par' instead of \def^^M{\par}'
% since this allows, for example, \let\par=\cr \obeylines \halign{...'
{\catcode\^^M=\active % these lines must end with %
\gdef\obeylines{\catcode\^^M\active \let^^M\par}%
\global\let^^M\par} % this is in case ^^M appears in a \write


so what's actually stored is

\catcode12\^^M\active\let ^^M13\par

which does the job. The \global\let^^M\par can be without the \global, but you could incur into problems if page breaks come along.

• Thanks to you: now I know of the existence of plain.tex. Very good answer. – Lagrange.el.Ciencia Apr 5 '18 at 16:52
• @egreg The \global\let^^M\par can be without the \global, but you could incur into problems if page breaks come along. You must have been thinking about something related (contents of \obeylines will be interrupted by a page break?) but distinct, because the \global in your quote of plain.tex is simply there to give some definition to the active ^^M, and it wouldn't have any effet without \global. – user4686 Apr 8 '18 at 21:37

You need ^^M to be active at time of definition, in order for the \let^^M\par to be legal. Check plain.tex for one way.

• First of all, thanks for the answer. I don't understand: isn't \catcode\^^M=13 making it active? – Lagrange.el.Ciencia Apr 5 '18 at 16:18
• @Lagrange.el.Ciencia No, it only does when \obeylines is called; but you need ^^M to be active in order to do \let^^M=\par and it isn't if the definition is not made when ^^M is active. – egreg Apr 5 '18 at 16:30
• @egreg Now I see. I did this: \catcode\^^M=13\def\obeylines{\catcode\^^M=13 \let ^^M=\par }\catcode\^^M=5` and it worked! – Lagrange.el.Ciencia Apr 5 '18 at 16:39