4

Basically I want to define a macro whose parameter should be treated as a "script", meaning that I want to print it in a verbatim way including line breaks and special characters. Furthermore, I want to use this parameter in a second way, namely as an input to create a qrcode (using the qrcode package). A very minimal example is the following:

\documentclass{article}
\usepackage{qrcode}

\newcommand{\script}[1]{
    #1\qrcode{#1}
}

\begin{document}
    \script{test}
\end{document}

When I do it like this, the parameter is obviously not interpreted as verbatim. Since I need the parameter at two different places (both interpreted in verbatim mode), I cannot use an environment either -- such as a listings environment -- since the body text cannot (directly) be used as parameter.

I played around with the environ package (see my earlier question: Is it possible to "scan" the text within an environment?) to capture the body text of an environment, but, again, didn't succeed to make it verbatim.

I also tried to work with \obeylines and \StrSubstitute, but it gets quite ugly really soon, and it didn't actually work well.

It looks rather easy, but I'm struggling with this for a long time now. Any suggestions?

  • Do I understand correctly that in #1\qrcode{#1} the first #1 should be verbatim but the second one not? Or should both occurences be verbatim? – clemens Jul 25 '15 at 15:49
  • No, both can (and should) be verbatim. – lukas.coenig Jul 25 '15 at 15:51
  • But then \script{\#} and \qrcode{\#} will give different QR codes… (just to be sure) – clemens Jul 25 '15 at 15:55
  • Hm, yeah, if you mean that \script{\#} should produce a qrcode of the two characters \ and #, while \qrcode{\#} would produce a qrcode of # (as far as I know). – lukas.coenig Jul 25 '15 at 16:06
  • Yes, that's what I mean. – clemens Jul 25 '15 at 16:07
4

I am not entirely sure that I understood what you want. However, your MWE can easily be achieved with xparse and its v type argument:

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

\NewDocumentCommand{\script}{v}{%
  \texttt{#1} \qrcode{#1}%
}

\begin{document}

\script{test} \script{&$\#$}

\end{document}

Keep in mind, though, that now since now the argument is read in verbatim in the first place \script{&$\#$} gives a different qrcode than using \qrcode{&$\#$} directly. If that is not what you want, then maybe

\NewDocumentCommand{\script}{v}{%
  \texttt{#1} \scantokens{\qrcode{#1}\ignorespaces}\relax
}

would be a solution.

The output with the first version (qrcode of verbatim input):

enter image description here

The output with the second version (qrcode like in direct use of \qrcode):

enter image description here


Idea for an environment doing similar things using listings (and its writefile aspect) and catchfile – the idea is to write the contents of the environment to an external file and then use it to produce the qrcode:

\documentclass{article}
\usepackage{qrcode,listings,catchfile}

\makeatletter
\lst@RequireAspects{writefile}
\lstnewenvironment{script}[1][]
  {%
    \lstset{#1}%
    \lst@BeginAlsoWriteFile{\jobname.script}%
  }
  {%
    \lst@EndWriteFile
    \CatchFileDef\script@tmp{\jobname.script}{}%
    \expandafter\qrcode\expandafter{\script@tmp}%
  }
\makeatother

\begin{document}

\begin{script}[basicstyle=\ttfamily,columns=fullflexible,gobble=2]
  foo bar

  baz
\end{script}

\qrcode{foo bar

baz
}

\end{document}
  • I'm not saying that it's NOT easy, I'm just saying that I was not clever enough to do it so far... ;-) This minimal example certainly works - you did it exactly as I intended it. However, I'll have to try it in my big project to be sure. I thought to have solved it several times in the past, just to find out that my minimal example was too minimal after all... (I'll let you know if you like.) – lukas.coenig Jul 25 '15 at 16:13
  • 1
    @lukas.coenig like with all macros who read their argument verbatim \script cannot be used inside of another macro – clemens Jul 25 '15 at 16:18
  • Okay, one thing doesn't work: line breaks are not allowed. – lukas.coenig Jul 25 '15 at 16:18
  • 1
    @lukas.coenig line breaks work with \NewDocumentCommand{\script}{+v}{...} (note the + in front of v). I also have some code with listings for an environment doing the same thing if you're interested. – clemens Jul 25 '15 at 23:06
  • 1
    @lukas.coenig see edited answer – clemens Jul 26 '15 at 10:58

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.