第二个参数设置为选项

第二个参数设置为选项

我制作了以下宏来生成自定义缩写

\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}

相关内容