有关的
我为列表制作了一些简单的宏,但我不知道如何使用 保存值\edef
。
我对创建列表的其他方式不感兴趣,因为这只是一个实验。
我想知道如何保存完全扩展的宏的值。
例如:
\unhbox
在\edef
编辑:我知道它不起作用,只是举了一个例子来解释它在 内部扩展
\hbox
但不在 内部扩展的想法\edef
。例子:
\newlist\mylist \mylist{append}{hello world} \begin{document} \setbox0=\hbox{\mylist[0]} \mylist[0]={bye} \edef\value{\unhbox0} Saved value: \value\par Meaning: {\tt\meaning\value}\par Current value: \mylist[0] \end{document}
我正在考虑制作一个可以扩展或表现得像
\unhbox
列表的代码
\makeatletter
\def\@parcialexpand#1#2{%
\def\reserved@a{#1}%
\edef\reserved@b{#2}%
\expandafter\reserved@a\reserved@b%
}
\def\@argument#1#2{%
\begingroup%
\def\reserved@a{\global#1=}%
\begingroup%
\aftergroup\reserved@a\aftergroup{%
\aftergroup##%
\aftergroup#2%
\aftergroup}%
\endgroup%
\endgroup%
}
\def\@list@command#1#2{\csname @list@name@#1@command@#2\endcsname}
\def\@list@value#1#2{\csname @list@name@#1@value@#2\endcsname}
\long\def\@list@setvalue#1#2#3{%
\begingroup%
\@temptokena=\expandafter{\@list@value{#1}{#2}}%
\def\reserved@a##1{\@temptokena=\expandafter{##1}}%
\expandafter\reserved@a\expandafter{\the\@temptokena}%
%
\edef\reserved@a{\the\@temptokena}%
\expandafter\gdef\reserved@a{#3}%
\endgroup%
}
\def\@list@ifexists#1{%
\edef\reserved@a{\csname @list@name@#1@exists\endcsname}%
\@temptokena=\expandafter{\csname @list@name@#1@exists\endcsname}%
\edef\reserved@b{\the\@temptokena}%
\ifx\reserved@b\reserved@a\relax%
}
\long\def\@list@append#1#2{%
\begingroup%
\@tempcnta=\@list@command{#1}{len}%
%
\def\reserved@a##1{%
\@list@setvalue{#1}{##1}{#2}%
}%
\expandafter\reserved@a\the\@tempcnta%
%
\@temptokena=\expandafter{\@list@command{#1}{len}}%
\def\reserved@a##1{\@temptokena=\expandafter{##1}}%
\expandafter\reserved@a\expandafter{\the\@temptokena}%
\edef\reserved@a{\the\@temptokena}%
%
\advance\@tempcnta by 1%
\expandafter\xdef\reserved@a{\the\@tempcnta}%
\endgroup%
}
\def\@list@pop#1{%
\begingroup%
\@tempcnta=\@list@command{#1}{len}%
%
\@temptokena=\expandafter{\@list@command{#1}{len}}%
\def\reserved@a##1{\@temptokena=\expandafter{##1}}%
\expandafter\reserved@a\expandafter{\the\@temptokena}%
\edef\reserved@a{\the\@temptokena}%
%
\advance\@tempcnta by -1%
\expandafter\xdef\reserved@a{\the\@tempcnta}%
%
\def\reserved@a##1{%
\@list@value{#1}{##1}%
}%
\expandafter\reserved@a\the\@tempcnta%
\endgroup%
}
\def\@list@push#1#2{%
\begingroup%
\def\reserved@a##1{\@list{#1}{append}{##1}}%
\expandafter\reserved@a\expandafter{#2}%
\endgroup%
}
\def\@list@checkexists#1{%
\@list@ifexists{#1}%
\@latex@error{\string\@list: Undefined list: #1}{}%
\fi%
}
\def\@list@checknoexists#1{%
\@list@ifexists{#1}%
\relax%
\else%
\@latex@error{\string\@list: Already exists: #1}{}%
\fi%
}
\def\@list#1{%
\@list@checkexists{#1}%
\@ifnextchar[{%
\@argument\@temptokena{1}%
\@parcialexpand{\def\reserved@a}{[\the\@temptokena]}{%
\@ifnextchar={%
\@argument\@temptokena{1}%
\@parcialexpand{\def\reserved@a=}{\the\@temptokena}{%
\@list@setvalue{#1}{####1}{################1}%
}%
\reserved@a%
}{%s
\@list@value{#1}{####1}%
}%
}%
\reserved@a%
}{%
\@argument\@temptokena{1}%
\@parcialexpand{\def\reserved@a}{\the\@temptokena}{%
\@list@command{#1}{####1}%
}%
\reserved@a%
}%
}
\def\@list@newlist#1#2{%
\@list@checknoexists{#1}%
\expandafter\def\csname @list@name@#1@exists\endcsname{}%
\expandafter\def\csname @list@name@#1@command@len\endcsname{0}%
\expandafter\def\csname @list@name@#1@command@append\endcsname{\@list@append{#1}}%
\expandafter\def\csname @list@name@#1@command@pop\endcsname{\@list@pop{#1}}%
\expandafter\def\csname @list@name@#1@command@push\endcsname{\@list@push{#1}}%
\def#2{\@list{#1}}%
}
\def\newlist#1{\expandafter\@list@newlist\expandafter{\string#1}#1}
\makeatother
笔记:
push
扩展值并执行append
一个例子
\newlist\list
\list{append}{hello world}
\begin{document}
Len is \list{len}\par
[0]: \list[0]
\end{document}
当我尝试使用\edef
\begin{document}
Len is \list{len}\par
[0]: \list[0]
\edef\zerovalue{\list[0]}
\end{document}
! TeX capacity exceeded, sorry [input stack size=5000].
\@argument #1#2->\begingroup \def \reserved@a
{\global #1=}\begingroup \afte...
l.149 \edef\zerovalue{\list
[0]}
! ==> Fatal error occurred, no output PDF file produced!
简单追踪
\def\expand#1{%
\toks0=\expandafter{#1}%
\showthe\toks0%
}
\def\makeexpand#1{\expandafter\expand\expandafter{#1}}
\makeexpand{\list[0]}
\makeexpand{\the\toks0}
\makeexpand{\the\toks0}
\message{LOOP^^J}
\makeexpand{\the\toks0}
> \@list@checkexists {\list}\@ifnextchar [{\@argument \@temptokena {1}\@parcial
expand {\def \reserved@a }{[\the \@temptokena ]}{\@ifnextchar ={\@argument \@te
mptokena {1}\@parcialexpand {\def \reserved@a =}{\the \@temptokena }{\@list@set
value {\list}{####1}{################1}}\reserved@a }{\@list@value {\list}{####
1}}}\reserved@a }{\@argument \@temptokena {1}\@parcialexpand {\def \reserved@a
}{\the \@temptokena }{\@list@command {\list}{####1}}\reserved@a }[0].
l.151 \makeexpand{\list[0]}
> \@list@ifexists {\list}\@latex@error {\string \@list : Undefined list: \list}
{}\fi \@ifnextchar [{\@argument \@temptokena {1}\@parcialexpand {\def \reserved
@a }{[\the \@temptokena ]}{\@ifnextchar ={\@argument \@temptokena {1}\@parciale
xpand {\def \reserved@a =}{\the \@temptokena }{\@list@setvalue {\list}{####1}{#
###############1}}\reserved@a }{\@list@value {\list}{####1}}}\reserved@a }{\@ar
gument \@temptokena {1}\@parcialexpand {\def \reserved@a }{\the \@temptokena }{
\@list@command {\list}{####1}}\reserved@a }[0].
l.152 \makeexpand{\the\toks0}
> \edef \reserved@a {\csname @list@name@\list@exists\endcsname }\@temptokena =\
expandafter {\csname @list@name@\list@exists\endcsname }\edef \reserved@b {\the
\@temptokena }\ifx \reserved@b \reserved@a \relax \@latex@error {\string \@lis
t : Undefined list: \list}{}\fi \@ifnextchar [{\@argument \@temptokena {1}\@par
cialexpand {\def \reserved@a }{[\the \@temptokena ]}{\@ifnextchar ={\@argument
\@temptokena {1}\@parcialexpand {\def \reserved@a =}{\the \@temptokena }{\@list
@setvalue {\list}{####1}{################1}}\reserved@a }{\@list@value {\list}{
####1}}}\reserved@a }{\@argument \@temptokena {1}\@parcialexpand {\def \reserve
d@a }{\the \@temptokena }{\@list@command {\list}{####1}}\reserved@a }[0].
l.153 \makeexpand{\the\toks0}
LOOP
> \edef \reserved@a {\csname @list@name@\list@exists\endcsname }\@temptokena =\
expandafter {\csname @list@name@\list@exists\endcsname }\edef \reserved@b {\the
\@temptokena }\ifx \reserved@b \reserved@a \relax \@latex@error {\string \@lis
t : Undefined list: \list}{}\fi \@ifnextchar [{\@argument \@temptokena {1}\@par
cialexpand {\def \reserved@a }{[\the \@temptokena ]}{\@ifnextchar ={\@argument
\@temptokena {1}\@parcialexpand {\def \reserved@a =}{\the \@temptokena }{\@list
@setvalue {\list}{####1}{################1}}\reserved@a }{\@list@value {\list}{
####1}}}\reserved@a }{\@argument \@temptokena {1}\@parcialexpand {\def \reserve
d@a }{\the \@temptokena }{\@list@command {\list}{####1}}\reserved@a }[0].
l.155 \makeexpand{\the\toks0}
答案1
您的\list[0]
扩展性不是完全可扩展的。\unhbox
不过,您所说的“扩展”是什么意思还不清楚。
这是一个不同的实现:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newlist}{m}
{
% allocate the new list
\montecino_lists_newlist:Nf #1 { \cs_to_str:N #1 }
}
\cs_new_protected:Nn \montecino_lists_newlist:Nn
{
\seq_new:c { l_montecino_lists_#2_seq }
\NewExpandableDocumentCommand{#1}{m}
{
\str_case:nnF { ##1 }
{
{len}{ \montecino_lists_len:n { #2 } }
{append}{ \montecino_lists_append:nn { #2 } }
{push}{ \montecino_lists_append:nn { #2 } }
{pop}{ \montecino_lists_pop:n { #2 } }
}
{ \montecino_lists_get:nn { #2 } { ##1 + 1 } }
}
}
\cs_generate_variant:Nn \montecino_lists_newlist:Nn { Nf }
\cs_new:Nn \montecino_lists_len:n
{
\seq_count:c { l_montecino_lists_#1_seq }
}
\cs_new_protected:Nn \montecino_lists_append:nn
{
\seq_put_right:cn { l_montecino_lists_#1_seq } { #2 }
}
\cs_new_protected:Nn \montecino_lists_pop:n
{
\seq_pop_right:cN { l_montecino_lists_#1_seq } \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\cs_new:Nn \montecino_lists_get:nn
{
\seq_item:cn { l_montecino_lists_#1_seq } { #2 }
}
\ExplSyntaxOff
\newlist\mylist
\mylist{append}{hello world}
\begin{document}
Len is \mylist{len}
[0]: \mylist{0}
\mylist{append}{ABC} \mylist{len}
\mylist{push}{DEF} \mylist{len}
\mylist{0} \mylist{1} \mylist{2}
\mylist{pop} \mylist{len}
\edef\test{\mylist{len}}\texttt{\meaning\test}
\edef\test{\mylist{0}}\texttt{\meaning\test}
\end{document}
append
我看不出你的和之间的区别push
,所以我用相同的功能实现了它们。
我也更改了名称,因为\list
它是在 LaTeX 中使用的。