宏扩展的问题

宏扩展的问题

以下代码有效,但如果您注释第 20 行并取消注释第 21 行,LaTeX 会抱怨 \endmap 未定义。我真的不明白为什么会这样,更不明白该怎么做。

\documentclass{article}
\usepackage[]{a4wide}
\usepackage[left]{lineno}

\newcommand{\define}{\newcommand}

\def\speakify#1:#2\par{{\itshape#1}: #2\par}
\def\map#1\par{\ifx\endmap#1\else\do#1\par\expandafter\map\fi}

\def\interviewstart{\linenumbers\let\do\speakify\map}
\def\interviewstop{\par\endmap\par\nolinenumbers}

\begin{document}

%\linenumbers\let\do\speakify\map
\interviewstart
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.
\par\endmap\par\nolinenumbers % line 20
%\interviewstop % line 21

\end{document}

答案1

您的\map命令有一个以 分隔的参数\par

当你这样做

\interviewstart
I: I have a question ...

L: Of course I will answer ...
\interviewstop % line 21

\end{document}

该宏\interviewstart被替换为

\linenumbers\let\do\speakify\map

并且的论点\map被认为是

I: I have a question ...

由于I不等于\endmap,因此遵循错误分支,最终导致另一个\map宏。

现在发生的\map

L: Of course I will answer ... \interviewstop

因为 TeX 在吸收宏时不会扩展标记,并且之前的空行\end{document}提供了\par分隔符。

同样,L不是\endmap,因此遵循错误分支,在扩展标记的过程中,TeX 到达\interviewstop,其替换文本包含\endmap未定义的。

当您有显式的 时\par\endmap\par\nolinenumbers,不会出现问题,因为第一个\par是参数分隔符,下一个\map命令将作为其参数吸收\endmap。由于您比较了两个未定义的标记,因此遵循 true 分支,从而获得幸福结局。

你要做的是吸收从\interviewstart到的整个文本\interviewstop,然后对吸收的标记进行处理。

\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}

在此处输入图片描述

此版本允许任意数量的空行

\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}

但环境要好得多。

\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}

答案2

对于这个环境,正常的乳胶语法是:

在此处输入图片描述

\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}

实际上我会使用如下语法

\item[L] I have a question....

那么你就不需要任何低级分隔宏或\everpar技巧。


在评论中,您要求将段落设置为斜体,将标签设置为粗体。

\newenvironment{interview}{\linenumbers\itshape\everypar{\additalic}}{\par}
\def\additalic#1:{\textup{\textbf{#1}}:}

相关内容