如何使 amsxtra \accentedsymbol 与下标等一起工作?

如何使 amsxtra \accentedsymbol 与下标等一起工作?

amsxtra包提供了\accentedsymbol排版参数并存储结果的命令。这可以加速 LaTeX 编译如果频繁使用大量重音符号等,则效果会更显著。问题是\accentedsymbol排版只有一种尺寸,因此您需要为所有数学样式设置不同的宏。

问题

我如何定义一个类似的命令,\accentedsymbol使其在所有数学显示样式中正常工作?

评论

解决方案可能涉及使用。这是一个手动\mathchoice实现解决方案的最小工作示例。这是最好的解决方案吗?(下面的参考资料中讨论了有关的一些问题。)如何实现自动化?由于这里的目标是性能,这是一个好的选择吗?(TeXbook 警告说它很慢,但由于我只排版保存的框,所以也许这没问题。它似乎可以很好地处理我测试过的中等规模的问题。)\mathchoice\mathchoice\mathchoice

\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}

示例输出。

参考

答案1

使用\mathchoice确实是答案。\accentedsymbol通过将带有重音的字符预编译到框中,然后每次都重复此框来工作。 因此大小是固定的,并且每个样式都需要不同的版本。 只有在处理公式时才会确定此样式,这就是您需要的原因\mathchoice。 但您可以模仿amsxtra定义来为您执行此操作:

\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}

有点拗口,但本质上只是生成不同的框,然后在里面使用它\mathchoice。与原始定义相比,我所做的更改是,我还使用预编译了框名称\edef,以便\csname里面的 s\mathchoice在定义时完成,而不是在执行时完成。

然而,正如 Egreg 所观察到的,\accentedsymbol如果你有双重口音,这个或我的变体才会真正有所收获,所以对于正常口音来说,它并没有太大帮助。

答案2

我尝试了以下

\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}

time pdflatex test1得到了

    5.06 real         4.93 user         0.06 sys

使用其他输入

\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}

电话里time pdflatex test2

    5.07 real         4.92 user         0.06 sys

所以没有太大区别。\accentedsymbol当需要设置双重音时,宏很有用。事实上,相同的文件,但\vec{\hat{\mathbf{k}}}}显示了非常最大的区别:有了它,编译时间\accentedsymbol\mathchoice以前相同,没有它,编译就需要几分钟:

   98.15 real        93.19 user         0.55 sys

相关内容