我想创建一个\openball[<optional size>]{<radius>}{<center>}
宏
\mathrm{B}_{<radius>}^\circ \lparen <center> \rparen
如果没有给出可选参数,并且
\mathrm{B}_{<radius>}^\circ <optional size>\lparen <center> <optional size>\rparen
如果给出了大小参数。因此示例用法如下:
\openball[\big]{ \varepsilon }{ \tfrac{1}{2} }
实现这一目标的最干净的方法是什么?
答案1
下面是与用途类似的实现mathtools
,使用 实现xparse
。
更新,添加如果半径参数为空,则\varepsilon
使用。
更新,现在也评论了
\documentclass[a4paper]{memoir}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\BB{s o m m} {%
\mathrm{B}
% add the subscript, _ is special in expl3, so we use \sb. We combine
% with a test on #3, if empty use \varepsilon
\sb{
\tl_if_blank:nTF {#3} {\varepsilon} {#3}
}
% if * is active we use \left...\right, modified with proper groups
\IfBooleanTF{#1}{%
\mathopen{}\mathclose\bgroup
\left( #4
\aftergroup\egroup
\right)
}{
% if no * we look for optional arg which is assumed to be a
% \big..., if none, just use normal ()'s
\IfNoValueTF{#2}{
( #4 )
}{
% if there is strip the \ from the [] arg, and append l and r to
% get the proper variants
\use:c {\cs_to_str:N #2 l} (
#4
\use:c {\cs_to_str:N #2 r} )
}
}
}
\ExplSyntaxOff
\begin{document}
\[
\BB{s}{b} \BB{}{b}\BB*{2}{\frac12} \BB[\Big]{3}{\sum_i}
\]
\end{document}
答案2
你可以一石二鸟:
\documentclass{article}
\usepackage{mathtools,xparse}
\DeclarePairedDelimiter{\paren}{(}{)}
\NewDocumentCommand{\ball}{t+ s O{} m m}{
% #1 is the possible +
% #2 is the possible *
% #3 is the optional size
% #4 is the radius
% #5 is the center
\mathrm{B}_{#4}\IfBooleanF{#1}{^\circ}
\IfBooleanTF{#2}
{\paren*{#5}}
{\paren[#3]{#5}}
}
\begin{document}
\[
\ball{s}{b}
\quad
\ball+{s}{b}
\quad
\ball*{2}{\frac{1}{2}}
\quad
\ball+*{2}{\frac{1}{2}}
\quad
\ball[\Big]{3}{\frac{1}{2}}
\]
\end{document}
呼叫\ball+
将排版封闭的球。
如果你想用 来表示封闭的球\bar{B}
,这很容易:改变线
\mathrm{B}_{#4}\IfBooleanF{#1}{^\circ}
进入
\IfBooleanTF{#1}{\bar{\mathrm{B}}}{\mathrm{B}^{\circ}}_{#4}
完整定义
\NewDocumentCommand{\ball}{t+ s O{} m m}{
% #1 is the possible +
% #2 is the possible *
% #3 is the optional size
% #4 is the radius
% #5 is the center
\IfBooleanTF{#1}{\bar{\mathrm{B}}}{\mathrm{B}^{\circ}}_{#4}
\IfBooleanTF{#2}
{\paren*{#5}}
{\paren[#3]{#5}}
}
输出将是
一种不同的方法,具有键值接口;如果未设置半径,则默认为\varepsilon
。
\documentclass{article}
\usepackage{mathtools,xparse}
\DeclarePairedDelimiter{\paren}{(}{)}
\ExplSyntaxOn
\NewDocumentCommand{\ball}{O{}m}
{
\group_begin:
\keys_set:nn { dorian/ball } { #1 }
% the B
\bool_if:NTF \l_dorian_ball_open_bool
{ \mathrm{B}\sp{\circ} }
{ \bar{\mathrm{B}} }
% radius
\sb{\l_dorian_ball_radius_tl}
%
\bool_if:NTF \l_dorian_ball_expand_bool
{ \paren* }
{ \exp_last_unbraced:NNo \paren[\l_dorian_ball_size_tl] }
{#2}
\group_end:
}
\bool_new:N \l_dorian_ball_expand_bool
\tl_new:N \l_dorian_ball_size_tl
\keys_define:nn { dorian/ball }
{
c .bool_set_inverse:N = \l_dorian_ball_open_bool,
c .default:n = true,
c .initial:n = false,
r .tl_set:N = \l_dorian_ball_radius_tl,
r .initial:n = \varepsilon,
size .code:n =
\str_if_eq:nnTF { * } { #1 }
{ \bool_set_true:N \l_dorian_ball_expand_bool }
{ \tl_set:Nn \l_dorian_ball_size_tl { #1 } },
}
\ExplSyntaxOff
\begin{document}
\[
\ball[r=s]{b}
\quad
\ball[c,r=s]{b}
\quad
\ball[size=*,r=2]{\frac{1}{2}}
\quad
\ball[c,size=*,r=2]{\frac{1}{2}}
\quad
\ball[size=\Big]{\frac{1}{2}}
\]
\end{document}
答案3
\newcommand*\openball[3][\relax]{\mathrm{B}^{\circ}_{#2}\mathopen{#1\lparen}#3\mathclose{#1\rparen}}
答案4
保持逗号分隔的语法:
\documentclass{article}
\usepackage{mathtools}
\def\radiusandcenter#1{\expandafter\splitatcomma#1\end}%
\def\splitatcomma#1,#2\end{\def\radius{#1}\def\center{#2}}%
\newcommand{\openball}[2][]{%
\radiusandcenter{#2}%
\mathrm{B}_{\radius}^\circ\mathopen{#1\lparen}\center\mathclose{#1\rparen}%
}
\begin{document}
\(\openball{\varepsilon,\tfrac{1}{2}}\)
\(\openball[\big]{\varepsilon,\tfrac{1}{2}}\)
\(\openball[\bigg]{\varepsilon,\tfrac{1}{2}}\)
\end{document}