我制作了以下宏来生成自定义缩写
\def\myacro#1[#2]#3{%
\newcounter{#1}%
\expandafter\edef\csname#1Acrshort\endcsname{#2}
\expandafter\edef\csname#1Acrlong\endcsname{#3 (#2)}
}%
\def\an#1{\stepcounter{#1}%
\ifnum\csname the#1\endcsname>1%
\csname#1Acrshort\endcsname%
\else%
\csname#1Acrlong\endcsname%
\fi
}
\myacro{cd}[CD]{Compact Disk}
\myacro{floppy}[Floppy]{Floppy Disk}
我的 TeX 文件是
\documentclass{book}
\begin{document}
This is a sample text \an{cd} This is a sample text \an{cd}.
\end{document}
我的问题是,当我删除可选参数时,我收到了错误消息。
\myacro{cd}{Compact Disk}
Runaway argument?
{\@newctr {{cd}{Compact Disk} \myacro {floppy}}}{}\expandafter \edef \ETC.
! Paragraph ended before \myacro was complete.
<to be read again>
\par
您能否提供建议。如何处理此类情况。提前感谢您的帮助。
答案1
TeX 基元\def
不知道“可选参数”的概念。可选参数是在更高级别(使用\newcommand
或\NewDocumentCommand
或类似方法)实现的抽象,用于检查指定的分隔符,并在用户未传递可选参数的情况下为基本定义提供适当的默认值。
您可以使用 LaTeX\@ifnextchar
来检查那里的可选参数。在您的例子中,的定义\myacro
会抓取第一个参数并检查下一个字符是否为[
。如果是,则调用中的实际代码\@myacro
并让它抓取中的参数[
...。]
否则,您将为可选参数提供默认值。您必须确保在 TeX 查找参数时找到定义中的\@myacro
任何内容。<paremeter text>
\documentclass{book}
\makeatletter
\def\myacro#1{%
\@ifnextchar[%]
{\@myacro{#1}}% If the next token is a [, read the argument
{\@myacro{#1}[#1]}% otherwise pass #1 as default
}
\def\@myacro#1[#2]#3{%
\newcounter{#1}%
\expandafter\edef\csname#1Acrshort\endcsname{#2}
\expandafter\edef\csname#1Acrlong\endcsname{#3 (#2)}
}
\makeatother
\def\an#1{%
\stepcounter{#1}%
\ifnum\csname the#1\endcsname>1
\csname#1Acrshort\endcsname
\else
\csname#1Acrlong\endcsname
\fi
}
\myacro{cd}[CD]{Compact Disk}
\myacro{floppy}{Floppy Disk}
\begin{document}
This is a sample text \an{cd} This is a sample text \an{cd}.
This is a sample text \an{floppy} This is a sample text \an{floppy}.
\end{document}
或者您可以使用xparse
:\NewDocumentCommand
\documentclass{book}
\usepackage{xparse}
\NewDocumentCommand\myacro
{ m % mandatory
O{#1} % optional whose default is the same as #1
m } % mandatory again
{%
\newcounter{#1}%
\expandafter\edef\csname#1Acrshort\endcsname{#2}
\expandafter\edef\csname#1Acrlong\endcsname{#3 (#2)}
}
\def\an#1{%
\stepcounter{#1}%
\ifnum\csname the#1\endcsname>1
\csname#1Acrshort\endcsname
\else
\csname#1Acrlong\endcsname
\fi
}
\myacro{cd}[CD]{Compact Disk}
\myacro{floppy}{Floppy Disk}
\begin{document}
This is a sample text \an{cd} This is a sample text \an{cd}.
This is a sample text \an{floppy} This is a sample text \an{floppy}.
\end{document}
LaTeX\newcommand
在这里不起作用,因为它要求可选参数是第一个。
使用属性列表的稍微不同的方法不会消耗每个首字母缩略词的计数器,并允许您拥有一个可扩展的\an
命令:
\documentclass{book}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g_saravanan_acro_prop
\NewDocumentCommand \myacro { m O{#1} m }
{
\prop_gput:Nnn \g_saravanan_acro_prop { #1~short } { #2 }
\prop_gput:Nnn \g_saravanan_acro_prop { #1~long } { #3 }
\prop_gput:Nnn \g_saravanan_acro_prop { #1~full } { #3~(#2) }
}
\NewExpandableDocumentCommand\an{ O{short} m }
{ \prop_item:Nn \g_saravanan_acro_prop { #2~#1 } }
\ExplSyntaxOff
\myacro{cd}[CD]{Compact Disk}
\myacro{floppy}{Floppy Disk}
\begin{document}
This is a sample text \an[full]{cd} This is a sample text \an{cd}.
This is a sample text \an[full]{floppy} This is a sample text \an{floppy}.
\end{document}