使用 XeTeX 以纯文本格式逐字逐句地表达

使用 XeTeX 以纯文本格式逐字逐句地表达

(我知道之前也有过类似的问题,但这个问题有点不同)

我想要一个逐字宏,它使用一个不太可能的字符作为逐字结束标记(不太可能,因为它不太可能包含在将成为逐字的文本中),并从附录 D 中查找了一些建议TeXbook,直到有件事引起了我的注意:

另一种方法是保持一个字符不可触碰。例如,可以定义一些东西,以便\verbatim⟨char⟩⟨text⟩⟨char⟩逐字排版⟨text⟩,其中不应⟨text⟩包含任何重复的分隔符⟨char⟩

\def\verbatim{\begingroup\setupverbatim\doverbatim}
\def\doverbatim#1{\def\next##1#1{##1\endgroup}\next}

现在,将其与 XeTeX 结合使用,我可以使用来自广泛 Unicode 范围的字符作为结束标记。(基于我可以做的发现,例如\def\fi{foo},它可以工作。)

唉,在上面添加附录 D 中前面提到的宏:

\def\setupverbatim{\tt\def\par{\leavevmode\endgraf} \catcode`\`=\active
   \obeylines\uncatcodespecials\obeyspaces}
\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}

并尝试一下( fi 字符是 Unicode fi-ligature),

\verbatim fi |\%_^foo{\it bar}
baz
\bye

给出有关 的错误Missing $,这意味着\verbatim宏有些地方无法正常工作。我就是搞不清楚是什么问题。

答案1

它是 后面的空格字符\verbatim

更改空格字符的 catcode 后,它不再被视为空格。考虑以下输出

\def\a#1\relax{`#1'}
\def\b{\catcode`\ =12 \a}

\a \relax

\b \relax

\bye

在此处输入图片描述

因此,您的示例仅以逐字模式排版,并在遇到 后的第二个空格后恢复正常

因此你需要有一个分隔符立即地因此\verbatim它的 catcode 不能是“字母”,否则它将被视为控制序列名称的一部分。

答案2

以下代码定义\verb命令:

\catcode`\@=11%
\def\verb{\expandafter\verb@make\string}%
\def\verb@make#1{\begingroup\tt%
  \let\verb@delim=#1%  Save the delimiter.
  \def\verb@print##1{%
    \if##1\verb@delim% If we found the end delimiter, end the group.
      \def\verb@print{\def\verb@print{}\endgroup}%
    \else%
      ##1% Print the char
    \fi%
    \expandafter\verb@print\string% Continue reading the next char.
  }%
  \expandafter\verb@print\string% Start reading.
}%
\catcode`\@=12%

一些例子:

\verb|{$x^y{}$\abc}|

\verb!{$x^y{}$\abc}!

\verb~${x^y{}$\abc}~

以上所有内容均产生逐字结果${x^y{}$\abc}

答案3

问题出在 后面的空格上\verbatim,Andrey 发现了这一点。需要注意的是, 后面的空格\verbatim会终止对控制序列名称的扫描,但不会立即将其标记化,因为在控制序列名称之后,TeX 必须进入“跳过空白状态”;因此, 后面的空格实际上是\verbatim被扩展并\setupverbatim更改了空格的类别代码后读取的。

如果您不想对可以分隔逐字片段的字符进行限制,则可以进行改进\doverbatim

\def\doverbatim#1{%
  \def\next{#1}%
  \ifx\next\activespacemacro
     \expandafter\doverbatim
  \else
    \def\next##1#1{##1\endgroup}%
    \expandafter\next
  \fi}
{\obeyspaces\gdef\activespacemacro{ }}

行尾不能用作分隔符(可以添加另一个测试)。后面可以跟任意数量的空格\verbatim

很好奇为什么你的代码会出现这个错误,但也很容易:made之后的空格\verbatim终止了它的效果,排版就像逐字逐句的一样

相关内容