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.

How can I give a box a minimal width, in math mode? That is, I would like a command something like \minwidth{exp}{width}, which will always typeset exp, but additionally, if the natural length of exp is less than width, will pad it by centering it in a box of width width.

For instance, $A \minwidth{i}{2em} B$ should come out like $A \makebox[2em][c]{i} B$; but $A \minwidth{WXYZ}{2em} B$ should come out like $A WXYZ B$.

The varwidth package provides this variable-width functionality, but only for a minipage, not for a plain box or similar.

(The use case is for a variant of the inline TikZ arrow commands defined in this answer, padding the arrow label to a minimal width, so that the arrow extends for large labels, but does not get too short when the label are short or absent.)

Edit: This turned out to be a bit of an XY problem: Harish Kumar has excellently answered my real problem, without answering this specific question. What I am now using, adapted from his answer, is:

\newcommand{\myto}[1][]{ \mathrel{
  \tikz[baseline={([yshift=-0.55ex]a.south)}]{%
    \node[minimum width=1.5em,align=center,inner xsep=0.3ex,inner ysep=0.15ex] (a) {$\scriptstyle #1$};
    \draw[->] (a.south west) -- ([xshift=0.6ex]a.south east);}
  }\mkern-1mu}

with usage as in $A \myto[f] B$.

I would still be interested in answers to the specific question asked, though.

share|improve this question

3 Answers 3

Here is a tikz only approach. Adjust exs suitably.

\documentclass{article}

\usepackage{tikz,mathtools}

\usetikzlibrary{arrows}

\newcommand*{\ident}[1]{\texttt{\small #1}}

\tikzstyle{refines} = [->, >=open triangle 45]

\newcommand{\refi}[3]{%
  \( #1 \)
  \tikz[baseline={([yshift=-0.5ex]a.south)}]{%
  \node[minimum width=2em,align=center] (a) {$#2$};     %%<<---- width here
  \draw[refines] (a.south west) --  ([xshift=1ex]a.south east);}   %% <<---- shift here
  \(#3 \)}

\begin{document}

This is a test \refi{\ident{1}}{\text{t}}{\ident{2}}\ident{2} that continues here.

This is a test \refi{1}{\text{longer text}}{1} that continues here.

A further test \refi{j_2}{\alpha-x e^{p/q}}{a^2} with more text.

\end{document}

enter image description here

The magic word here is minimum width=2em option for the node. I have also used some xshift for the arrow head to make it more symmetric. Adjust these values as you need.

share|improve this answer
    
Fantastic; thankyou! Some of the specifics of the linked question are irrelevant to my case, though, so I’ve ended up using a slightly different (maybe more generally applicable) version; see edit to question. –  Peter LeFanu Lumsdaine Jul 7 at 11:49

\makebox puts its contents into a box, whose dimensions are available as \width, \height, \depth inside the optional arguments of \makebox:

\documentclass{article}

\newcommand*{\minwidthbox}[2]{%
  \makebox[{\ifdim#2<\width\width\else#2\fi}]{#1}%
}

\begin{document}
  \noindent
  [\minwidthbox{i}{2em}]\\\relax
  [\minwidthbox{WXYZ}{2em}]
\end{document}

Result

Extended example with automatic math mode and style detection:

\documentclass{article}

\newcommand*{\minwidthbox}[2]{%
  \relax
  \ifmmode
    \mathpalette{\minwidthboxmath{#1}{#2}}{}%
  \else
    \makebox[{\ifdim#2<\width\width\else#2\fi}]{#1}%
  \fi
}
\newcommand*{\minwidthboxmath}[4]{%
  % #1: box contents
  % #2: minimum width
  % #3: math style
  % #4: unused
  \mbox{\minwidthbox{$#3#1$}{#2}}%
}

\begin{document}
  \noindent
  [\minwidthbox{i}{2em}]\\\relax
  [\minwidthbox{WXYZ}{2em}]

  \noindent
  $a\minwidthbox{i}{2em}b$\\
  $a\minwidthbox{WXYZ}{2em}b$
\end{document}

Result of extended example

share|improve this answer

Pushing further Heiko's idea, but letting mathtools do the job:

\documentclass{article}
\usepackage{mathtools}

\DeclareRobustCommand{\minwidthbox}[2]{%
  \ifmmode
    \expandafter\mathmakebox
  \else
    \expandafter\makebox
  \fi
  [\ifdim#2<\width\width\else#2\fi]{#1}%
}

\begin{document}
\noindent
[\minwidthbox{i}{2em}]\\\relax
[\minwidthbox{WXYZ}{2em}]

\noindent
$a\minwidthbox{i}{2em}b$\\
$a\minwidthbox{WXYZ}{2em}b$

\noindent
$A\xrightarrow{i}B$\\
$A\xrightarrow{\minwidthbox{i}{3em}}B$% exaggerated

\end{document}

enter image description here

share|improve this answer

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.