我有几个想要覆盖的命令。这些命令的代码几乎相同,所以我决定使用 prop 模块。但是当我对命令使用 #1 #...n 时,我收到一个错误,提示缺少\begin{document}
。这是我为此编写的一部分代码。是的,我可以分别覆盖 chapter、section、sub...section、paragraph 命令,但在我看来,使用迭代会使我的代码更易读,而比单独覆盖每个命令的代码更少。第二个问题是,如何在 的第二个参数中使用我的代码\prop_map_function:NN
,即不为此创建特殊命令,因为我不想为此 \iterate 创建特殊命令。如果不创建命令就无法进行迭代,请至少帮我解决第一个问题。非常感谢大家的帮助。
\ExplSyntaxOn
\prop_new:N {\g_sections_prop}
\prop_gput:Nnn{\g_sections_prop}{\chapter}{h1}
\prop_gput:Nnn{\g_sections_prop}{\section}{h2}
\prop_gput:Nnn{\g_sections_prop}{\subsection}{h3}
\prop_gput:Nnn{\g_sections_prop}{\subsubsection}{h4}
\prop_gput:Nnn{\g_sections_prop}{\paragraph}{h5}
\protected\def\iterate#1#2{
\ifdef{#1}{
\let#1=c@#1
\renewcommand{#1}[1]{
\tagstructbegin{tag=#2}
\tagmcbegin{tag=#2}
c@#1{##1}
\tagmcend
\tagstructend
}
}
}
\prop_map_function:NN{\g_sections_prop}{\iterate}
\ExplSyntaxOff
答案1
第二个参数\prop_gput:Nnn
是字符串化的,因此当你使用它时它不再是一个控制序列。
正确的实现可能是
\documentclass{book}
\usepackage{expl3}
\ExplSyntaxOn
\prop_new:N \g_kozlovskiy_sections_prop
\prop_gset_from_keyval:Nn \g_kozlovskiy_sections_prop
{
chapter=h1,
section=h2,
subsection=h3,
subsubsection=h4,
paragraph=h5,
}
\cs_new_protected:Nn \__kozlovskiy_iterate:nn
{
\cs_if_exist:cT { #1 }
{
\cs_set_eq:cc { orig@#1 } { #1 }
\cs_gset_protected:cpn { #1 } ##1
{
\tagstructbegin{tag=#2}
\use:c { orig@#1 } { ##1 }
\tagmcend
\tagstructend
}
}
}
\prop_map_function:NN \g_kozlovskiy_sections_prop \__kozlovskiy_iterate:nn
\ExplSyntaxOff
\show\chapter
\stop
您可以避免使用以下方法定义迭代命令\prop_map_inline:Nn
\documentclass{book}
\usepackage{expl3}
\ExplSyntaxOn
\prop_new:N \g_kozlovskiy_sections_prop
\prop_gset_from_keyval:Nn \g_kozlovskiy_sections_prop
{
chapter=h1,
section=h2,
subsection=h3,
subsubsection=h4,
paragraph=h5,
}
\prop_map_inline:Nn \g_kozlovskiy_sections_prop
{
\cs_if_exist:cT { #1 }
{
\cs_set_eq:cc { orig@#1 } { #1 }
\cs_gset_protected:cpn { #1 } ##1
{
\tagstructbegin{tag=#2}
\use:c { orig@#1 } { ##1 }
\tagmcend
\tagstructend
}
}
}
\ExplSyntaxOff
\show\chapter
\stop
控制台上的输出是
> \chapter=\protected\long macro:
#1->\tagstructbegin {tag=h1}\use:c {orig@chapter}{#1}\tagmcend \tagstructend .
如果该类不是,book
但是article
,\chapter
则不会被定义。
你可以\use:c
用一些技巧来避免:
\documentclass{book}
\usepackage{expl3}
\ExplSyntaxOn
\prop_new:N \g_kozlovskiy_sections_prop
\prop_gset_from_keyval:Nn \g_kozlovskiy_sections_prop
{
chapter=h1,
section=h2,
subsection=h3,
subsubsection=h4,
paragraph=h5,
}
\prop_map_inline:Nn \g_kozlovskiy_sections_prop
{
\cs_if_exist:cT { #1 }
{
\cs_set_eq:cc { orig@#1 } { #1 }
\cs_gset_protected:cpx { #1 } ##1
{
\exp_not:N \tagstructbegin{tag=#2}
\exp_not:c { orig@#1 } { ##1 }
\exp_not:N \tagmcend
\exp_not:N \tagstructend
}
}
}
\ExplSyntaxOff
\show\chapter
\stop
这样我们得到
> \chapter=\protected\long macro:
#1->\tagstructbegin {tag=h1}\orig@chapter {#1}\tagmcend \tagstructend .