3

I'm trying to store the text output of a shell command mktemp and reuse it later in another latex command. I'm attempting to do this using \savebox and \usebox as below. When using \usebox outside a command, the saved text is printed correctly. However, when used inside other commands like \write18 and \includegraphics, the \usebox command appears to not be macroexpanded correctly:

\newcommand{\mktemp}[0]{
  \input{|"mktemp"}
}

\newcommand{\hrefqr}[2]{%
  \tracingall
  \newsavebox{\tmp}
  \savebox{\tmp}{\mktemp}
  %% verify that \tmp is the same file and not repeated mktemp calls
  \usebox{\tmp} \\
  \usebox{\tmp} \\
  \immediate\write18{qrencode #1 -o \usebox{\tmp}}
  \href{#1}{#2 \includegraphics[]{\usebox{\tmp}}}
}
\begin{document}
\hrefqr{www.example.com}{This is example.com}
\end{document}

From the logs:

\write->qrencode www.example.com -o \usebox {\tmp }

\usebox ->\protect \usebox  

\usebox  #1->\leavevmode \copy #1\relax 
#1<-\tmp 

\leavevmode ->\unhbox \voidb@x 
runsystem(qrencode www.example.com -o \protect \unhbox \voidb@x \copy \tmp \rel
ax )...executed safely (allowed).

And later:

! LaTeX Error: File `\usebox {\tmp }' not found.

from the expansion of:

#1<-This is example.com \includegraphics []{\usebox {\tmp }}

What am I doing wrong?

4
  • Aside: you have loads of unterminated line ends in your source - you'll introduce lots of unwanted space
    – Joseph Wright
    Commented Jun 5, 2023 at 6:40
  • 1
    Store your text in a command, not a box. Commented Jun 5, 2023 at 6:44
  • Storing the marco in a command appears to re-invoke the macro multiple times, generating different temp filenames.
    – user84207
    Commented Jun 5, 2023 at 6:58
  • usebox is not expandable but you can not use a box as a filename. You already error without all your code and \includegraphics{\mbox{example-image}} what would you want the box to do here? Commented Jun 5, 2023 at 7:53

1 Answer 1

6

You can't store text in a box and retrieve it by macro expansion. When you do \savebox{\tmp}{some text} the argument is stored in the box register as already typeset.

Here's a working implementation. I create a directory, rather than a file, and in it I create temp.png, otherwise \includegraphics wouldn't be able to determine its size. See https://stackoverflow.com/a/59638023.

If your version of mktemp supports -suffix, you can use it, see later for details.

\documentclass{article}
\usepackage{catchfile}
\usepackage{graphicx}
\usepackage{hyperref}

\ExplSyntaxOn

\NewDocumentCommand{\hrefqr}{mO{}m}
 {
  % get the name of a temporary file
  \sys_get_shell:nnN { mktemp ~ -d } { } \l_tmpa_tl
  \tl_trim_spaces:N \l_tmpa_tl
  % build the QRcode
  \sys_shell_now:x { qrencode ~ #1 ~ -o ~ \l_tmpa_tl/temp.png }
  %
  \href { #1 } { #3 ~ \includegraphics[#2]{ \l_tmpa_tl/temp.png } }
 }

\ExplSyntaxOff

\begin{document}

\hrefqr{www.example.com}{This is example.com}

\hrefqr{www.example.com}[scale=0.5]{This is example.com}

\end{document}

enter image description here

On my system, mktemp doesn't support --suffix, but gmktemp (installed with Homebrew as part of coreutils) does.

\documentclass{article}
\usepackage{catchfile}
\usepackage{graphicx}
\usepackage{hyperref}

\ExplSyntaxOn

\NewDocumentCommand{\hrefqr}{mO{}m}
 {
  % get the name of a temporary file
  \sys_get_shell:nnN { gmktemp ~ --suffix ~.png } { } \l_tmpa_tl
  \tl_trim_spaces:N \l_tmpa_tl
  % build the QRcode
  \sys_shell_now:x { qrencode ~ #1 ~ -o ~ \l_tmpa_tl }
  %
  \href { #1 } { #3 ~ \includegraphics[#2]{ \l_tmpa_tl } }
 }

\ExplSyntaxOff

\begin{document}

\hrefqr{www.example.com}{This is example.com}

\hrefqr{www.example.com}[scale=0.5]{This is example.com}

\end{document}
5
  • I probably wouldn't use mktemp (and generate the name in tex) but if you do, better to use mktemp XXXXXX.png rather than append .png later otherwise all the checks mktemp does about not overwriting file names are wasted Commented Jun 5, 2023 at 8:57
  • @DavidCarlisle mktemp wants trailing X's. I'll give other suggestions.
    – egreg
    Commented Jun 5, 2023 at 10:23
  • oh, works here: $ mktemp XXX.png makes nyF.png Commented Jun 5, 2023 at 10:31
  • 1
    @DavidCarlisle Not on all systems, unfortunately.
    – egreg
    Commented Jun 5, 2023 at 10:56
  • Thanks. This was more complicated than I thought. Is there a relatively concise latex programming guide you can recommend?
    – user84207
    Commented Jun 5, 2023 at 20:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .