命令前后可以带有参数吗?

命令前后可以带有参数吗?

我正在尝试创建一个LaTeX3命令,无论其参数位于命令之前还是之后,其工作方式都相同。例如,我想\squared将 定义为\m\squared或 ,\squared\m其中\m定义为\mathrm{m}。两者都应产生$\mathrm{m}^2$。以下是我一直在使用的标记。

\documentclass[10pt]{article}
\usepackage{xparse}

\newcommand*{\unit}[2]{\ensuremath{#1\;#2}}
\newcommand*{\metre}{\ensuremath{\mathrm{m}}}
\newcommand*{\m}{\metre}

\DeclareDocumentCommand \square { m } {%

  \IfNoValueTF #1 {%
    $^2$
  }{%
    $#1^2$
  }%
}%

\begin{document}

The command used as a prefix gives \square\m.

The command used as a postfix gives \m\square\ .

\end{document}

第一个例子排版正确,除了一个我无法解释的换行符,但第二个例子在和指数之间也有换行符\m。我尝试将参数设为可选,但也没有用。

如果我所想到的构造不可行也没关系,因为我可以在参数之前和之后使用略有不同的命令。

答案1

一般来说,TeX 不允许使用“先看”命令,而只允许“后看”(例外情况是诸如\overLuaTeX 回调之类的原语来改变处理流程)。因此,处理这两种情况的唯一方法是让它们“知道”接下来会发生什么。因此,例如可以这样做

\documentclass{article}
\newcommand*{\metre}{%
  \ensuremath{\mathrm{m}}%
}
\newcommand*{\m}{\metre}
\makeatletter
\newcommand*{\square}{%
  \@ifnextchar\metre
    {\square@aux}
    {%
      \@ifnextchar\m
        {\square@aux}
        {\ensuremath{^{2}}}%
    }%
}
\newcommand{\square@aux}[1]{%
  \ensuremath{#1^{2}}%
}
\begin{document}
The command used as a prefix gives \square\m.

The command used as a postfix gives \m\square.
\end{document}

它会提前查看后面的标记\square并做出相应的选择。您会发现,对于一长串的单元来说,这会变得难以处理:一种可能的解决方法是在每个单元的开头使用“标记标记”,进行部分扩展,然后检查该标记。这可能看起来像

\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\let\joeh@unit@marker\relax
\newcommand*{\metre}{%
  \joeh@unit@marker
  \@firstofone{\ensuremath{\mathrm{m}}}% \@firstofone needed to remove "{" and "}"
}
\newcommand*{\m}{\metre}
\newcommand*{\square}{%
  \expandafter\square@aux@i
  \romannumeral-`0%
}
\newcommand{\square@aux@i}{%
  \@ifnextchar\joeh@unit@marker % Tests by meaning
    {\square@aux@ii}
    {\ensuremath{^{2}}}%
}
\newcommand{\square@aux@ii}[1]{%
  \ifnum\pdf@strcmp{\unexpanded{#1}}{\unexpanded{\joeh@unit@marker}}=\z@
    \expandafter\square@aux@iii
  \else
    \expandafter\square@aux@iv
  \fi
    {#1}%
}
\newcommand{\square@aux@iii}[3]{%
  % #1 = \joeh@unit@marker
  % #2 = \@firstofone
  % #3 = Unit code
  \ensuremath{#3^{2}}%
}
\newcommand{\square@aux@iv}[1]{%
  #1%
  \ensuremath{^{2}}%
}
\begin{document}
The command used as a prefix gives \square\m.

The command used as a postfix gives \m\square.
\end{document}

您会发现这有点棘手,特别是涵盖许多情况。

更大的问题出现在更复杂的单位上。例如,

\m\square\kg

到底是什么意思?在更复杂的情况下,正确处理间距和含义是我们siunitx的目标,其中一部分就是区分“添加到下一个单元的能力”和“添加到上一个单元的能力”。

相关内容