\ProvidesPackage{scalerel}
[2014/03/10 v1.6
 Routines for constrained scaling and stretching of objects,
 relative to a reference object or in absolute terms]
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Steven B. Segletes.

% V1.01-Correct typos in documentation
% V1.1 -Corrected usepackage dependencies; Significant doc rewrite.
% V1.2 -Added \scaleleftright and \stretchleftright; revised docs.
% V1.3 -Corrected missing % in stretch routines, added \hstretch and
%       \vstretch commands; fixed version number in .sty file
% V1.4 -Auto-detect mathmode and style; use the proper math display
%       style; Allow \ignoremathstyle and \discernmathstyle to
%       revert to former approach in rare cases and return to new
%       approach.
%      -Added \Isnextbyte as a supplemental routine
%      -Added \scaleobj (like \scalebox, but defaults to math mode
%       using current display style).
% V1.5 -Eliminated mathstyle package because of incompatibilites with
%       many other packages.  Implemented \mathchoice approach instead.
% V1.6 -Made available \LMex and \LMpt lengths (Local Math ex and
%       Local Math pt), usable inside \ThisStyle arguments (1ex/pt in 
%       \textstyle and \displaystyle, 0.7ex/pt in \scriptstyle, and
%       0.5ex/pt in \scriptscriptstyle).
%      -Revised/shortened/improved \Isnextbyte.
%      -Replaced ifthen package calls with etoolbox calls.

\usepackage{calc}
\usepackage{graphicx}
\usepackage{etoolbox}
\global\newlength\thesrwidth
\global\newlength\thesrheight
\global\newlength\srblobheight
\global\newlength\srblobdepth
\global\newlength\mnxsrwidth
\newsavebox{\prebox}
\newlength\LMex
\newlength\LMpt
\def\scriptstyleScaleFactor{.7}
\def\scriptscriptstyleScaleFactor{.5}

\newcommand\scalerel{\@ifstar{\scalerelplain}{\scalerelplus}}

\newcommand\scalerelplain[3][99in]{\ThisStyle{%
  \sbox{\prebox}{\@obj{#2}}%
  \setbox0\hbox{\@obj{#3}}%
  \setlength\srblobheight{\ht0+\dp0}%
  \setlength\srblobdepth{\dp0}%
  \setbox0\hbox{\@obj{#2}}%
  \setlength\thesrwidth{\wd0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \setlength\thesrheight{\ht0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \setlength\mnxsrwidth{#1}%
  \ifdim\thesrwidth>\mnxsrwidth\setlength\thesrwidth{\mnxsrwidth}\fi%
  \raisebox{-\srblobdepth+\dp0*\ratio{\srblobheight}{\ht0+\dp0}}%
           {\resizebox{\thesrwidth}{\thesrheight}{\usebox{\prebox}}}%
  }%
}

\newcommand\scalerelplus[3][99in]{\scalerelplain[#1]{#2}{#3}#3}

\newcommand\stretchrel{\@ifstar{\stretchrelplain}{\stretchrelplus}}

\newcommand\stretchrelplain[3][10000]{\ThisStyle{%
  \sbox{\prebox}{\@obj{#2}}%
  \setbox0\hbox{\@obj{#3}}%
  \setlength\srblobheight{\ht0+\dp0}%
  \setlength\srblobdepth{\dp0}%
  \setbox0\hbox{\@obj{#2}}%
  \setlength\thesrwidth{\wd0}%
  \setlength\thesrheight{\ht0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \setlength\mnxsrwidth{\thesrheight*100/#1}%
  \ifdim\thesrwidth<\mnxsrwidth\setlength\thesrwidth{\mnxsrwidth}\fi%
  \raisebox{-\srblobdepth+\dp0*\ratio{\srblobheight}{\ht0+\dp0}}%
           {\resizebox{\thesrwidth}{\thesrheight}{\usebox{\prebox}}}%
  }%
}

\newcommand\stretchrelplus[3][10000]{\stretchrelplain[#1]{#2}{#3}#3}

\newcommand\scaleto[3][99in]{\ThisStyle{%
  \sbox{\prebox}{\@obj{#2}}%
  \setlength\srblobheight{#3}%
  \setlength\srblobdepth{0pt}%
  \setbox0\hbox{\@obj{#2}}%
  \setlength\thesrwidth{\wd0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \setlength\thesrheight{\ht0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \setlength\mnxsrwidth{#1}%
  \ifdim\thesrwidth>\mnxsrwidth\setlength\thesrwidth{\mnxsrwidth}\fi%
  \setlength\srblobdepth{\dp0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \raisebox{-\srblobdepth+\dp0*\ratio{\srblobheight}{\ht0+\dp0}}%
           {\resizebox{\thesrwidth}{\thesrheight}{\usebox{\prebox}}}%
  }%
}

\newcommand\stretchto[3][10000]{\ThisStyle{%
  \sbox{\prebox}{\@obj{#2}}%
  \setlength\srblobheight{#3}%
  \setlength\srblobdepth{0pt}%
  \setbox0\hbox{\@obj{#2}}%
  \setlength\thesrwidth{\wd0}%
  \setlength\thesrheight{\ht0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \setlength\mnxsrwidth{\thesrheight*100/#1}%
  \ifdim\thesrwidth<\mnxsrwidth\setlength\thesrwidth{\mnxsrwidth}\fi%
  \setlength\srblobdepth{\dp0*\ratio{\srblobheight}{\ht0+\dp0}}%
  \raisebox{-\srblobdepth+\dp0*\ratio{\srblobheight}{\ht0+\dp0}}%
           {\resizebox{\thesrwidth}{\thesrheight}{\usebox{\prebox}}}%
  }%
}

\def\bl@nk{\rule{-.01ex}{1ex}}

\newcommand\scaleleftright[4][99in]{%
  \if.#2\def\leftarg{\bl@nk}\else\def\leftarg{#2}\fi%
  \if.#4\def\rightarg{\bl@nk}\else\def\rightarg{#4}\fi%
  \scalerel[#1]{\leftarg}{#3}\scalerel*[#1]{\rightarg}{#3}%
}
\newcommand\stretchleftright[4][10000]{%
  \if.#2\def\leftarg{\bl@nk}\else\def\leftarg{#2}\fi%
  \if.#4\def\rightarg{\bl@nk}\else\def\rightarg{#4}\fi%
  \stretchrel[#1]{\leftarg}{#3}\stretchrel*[#1]{\rightarg}{#3}%
}

\newcommand\hstretch[2]{%
  \ThisStyle{\stretchrel*{\scalebox{#1}{\@obj{#2}}}{#2}}}

\newcommand\vstretch[2]{%
  \ThisStyle{\stretchrel*{#2}{\scalebox{#1}{\@obj{#2}}}}}

\newcommand\scaleobj[2]{%
  \ThisStyle{\scalebox{#1}{\@obj{#2}}}}

% DETERMINE IF THE SCALEREL ROUTINE WAS CALLED IN MATH MODE.
% IF SO, USE THE PROPER MATH DISPLAY STYLE FOR THE CALL,
% *UNLESS* THE FIRST CHARACTER OF THE ARGUMENT IS A $ SIGN,
% SIGNIFYING A DESIRED ESCAPE FROM MATH MODE FOR THE ARGUMENT.
\newcommand\@obj[1]{%
  \if T\@mmode%
    \Isnextbyte[q]{$}{#1}%
    \if F\theresult%
      $\SavedStyle#1$%
    \else%
      $#1$%
    \fi%
  \else%
    $#1$%
  \fi%
}

\let\sv@obj\@obj

\newcommand\discernmathstyle{\let\@obj\sv@obj}

% \ignoremathstyle WOULD BE USED RARELY, ONLY IF ONE WANTED TO USE
% DOLLAR ($) DELIMITERS IN THE *MIDDLE* OF A scalerel ARGUMENT
\newcommand\ignoremathstyle{\renewcommand\@obj[1]{$##1$}}

\def\@mstyleD{\displaystyle}
\def\@mstyleT{\textstyle}
\def\@mstyleS{\scriptstyle}
\def\@mstyles{\scriptscriptstyle}
%
\def\SavedStyle{\csname @mstyle\m@switch\endcsname}
%
\newcommand\ThisStyle[1]{%
  \ifmmode%
    \def\@mmode{T}\mathchoice%
      {\edef\m@switch{D}\LMex=1ex\relax\LMpt=1pt\relax#1}%
      {\edef\m@switch{T}\LMex=1ex\relax\LMpt=1pt\relax#1}%
      {\edef\m@switch{S}\LMex=\scriptstyleScaleFactor ex\relax%
                        \LMpt=\scriptstyleScaleFactor pt\relax#1}%
      {\edef\m@switch{s}\LMex=\scriptscriptstyleScaleFactor ex\relax%
                        \LMpt=\scriptscriptstyleScaleFactor pt\relax#1}%
  \else%
    \def\@mmode{F}%
    \edef\m@switch{T}\LMex=1ex\relax\LMpt=1pt\relax#1%
  \fi%
}
%

% THIS CAN REPLACE \isnextbyte IN STRINGSTRINGS PACKAGE
% BECAUSE IT WORKS ON CHARS THAT CAN'T BE \edef'ED (\dag, ETC.)
\newcommand\Isnextbyte[3][v]{%
  \def\SR@Letter@A{#2}%
  \SR@nextbyte{\SR@Letter@B}#3\relax\relax\relax%
  \ifdefstrequal{\SR@Letter@A}{\SR@Letter@B}%
    {\edef\theresult{T}}{\edef\theresult{F}}%
  \if q#1\else\theresult\fi%
}
\def\SR@nextbyte#1#2#3\relax{\def#1{#2}}

\endinput