# Reformat \frac depending on numerator/denominator size difference

Is it possible to detect cases where the second argument of \frac is much smaller than the first argument, and split it? Namely (I'm using a new macro name \wfrac to simplify things),

\wfrac{x}{2} % => \frac{x}{2}
\wfrac{x+y}{2} % => \frac{1}{2}\left(x+y\right)
\wfrac{\sum_{i=1}^{N} i^3}{x+y+z+t}
% => \frac{1}{x+y+z+t} \left(\sum_{i=1}^{N} i^3\right)
% => or \left(\sum_{i=1}^{N} i^3\right) / \left(x+y+z+t\right)
\wfrac{\sum_{i=1}^{N} i^3}{\sum_{i=1}^{N} i}
% => \frac{...}{...} (unchanged)


Feel free to tell me that this is a bad idea.

EDIT: As David notes in his comment, it is not clear what I define as bigger/smaller. The third example in particular features a case where the numerator is taller, but the denominator is wider. he also notes that \wfrac{x}{y} could become (x)/(y). I am building the requirements as I write the question, so feel free to tweak them at your will.

\wfrac{x}{y} should become one of \frac{x}{y}, or \frac{1}{y}(x), or (x)/(y), with ()/ scaling as appropriate. Here is one scheme that could give nice results. Denote hx, hy the heights (plus depths) of x and y; wx, wy their widths; h0 and w0 customizable thresholds for what is considered "small", for instance the dimensions of the formula $a+b$, but probably the threshold should depend on the \mathstyle.

1. If hy < h0 and wy < w0,

1. If hx < h0 and wx < max(w0, 2 * wy), use \frac{x}{y}.
2. Otherwise use \frac{1}{y}(x).
2. Otherwise use (x)/(y).

• Is there something wrong with simply boxing up the top and bottom and then measuring them? – Joseph Wright Aug 1 '12 at 16:23
• Hmm, seems useful, maybe it can be merged into xfrac if possible. How about put the two args into boxes and measure them? – Leo Liu Aug 1 '12 at 16:24
• What's the criterion for "much smaller"? In the third example with cm fonts and textsyle setting, the denominator is wider than the numerator but you still split. (If splitting because something is big I think I'd favour changing to (#1)/(#2) rather than \frac{1}{#2}(#1) as it avoids cramping either argument. – David Carlisle Aug 1 '12 at 16:35
• @DavidCarlisle I tried to clarify my mind. Admittedly this is still not a good question. – Bruno Le Floch Aug 1 '12 at 17:08
• @barbarabeeton Thanks for the new title, I updated it somewhat toward what you propose. – Bruno Le Floch Aug 1 '12 at 17:52

I though this was an interesting question, so I gave it a try.
Let me start off with the result:

main.tex:

\documentclass{article}
\usepackage{wfrac}

\begin{document}
\setmaxeq{a+b} % Reference equation for size

$\wfrac{x}{2}$
$\wfrac{x+y}{2}$
$\wfrac{\sum_{i=1}^{N} i^3}{x+y+z+t}$
$\wfrac{\sum_{i=1}^{N} i^3}{\sum_{i=1}^{N} i}$

\setmax{34pt}{10pt} % Manual maximum size

$\wfrac{\sum_{i=1}^{N} i^3}{\sum_{i=1}^{N} i}$

\setmaxeq{x} % Reference equation again

$\wfrac{x}{x}$
$\efrac{x}{x}$
\end{document}


And it looks like this:

## Options:

• text: compare to the equation in \textstyle.
• display: compare to the equation in \displaystyle.
• none: compare to the equation in whatever style is currently active.
• noparen: no parentheses
• small: small maximum height and width
• big: big maximum height and width
• huge: huge maximum height and width
• lparen: set left paren, eg: lparen=\left[
• rparen: set right paren, eg: rparen={\right]}
• div: set division mark, eg: div=\div

## Commands

1. \wfrac: fraction following 'less' rules.
2. \efrac: fraction following 'less or equal' rules.
3. \setmax: set the maximum size.
4. \setmaxeq: set the maximum size using a reference equation.
5. \getmax: get the maximum size.
6. \getsize: get the size from an equation.
7. \setparen: set the parentheses, takes two arguments.
8. \setdiv: set the division mark.

And here is wfrac.sty:

\NeedsTeXFormat{LaTeX2e}[1994/12/01]
\ProvidesPackage{wfrac}[2012/11/03 v1.01 intelligent fractions]

% Lengths and widths
\newdimen \wfrac@hx
\newdimen \wfrac@hy
\newdimen \wfrac@hmax
\newdimen \wfrac@wx
\newdimen \wfrac@wy
\newdimen \wfrac@wmax
\newdimen \wfrac@wmaxcalc

% Parenthesis and division mark
\newcommand*{\wfrac@lparen}{\left(}
\newcommand*{\wfrac@rparen}{\right)}
\newcommand*{\wfrac@div}{\middle/}

% Options
\IfFileExists{xkeyval.sty}{
\RequirePackage{xkeyval}
\DeclareOptionX{lparen}{\renewcommand*{\wfrac@lparen}{##1}}
\DeclareOptionX{rparen}{\renewcommand*{\wfrac@rparen}{##1}}
\DeclareOptionX{div}{\renewcommand*{\wfrac@div}{##1}}
}{
\let\DeclareOptionX\DeclareOption
\let\ExecuteOptionsX\ExecuteOptions
\let\ProcessOptionsX\ProcessOptions
}

\DeclareOptionX{text}{\edef\wfrac@style{\textstyle}}
\DeclareOptionX{display}{\edef\wfrac@style{\displaystyle}}
\DeclareOptionX{none}{\edef\wfrac@style{}}
\DeclareOptionX{small}{\wfrac@wmax = 25pt \wfrac@hmax = 10pt}
\DeclareOptionX{big}{\wfrac@wmax = 50pt \wfrac@hmax = 50pt}
\DeclareOptionX{huge}{\wfrac@wmax = 100pt \wfrac@hmax = 100pt}
\ExecuteOptionsX{text,small}
\ProcessOptionsX\relax

% Fraction variations
\newcommand*{\wfrac@Afrac}[2]{\left. \wfrac@lparen #1 \wfrac@rparen \wfrac@div \wfrac@lparen #2 \wfrac@rparen \right.}
\newcommand*{\wfrac@Bfrac}[2]{\frac{1}{#2}\wfrac@lparen #1 \wfrac@rparen}
\newcommand*{\wfrac@Cfrac}[2]{\frac{#1}{#2}}

% Main commands
\newcommand*\setparen[2]{
\renewcommand*{\wfrac@lparen}{#1}
\renewcommand*{\wfrac@rparen}{#2}
}

\newcommand*\setdiv[1]{
\renewcommand*{\wfrac@div}{#1}
}

\newcommand*\setmax[2]{
\wfrac@wmax = #1
\wfrac@hmax = #2
}

\newcommand*\setmaxeq[1]{
\settowidth{\wfrac@wmax}{$\wfrac@style #1$}
\settoheight{\wfrac@hmax}{$\wfrac@style #1$}
}

\newcommand*\getmax{
\the\wfrac@wmax $\times$ \the\wfrac@hmax
}

\newcommand*\getsize[1]{
\settowidth{\wfrac@wx}{$\wfrac@style #1$}
\settoheight{\wfrac@hx}{$\wfrac@style #1$}
\the\wfrac@wx $\times$ \the\wfrac@hx
}

\newcommand*\wfrac[2]{
\settowidth{\wfrac@wx}{$\wfrac@style #1$}
\settowidth{\wfrac@wy}{$\wfrac@style #2$}
\settoheight{\wfrac@hx}{$\wfrac@style #1$}
\settoheight{\wfrac@hy}{$\wfrac@style #2$}
% max(w0, 2 * wy)
\ifdim \wfrac@wmax < 2\wfrac@wy
\wfrac@wmaxcalc = 2\wfrac@wy
\else
\wfrac@wmaxcalc = \wfrac@wmax
\fi
%
\ifdim \wfrac@hy < \wfrac@hmax
\ifdim \wfrac@wy < \wfrac@wmax
\ifdim \wfrac@hx < \wfrac@hmax
\ifdim \wfrac@wx < \wfrac@wmaxcalc
\let\wfrac@frac=\wfrac@Cfrac
\else
\let\wfrac@frac=\wfrac@Bfrac
\fi
\else
\let\wfrac@frac=\wfrac@Bfrac
\fi
\else
\let\wfrac@frac=\wfrac@Afrac
\fi
\else
\let\wfrac@frac=\wfrac@Afrac
\fi
%
\wfrac@frac{#1}{#2}
}

\newcommand*\efrac[2]{
\settowidth{\wfrac@wx}{$\wfrac@style #1$}
\settowidth{\wfrac@wy}{$\wfrac@style #2$}
\settoheight{\wfrac@hx}{$\wfrac@style #1$}
\settoheight{\wfrac@hy}{$\wfrac@style #2$}
% max(w0, 2 * wy)
\ifdim \wfrac@wmax < 2\wfrac@wy
\wfrac@wmaxcalc = 2\wfrac@wy
\else
\wfrac@wmaxcalc = \wfrac@wmax
\fi
%
\ifdim \wfrac@hy > \wfrac@hmax
\let\wfrac@frac=\wfrac@Afrac
\else
\ifdim \wfrac@wy > \wfrac@wmax
\let\wfrac@frac=\wfrac@Afrac
\else
\ifdim \wfrac@hx > \wfrac@hmax
\let\wfrac@frac=\wfrac@Bfrac
\else
\ifdim \wfrac@wx > \wfrac@wmaxcalc
\let\wfrac@frac=\wfrac@Bfrac
\else
\let\wfrac@frac=\wfrac@Cfrac
\fi
\fi
\fi
\fi
%
\wfrac@frac{#1}{#2}
}

\endinput

• Great suggestions! I've added a new version of wfrac.sty. It includes the \setparen{...}{...} and \setdiv{...} commands to change the parentheses and division mark. I've also added options: text, display, none, noparen, small, big, huge, lparen, rparen and div. – Silke Nov 3 '12 at 12:36
• It would be even nicer to control the presence of absence of parentheses for the numerator and denominator of each fraction independently: I am thinking of the case where a numerator or denominator is a single object. For instance, \wfrac[paren = num]{x+y}{e^{i\pi xyz}} could give (x+y)/e^{i\pi xyz}. The values of the paren option would be num, denom, none, both or variants of that. That is actually not enough for cases like \wfrac{\sum_j x_j}{y}, for which correct forms are \frac{#1}{#2}, (#1)/#2, and \frac{1}{#2}#1, with parentheses or not around #1. – Bruno Le Floch Nov 3 '12 at 17:09