我认为在适当的地方打开/关闭语法会使一切正常工作,但我无法在里面使用\ExplSyntaxOn
/ ,所以以下代码示例不起作用:Off
\NewDocumentEnvironment
\documentclass[varwidth]{standalone}
\usepackage{expl3}
\usepackage{xparse}
\begin{document}
\NewDocumentEnvironment{myPar}{}
{
\parbox{40mm}
{% START PARBOX
\ExplSyntaxOn
\dim_new:N\myDim % DOESN'T WORK
\ExplSyntaxOff
}
{
} % END PARBOX
}
\begin{myPar}
Wikipedia is hosted by the Wikimedia Foundation, a non-profit organization that also hosts a range of other projects.
\end{myPar}
\end{document}
因此,我必须将环境括在语法开关中,如下所示,但传递给环境的任何内容都会丢失空格:
\documentclass[varwidth]{standalone}
\usepackage{expl3}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn % BROUGHT OUTSIDE
\NewDocumentEnvironment{myPar}{}
{
\parbox{40mm}
{% START PARBOX
\dim_new:N\myDim % WORKS (BUT NO SPACES REMAIN)
}
{
} % END PARBOX
}
\ExplSyntaxOff % BROUGHT OUTSIDE
% SPACES OF THE FOLLOWING CONTENT ARE STRIPPED
\begin{myPar}
Wikipedia is hosted by the Wikimedia Foundation, a non-profit organization that also hosts a range of other projects.
\end{myPar}
\end{document}
如何保留传递内容的空格而不将其替换为~
符号?
顺便说一句,以下不会删除空格(但\parbox
我需要它):
\documentclass[varwidth]{standalone}
\usepackage{expl3}
\usepackage{xparse}
\begin{document}
\ExplSyntaxOn % BROUGHT OUTSIDE
\NewDocumentEnvironment{myPar}{}
{
\dim_new:N\myDim % WORKS (NO SPACES STRIPPED BUT NO PARBOX)
} {}
\ExplSyntaxOff % BROUGHT OUTSIDE
% NO SPACES STRIPPED FROM THE FOLLOWING CONTENT (BUT NO PARBOX)
\begin{myPar}
Wikipedia is hosted by the Wikimedia Foundation, a non-profit organization that also hosts a range of other projects.
\end{myPar}
\end{document}
答案1
您在用不正确的缩进欺骗自己。请记住,TeX 并不关心缩进;任何右括号都会结束由最后一个左括号开始的组。让我们看看第二个代码片段中具有正确缩进的环境定义(即反映 TeX 如何读取您的代码的缩进)。
\ExplSyntaxOn % BROUGHT OUTSIDE
\NewDocumentEnvironment{myPar}{}
{
\parbox{40mm}
{% START PARBOX
\dim_new:N\myDim % WORKS (BUT NO SPACES REMAIN)
}
{
} % END PARBOX
}
\ExplSyntaxOff % BROUGHT OUTSIDE
如您所见,您的\parbox
代码在该\dim_new:N
行之后就结束了,然后有一个空组,然后环境启动代码的组就结束了。重要的是没有环境结束代码before \ExplSyntaxOff
,表示将\ExplSyntaxOff
其本身作为环境结束代码。
因此,expl3
语法保持打开状态,这会导致所有空格被吞噬(以及其他破坏)。这并非仅限于您的环境。在环境之外添加任何文本,\begin{myPar} .. \end{mypar}
您都会看到相同的问题。在环境之后也是如此,因为\ExplSyntaxOff
环境末尾的 仅限于环境组,并且对其外部没有任何影响。
正如 Ulrike Fischer 指出的那样她的评论,在环境中使用也是有问题的。当你第二次使用环境时,\dim_new:N\myDim
你会得到一个错误信息告诉你已经定义了。在序言中定义一次,然后只在环境内使用它。\myDim
\myDim
您可以使用 -type 参数来避免分组问题b
,如下所述Henri Menke 的回答或者直接使用 aminipage
代替 a \parbox
:
\ExplSyntaxOn
\NewDocumentEnvironment{myPar}{}{
\begin{minipage}{40mm}
% Don't do \dim_new:N\myDim here!
}{
\end{minipage}
}
\ExplSyntaxOff
答案2
1. 代币列表不平衡
从传统意义上来说,你要做的就是
\newenvironment{myPar}
{%
\parbox{40mm}{% start \parbox
}
{%
}% end \parbox
}
这本来就是错误的代码。以不同的方式编写可以更好地看到会发生什么
\newenvironment{myPar}{\parbox{40mm}{}{}}
这是未完成,因为它缺少的第三个强制参数\newenvironment
。
这是不是宏的参数中可能存在括号不平衡的标记列表。}
您打算平衡之前{
的\parbox
,但实际上匹配了}
后 \parbox
. 混乱随之而来。
2. 内部语法标记
任何想深入研究 LaTeX 编程的人都应该了解标记化。当输入被 TeX 吸收时,它会被转换成标记:符号标记(韦尔戈、命令)和字符标记。后者有其类别代码永久附着。所以如果你说
\newcommand{\foo}{\makeatletter @\makeatother}
您将获得执行@
时所具有的类别代码。因此,如果您这样做\newcommand
\newcommand{\foo}{\makeatletter\dimen@=2\p@\makeatother}
执行时,\foo
你会收到令人费解的错误消息,除非定义被其本身包围\makeatletter
。\makeatother
但定义内部的那些则什么也不做。参见\makeatletter 和 \makeatother 起什么作用?了解更多信息。
\ExplSyntaxOn
它与和完全相同\ExplSyntaxOff
。
在第二次尝试中,将它们带出 的代码时myPar
,由于第 1 章中描述的错误,\ExplSyntaxOff
被视为myPar
环境的“结束部分”,因此它不会被执行,并且\ExplSyntaxOn
在读取 后面的文本时仍然有效\begin{myPar}
。
3. 其他
\dim_new:N
无论如何,作为环境的一部分执行操作都是错误的。\newlength
在环境内部执行操作也是错误的,尽管它不会引发错误。让我们看一个例子
\newenvironment{foo}{\newlength{\foolen}}{}
将尽职尽责地创建并浪费一个新的跳过寄存器每个的调用\begin{foo}
。这是因为名称分配是本地的,但寄存器分配是全局的,因为 LaTeX 不想冒险以不同的方式引用同一个寄存器。
事情expl3
有点不同:
\NewDocumentEnvironment{foo}{}
{\dim_new:N \myDim}
{}
(正确地用\ExplSyntaxOn
和包围\ExplSyntaxOff
),并且名称赋值是全局的。因此\begin{foo}
第二次调用时 LaTeX 将引发错误。
4.如何制作一个有环境的parbox?
minipage
当然使用。
答案3
使用新b
类型参数,该参数可捕获环境主体,以便像常规参数一样使用#1
。+b
允许多个段落。
\documentclass[varwidth]{standalone}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment { myPar } { +b }
{
\parbox { 40mm }
{
\dim_new:N \myDim
#1
}
} { }
\ExplSyntaxOff
\begin{document}
\begin{myPar}
Wikipedia is hosted by the Wikimedia Foundation, a non-profit organization that also hosts a range of other projects.
\end{myPar}
\end{document}