如何定义带有数字的宏?

如何定义带有数字的宏?

可能重复:
定义包含数字的命令/缩写

我如何将宏定义为\text1\text2... \text3 ,当调用时会产生具有不同宽度的文本?

答案1

有很多种方法可以实现这一点:

1)假设,您只需要 text0......text9最简单的方法是欺骗您的用户您正在提供一个命令\textn,而实际上您只提供了一个参数宏,定义如下:

  \def\text#1{...}

注意text已定义,amsmath因此您将覆盖它。

2) 您可以为用户定义不同的环境。鲜为人知的事实是,LaTeX 环境可以使用任意字符组合。这些可以称为:

  \begin{text1}...\end{text1} 

3)最难采用的方法是通过控制序列

  \expandafter\def\csname...\endcsname 

这是宏编写者常用的技术,特别是如果你想要自动化这个过程并且有一个算法来自动定义这些命令。使用这种类型的定义的缺点是你不能直接调用这样的宏。你也需要使用 来调用它\csname...\endcsname。LaTeX 提供了等效的包装器\@namedef\@nameuse,我在下面最简的文件中将其用作最后一个定义。

附加事实。我在代码中使用了 TeX,将文本中每个 的\narrower左右缩进分别增加了一个\leftskip和。\rightskip\narrower

我还使用了 \usepackage[latin]{babel}以便正确地将拉丁语连字符化,因为在第一次运行 MWE 时,有些单词很不好看!拉丁语由包生成lipsum,它提供了用于测试的示例段落。

最后,我不建议使用这样的宏名因为它们在语义上不正确,\text1代表的是引文、章节还是其他内容?而是花了一些时间来确定文档的主要结构组件,并用适当的名称定义它们。

\documentclass{article}
\usepackage{lipsum}
\usepackage[latin]{babel}
\begin{document}
\def\text#1{\ifnum#1=1
          \leavevmode
          \narrower\narrower\narrower\narrower 
          \marginpar{Type 1} 
       \else
          \ifnum#1=2 
            \leavevmode
            \narrower\narrower\narrower
            \narrower\narrower\narrower 
            \marginpar{Type 2}
          \else
            \relax
       \fi\fi}
{\text1
\lipsum[1]}
{\text2
\lipsum[1]}
\newenvironment{text1}
{\bgroup \leavevmode \narrower\narrower\narrower
 \marginpar{Type 1 text}}
{\egroup }
\newenvironment{text2}
{\bgroup\leavevmode 
 \narrower\narrower\narrower
 \narrower\narrower\narrower     
 \marginpar{Type 2 text}}
{\egroup }
\begin{text1}
\lipsum[1]
\end{text1}
\begin{text2}
\lipsum[1]
\end{text2}
\expandafter\def\csname Text1\endcsname{\leavevmode
          \narrower\narrower\narrower
          \marginpar{csname Type 1}}
\makeatletter
\@namedef{Text2}{\leavevmode
          \narrower\narrower\narrower
          \narrower\narrower\narrower
          \marginpar{defined using @namedef Type 2}}
{\csname Text1\endcsname
\lipsum[1]}
{\@nameuse{Text2}
\lipsum[1]}
\makeatother

\texttt{\meaning\narrower}
\end{document}

答案2

TeX FAQ 中有关于宏名称中的非字母(其中一项建议是“为你的宏选择另一个名称,一个仅包含普通字母的名称”

答案3

您不能定义名称中带有数字的宏,因为宏名称的所有部分都必须由类别中的字符组成(类别代码 11)且 0-9 数字来自类别其他(类别代码 12)。TeX 似乎只在它们属于这个类别时才将它们识别为数字,因此更改这一点会破坏一切。

正如 Yiannis Lazarides 所提到的,您可以定义一个将数字作为第一个参数的宏。只要它只有一位数字(0-9),它就可以不用括号!然后您可以在宏中使用\ifcase或使用使用罗马数字的内部宏:

\documentclass{article}

\newcommand*{\test}[1]{\csname test\romannumeral#1\endcsname}
\newcommand*{\testi}[1]{{\tiny#1}}
\newcommand*{\testii}[1]{{\scriptsize#1}}
\newcommand*{\testiii}[1]{{\footnotesize#1}}
\newcommand*{\testiv}[1]{{\small#1}}
\newcommand*{\testv}[1]{{{\normalsize#1}}
\newcommand*{\testvi}[1]{{\large#1}}
\newcommand*{\testvii}[1]{{\Large#1}}
\newcommand*{\testviii}[1]{{\LARGE#1}}
\newcommand*{\testix}[1]{{\Huge#1}}

\begin{document}
\par\test1{text}
\par\test2{text}
\par\test3{text}
\par\test4{text}
\par\test5{text}
\par\test6{text}
\par\test7{text}
\par\test8{text}
\par\test9{text}
\end{document}

内部宏不需要接受参数。

例如\ifcase

\newcommand*{\test}[1]{%
    \ifcase#1%
    \relax % 0
      \tiny
    \or % 1
      \scriptsize
    \or % 2
      ...
    \or % 3
      ...
      ...
      ...
    \or % 8
      ...
    \or % 9
      ...
    \else % everything else
      ...
    \fi
}

相关内容