我似乎陷入了困境,现在正在通过反复试验来寻找正确的方法来做到这一点。
以下是一个总体思路:
% I DECLARE NEW MACROS WITH NAMES AS DEFFINITION. AND ASIGN LETTERS TO PEOPLE SINCE NUMBERS ARE FORBIDEN IN MACRO'S NAMES.
\newcommand{\AuthorNameA}{John}
\newcommand{\AuthorSurnameA}{Doe}
\newcommand{\AuthorNameB}{Jane}
\newcommand{\AuthorSurnameB}{Doe}
\newcommand{\AuthorNumber}{3}
% DECLARE NEW COUNTER
\newcounter{loopTitleCoverAuthor}
% START WITH LOOP
\forloop{loopTitleCoverAuthor}{1}{
%COMPARE COUNTER WITH DEFINITION OF MACRO SET PREVIOUSLY
\value{loopTitleCoverAuthor} < \value{bfThesisAuthorNumber}
}{
% IF CONDITION IS TRUE CHECK IF MACRO WITH PARTICULLAR ENDING IS DEFINED AND IF IT IS, PRINT NAME AND SURNAME
\ifdefined\expandafter\AuthorName\Alph{loopTitleCoverAuthor}
\expandafter\AuthorName\Alph{loopTitleCoverAuthor} \textsc{\expandafter\AuthorSurname\Alph{loopTitleCoverAuthor}}\\
\fi
}
a) 不出所料,这不起作用。我遇到的第一个问题是将计数器与宏值进行比较。因此,为了继续并查看可能还有哪些错误,我将条件部分更改为:
\value{loopTitleCoverAuthor} < 3 %\value{bfThesisAuthorNumber}
b) 然后我在检查时遇到了问题\ifdefined
,所以我也将其注释掉,并且总是调用姓名和姓氏宏。
c) 最后,我遇到了一个问题\expandafter
(我认为)。我现在得到了输出,但不是它应该有的样子。它省略了\AuthorName
和,\AuthorSurname
并且只打印了\Alph
计数器步骤。
我希望看到:
John Doe
Jane Doe
我得到:
AA
BB
因此,我的问题是:
\forloop
在(a)的条件中可以使用宏的值吗?我应该如何重新格式化
\ifdefined
以正确检查每个循环中是否定义了宏(\AuthorNameA
在第一个循环中,\AuthorNameB
在第二个循环中...)(b)? 我也尝试了\csname
,多个 \expandafter,\expandafter
before\ifdefined
,... 这里没有描述:https://www.tug.org/TUGboat/tb09-1/tb20bechtolsheim.pdf似乎有效(或者更可能的是,我做了一些明显错误的事情,但看不到它)。我应该改变什么才能
\AuthorNameA
扩大(c)?有没有更好的方法来做到这一点?在一个文件中声明“控件和变量”,然后
\input
在该文件中循环使用这些宏的值来显示和控制输出?
答案1
这个测试\value{A} < \value{B}
对我有用。
我已经使用了\@ifundefined{csname}{true}{false}
其中csname
没有转义字符的要测试的命令名称\
。
这里最重要的是用 构建各种命令名称\csname foo\Alph{...}\endcsname
。
\documentclass{article}
\usepackage{forloop}
\newcommand{\AuthorNameA}{John}
\newcommand{\AuthorSurnameA}{Doe}
\newcommand{\AuthorNameB}{Jane}
\newcommand{\AuthorSurnameB}{Doe}
\newcommand{\AuthorNumber}{5}
% DECLARE NEW COUNTER
\newcounter{loopTitleCoverAuthor}
\newcounter{bfThesisAuthorNumber}
\setcounter{bfThesisAuthorNumber}{\AuthorNumber}
\begin{document}
% START WITH LOOP
\makeatletter
\forloop{loopTitleCoverAuthor}{1}{%
% COMPARE COUNTER WITH DEFINITION OF MACRO SET PREVIOUSLY
\value{loopTitleCoverAuthor} < \value{bfThesisAuthorNumber} % End condition
}{
\@ifundefined{AuthorName\Alph{loopTitleCoverAuthor}}{%
Booooooooooooo: Author \Alph{loopTitleCoverAuthor} is not defined!
}{
Hooray: Author \Alph{loopTitleCoverAuthor} exists and is \csname AuthorName\Alph{loopTitleCoverAuthor}\endcsname
\csname AuthorName\Alph{loopTitleCoverAuthor}\endcsname\ \textsc{\csname AuthorSurname\Alph{loopTitleCoverAuthor}\endcsname}
}
}
\makeatother
\end{document}
答案2
您的代码存在一些问题。
代码
\ifdefined\expandafter\AuthorName\Alph{loopTitleCoverAuthor}
测试是否
\expandafter
定义。然而代码
\expandafter\ifdefined\expandafter\AuthorName\Alph{loopTitleCoverAuthor}
也不会有什么好处,因为当
loopTitleCoverAuthor
值为 1 时,你会得到\ifdefined\AuthorName A
而不是如您所希望的那样出现单个标记。
同样地,当你这样做时
\expandafter\AuthorName\Alph{loopTitleCoverAuthor}
在真实部分,你得到二代币,而不是
\AuthorNameA
。
你能怎麼做?
诀窍是使用\ifcsname
和\csname
。你第一的想要生成一个标记,其名称AuthorName
由计数器的字母值组成:
\ifcsname AuthorName\Alph{loopTitleCoverAuthor}\endcsname
\expandafter\AuthorName\Alph{loopTitleCoverAuthor}
\textsc{\csname AuthorSurname\Alph{loopTitleCoverAuthor}\endcsname}\\
\fi
不需要\expandafter
,因为\ifcsname
和会进行完全扩展,直到找到\csname
匹配为止。\endcsname
答案3
尽管已经有了很好的答案,但我还是贡献了我用于当前不断增长的 Liederbuch 包的版本:
\def\TesT#1{
\expandafter\def\csname test\Alph{#1}\endcsname{}
}
\newcounter{wseva}
\setcounter{wseva}{4}
\TesT{wseva}
\def\doesItExist#1{
\expandafter\ifx\csname test\Alph{#1}\endcsname\relax
no
\else
yes
\fi
}
\begin{document}
\doesItExist{wseva}
\end{document}
如果的内容\csname
不存在,则返回\relax
。比较\ifx\theExpandedCsname\relax
返回 true。否则返回 false,并且\else
将运行该部分。