5

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?

8
  • 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?
    – cgnieder
    Jul 25, 2015 at 15:49
  • No, both can (and should) be verbatim. Jul 25, 2015 at 15:51
  • But then \script{\#} and \qrcode{\#} will give different QR codes… (just to be sure)
    – cgnieder
    Jul 25, 2015 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). Jul 25, 2015 at 16:06
  • Yes, that's what I mean.
    – cgnieder
    Jul 25, 2015 at 16:07

1 Answer 1

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}
8
  • 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.) Jul 25, 2015 at 16:13
  • 1
    @lukas.coenig like with all macros who read their argument verbatim \script cannot be used inside of another macro
    – cgnieder
    Jul 25, 2015 at 16:18
  • Okay, one thing doesn't work: line breaks are not allowed. Jul 25, 2015 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.
    – cgnieder
    Jul 25, 2015 at 23:06
  • 1
    @lukas.coenig see edited answer
    – cgnieder
    Jul 26, 2015 at 10:58

You must log in to answer this question.

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