6

How can I force \myget{second} been expanded before \qrcode{xxx} gets the macro as argument which seems to be the problem to me. \qrcode{foobar} works as it should.

\documentclass{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{qrcode}
\usepackage{xstring}

\def\Testmap{
  {first}{blue}
  {second}{red}
  {foo.bar}{orange}
  {4}{violet}
  {bla}{green}
  {6}{violet}
  {7}{violet}
  {8}{black}
}

\def\xget#1#2{\expandafter\xgetimpl#1{#2}{}\xget{#1}{#2}}%
\def\xgetimpl#1#2#3\xget#4#5{%
\IfEq{#5}{#1}{#2}{\xgetimpl#3\xget{#4}{#5}}%
}%

\protect\def\myget#1{\xget{\Testmap}{#1}}%

\begin{document}

\qrcode{\myget{second}}    %%%% !!!!!!!!!!!!
% \myget{second}           %%%% this works fine (prints 'red' as expected)

\end{document}

I tried putting several \protect, \expandafter and whatever on several places in this code, but nothing worked or gave me a hint where to look next. Using \edef\tmp{\myget{second}} wasn't helpful either.

Here is the relevant part of pdflatex *.log file:

! Undefined control sequence.
\in@ #1#2->\begingroup \def \in@@ 
                  ##1#1{}\toks@ \expandafter {\in@@ #2{}{}#1...
l.27 \qrcode{\myget{second}}

The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Illegal parameter number in definition of \qr@texttoencode.
<to be read again> 
          1
l.27 \qrcode{\myget{second}}

You meant to type ## instead of #, right?
Or maybe a } was forgotten somewhere earlier, and things
are all screwed up? I'm going to assume that you meant ##.

! Undefined control sequence.
\in@ ...f \in@@ ##1#1{}\toks@ \expandafter {\in@@ 
                          #2{}{}#1}\edef \in@@ {\the...
l.27 \qrcode{\myget{second}}

The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

! Undefined control sequence.
\in@ ... \expandafter {\in@@ #2{}{}#1}\edef \in@@ 
                          {\the \toks@ }\expandafter...
l.27 \qrcode{\myget{second}}

The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.

)
! Incomplete \iffalse; all text was ignored after line 27.
<inserted text> 
        \fi 
<*> test.tex

The file ended while I was skipping conditional text.
This kind of error happens when you say `\if...' and forget
the matching `\fi'. I've inserted a `\fi'; this might work.

! Emergency stop.
<*> test.tex

*** (job aborted, no legal \end found)

migrated from stackoverflow.com Apr 7 '16 at 9:07

This question came from our site for professional and enthusiast programmers.

  • 1
    It is not possible as it, because \xget is not fully expandable. – Henri Menke Apr 7 '16 at 9:23
3

I suggest using l3prop property lists for this cause. Access to their elements is fully expandable and thus usable in arguments.

\documentclass{article}
\usepackage{qrcode}
\usepackage{xparse}

\ExplSyntaxOn

\prop_new:N \l_stefan_testmap_prop

\prop_put:Nnn \l_stefan_testmap_prop {first} {blue}
\prop_put:Nnn \l_stefan_testmap_prop {second} {red}
\prop_put:Nnn \l_stefan_testmap_prop {foo.bar} {orange}
\prop_put:Nnn \l_stefan_testmap_prop {4} {violet}
\prop_put:Nnn \l_stefan_testmap_prop {bla} {green}
\prop_put:Nnn \l_stefan_testmap_prop {6} {violet}
\prop_put:Nnn \l_stefan_testmap_prop {7} {violet}
\prop_put:Nnn \l_stefan_testmap_prop {8} {black}

\DeclareExpandableDocumentCommand \myget { m }
 {
  \prop_item:Nn \l_stefan_testmap_prop { #1 }
 }

\ExplSyntaxOff

\begin{document}

\qrcode{\myget{second}}

\end{document}

enter image description here

1

You need some expandable macro. By the way the \protect in the MWE should not have been there. It had no effect and replaced by the correct \protected it would have had the effect of a non usable inside \qrcode \myget.

\documentclass{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage{qrcode}
\usepackage{xinttools}

\xintForpair #1#2 in {
  (first, blue),
  (second, red),
  (foo.bar, orange),
  (4, violet),
  (bla, green),
  (6, violet),
  (7, violet),
  (8, black)
}\do {\expandafter\def\csname Testmap_#1\endcsname {#2}}

\def\myget #1{\csname Testmap_\xintZapSpaces{#1}\endcsname}

\begin{document}

\textcolor{\myget{first}}{\qrcode{\myget{first}}}    %%%% ok

\textcolor{\myget{second}}{\qrcode{\myget{second}}}    %%%% ok

\end{document}

Blockquote

Your Answer

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