定义宏时如何执行 unvbox?

定义宏时如何执行 unvbox?

这是解决问题的另一种方法”如何将两个标志之间的部分文本写入文件?“。

我尝试“记住”文本的某些部分,以便以后使用。因此,我

\newbox\@tmpbox
\def\startsync{\setbox\@tmpbox\vbox\bgroup}
\def\esync{\egroup\writepart}
\def\syncpoint{\esync\startsync}
\newcount\p@rts
\p@rts0
\long\def\writepart{
    \advance\p@rts1
    \@roman\p@rts\par
    \expandafter\xdef\csname apart\@roman\p@rts\endcsname{\unvbox\@tmpbox}
}
\def\insrt#1{\csname apart\@roman #1\endcsname}

但是 TeX 没有按照我的要求做:\xdef定义像\aparti未扩展的这样的宏\unvbox\@tmpbox,所以,当我调用时\insrt{1},我看到的是最新文本部分的内容而不是第一个!

我如何定义这个宏,以便每个宏都\apartXXX可以扩展为相应的文本部分?

答案1

我想你想要这样的东西;请注意,你不能在宏中存储框,但你可以存储令牌。

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l_eddyem_sync_items_seq
\int_new:N \g_eddyem_sync_part_int

\cs_new_protected:Npn \startsync #1 \endsync
 {
  \seq_set_split:Nnn \l_eddyem_sync_items_seq { \syncpoint } { #1 }
  \seq_map_inline:Nn \l_eddyem_sync_items_seq
   {
    \int_gincr:N \g_eddyem_sync_part_int
    \tl_new:c { g_eddyem_sync_part \int_to_roman:n { \g_eddyem_sync_part_int} _tl }
    \tl_gset:cn { g_eddyem_sync_part \int_to_roman:n { \g_eddyem_sync_part_int} _tl } { ##1 }
    \int_to_roman:n \g_eddyem_sync_part_int\par
   }
 }

\NewDocumentCommand{\insrt}{m}
 {
  \tl_use:c { g_eddyem_sync_part \int_to_roman:n { #1 } _tl }
 }
\ExplSyntaxOff

\begin{document}

\startsync
This is the first part
\syncpoint
This is the second part
\syncpoint
This is the third part
\endsync

Some text in between

\startsync
This is the fourth part
\endsync

Some text before printing the parts

\insrt{1}

\insrt{2}

\insrt{4}

\insrt{3}

\end{document}

在此处输入图片描述

这是如何工作的?首先,我们收集\startsync和之间的所有标记\endsync,然后在\syncpoint(如果出现,这是可选的)处拆分项目。

拆分后,每个项目都保存在一个标记列表变量中,该变量由一个整数变量索引,该整数变量在找到每个项目时递增。

\insrt仅获取其参数并传递适当变量的内容。

相关内容