我想定义一个命令\myfrac
,该命令接受 2 个参数,#1 / #2
如果它是文本样式(例如$\myfrac 1 2$
)则返回,\frac{#1}{#2}
如果它是显示样式(例如\[ \myfrac 1 2 \]
)则返回。
是否有任何命令,如\ifinline
检查样式,或者是否有任何替代方案\myfrac
?
答案1
请尝试使用以下标签:
\documentclass{book}
\usepackage{amsmath}
\begin{document}
\newcommand{\myfrac}[2]{#1/#2}
\everydisplay{\let\myfrac\frac}
$\myfrac1 2$
\[
\myfrac1 2
\]
\end{document}
答案2
你可以使用\mathchoice
它。它需要四个参数(用于所有四种数学模式),并在显示模式下排版第一个参数,在文本模式下排版第二个参数,在脚本和脚本模式下排版其余参数。以下代码可以说明这一点:
\documentclass{article}
\newcommand{\myfrac}[2]{\mathchoice{\frac{#1}{#2}}{#1/#2}{#1/#2}{#1/#2}}
\newcommand{\myfraca}[2]{\mathchoice{\frac{#1}{#2}}{(#1)/(#2)}{(#1)/(#2)}{(#1)/(#2)}}
\begin{document}
Text mode \(\myfrac12\). Display mode \[\myfrac12.\]
This is fine: \[\myfrac{x+y}{z+1},\] but this isn't: \(\myfrac{x+y}{z+1}\).
Both are fine: \[\myfraca{x+y}{z+1},\] \(\myfraca{x+y}{z+1}\).
But in this case parentheses are awful: \[\myfraca{x}{z},\] \(\myfraca{x}{z}\).
\end{document}
但正如您所见,使用\mathchoice
不太适合您想要的分数,因为它们有时需要括号,有时则不需要。上述代码的结果如下:
答案3
新答案
此版本检查单个标记,但忽略一组上标和下标,因此这应该比下面的版本产生更好的结果。此外,除了带星号的变体(永远不会使用括号)之外,无星号变体的可选参数可用于控制应将哪个参数放在括号中(none
或n
、first
或1
、second
或2
、both
或b
—— 因此\myfrac*
与 相同\myfrac[n]
)。
注意:由于我总是很难记住正确的 LaTeX2e 宏接口\protected
,因此以下使用简单的语法\protected\def
...
\documentclass{article}
\usepackage{expkv-def}
\makeatletter
% key=val interface (no =val here, so key interface?)
\ekvdefinekeys{myfrac}
{
nmeta none = n
,protected noval n =
\let\myfrac@dividend\@firstoftwo
\let\myfrac@divisor \@firstoftwo
,nmeta first = 1
,protected noval 1 =
\let\myfrac@dividend\@secondoftwo
\let\myfrac@divisor \@firstoftwo
,nmeta second = 2
,protected noval 2 =
\let\myfrac@dividend\@firstoftwo
\let\myfrac@divisor \@secondoftwo
,nmeta both = b
,protected noval b =
\let\myfrac@dividend\@secondoftwo
\let\myfrac@divisor \@secondoftwo
}
% shortcut for \ekvset{myfrac}
\protected\ekvsetdef\myfrac@kv{myfrac}
% borrow a robust test from expl3
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_if_single:nTF { o }
\cs_new_eq:NN \myfrac@ifsingle \tl_if_single:oTF
\ExplSyntaxOff
% macro implementation
\protected\def\myfrac{\begingroup\@ifstar{\myfrac@kv{n}\myfrac@do}\myfrac@}
\protected\def\myfrac@{\ekvoptargTF\myfrac@manual\myfrac@auto}
% optional argument given, should specify the rules for parenthesis
\protected\def\myfrac@manual#1%
{%
\myfrac@kv{#1}%
% error detection
\unless\ifdefined\myfrac@dividend
\GenericError
{}{myfrac Error: Missing specification in optional argument}{}{}%
\expandafter\@firstoftwo\expandafter\myfrac@auto
\fi
\myfrac@do
}
% no optional argument given, so we need to test and decide
\protected\def\myfrac@auto#1#2%
{%
\myfrac@decide\myfrac@dividend{#1}%
\myfrac@decide\myfrac@divisor {#2}%
\myfrac@do{#1}{#2}%
}
% everything determined, so output
\protected\def\myfrac@do#1#2%
{%
\mathchoice
{\frac{#1}{#2}}
{\myfrac@enquote{#1}{#2}}
{\myfrac@enquote{#1}{#2}}
{\myfrac@enquote{#1}{#2}}%
\endgroup
}
% output helper
\def\myfrac@enquote#1#2{\myfrac@dividend{#1}{(#1)}/\myfrac@divisor{#2}{(#2)}}
% set things up for strip
\protected\def\myfrac@decide#1#2%
{\myfrac@strip\@empty#2\myfrac@mark ^{}_{}\myfrac@stop#1}
% remove first superscript
\protected\def\myfrac@strip#1^#2{\myfrac@strip@#1}
% remove first subscript
\protected\def\myfrac@strip@#1_#2{\myfrac@decide@#1}
% check if now only a single token/group is left
\protected\def\myfrac@decide@#1\myfrac@mark#2\myfrac@stop#3%
{\myfrac@ifsingle{#1}{\let#3\@firstoftwo}{\let#3\@secondoftwo}}
\makeatother
% test command so that I don't need to type as much in the document body.
\newcommand\mytest[3][]
{%
% not-so-robust empty-arg test (fine for the input below)
\ifx\relax#1\relax
Text mode \(\myfrac{#2}{#3}\). Display mode \[\myfrac{#2}{#3}.\]%
\else
\texttt{#1}:
Text mode \(\myfrac[#1]{#2}{#3}\). Display mode \[\myfrac[#1]{#2}{#3}.\]%
\fi
}
\begin{document}
\section{automatic}
\mytest{x+y}{z+1}
\mytest{x_y}{z_1}
\mytest{x_y^2}{z_1+2}
\section{manual}
Starred: \(\myfrac*{x_y}{z_1},\) \[\myfrac*{x_y}{z_1}.\]
\mytest[first]{x}{z}
\mytest[second]{x}{z}
\mytest[both]{x}{z}
\mytest[none]{x+y}{z+1}
\end{document}
旧答案
这个测试一个参数中有多少个标记\myfrac
,如果有多个,则将它们括在括号中。带星号的版本不使用该检查。
\documentclass{article}
\makeatletter
\def\my@enparen#1#2;{%
\ifx\relax#2\relax%
#1%
\else%
(#1#2)%
\fi}
\newcommand{\myfrac}{\@ifstar{\@myfrac}{\@@myfrac}}
\newcommand{\@myfrac}[2]{\mathchoice{\frac{#1}{#2}}{#1/#2}{#1/#2}{#1/#2}}
\newcommand{\@@myfrac}[2]{\mathchoice{\frac{#1}{#2}}{\my@enparen#1;/\my@enparen#2;}{\my@enparen#1;/\my@enparen#2;}{\my@enparen#1;/\my@enparen#2;}}
\begin{document}
Text mode \(\myfrac{x+y}{z+1}\). Display mode \[\myfrac{x+y}{z+1}.\]
This is fine: \[\myfrac{x_y}{z_1},\] but this isn't: \(\myfrac{x_y}{z_1}\).
Both are fine: \[\myfrac*{x_y}{z_1},\] \(\myfrac*{x_y}{z_1}\).
\end{document}