我想在样式文件中定义一系列保存框\fooA
、\fooB
等等,并引入如下命令
\newcommand{\foo}[1]{....}
\usebox{\fooA}
如果 的参数\foo
为 1,则产生\usebox{\fooB}
;如果 的参数\foo
为 2,则产生;等等。
肯定有一种简单的方法来实现这一点,但我不懂。
谢谢!
答案1
这使用计数器来快速将数字“翻译”为字符。但是,这是一种快速而粗略的用法,因为它不会检查可能的最大数字(即 26)
此外,还应检查盒子名称\fooA
等是否存在。
框命令\foo
是在内部使用创建的\csname foo\Alph{boxcounter}\endsname
。
\documentclass{article}
\usepackage{xcolor}%
\usepackage{blindtext}
\newsavebox{\fooA}
\newsavebox{\fooB}
\newcounter{boxcounter}
\newcommand{\foo}[1]{%
\setcounter{boxcounter}{#1}%
\usebox{\csname foo\Alph{boxcounter}\endcsname}
}%
\savebox{\fooA}{\textcolor{red}{\blindtext}}
\savebox{\fooB}{\textcolor{blue}{\blindtext}}
\begin{document}
\noindent\foo{1}\par
\noindent\foo{2}
\end{document}
答案2
只有在不使用时使用\Alph
才是安全的。有些语言会重新定义以适应不同的字母表;想想捷克语,它的字母顺序是babel
\Alph
A B C Č D E F G H CH I ...
并且\foo{4}
在这种情况下肯定不会起作用。
您可能坚持使用 ASCII,并且为了独立地获得正确的结果,babel
您可以使用一个古老的技巧:
\newcommand{\foo}[1]{%
\begingroup\lccode`?=\dimexpr64+#1\relax % the code for A is 65
\lowercase{\endgroup\usebox{\csname foo?\endcsname}}
}
这利用了您在框名称前添加小写前缀这一事实foo
。我将展示一个与此无关的解决方案。
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\newcommand{\allocateboxes}[2]{% #1 = prefix, #2 = list of letters to be used
\expandafter\newcommand\csname #1\endcsname[1]{%
\usebox{\csname JPi@box@##1@\endcsname}%
}%
\count@=\z@
\@for\next:=#2\do{%
\advance\count@\@ne
\expandafter\newsavebox\csname #1\next\endcsname
\expandafter\edef\csname JPi@box@\the\count@ @\endcsname{%
\expandafter\noexpand\csname #1\next\endcsname
}%
}%
}
\makeatother
\allocateboxes{Foo}{A,B}
\savebox{\FooA}{\textcolor{red}{This is box A}}
\savebox{\FooB}{\textcolor{blue}{This is box B}}
\begin{document}
\noindent\Foo{1}\par
\noindent\Foo{2}
\end{document}