TL2017 弄坏了我的盒子

TL2017 弄坏了我的盒子

这与 LaTeX3 和 TL2017 中引入的变化有关。

我正在定义一个构造框的命令,但我需要在框的开头放入一些内容。因此,我先查找左括号,从流中吸收它,执行我想要执行的额外操作,然后使用 来开始框\c_group_begin_token

这在 TL2016 中有效,但在 TL2017 中却有缺陷。

具体来说,如下代码:

\documentclass{article}

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\box_new:N \l__tmpa_box

\cs_new_nopar:Npn \dobox
{
  \exp_after:wN \dobox_aux: \tex_let:D \l_peek_token =
}

\cs_new_nopar:Npn \dobox_aux:
{
  \hbox_set:Nn \l__tmpa_box
  \c_group_begin_token
  in~the~box~
}

\cs_new_nopar:Npn \dobebox
{
  \box_use:N \l__tmpa_box
}

\ExplSyntaxOff

\begin{document}

greetings
\dobox{hello world}
everyone
\dobebox

\end{document}

在 TL2016 中编译产生输出:

greetings  everyone in the box hello world

但在 TL2017 中,我收到了一个投诉:

! Missing } inserted.
<inserted text> 
                }
l.32 \dobox
           {hello world}
? 
! Too many }'s.
l.32 \dobox{hello world}

? 

产生的输出是:

greetings in the box hello world everyone

表明盒子构造被忽略了。

有没有办法来解决这个问题?

答案1

标准 TeX 代码的翻译:

\newbox\mybox

\def\dobox{%
  \expandafter\doboxaux\let\mytoken =%
}

\def\doboxaux{%
  \setbox\mybox=\hbox\bgroup in the box
}

\def\dobebox{%
  \copy\mybox
}

请注意,这\expandafter将什么也不做。当你调用

\dobox{hello world}

\doboxaux立即被展开,你得到

\setbox\mybox=\hbox\bgroup in the box \let\mytoken={hello world}

{吞噬\let\mytoken=,因此框将包含“hello world”。

结果是

盒子里的问候 大家好,世界

\hbox_set:Nn \l__tmpa_box然而,非常不同于\setbox\mybox=\hbox。后者接受\bgroup(在expl3术语中\c_begin_group_token)而前者不接受,因为它是一个双参数函数,并且n参数不能被 分隔\bgroup

过去可能存在的事实无关紧要。你滥用了expl3。以下是\cs_show:N \hbox_set:Nn结果

> \hbox_set:Nn=\protected\long macro:#1#2->\tex_setbox:D #1\tex_hbox:D
{\group_begin: #2\group_end: }.

因此您会看到 被#2抓取为正常参数。您的(错误)宏过去之所以能工作#2是因为\c_group_begin_token。其效果与您在 LaTeX2e 中获得的效果非常相似,\mbox\bgroup foo\egroup似乎可以工作,但实际上却不行。 的定义\hbox_set:Nn已更改,并且(错误)混合物现在会引发错误。

你可能想做

\def\dobox{%
  \afterassignment\doboxaux\let\mytoken=
}

\def\doboxaux{%
  \setbox\mybox=\hbox\bgroup in the box
}

\def\dobebox{%
  \copy\mybox
}

唉,expl3没有提供接口\afterassignment

相关内容