I was recently messing up with making a business card in LaTeX (mostly following this great tutorial from Olivier Pieters) and, of course, I tried adding a QR code on the back of the card that people could scan to quickly save my contact.
A sensible person will export a .vcf file from their favourite contacts application, copy the text inside the \qrcode
command in the LaTeX file, find out that you could need to replace newlines with \?
to compile correctly and call it a day.
But I’m no sensible person, and I wondered why couldn’t I just save the .vcf file on disk and include it directly inside the qrcode command, something like \qrcode{\input\mycard.vcf}}
to make the LaTeX file a little lighter and to save the 3 seconds inconvenience I’d have if I wanted to modify the .vcf file in the future (seriously, how often do you change your contact info?); but I quickly found this command would fail with obscure error messages.
This brought me down a rabbit hole I really didn’t believe possible for such a seemingly trivial task, but I’m stubborn and wanted to understand why I had to waste 2 hours on a problem that would hopefully save 30 seconds to future me. Apparently, this was not a problem anybody every had, or at least not that I could find, but from what I understood by reading around, the issue is that a newline means something particular in LaTeX, and encountering one will interrupt the \qrcode
command, failing the compilation.
I tried many snippets I found online: commands that supposedly included file contents verbatim, commands that escaped newlines in macros after loading from disk; I even tried making a loop, reading file line by line (another weird LaTeX interaction that made me scratch my head) and adding \?
after every line… none of this worked. Out of desperation, I resulted to ask ChatGPT and, to my surprise, it spat out some LaTeX commands that (after some tweaking and ask-chatgpt-the-same-question-trice) actually did what I needed.
Anyway, this is the code to make it work: basically you define a command that will create a macro with the verbatim content of the file, converting the newline and carriage return characters to literal bytes. I don’t know what expl is, I can’t fathom what these weird commands with double underscores do, but they work. I hope that will help someone eventually who encounters my same problem.
\usepackage{qrcode}
\usepackage{expl3,xparse}
\begin{document}
\ExplSyntaxOn
\tl_new:N \l__vcf_tl
\ior_new:N \l__vcf_ior
\NewDocumentCommand{\vcardfromfile}{mm}
{
\tl_clear:N \l__vcf_tl
\ior_open:Nn \l__vcf_ior { #1 }
\ior_map_inline:Nn \l__vcf_ior
{
\tl_put_right:Nn \l__vcf_tl { ##1 }
% append ASCII LF (category 12, char code 10)
\tl_put_right:Nx \l__vcf_tl { \char_generate:nn {10} {12} }
}
\ior_close:N \l__vcf_ior
\tl_set_eq:NN #2 \l__vcf_tl
}
\ExplSyntaxOff
\vcardfromfile{mycard.vcf}{\myvcard}
\qrcode{\myvcard}
\end{document}