1

I collaborate with multiple people to write latex documents, over dropbox, and the paths to the various folders (where the graphs and bibliographics reside, for instance) are distinct for each of the collaborators. So I am trying to use etoolbox to define a variable "whoami", so that the person currently editingthe file can change it once in the beginning and everything will get changed in the document. However, it's not behaving as expected; here's a minimal non-working example:

\documentclass{article}
\usepackage{etoolbox}

\newcommand{\whoami}{PB}

\begin{document}

\ifstrequal{\whoami}{PB}{%
I am PB}{% false
I am not PB}

\end{document}

I was expecting the output to yield "I am PB", but it yields "I am not PB". I suspect \whoami is not of the string data type, if such a thing exists (sorry, don't know much TeX, only LaTeX). I also tried to define "whoami" using \string:

\def\whoami{\string PB}

That didn't work as well, and in fact made things worse! Any help will be appreciated.

  • sorry, I realized the code showed up all screwed up. Here's a corrected version: \documentclass{article} \usepackage{etoolbox} \newcommand{\whoami}{PB} \begin{document} \ifstrequal{\whoami}{PB}{I am PB}{I am not PB} \end{document} – pb2017 Sep 16 '17 at 20:26
  • 1
    Welcome to TeX.SX! In order to show code, type it, select it and hit Control-K or click on the {} button above the editing window. – egreg Sep 16 '17 at 20:28
  • 1
    \expandafter\ifstrequal\expandafter{\whoami}{PB}{I am PB}{I ain't PB} should work. Welcome to the joys of \expandafter. ;-) – egreg Sep 16 '17 at 20:30
2

If you are really have to handle "multiple" people, I wouldn't use \if-whatever to choose. This can get quite confusing and error prone if you have to add more definitions or more people. I would use something like this:

\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}
2

A version without etoolbox, using \pdfstrcmp and a command that has the same functionality than \ifstrequal, but using expansion. Otherwise use \expandafter\ifstrequal\expandafter{\whoami}{PB}.

The reason why \ifstrequal does not work here is that its argument is detokenized, so \whoami is basically "whoami and this is not the same as PB then.

\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}
  • Ah, so that is what "detokenized" means! Thanks; that clears things up a lot! – pb2017 Sep 16 '17 at 21:39
2

You can define some infrastructure, so to be able to define several variables depending on the collaborator. Just one line has to be changed by each one.

\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}

enter image description here

If I change the line to

\selectcollaborator{egreg}

the same document will print

enter image description here

  • egreg, thanks a bunch! This is the most awesome-est solution! I am using it now. The only trouble is it seems to be use tex programming at a level far higher than mine (which is 0), so if something breaks I won't be able to fix! – pb2017 Oct 2 '17 at 23:23
  • @pb2017 I added some comments to the code, but some knowledge of expl3 (texdoc interface3) is needed nonetheless. – egreg Oct 3 '17 at 6:41
0

Sorry, it appears I pulled the trigger too soon. Replacing \ifstrequal by \ifdefstring makes it "work", though I still don't fully understand why.

  • 1
    \ifstrequal compares two strings (\ifstrequal{PB}{BP}{same}{not same}) but \ifdefstring compares the replacement text (definition) of a command with a string (\ifdefstring{\whoami}{PB}{am PB}{not PB}). – Nicola Talbot Sep 16 '17 at 21:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.