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.

The amsxtra package provides the \accentedsymbol command which typesets the argument and stores the result. This can speed up LaTeX compilation significantly if lots of accents etc. are used frequently. The problem is that \accentedsymbol typesets only one size, so you need to have different macros for all math styles.

Question

How can I define a command similar to \accentedsymbol that works properly in all math display styles?

Comments

The solution probably involves using \mathchoice. Here is a minimal working example that implements a \mathchoice solution by hand. Is this the best solution? (Some issues about \mathchoice are discussed in the references below.) How can this be automated? Since the goal here is performace, is \mathchoice a good option? (The TeXbook warns that it is slow, but since I am only typesetting saved boxes, maybe this is fine. It seems to work well with intermediate sized problems I have tested.)

\documentclass{standalone}
\usepackage{amsxtra}

\accentedsymbol\vkbad{\vec{\mathbf{k}}}

\accentedsymbol\vkD{\displaystyle \vec{\mathbf{k}}}
\accentedsymbol\vkT{\textstyle \vec{\mathbf{k}}}
\accentedsymbol\vkS{\scriptstyle \vec{\mathbf{k}}}
\accentedsymbol\vkSS{\scriptscriptstyle \vec{\mathbf{k}}}
\newcommand{\vk}{\mathchoice{\vkD}{\vkT}{\vkS}{\vkSS}}

\begin{document}
This is bad: $\vkbad = x_{\vkbad}$.  This is good: $\vk = x_{\vk}$.
\end{document}

Sample output.

References

share|improve this question

2 Answers 2

up vote 7 down vote accepted

Using \mathchoice is indeed the answer. The \accentedsymbol works by precompiling the character with accent(s) into a box and then resuing this box each time. So the size is fixed and you need different versions per style. This style is only determined when the formula is processed and that is why you need \mathchoice. But you can mimic the amsxtra definition to do this for you:

\documentclass{standalone}

\makeatletter

\def\xaccentedsymbol#1#2{%
  \newcommand#1{}%
  \expandafter\newbox
    \csname D\expandafter\@gobble\string#1@box\endcsname
  \expandafter\setbox
    \csname D\expandafter\@gobble\string#1@box\endcsname
      \hbox{$\m@th \displaystyle #2$}%
  \expandafter\newbox
    \csname T\expandafter\@gobble\string#1@box\endcsname
  \expandafter\setbox
    \csname T\expandafter\@gobble\string#1@box\endcsname
      \hbox{$\m@th \textstyle #2$}%
  \expandafter\newbox
    \csname S\expandafter\@gobble\string#1@box\endcsname
  \expandafter\setbox
    \csname S\expandafter\@gobble\string#1@box\endcsname
      \hbox{$\m@th \scriptstyle #2$}%
  \expandafter\newbox
    \csname SS\expandafter\@gobble\string#1@box\endcsname
  \expandafter\setbox
    \csname SS\expandafter\@gobble\string#1@box\endcsname
      \hbox{$\m@th \scriptscriptstyle #2$}%
  \edef#1{\mathchoice
      {\copy\csname D\expandafter\@gobble\string#1@box\endcsname{}}%
      {\copy\csname T\expandafter\@gobble\string#1@box\endcsname{}}%
      {\copy\csname S\expandafter\@gobble\string#1@box\endcsname{}}%
      {\copy\csname SS\expandafter\@gobble\string#1@box\endcsname{}}}%
}
\makeatother

\xaccentedsymbol\vk{\vec{\mathbf{k}}}

\begin{document}
   This is good: $\vk = x_{\vk}$.
\end{document}

Quite a mouthful, but essentially only generating the different boxes and then using it inside \mathchoice. What I changed compared to the original definition is however that I also precompile the box names by using \edef, so that the \csnames inside \mathchoice are done at defintion time not at execution time.

Still as egreg observed this \accentedsymbol or my variant are only really gaining somehting if you have double accents, so for normal accents it doesn't help much.

share|improve this answer
2  
One should also realize that these accented symbols will not change size in a \small or \large context. –  egreg May 2 '12 at 13:13
1  
@egreg good point - essentially that means those commands are needed in headings or footnotes etc. one would either need to define yet another set of variants each or better simply use the base definitions in those cases. –  Frank Mittelbach May 2 '12 at 13:23

I tried the following

\documentclass{article}
\usepackage{amsxtra}

\newcommand{\vk}{\vec{\mathbf{k}}}

\begin{document}
\newcount\lp
\loop\ifnum\lp<100000
\advance\lp 1
\setbox0=\hbox{This is good: $\vk = x_{\vk}$.}
\repeat
\end{document}

and with time pdflatex test1 I got

    5.06 real         4.93 user         0.06 sys

With this other input

\documentclass{article}
\usepackage{amsxtra}

\accentedsymbol\vkD{\displaystyle \vec{\mathbf{k}}}
\accentedsymbol\vkT{\textstyle \vec{\mathbf{k}}}
\accentedsymbol\vkS{\scriptstyle \vec{\mathbf{k}}}
\accentedsymbol\vkSS{\scriptscriptstyle \vec{\mathbf{k}}}
\newcommand{\vk}{\mathchoice{\vkD}{\vkT}{\vkS}{\vkSS}}

\begin{document}
\newcount\lp
\loop\ifnum\lp<100000
\advance\lp 1
\setbox0=\hbox{This is good: $\vk = x_{\vk}$.}
\repeat
\end{document}

the call time pdflatex test2 gave

    5.07 real         4.92 user         0.06 sys

So there's not much difference. The \accentedsymbol macro is useful when double accents are to be set. Indeed, the same files, but with \vec{\hat{\mathbf{k}}}} showed a very big difference: with \accentedsymbol and \mathchoice the time was the same as before, without it the compilation took minutes:

   98.15 real        93.19 user         0.55 sys
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.