我正在尝试创建一个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 不允许使用“先看”命令,而只允许“后看”(例外情况是诸如\over
LuaTeX 回调之类的原语来改变处理流程)。因此,处理这两种情况的唯一方法是让它们“知道”接下来会发生什么。因此,例如可以这样做
\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
的目标,其中一部分就是区分“添加到下一个单元的能力”和“添加到上一个单元的能力”。