etoolbox 中 \ifstrequal 的问题

etoolbox 中 \ifstrequal 的问题

我与多人合作通过 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 可以让它“起作用”,尽管我仍然不完全明白为什么。

相关内容