Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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).

share|improve this question
3  
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
add comment

1 Answer

up vote 7 down vote accepted

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:

result

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{noparen}{\renewcommand*{\wfrac@lparen}{}\renewcommand*{\wfrac@rparen}{}}
\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
share|improve this answer
    
Nice! It might be better to define \newcommand*{\wfrac@Afrac}[2]{\left.\left(#1\right)\middle/\left(#2\right)\righ‌​t.}, \newcommand*{\wfrac@Bfrac}[2]{\frac{1}{#2}\left(#1\right), and \newcommand*{\wfrac@Cfrac}[2]{\frac{#1}{#2}}, and in the nested conditionals use \let\wfrac@frac=\wfrac@Afrac (or Bfrac, Cfrac...), and outside the conditionals call \wfrac@frac{#1}{#2}. This is a bit safer to allow for arbitrary arguments #1 and #2. Also, it would be nice to provide a variant which does not add parentheses in the A and B forms, but I am not sure what syntax is best. –  Bruno Le Floch Nov 3 '12 at 11:35
    
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. –  Silex 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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.