issue with macro expansion
Your \map
command has one argument delimited by \par
.
When you do
\interviewstart
I: I have a question ...
L: Of course I will answer ...
\interviewstop % line 21
\end{document}
the macro \interviewstart
is replaced by
\linenumbers\let\do\speakify\map
and the argument to \map
is taken to be
I: I have a question ...
Since I
is not equal to \endmap
, the false branch is followed, eventually leading to another \map
macro.
What happens now is that the argument to \map
is
L: Of course I will answer ... \interviewstop
because TeX doesn't expand tokens when absorbing macros and the blank line before \end{document}
provides the \par
delimiter.
Again, L
is not \endmap
, so the false branch is followed and in the course of expanding the tokens TeX comes to \interviewstop
, whose replacement text contains \endmap
, which is not defined.
When you have the explicit \par\endmap\par\nolinenumbers
, there is no problem, because the first \par
is the argument delimiter and the next \map
command will absorb \endmap
as its argument. Since you compare two undefined tokens, the true branch is followed, leading to a happy end.
What you have to do is to absorb the whole text from \interviewstart
to \interviewstop
and then do the work on the absorbed tokens.
\documentclass{article}
\usepackage[left]{lineno}
\def\speakify#1: #2\par{\textit{#1}: #2\par}
\long\def\map#1\par{%
\ifx\interviewstart#1%
\else
\speakify#1\par
\expandafter\map
\fi
}
\long\def\interviewstart#1\interviewstop{%
\linenumbers
\map#1\par\interviewstart\par
\nolinenumbers
}
\begin{document}
\interviewstart
I: I have a question ...
L: Of course I will answer ...
\interviewstop
\end{document}
This version allows any number of blank lines
\documentclass{article}
\usepackage[left]{lineno}
\def\speakify#1: #2\par{\textit{#1}: #2\par}
\long\def\map#1\par{%
\ifx\hfuzz#1\hfuzz
\let\next\map
\else
\ifx\interviewstart#1%
\let\next\relax
\else
\speakify#1\par
\let\next\map
\fi
\fi
\next
}
\long\def\interviewstart#1\interviewstop{%
\linenumbers
\map#1\par\interviewstart\par
\nolinenumbers
}
\begin{document}
\interviewstart
I: I have a question ...
L: Of course I will answer ...
\interviewstop
\end{document}
An environment is, however, much better.
\documentclass{article}
\usepackage[left]{lineno}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{interview}{m}
{
\par
\linenumbers
\keys_set:nn { hkbst/interview } { #1 }
}
{
\par
}
\NewDocumentCommand{\Q}{}{\par\textit{\l_hkbst_questioner_tl}:~}
\NewDocumentCommand{\A}{}{\par\textit{\l_hkbst_answerer_tl}:~}
\keys_define:nn { hkbst/interview }
{
q .tl_set:N = \l_hkbst_questioner_tl,
a .tl_set:N = \l_hkbst_answerer_tl,
}
\ExplSyntaxOff
\begin{document}
\begin{interview}{q=I,a=L}
\Q I have a question ...
\A Of course I will answer ...
\end{interview}
\end{document}
The normal latex syntax for this would be an environment:
\documentclass{article}
\usepackage[]{a4wide}
\usepackage[left]{lineno}
\newenvironment{interview}{\linenumbers\everypar{\additalic}}{\par}
\def\additalic#1:{\textit{#1}:}
\begin{document}
\begin{interview}
I: I have a question for you that I would really like to know the answer to. Could you please explain it in your own words while the moon is still high in the sky? That would be lovely thank you very much!
L: Of course I will answer gladly all questions you might have no matter how silly I feel they may be provided payment is made in full before commencement of the answering phase.
\end{interview}
\end{document}
Actually I would have used a syntax such as
\item[L] I have a question....
then you would not have needed any low level delimited macros or \everpar
tricks.
In comments you ask for a variant that sets the paragraph in italic and the label in bold.
\newenvironment{interview}{\linenumbers\itshape\everypar{\additalic}}{\par}
\def\additalic#1:{\textup{\textbf{#1}}:}