我确信以前有人以某种形式问过这个问题,但我找不到例子,所以。我有两个变量(来自外部系统)x
和y
。我想在二维码中每行对它们进行编码。所以如果x=This is
和y=my message
我希望能够编码\x\?\y
为:
This is
my message
但是。部分数据也将包含在文档的其他地方,并且设计为供人类阅读。因此,逃脱是可能的(从外部),但前提是它不会影响这一点。
我得到的是:
Thisis
mymessage
来自我的 SSCCE:
\documentclass[12pt,a4paper]{article}
\usepackage{qrcode}
\def\x{This is}
\def\y{my message}
\def\qrdata{\x\?\y}
\begin{document}
\qrcode[tight,nolink,height=46mm,level=H]{\qrdata};
\end{document}
我的问题是:
- 如何自动
用转义形式替换
\
?我查看过 etoolbox 和 patchcmd 等软件包,但据我所知,它们会替换现有命令,而我不想这样做(或者我可能不太明白如何使用它们)。我尝试寻找可以将定义转换为转义形式的软件包。
如果这很重要,我会使用 xelatex 和 texlive。便携式解决方案是理想的;特定于 xetex 的解决方案也可以。
答案1
使用 LaTeX(不幸的是,我得到了一个带有 XeLaTeX 的 ghostscript Last OS error: Permission denied
,我似乎无法通过),你可以使用以下方式进行pst-barcodes
编译--shell-escape
\documentclass{article}
\usepackage{pst-barcode}
\usepackage{auto-pst-pdf}
\def\x{This is}
\def\y{my message}
\def\qrdata{\x\string\n\y}
\begin{document}
\begin{pspicture}(46mm,46mm)
\psbarcode{\qrdata}{eclevel=H}{qrcode}
\end{pspicture}
\end{document}
答案2
以下是使用qrcode
包本身的解决方案。
首先,关于类别代码的概念,我想说几句。对于 LaTeX 来说,空格具有特殊含义,这反映在解析文档时空格的存储方式上:空格被分配类别代码 10,而字母和非字母符号则被分配类别代码 11 和 12(请参阅类别代码是什么?了解更多信息)。\qrcode
宏逐字处理参数,这意味着空格在 中会失去其特殊含义\qrcode
。但是,如果空格位于宏定义中,例如,则在看到它\def\x{this is}
之前,它已被处理并分配了特殊类别代码\qrcode
。不幸的是,在这种情况下,它不再转换为常规字符,因此空格不会被编码到二维码中。
一种可能的解决方案是暂时将空格字符的类别代码切换为常规字符(类别代码 12),然后处理宏定义,然后将类别代码设置回 10。可以使用命令\catcode`[character]=[code]
(注意反引号)切换类别代码。MWE 为此:
\documentclass[12pt,a4paper]{article}
\usepackage{qrcode}
\catcode`\ =12
\def\myx{This is}
\def\myy{my message}
\def\qrdata{\myx\?\myy}
\catcode`\ =10
\begin{document}
x=\myx
y=\myy
\qrcode[tight,height=46mm,level=H]{\qrdata}
\end{document}
上面的代码生成的二维码是正确的,即它包含空格。但是,如果您使用文档本身中的宏\myx
和\myy
来打印内容,则空格将无法正确打印。由于它们现在是常规字符(在这些宏中,文档中的其他地方空格仍然是特殊字符),LaTeX 将打印当前字体中 32 号位置中的任何内容,这可能是␣
或̷
字符之类的内容。
可以使用tokcycle
包来解决此问题。此包有一组命令,用于逐个标记读取序列标记并将其写回,并对单个标记进行可选修改。这可用于读取包含类别 12 空间(例如两个输入宏)的标记列表,并将这些空间转换为常规类别 10 空间。然后可以在文档中正常使用生成的修改后的标记列表。
相关的宏是,\Characterdirective
它会针对一个标记循环中的每个字符调用。只应处理空格,因此在此宏中可以使用宏进行测试\tctestifx
。为了与类别 12 空间进行具体比较,我们需要这样一个空间的表示,我们可以通过在类别代码为 12 时为命名宏分配一个空间值(在下面的代码中调用)来实现。现在,在真条件下可以返回\twelvesp
值,而在假条件下可以返回输入字符不变。重要的是,在定义期间,空格的 catcode 应该是 10 ,以便替换字符确实具有 catcode 10。#1
\Characterdirective
这种方法基于https://tex.stackexchange.com/a/574593/(该答案的‘补充’部分)。
完整 MWE:
\documentclass[12pt,a4paper]{article}
\usepackage{qrcode}
\usepackage{tokcycle}
\catcode`\ =12
\let\twelvesp \relax
\def\myx{This is}
\def\myy{my message}
\def\qrdata{\myx\?\myy}
\catcode`\ =10
\Characterdirective{%
\tctestifx{\twelvesp#1}{\addcytoks{ }}{\addcytoks{#1}}}
\def\somex{\expandafter\tokencyclexpress\myx\endtokencyclexpress}
\def\somey{\expandafter\tokencyclexpress\myy\endtokencyclexpress}
\begin{document}
x=\somex
y=\somey
\qrcode[tight,height=46mm,level=H]{\qrdata}
\end{document}
结果:
注意:当 catcode 为 12 时,请避免在代码中的任何地方使用任何空格(宏文本内部除外),否则您将收到各种错误。