2

I'm looking for a way to get the following done

I want to have a command

\setcitation[2]

with the following definition

\def\setcitation#1#2{\lowercase{\expandafter\gdef\csname mycommoncitation#1\endcsname}{#2}}

Essentially, what it does is each time it is called with arguments xXx and yyy, it creates a new command

\mycommoncitationxxx

defined as

\yyy

Now, given an input, xxX, I would like to get yyy out. So what has to happen: convert xxX to lowercase xxx, call \mycommoncitationxxx

I tried doing this as follows:

\newcommand\getcitation[1]{%
\lowercase{\csuse{mycommoncitation#1}}
}

And as follows:

\newcommand\getcitation[1]{\lowercase{\expandafter\gdef\csname mycommoncitation#1\endcsname}}

However niether work.

For the first part (the definition of my setcitation command) I based my solution on build a capitalized CS from a lowercase string and to give it a definition

For the second part, I don't find any help yet.

Complete example, that also shows how I want to use these commands:

\documentclass{article} 
\usepackage{etoolbox} 
\newcommand{\setcitation}[2]{\lowercase{\csdef{mycommoncitation#1}}{#2}} 
\newcommand{\getcitation}[1]{\lowercase{\csuse{mycommoncitation#1}}} 

\newcommand{\getcitationifexistsotherwiseinput}[1]{\lowercase{\ifcsdef{mycommoncitation#1}{\getcitation{#1}}{#1}}}


\begin{document} 
\setcitation{Foo}{Bar} 
\getcitation{Foo} 
\mycommoncitationfoo
\getcitationifexistsotherwiseinput{Foo} %My expectation: Bar
\getcitationifexistsotherwiseinput{foo} %my expectation: Bar
\getcitationifexistsotherwiseinput{boo} %my expectation: boo
%Now I want a command that returns 
% \getcitation{FOO} 

\cite{\getcitation{foo}} %my expectaiton: "undefined citation Bar"
\end{document}

here, in the line \cite{...} things start to go wrong.

BartBog
  • 151
  • 1
    Related: http://tex.stackexchange.com/questions/173481/expandably-change-letter-case-and-use-inside-csname-without-a-package – Steven B. Segletes Jan 20 '17 at 13:15
  • lowercase is not expandable so does not work inside \cite if you don't mind enumerating all the letters (eg if you only allow a-z, not accented letters) then it is possible to write an expandable version. Or simpler use a modified command say \lccite that applies lowercase then \cite` – David Carlisle Jan 20 '17 at 13:57
  • The problem with that is that I cometimes want to use it in the form \cite{something,\getcitation{somethingelse}}, SO I'ld basically ahve to patch the entire cite command... – BartBog Jan 20 '17 at 14:51
  • @BartBog well then you can use the expandable lowercase commands in the question that Steven linked – David Carlisle Jan 20 '17 at 15:43

2 Answers2

4

You need an expandable version of \lowercase:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\setcitation}{mm}
 {
  \prop_gput:Nxn \g_bartbog_citations_prop { \str_lowercase:n { #1 } } { #2 }
 }
\DeclareExpandableDocumentCommand{\getcitation}{m}
 {
  \prop_item:Nf \g_bartbog_citations_prop { \str_lowercase:n { #1 } }
 }

\cs_generate_variant:Nn \prop_gput:Nnn { Nx }
\cs_generate_variant:Nn \prop_item:Nn { Nf }
\prop_new:N \g_bartbog_citations_prop
\ExplSyntaxOff

\setcitation{Foo}{Bar} 

\begin{document}
\getcitation{Foo} 
\getcitation{foo} 
\getcitation{FOO} 

\cite{\getcitation{Foo}},
\cite{\getcitation{foo}},
\cite{\getcitation{FOO}}

\begin{thebibliography}{1}

\bibitem{Bar} Whatever

\end{thebibliography}

\end{document}

I used a property list for compactness.

enter image description here

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
egreg
  • 1,121,712
  • When I try this, I get a lot of LaTeX Warning: Citation `' on page 1 undefined on input line 28. errors and getctation does not print anything... – BartBog Jan 25 '17 at 09:25
  • Also: could you extend your answer with a command like getcitationifexistsotherwiseinput in my question. It is not clear to me how to check existance in explsyntax – BartBog Jan 25 '17 at 09:28
  • @BartBog What are you expecting? You're passing something to \cite which it doesn't know. What can be done is making the message something like LaTeX Warning: Citation `MISSING' on page 1 undefined on input line 28, not much more. – egreg Jan 25 '17 at 12:05
  • What I mean is that when I run exactly your code, I don't get Bar Bar Bar [1] [1] [1] but [?] [?] [?]. I.e., it does not seem to be working. Concretely, if I remove the \str_lower_case:n from getcitation, One of the \getcitations works... – BartBog Jan 25 '17 at 12:23
  • @BartBog Are you sure you have an up-to-date TeX system? – egreg Jan 25 '17 at 12:25
  • I just fiddled around a bit with different TeX systems on [https://papeeria.com/] I noticed that with Texlive 2015, it goes wrong, but with Texlive 2016 it works. Unfortunately, I am sharing my latex code and this needs to work on machines where I cannot control the TeX system... Any idea on how to fix it? – BartBog Jan 25 '17 at 12:28
  • Also when I replace the lowercase in my example with str_lower_case, things still don't work. So expandability of lowercase seems to not be the only issue. (aside from Texlive 2016) – BartBog Jan 25 '17 at 14:07
0

I just posted another answer to Expandably change letter case and use inside \csname, without a package.

That answer can be found at https://tex.stackexchange.com/a/349895/118714 .

That answer contains a routine \UD@ExpandableLowercase which delivers lowercasing of those 26 catcode-11(letter)-character-tokens that correspond to the 26 letters of the latin alphabet within two expansion steps. That routine does not require eTeX or the like extensions.

(!!!Be aware that having TeX read and tokenize input consisting of characters of the latin alphabet usually yields catcode-11(letter)-character tokens while expanding \string, \meaning, \jobmane and the like primitives delivers catcode-12(other)-character-tokens!!!)

As a (probably disliked) side effect that routine does replace pairs of matching catcode-1-character-tokens and catcode-2-character-tokens by pairs of matching curly catcode-1-brace-tokens and curly catcode-2-brace-tokens, i.e. { and }.

I think this should not be a problem with plain TeX and LaTeX2e as with these formats usually the only character with category code 1 is the opening curly brace { and the only character with category code 2 is the closing curly brace }.

Ulrich Diez
  • 28,770