我与多人合作通过 Dropbox 编写 Latex 文档,各个文件夹(例如,图表和参考书目所在的文件夹)的路径对于每个合作者来说都是不同的。因此,我尝试使用 etoolbox 定义一个变量“whoami”,以便当前编辑文件的人可以在开始时更改一次,文档中的所有内容都会更改。但是,它的表现并不如预期;这是一个最小的非工作示例:
\documentclass{article}
\usepackage{etoolbox}
\newcommand{\whoami}{PB}
\begin{document}
\ifstrequal{\whoami}{PB}{%
I am PB}{% false
I am not PB}
\end{document}
我原本期望输出结果为“I am PB”,但结果却是“I am not PB”。我怀疑\whoami
不是字符串数据类型,如果存在这样的数据类型的话(抱歉,我不太懂 TeX,只懂 LaTeX)。我还尝试使用以下命令定义“whoami” \string
:
\def\whoami{\string PB}
但这并没有起到什么作用,事实上,情况变得更糟了!任何帮助都将不胜感激。
答案1
不带 的版本etoolbox
,使用\pdfstrcmp
和 ,其功能与 相同,但使用扩展的命令\ifstrequal
。否则使用\expandafter\ifstrequal\expandafter{\whoami}{PB}
。
\ifstrequal
这里不起作用的原因是它的参数被去标记化了,所以\whoami
基本上"whoami
和那时不一样PB
。
\documentclass{article}
\newcommand{\whoami}{PB}
\newcommand{\ifstringequal}[4]{%
\ifnum\pdfstrcmp{#1}{#2}=0
#3%
\else
#4%
\fi
}
\begin{document}
\ifstringequal{\whoami}{PB}{%
I am PB}{% false
I am not PB}
\ifstringequal{\whoami}{SomebodyElse}{%
I am somebody else!
}{%
I am a different person and not somebody else%
}
\end{document}
答案2
如果您确实必须处理“多个”人,我不会使用 \if-whatever 进行选择。如果您必须添加更多定义或更多人,这可能会变得非常混乱且容易出错。我会使用类似这样的方法:
\documentclass{article}
\usepackage{etoolbox}
\csdef{path-PB}{path of PB}
\csdef{path-UF}{path of UF}
% more definitions
\newcommand\whoami{PB}
\newcommand\mypath{\csuse{path-\whoami}}
\begin{document}
\mypath
\renewcommand\whoami{UF}
\mypath
\end{document}
答案3
您可以定义一些基础结构,以便能够根据协作者定义多个变量。每个人只需更改一行即可。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% the inner function that sets up a collaborator;
% just load the corresponding property list with
% the given properties; we use a temporary property list
% and then set the one corresponding to the collaborator
% equal to it
\cs_new_protected:Nn \pb_prop_gset_bykeys:Nn
{
\prop_clear:N \l__pb_temp_prop
\keys_set:nn { pb/propbykey } { #2 }
\prop_gset_eq:NN #1 \l__pb_temp_prop
}
% this allows calling the property list "by name"
\cs_generate_variant:Nn \pb_prop_gset_bykeys:Nn { c }
% we allow any key; XYZ=abc will load the property
% XYZ = abc
\keys_define:nn { pb/propbykey }
{
unknown .code:n = \prop_put:Nxn \l__pb_temp_prop { \l_keys_key_tl } { #1 }
}
% a useful variant (we need full expansion to get the key name
% because it can only be accessed at by \l_keys_key_tl
\cs_generate_variant:Nn \prop_put:Nnn { Nx }
% the main user function; declare a property list
% for the given user and then call the internal
% function described above
\NewDocumentCommand{\setupcollaborator}{mm}
{% #1 = identifier string, #2 = set of key-value pairs
\prop_new:c { g_collaborator_#1_prop }
\pb_prop_gset_bykeys:cn { g_collaborator_#1_prop } { #2 }
}
% The function to tell LaTeX who is the current collaborator;
% traverse the property list and, for every item, say {XYZ}{abc},
% do the equivalent of \def\XYZ{abc}
\NewDocumentCommand{\selectcollaborator}{m}
{
\prop_map_inline:cn { g_collaborator_#1_prop }
{
\tl_set:cn { ##1 } { ##2 }
}
}
\ExplSyntaxOff
\setupcollaborator{pb}
{% pb is on windoze
NAME=pb2017,
PATH=K:/whatever,
REFRESHMENT=tea,
}
\setupcollaborator{egreg}
{% egreg is on Mac OS
NAME=Green Square,
PATH=\string~/Dropbox,
REFRESHMENT=ice cream,
}
\selectcollaborator{pb}
\begin{document}
Path is \PATH
Bring some \REFRESHMENT{} for \NAME.
\end{document}
如果我把代码改成
\selectcollaborator{egreg}
将打印相同的文档
答案4
抱歉,看来我下手太快了。用 \ifdefstring 替换 \ifstrequal 可以让它“起作用”,尽管我仍然不完全明白为什么。