我需要制作一个满足以下条件的智能矢量命令:
- 有三个参数:可选的第一个参数指定分隔符(默认为逗号);必需的第二个参数指定一个或多个以逗号分隔的组件,这些组件可以是数字或数学表达式;可选的第三个参数指定物理单位。
如果使用 调用该命令,
\smartvector{2,4,3}[m]
则它应该将数字排版为尖括号中的分隔列表,由要求 1 中指定的分隔符分隔,单位位于右括号外。逗号分隔列表中的所有条目都必须是数字。请参阅下面的 MWE;我已经让它工作了。请注意,单位是可选的,可以省略。这是一个例子。我想添加调用命令的功能,
\smartvector{2}[m]
并让它只排版数字和单位,不带括号或逗号。所以我认为我需要测试强制第二个参数中的逗号分隔列表是否是单个数字。这是一个例子。如果逗号分隔的列表包含任何非数字项,则应
\smartvector{2x^2,y^3,2}
按照要求 2 进行排版,但必须省略单位。用户会知道省略单位,因为代数表达式没有单位。以下是一个例子。
因此,我认为归根结底是解析逗号分隔列表并执行一些逻辑,但我必须承认我不理解 MWE 的这一部分,这是另一个线程提供给我的。我不想再犯货物崇拜编程的错误了。
这是我的 MWE:
\documentclass[10pt]{article}
\usepackage{xargs}
\makeatletter
\newcommandx\smartvector[3][1={,},3=,usedefault]{\ensuremath{%
\global\def\smart@delim{#1}%
\left\langle
\smart@vector #2,\relax\noexpand\@eolst%
\right\rangle{\;#3}}}%
\def\smart@vector #1,#2\@eolst{%
\ifx\relax#2\relax
#1
\else
#1\smart@delim
\smart@vector #2\@eolst%
\fi}
\makeatother
\newcommand{\m}{\ensuremath{\mathrm{m}}}
\begin{document}
\[
\smartvector{2,4,3}[\m]
\]
\end{document}
答案1
如果我理解正确的话,以下应该有效:
- 在我看来,如果用户知道省略单位,则您的情况 (1) 和 (3) 是相同的。以下内容做出了这一假设。
\documentclass{article}
\usepackage{xparse}
\usepackage{mathtools}
\ExplSyntaxOn
\NewDocumentCommand{\smartvector}{ O{,} m O{} }
{
\smart_vector:nnn {#1}{#2}{#3}
}
\cs_new:Npn \smart_vector:nnn #1#2#3
{
\tl_set:Nn \l_tmpa_tl {#2}
\tl_replace_all:Nnn \l_tmpa_tl {,}{#1}
\tl_if_blank:nTF {#3}
{
\langle \tl_use:N \l_tmpa_tl \rangle
}
{
\tl_if_in:NnTF \l_tmpa_tl {#1}
{
\langle\tl_use:N \l_tmpa_tl\rangle\ \mathrm{#3}
}
{
\tl_use:N \l_tmpa_tl\ \mathrm{#3}
}
}
}
\ExplSyntaxOff
\begin{document}
$\smartvector[;]{1,2,3}[m/s]$\par
$\smartvector{1,2}$\par
$\smartvector{1}[m]$\par
$\smartvector{x^2,y^2}$\par
\end{document}
答案2
一个较短的 LaTeX3 版本,使用了最近添加的功能 ( \seq_use:Nnnn
);我也使用它siunitx
作为单位。
\documentclass{article}
\usepackage{siunitx,xparse}
\ExplSyntaxOn
\NewDocumentCommand{\smartvector}{ O{,} m o }
{
\joe_smart_vector:nn { #1 } { #2 }
\IfValueT{#3}{\,\si{#3}}
}
\seq_new:N \l__joe_list_seq
\cs_new_protected:Npn \joe_smart_vector:nn #1 #2
{
\seq_set_split:Nnn \l__joe_list_seq { , } { #2 }
\int_compare:nF { \seq_count:N \l__joe_list_seq = 1 } { \langle }
\seq_use:Nnnn \l__joe_list_seq { #1 } { #1 } { #1 }
\int_compare:nF { \seq_count:N \l__joe_list_seq = 1 } { \rangle }
}
\ExplSyntaxOff
\begin{document}
$\smartvector[;]{1,2,3}[m/s]$\par
$\smartvector{1,2}$\par
$\smartvector{1}[m]$\par
$\smartvector{x^2,y^2}$\par
\end{document}