2

The problem is that \obeylines macro is not working while it's inside \def

Compare:

\long\def\linesaver#1{\obeylines#1}
\linesaver{
Test1
Test2
}

VS

{
\obeylines
Test3

Test4
Test5
}

First does not saving newlines, but second does. Why?

Disregard targets i'm trying to reach - consider i'm just trying to understand how exactly tex works under the hood.

  • Welcome to TeX.SX! \obeylines has no effect when used in the argument to another command, because it works by changing category codes. – egreg Nov 23 '15 at 21:46
  • Maybe http://tex.stackexchange.com/questions/65010/command-obeylines-in-a-macro helps? – jarauh Nov 23 '15 at 21:54
  • @jarauh helps a bit, but if I implement \linesaver command in a similar style like \makeAddress and put in inside another block like a \something{\linesaver{...}} it's not working again. Probably need much more complicated hack or workaround. – Alexander Taran Nov 23 '15 at 22:27
  • Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. A suggestion: Do us a favour and change your username to something more telling than "user1234". – Martin Schröder Nov 24 '15 at 08:24
  • What do you really want to achieve? – Martin Schröder Nov 24 '15 at 08:25
  • @user1038085 Because the answering here is blocked, I do answer only in this comment. The \obeylines macro changes catcodes and you must read the text from file after these catcodes are changed. And don't forget to return the catcode setting back. For example you can put the whole processing into a group. Your intend can be implemented by \def\linesaver{\bgroup\obeylines\linesaverA} \def\linesaverA#1{#1\egroup}. – wipet Nov 24 '15 at 12:39

1 Answers1

3

Let's see what happens with the call

\long\def\linesaver#1{\obeylines#1}

\linesaver{
Test1
Test2
}

Since \linesaver has one argument, TeX absorbs it and performs tokenization; so the end-of-lines get changed into space tokens before \obeylines enters into action. It does when the argument has already been absorbed, so there's no ^^M in the argument and, moreover, changing category code has no effect on tokens that have already been scanned by TeX.

The only effect is that \obeylines will be in force from now on, because there's no grouping.

egreg
  • 1,121,712
  • Does the situation improve if you \def\linesaver#1{\scantokens{\obeylines#1}}? – jarnosc Nov 23 '15 at 21:59
  • @erreka No. The category code 5 line terminators will already have been converted and there's no way to resurrect them. – egreg Nov 23 '15 at 22:05