我正在尝试按照学校的论文标准创建一个课程,当我尝试实现首字母缩略词列表时遇到了问题,因为这个列表应该按字母顺序排序,而我发现的包与我实现的课程不兼容。所以我决定使用数组进行自己的实现。
我可以创建数组(其中数组的每个元素都使用\foo#1
作为中的新索引),但要对该数组进行排序,我需要在数组的特定位置插入一个元素。#1
\csname foo#1 \endcsname
我现在的代码示例是:
\documentclass[]{report}
\newcounter{countArrayTest}
\setcounter{countArrayTest}{0}
\newcommand{\appendElement}[1]{%
\expandafter\newcommand\csname arraytest\the\value{countArrayTest} \endcsname{#1}
\stepcounter{countArrayTest}
}
\newcommand{\getIndexElement}[1]{
\csname arraytest#1 \endcsname
}
\newcommand{\testInsert}{%
\expandafter\renewcommand\csname arraytest1 \endcsname{\getIndexElement{0}}
\expandafter\renewcommand\csname arraytest0 \endcsname{Test1}
}
\newcounter{CountTempAux}
\newcommand{\showAll}{%
\setcounter{CountTempAux}{0}
\loop\ifnum\value{CountTempAux}<\value{countArrayTest}
\csname arraytest\the\value{CountTempAux} \endcsname
\stepcounter{CountTempAux}
\repeat
}
\begin{document}
\appendElement{Element1}
\appendElement{Element2}
\testInsert
\showAll
\end{document}
问题是,我期望答案是“Test1 Element1”,但我得到的是“Test1 Test1”。
有什么建议可以解决这个问题吗?
答案1
我同意艾伦·芒恩评论说,如果你向我们展示你尝试使用的缩写包所遇到的问题,可能会更容易一些(acronym
?glossaries
?)。
对于你现在的问题:你遇到的问题在于
\newcommand{\testInsert}{%
\expandafter\renewcommand\csname arraytest1 \endcsname{\getIndexElement{0}}
\expandafter\renewcommand\csname arraytest0 \endcsname{Test1}
}
\arraytest1
是不是定义为\arraytest0
但为\getIndexElement{0}
。稍后当你在里面调用它时\showall
\arraytest0
已经被重新定义为Test1
。
为了存储\arraytest0
你需要扩展的内容\getIndexEntry{0}
\newcommand{\testInsert}{%
\expandafter\edef\csname arraytest1 \endcsname{\getIndexElement{0}}%
\expandafter\renewcommand\csname arraytest0 \endcsname{Test1}%
}
现在
\appendElement{Element1}\appendElement{Element2}
\testInsert
\showAll
会给
测试1 元素1
\arraytest0
但如果包含不可扩展的内容,这将不起作用:
\appendElement{\textbf{Element1}}\appendElement{Element2}
\testInsert
\showAll
在这种情况下你可以使用\protected@edef
\makeatletter
\newcommand{\testInsert}{%
\expandafter\protected@edef\csname arraytest1 \endcsname{\getIndexElement{0}}%
\expandafter\renewcommand\csname arraytest0 \endcsname{Test1}%
}
\makeatother
\appendElement{\textbf{Element1}}\appendElement{Element2}
\testInsert
\showAll
测试1元素1
您还可以使用etoolbox
的\csletcs
(*):
\usepackage{etoolbox}
\newcommand{\testInsert}{%
\csletcs{arraytest1}{arraytest0}%
\expandafter\renewcommand\csname arraytest0\endcsname{Test1}%
}
(*) 您当前的定义showall
在元素之间产生了很多空格。为了避免这种情况,您应该注释掉所有不以命令结尾的行:
\newcommand{\showAll}{%
\setcounter{CountTempAux}{0}%
\loop\ifnum\value{CountTempAux}<\value{countArrayTest}%
\csname arraytest\the\value{CountTempAux} \endcsname
\stepcounter{CountTempAux}%
\repeat
}
这同样适用于您定义的其他所有命令。例如
\newcommand{\appendElement}[1]{%
\expandafter\newcommand\csname arraytest\the\value{countArrayTest} \endcsname{#1}
\stepcounter{countArrayTest}
}
定义\arraytest0
(包括 ! 后面的空格,0
除非您更改它,否则\csletcs
我的代码将无法工作)并在调用时产生两个额外的空格。更好的是:
\newcommand{\appendElement}[1]{%
\expandafter\newcommand\csname arraytest\the\value{countArrayTest}\endcsname{#1}%
\stepcounter{countArrayTest}%
}
你可能想要使用\@namedef
或etoolbox
无论如何\csdef
:
\newcommand{\appendElement}[1]{%
\@namedef{arraytest\the\value{countArrayTest}}{#1}%
\stepcounter{countArrayTest}%
}
答案2
如果您愿意投入这么多工作,那么这个tocloft
套餐也许是值得尝试的。tocloft
这是关于该软件包的快速入门文章。它会将一个文件放入编译目录中,您可以通过该sort(1)
文件或另一个实用程序作为构建过程的一部分来运行它。