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.

I would like to make a macro, \vfrac, which output would look like:

$$\displaylines{
  \displaystyle\raise.25ex\hbox{$\displaystyle1$}\!/\!\lower.5ex\hbox{$\displaystyle2$} \cr
  \textstyle\raise.25ex\hbox{$\textstyle1$}\!/\!\lower.5ex\hbox{$\textstyle2$}\cr
  \scriptstyle\raise.25ex\hbox{$\scriptstyle1$}\!/\!\lower.5ex\hbox{$\scriptstyle2$}\cr
  \scriptscriptstyle\raise.25ex\hbox{$\scriptscriptstyle1$}\!/\!\lower.5ex\hbox{$\scriptscriptstyle2$}\cr
}$$

enter image description here

I use the plain-format, so I tried to follow the TeXbook Appendix B:

\catcode`@=11
\def\vfrac#1#2{\mathpalette\vfr@c{#1}{#2}}
\def\vfr@c#1#2{\raise.5ex\hbox{$#1$}/\lower.25ex\hbox{$#2$}}
\catcode`@=12
$\vfrac{1}{2} \quad {}^{\vfrac12}$

which looks like

enter image description here

What is this I don't even...

Oh wait, it looks like it's taking the "1" as the second argument. A quick search through tex.sx gives me Hendrik's question, where he just gives an empty first argument to \mathpalette. However, when I try that in my above macro, I get an error ! Argument of \vfr@c has an extra }.

I'm at loss. How does \mathpalette work?

share|improve this question
    
Does defining \vfrac using \def\vfrac#1#2{\mathpalette\relax{\vfr@c{#1}{#2}}} or \def\vfrac#1#2{\mathpalette{\vfr@c{#1}{#2}}\relax} solve your problem? –  Werner Nov 10 '11 at 19:15
    
@Werner: it fixed the correct reading of arguments, but the \hbox contents do not get the correct size (now that I think about it, how could they). I should somehow be able to put the first argument to \mathpalette as an argument to \vr@c I think. –  morbusg Nov 10 '11 at 19:19
add comment

2 Answers

up vote 13 down vote accepted

\mathpalette comes very handy in many situations where similar token lists must be passed to \mathchoice, that is, we want an expansion of the form

\mathchoice
  {<something in \displaystyle>}
  {<something in \textstyle>}
  {<something in \scriptstyle>}
  {<something in \scriptscriptstyle>}

However, to allow for maximum flexibility, the first argument to \mathpalette must be a two-argument macro, whose first argument is a math style declaration. Let's see an example, Plain TeX definition of \in:

\def\notin{\mathrel{\mathpalette\c@ncel\in}}

This is followed by

\def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}

Don't look at the complications of \c@ncel but at the fact that the first argument must indeed be a style declaration. If TeX finds \notin it will do \mathrel{\mathpalette\c@ncel\in}, and the subformula inside \mathrel is expanded into

\mathchoice
  {\c@ncel\displaystyle{\in}}%
  {\c@ncel\textstyle{\in}}%
  {\c@ncel\scriptstyle{\in}}%
  {\c@ncel\scriptscriptstyle{\in}}

so, in text style the math list to typeset will be \c@ncel\textstyle{\in}, that is

\m@th\ooalign{$\hfil\textstyle\mkern1mu/\hfil$\crcr$\textstyle\in$}

Here \ooalign is the trick that allows for superimposing characters (it's a simple \halign but baseline skip is suppressed). The effect is of superimposing a slighly offset bar to \in.

The call of \mathpalette can also be of the form \def\xyz{\mathpalette\XYZ} and in this case the macro \xyz will appear to take an argument, which will actually be the second argument for \XYZ. And this is why the macro is defined this way.

Your \vfrac macro can be defined via \mathpalette, since the structure is the same; but the two arguments must be gathered before calling \mathpalette and stored in some macros:

\catcode`@=11
\def\vfrac#1#2{\def\vf@num{#1}\def\vf@den{#2}\mathpalette\vfr@c\relax}
\def\vfr@c#1#2{%
  \raise.5ex\hbox{$\m@th#1\vf@num$}\!/\!\lower.25ex\hbox{$\m@th#1\vf@den$}}
\catcode`@=12

(As Aditya observes, \m@th should always be called in these cases.) Here we don't need the second argument for \vfr@c, but it must be there anyway; one can use \relax or {}, it's the same: that second argument will never be used.

share|improve this answer
    
Ah, ofcourse! I was so stuck at thinking how to transport the parameters "as is" to the helper macro, it didn't even occur to me you could just \def them. Thanks! –  morbusg Nov 11 '11 at 4:43
add comment

\mathpalette is defined as

\def\mathpalette#1#2{%
  \mathchoice
    {#1\displaystyle{#2}}%
    {#1\textstyle{#2}}%
    {#1\scriptstyle{#2}}%
    {#1\scriptscriptstyle{#2}}}

and therefore takes two arguments. The first argument is typeset as-is in the respective style as chosen by \mathchoice, while the second argument is typeset with a forced style.

The elementary nature of your \vfrac macro, it suffices to supply \relax as the first #1 or second #2 argument to \mathpalette.


A better choice might be to use \mathchoice directly in your definition of \vfrac:

$$\displaylines{
  \displaystyle\raise.25ex\hbox{$\displaystyle1$}\!/\!\lower.5ex\hbox{$\displaystyle2$} \cr
  \textstyle\raise.25ex\hbox{$\textstyle1$}\!/\!\lower.5ex\hbox{$\textstyle2$}\cr
  \scriptstyle\raise.25ex\hbox{$\scriptstyle1$}\!/\!\lower.5ex\hbox{$\scriptstyle2$}\cr
  \scriptscriptstyle\raise.25ex\hbox{$\scriptscriptstyle1$}\!/\!\lower.5ex\hbox{$\scriptscriptstyle2$}\cr
}$$

\def\vfrac#1#2{%
  \mathchoice%
    {\raise.5ex\hbox{$\displaystyle#1$}/\lower.25ex\hbox{$\displaystyle#2$}}% \displaystyle
    {\raise.5ex\hbox{$\textstyle#1$}/\lower.25ex\hbox{$\textstyle#2$}}% \textstyle
    {\raise.5ex\hbox{$\scriptstyle#1$}/\lower.25ex\hbox{$\scriptstyle#2$}}% \scriptstyle
    {\raise.5ex\hbox{$\scriptscriptstyle#1$}/\lower.25ex\hbox{$\scriptscriptstyle#2$}}% \scriptscriptstyle
}%

$\vfrac{1}{2} \quad {}^{\vfrac12}$

enter image description here

You may have to change the \raise and \lower quantities to match that in your \displaylines depending on your usage. Moreover, now you're down to one macro!

share|improve this answer
    
That's nice, thanks, but every time I find myself writing the exact same thing more than once, I get the feeling I'm doing something wrong. –  morbusg Nov 10 '11 at 19:49
4  
You should set \mathsurround to 0 to avoid extra spacing around math. Usually this is done by using \hbox{\m@th$...$} –  Aditya Nov 10 '11 at 20:19
    
@morbusg: That's true. But it's better that such coding is hidden from view in a macro that it clutter the readability within the general document. –  Werner Nov 10 '11 at 20:28
    
The explicit \mathchoice approach is definitely the way to go in case I need to make small adjustments to each style level. Thanks again! –  morbusg Nov 11 '11 at 4:46
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.