测试内联数学模式

测试内联数学模式

我想定义一个命令\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

基于@SergeiGolovan 的回答

新答案

此版本检查单个标记,但忽略一组上标和下标,因此这应该比下面的版本产生更好的结果。此外,除了带星号的变体(永远不会使用括号)之外,无星号变体的可选参数可用于控制应将哪个参数放在括号中(nonenfirst1second2bothb—— 因此\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}

在此处输入图片描述

相关内容