4

Is there a way to create a qr code in LaTeX with koma variables as input?

am using the package qrcode and everything works fine and the package is easy to use. However, when I am trying to use a koma variable as the input for the text LaTeX crashes.

This works:

\documentclass{scrlttr2}
\usepackage[final]{qrcode}

\setkomavar{fromemail}{me@it.is}

\newcommand{\texttoconvert}{mailto:me@it.is} \begin{document} \begin{letter}{} \qrcode[height=1.5cm]{\texttoconvert} \end{letter} \end{document}

But this does not:

\documentclass{scrlttr2}
\usepackage[final]{qrcode}

\setkomavar{fromemail}{me@it.is}

\newcommand{\texttoconvert}{mailto:\usekomavar{fromemail}} \begin{document} \begin{letter}{} \qrcode[height=1.5cm]{\texttoconvert} \end{letter} \end{document}

Why is that? It also does not work to use koma variables directly in qrcode...

muzimuzhi Z
  • 26,474
mrCarnivore
  • 1,505

3 Answers3

5

Unfortunately \usekomavar is not fully expandable, see its doc in Koma-Script manual (2022-10-12), sec. 4.5. Variables.

But \usekomavar accepts a "styling" command as its optional argument, which will act on the value of variable. That is, after \setkomavar{<name>}{<content>},

\usekomavar[\mycmd]{<name>}
% is equivalent to
\mycmd{<content>}

Apply this trick to OP's use case:

\documentclass{scrlttr2}
\usepackage[final]{qrcode}

\setkomavar{fromemail}{me@it.is}

\newcommand{\QRmailto}[2][]{\qrcode[#1]{mailto:#2}}

\begin{document} \begin{letter}{} \usekomavar[{\QRmailto[height=1.5cm]}]{fromemail} \end{letter} \end{document}

enter image description here

Since now the text to be encoded in qr code is tokenized before passed to \qrcode, special characters (#$&^_~%␣\{}) may need to be escaped (\#\$\&\^\_\~\%\␣\\\{\}), see qrcode package doc (2015/01/08 v1.51), sec. 2.3 Special characters.

\documentclass{scrlttr2}
\usepackage[final]{qrcode}

\setkomavar{fromemail}{me@it.is}

% \myQrcode[<opts>]{<pre>}{<post>}{<text>} % => \qrcode [<opts>]{<pre><text><post>} \newcommand{\myQrcode}[4][]{\qrcode[#1]{#2#4#3}}

\begin{document} \begin{letter}{} \usekomavar [{\myQrcode[height=1.5cm] {mailto:} {?subject=ABC/123&body=Hello\ and\ welcome}}] {fromemail} % <QR code requested for "mailto:me@it.is?subject=ABC/123&body=Hello and welcome" in version 0-M.> \end{letter} \end{document}

muzimuzhi Z
  • 26,474
  • Thank you. This does work and is very simple. However, it does no longer work when I want to add subject and text as in \newcommand{\QRmailto}[2][]{\qrcode[#1]{mailto:#2?subject=ABC/123&body=Hello and welcome,}}. Then the spaces in the body are omitted. Why? – mrCarnivore Mar 12 '23 at 14:01
  • 1
    @mrCarnivore According to qrcode doc, using \ does the trick. – muzimuzhi Z Mar 12 '23 at 14:59
  • Thank you for your answer and the help you have given me! escaping the spaces does work. I was confused since it worked when using plain text in qrcode without needing to escape the spaces. – mrCarnivore Mar 12 '23 at 15:18
5

The \usekomavar command is not expandable. You can define an expandable version (that won't check whether the variable is actually defined, beware).

\documentclass{scrlttr2}
\usepackage[final]{qrcode}

\setkomavar{fromemail}{me@it.is}

\newcommand{\texttoconvert}{mailto:\expkomavar{fromemail}}

\makeatletter \NewExpandableDocumentCommand{\expkomavar}{sO{@firstofone}m}{% \IfBooleanTF{#1}{% \expkomavar* \expkomavar@name{#2}{#3}% }{% \expkomavar \expkomavar@var{#2}{#3}% }% } \newcommand{\expkomavar@name}[2]{#1{@nameuse{scr@#2@name}}} \newcommand{\expkomavar@var}[2]{#1{@nameuse{scr@#2@var}}} \makeatother

\begin{document}

\begin{letter}{}

\qrcode[height=1.5cm]{\texttoconvert}

\bigskip

\qrcode[height=1.5cm]{mailto:me@it.is}

\end{letter}

\end{document}

enter image description here

The two QR-codes are the same, as witnessed by the log file where we find

<Reading QR code for "mailto:me@it.is" at level 2-Q from aux file.>

for the second instance, meaning that the package recognizes it's the same as a previously built one.

egreg
  • 1,121,712
1

I have talked to Markus Kohm (author of koma-script) and he told me that the intended solution with koma-script is to use the ability of \usekomavar to expand the koma-variable into the first parameter of the optional variable \usekomavar[<command>]{<komavariable>}.

Like this:

\newcommand*{\qrcodewithprefix}[2][mailto:]{\qrcode{#1#2}}
\usekomavar[\qrcodewithprefix]{fromemail}

or even shorter:

\usekomavar[\def\fromemail]{fromemail}
\qrcode{mailto:\fromemail}

His main reason for this are that this solution (compared to the more low level solutions) enables helpful error messages.

If you try a typo in the koma-variable and write \usekomavar[\def\fromemail]{frommail} instead you get the following error message:

Class scrlttr2 Error: KOMA-Script variable not defined. \usekomavar[\def\fromemail]{frommail}

This does not happen if you instead used:

\def\fromemail{example-\csname scr@fromemail@var\endcsname}

When you introduce a typo then you only get a very confusing:

Undefined control sequence. \qrcode{mailto:\fromemail}

To sum it up the easy and clean solution is to define \fromemail and with \usekomavar expand the contents of the koma-variable fromemail into it and from then on use \fromemail instead of the koma-variable when needing the expanded variant:

\documentclass{scrlttr2}

\setkomavar{fromemail}{john@doe.com} \usepackage[final]{qrcode} \usekomavar[\def\fromemail]{fromemail} \begin{document} \qrcode{mailto:\fromemail} \end{document}

mrCarnivore
  • 1,505