是否可以将变量传递给 \def\barcode 代码?如果可以,如何传递?

是否可以将变量传递给 \def\barcode 代码?如果可以,如何传递?

我用morsbug 的代码用于生成 isbn 条形码。它工作正常,至少只要我以字符串形式提供 isbn。如果我使用\newcommand{\isbn}{123...}编译定义的变量传递 isbn 号,则编译会失败。

以下 MWE 应该阐明这一目标:

\documentclass{article}

\def\barcode#1#2#3#4#5#6#7{\begingroup%
\dimen0=0.1em
\def\stack##1##2{\oalign{##1\cr\hidewidth##2\hidewidth}}%
\def\0##1{\kern##1\dimen0}%
\def\1##1{\vrule height10ex width##1\dimen0}%
\def\L##1{\ifcase##1\bc3211##1\or\bc2221##1\or\bc2122##1\or\bc1411##1%
    \or\bc1132##1\or\bc1231##1\or\bc1114##1\or\bc1312##1\or\bc1213##1%
    \or\bc3112##1\fi}%
\def\R##1{\bgroup\let\next\1\let\1\0\let\0\next\L##1\egroup}%
\def\G##1{\bgroup\let\bc\bcg\L##1\egroup}% reverse
\def\bc##1##2##3##4##5{\stack{\0##1\1##2\0##3\1##4}##5}%
\def\bcg##1##2##3##4##5{\stack{\0##4\1##3\0##2\1##1}##5}%
\def\bcR##1##2##3##4##5##6{\R##1\R##2\R##3\R##4\R##5\R##6\11\01\11\09%
    \endgroup}%
\stack{\09}#1\11\01\11\L#2%
\ifcase#1\L#3\L#4\L#5\L#6\L#7\or\L#3\G#4\L#5\G#6\G#7%
\or\L#3\G#4\G#5\L#6\G#7\or\L#3\G#4\G#5\G#6\L#7%
\or\G#3\L#4\L#5\G#6\G#7\or\G#3\G#4\L#5\L#6\G#7%
\or\G#3\G#4\G#5\L#6\L#7\or\G#3\L#4\G#5\L#6\G#7%
\or\G#3\L#4\G#5\G#6\L#7\or\G#3\G#4\L#5\G#6\L#7%
\fi\01\11\01\11\01\bcR}

\begin{document}
\barcode 7046260816138 %<-- compilation succeeds

\newcommand{\isbn}{7046260816138}
%\barcode {\isbn} %<-- compilation fails
\end{document}

答案1

由于要传递的最终字符串\barcode只能是数字,因此让宏符合 LaTeX 语法是有意义的进行充分扩展。

\documentclass{article}

\makeatletter
\newcommand{\barcode}[1]{%
  \begingroup\edef\x{\endgroup\noexpand\@barcode#1}\x
}

\def\@barcode#1#2#3#4#5#6#7{\begingroup%
\dimen0=0.1em
\def\stack##1##2{\oalign{##1\cr\hidewidth##2\hidewidth}}%
\def\0##1{\kern##1\dimen0}%
\def\1##1{\vrule height10ex width##1\dimen0}%
\def\L##1{\ifcase##1\bc3211##1\or\bc2221##1\or\bc2122##1\or\bc1411##1%
    \or\bc1132##1\or\bc1231##1\or\bc1114##1\or\bc1312##1\or\bc1213##1%
    \or\bc3112##1\fi}%
\def\R##1{\bgroup\let\next\1\let\1\0\let\0\next\L##1\egroup}%
\def\G##1{\bgroup\let\bc\bcg\L##1\egroup}% reverse
\def\bc##1##2##3##4##5{\stack{\0##1\1##2\0##3\1##4}##5}%
\def\bcg##1##2##3##4##5{\stack{\0##4\1##3\0##2\1##1}##5}%
\def\bcR##1##2##3##4##5##6{\R##1\R##2\R##3\R##4\R##5\R##6\11\01\11\09%
    \endgroup}%
\stack{\09}#1\11\01\11\L#2%
\ifcase#1\L#3\L#4\L#5\L#6\L#7\or\L#3\G#4\L#5\G#6\G#7%
\or\L#3\G#4\G#5\L#6\G#7\or\L#3\G#4\G#5\G#6\L#7%
\or\G#3\L#4\L#5\G#6\G#7\or\G#3\G#4\L#5\L#6\G#7%
\or\G#3\G#4\G#5\L#6\L#7\or\G#3\L#4\G#5\L#6\G#7%
\or\G#3\L#4\G#5\G#6\L#7\or\G#3\G#4\L#5\G#6\L#7%
\fi\01\11\01\11\01\bcR}
\makeatother

\begin{document}

\barcode{7046260816138}

\newcommand{\isbn}{7046260816138}
\barcode{\isbn}

\end{document}

请注意第一个例子的语法变化:原始示例,其后紧跟着的数字\barcode在 LaTeX 环境中容易出错。

在此处输入图片描述

答案2

由于您已将命令定义为吸收 7 个标记,因此您不能只使用一个。但是,如果您知道变量包含 7 个字符,则可以使用\expandafter。以下代码中的重要行是\expandafter\barcode \isbn

\documentclass{article}

\def\barcode#1#2#3#4#5#6#7{\begingroup%
\dimen0=0.1em
\def\stack##1##2{\oalign{##1\cr\hidewidth##2\hidewidth}}%
\def\0##1{\kern##1\dimen0}%
\def\1##1{\vrule height10ex width##1\dimen0}%
\def\L##1{\ifcase##1\bc3211##1\or\bc2221##1\or\bc2122##1\or\bc1411##1%
    \or\bc1132##1\or\bc1231##1\or\bc1114##1\or\bc1312##1\or\bc1213##1%
    \or\bc3112##1\fi}%
\def\R##1{\bgroup\let\next\1\let\1\0\let\0\next\L##1\egroup}%
\def\G##1{\bgroup\let\bc\bcg\L##1\egroup}% reverse
\def\bc##1##2##3##4##5{\stack{\0##1\1##2\0##3\1##4}##5}%
\def\bcg##1##2##3##4##5{\stack{\0##4\1##3\0##2\1##1}##5}%
\def\bcR##1##2##3##4##5##6{\R##1\R##2\R##3\R##4\R##5\R##6\11\01\11\09%
    \endgroup}%
\stack{\09}#1\11\01\11\L#2%
\ifcase#1\L#3\L#4\L#5\L#6\L#7\or\L#3\G#4\L#5\G#6\G#7%
\or\L#3\G#4\G#5\L#6\G#7\or\L#3\G#4\G#5\G#6\L#7%
\or\G#3\L#4\L#5\G#6\G#7\or\G#3\G#4\L#5\L#6\G#7%
\or\G#3\G#4\G#5\L#6\L#7\or\G#3\L#4\G#5\L#6\G#7%
\or\G#3\L#4\G#5\G#6\L#7\or\G#3\G#4\L#5\G#6\L#7%
\fi\01\11\01\11\01\bcR}

\begin{document}
\barcode 7046260816138 %<-- compilation succeeds

\newcommand{\isbn}{7046260816138}
\expandafter\barcode \isbn
\end{document}

相关内容