重新定义 \intertext 和 \shortintertext 来测量它们的宽度

重新定义 \intertext 和 \shortintertext 来测量它们的宽度

我正在尝试测量自然宽度align*(使用documentclass选项fleqn),并在评论中被告知 确定 align* 的自然宽度:varwidth 使用 \linewidth,即使显示正确\intertext使用整个\linewidth。因此,解决方案声音简单,重新定义\intertext\shortintertext并通过 分别测量它们\varwidth

问题在于重新定义这两个宏似乎有些棘手,因为\let似乎忽略了使用。MWE 旨在通过测量和的宽度\intertext\shorintertext其余部分分开来解决最后两个测试用例align*

在此处输入图片描述

参考:

代码:

\documentclass[fleqn]{article}
\usepackage{etoolbox}
\usepackage{mathtools}
\usepackage{varwidth}

\usepackage{printlen}
\uselengthunit{mm}

\makeatletter
%% Fix for varwidth to work with fleqn option
%% https://tex.stackexchange.com/questions/394778/align-in-varwidth-seems-to-ignore-fleqn-option
\let\@vwid@eqmodetrue\@vwid@eqmodefalse

\newsavebox{\@IntertextSavebox}
\newlength{\@MaxIntertextWidth}
\newcommand{\MeasureIntertext}[1]{%
    \savebox{\@IntertextSavebox}{%
        \begin{varwidth}{\linewidth}
            #1%
        \end{varwidth}%
    }%
    %% Keep track of the maximum width of any \shorintertext and
    %% \intertext within this align* environment.
    \ifdim\wd\@IntertextSavebox>\@MaxIntertextWidth
        \setlength{\@MaxIntertextWidth}{\wd\@IntertextSavebox}%
    \fi
}%
\newsavebox{\@NonIntertextBox}
\newcommand{\GetNaturalVarwidth}[3]{%
    %% #1 = length to contain the width
    %% #2 = title for this test case
    %% #3 = text to measure
    \setlength{\@MaxIntertextWidth}{0pt}%
    \savebox{\@NonIntertextBox}{%
        \begin{varwidth}{\linewidth}
            %% ------------------------------------------------------ Problem Area
            %% This attempt to redefine these two seems to be ignored.
            \let\shortintertext\MeasureIntertext
            \let\intertext\MeasureIntertext
            %% ------------------------------------------------------ 
            #3%
        \end{varwidth}%
    }%
    %% ------------------------------------------
    %% For debugging purposes show the box.
    \medskip\par
    \noindent%
    {\bfseries#2}%
    \par\noindent
    \fboxsep=0pt
    \fbox{%
        \usebox{\@NonIntertextBox}%
    }%
    \ifdim\wd\@IntertextSavebox>\wd\@NonIntertextBox
        \setlength{#1}{\wd\@IntertextSavebox}%
    \else
        \setlength{#1}{\wd\@NonIntertextBox}%
    \fi
    {\par\tiny Natural Width is \printlength{#1}.}%
}%
\makeatother

\newlength{\NaturalWidth}
\begin{document}
\GetNaturalVarwidth{\NaturalWidth}{Small text}{Small text}% Works

%% These two don't work, but right now am just focusing on align*
%\GetNaturalVarwidth{\NaturalWidth}{Single Display Equation}{%
%\[
%    F = ma.
%\]
%}
%
%\GetNaturalVarwidth{\NaturalWidth}{Single display equation with text}{%
%Single display equation
%\[
%    F = ma.
%\]
%and some more text.%
%}

\GetNaturalVarwidth{\NaturalWidth}{Single align*}{%
\begin{align*}
    F &= ma.
\end{align*}%
}

\GetNaturalVarwidth{\NaturalWidth}{Align* with text}{%
Famous Equations:
\begin{align*}
    F &= ma. \\
    E &= mc^2,
\end{align*}%
or at least they should be famous.
}

\GetNaturalVarwidth{\NaturalWidth}{Align* with shortintertext}{%
\begin{align*}
    F &= ma. \\
    \shortintertext{and}
    E &= mc^2,
\end{align*}%
}
This one above should be 23.42914mm.

\GetNaturalVarwidth{\NaturalWidth}{Align* with intertext}{%
\begin{align*}
    F &= ma. \\
    \intertext{with some longer intertext}
    E &= mc^2,
\end{align*}%
}
This one above should be greater than 23.42914mm 
(which is width of just the nonintertext portion).

\end{document}

列表文件

收到错误

Undefined control sequence.
\shortintertext ...th }\normalbaselines \if_dim:w

在运行提供的答案时我认为我应该包括以下输出\listfiles

 *File List*
 article.cls    2014/09/29 v1.4h Standard LaTeX document class
   fleqn.clo    2016/12/29 v1.2a Standard LaTeX option (flush left equations)
  size10.clo    2014/09/29 v1.4h Standard LaTeX file (size option)
etoolbox.sty    2018/02/11 v2.5e e-TeX tools for LaTeX (JAW)
mathtools.sty    2018/01/08 v1.21 mathematical typesetting tools
  keyval.sty    2014/10/28 v1.15 key=value parser (DPC)
    calc.sty    2014/10/28 v4.3 Infix arithmetic (KKT,FJ)
 mhsetup.sty    2017/03/31 v1.3 programming setup (MH)
 amsmath.sty    2017/09/02 v2.17a AMS math features
 amstext.sty    2000/06/29 v2.01 AMS text
  amsgen.sty    1999/11/30 v2.0 generic functions
  amsbsy.sty    1999/11/29 v1.2d Bold Symbols
  amsopn.sty    2016/03/08 v2.02 operator names
varwidth.sty    2009/03/30 ver 0.92;  Variable-width minipages
printlen.sty    2009/09/03 v1.1a print lengths with units
graphicx.sty    2017/06/01 v1.1a Enhanced LaTeX Graphics (DPC,SPQR)
graphics.sty    2017/06/25 v1.2c Standard LaTeX Graphics (DPC,SPQR)
    trig.sty    2016/01/03 v1.10 sin cos tan (DPC)
graphics.cfg    2016/06/04 v1.11 sample graphics configuration
  pdftex.def    2018/01/08 v1.0l Graphics/color driver for pdftex
supp-pdf.mkii
epstopdf-base.sty    2016/05/15 v2.6 Base part for package epstopdf
infwarerr.sty    2016/05/16 v1.4 Providing info/warning/error messages (HO)
  grfext.sty    2016/05/16 v1.2 Manage graphics extensions (HO)
kvdefinekeys.sty    2016/05/16 v1.4 Define keys (HO)
 ltxcmds.sty    2016/05/16 v1.23 LaTeX kernel commands for general use (HO)
kvoptions.sty    2016/05/16 v3.12 Key value format for package options (HO)
kvsetkeys.sty    2016/05/16 v1.17 Key value parser (HO)
etexcmds.sty    2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO)
ifluatex.sty    2016/05/16 v1.4 Provides the ifluatex switch (HO)
pdftexcmds.sty    2018/01/21 v0.26 Utility functions of pdfTeX for LuaTeX (HO)
   ifpdf.sty    2017/03/15 v3.2 Provides the ifpdf switch
epstopdf-sys.cfg    2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Live
 ***********

答案1

如果在支持该包的某些环境之外使用它,amsmath则会导致出现错误消息。它过去常在这些环境中定义。因此,需要重新定义。\intertext\intertext@\intertext\intertext@

\shortintertext由包提供mathtools,可以直接重新定义。

以下代码片段\vbox{...}\begin{varwidth}{\linewidth}...\end{varwidth}\intertext替换\shortintertext

\def\intertext@measuring{% see \intertext@ in amsmath
  \def\intertext##1{%
    \ifvmode\else\\\@empty\fi
    \noalign{%
      \penalty\postdisplaypenalty\vskip\belowdisplayskip
      %\vbox{
      \begin{varwidth}{\linewidth}%
        \normalbaselines
        \ifdim\linewidth=\columnwidth
        \else \parshape\@ne \@totalleftmargin \linewidth
        \fi
        \noindent##1\par
      %}%
      \end{varwidth}%
      \penalty\predisplaypenalty\vskip\abovedisplayskip%
    }%
  }%
}

\MHInternalSyntaxOn
\def\shortintertext@measuring#1{% see \MT_shortintertext:n in mathtools
  \ifvmode\else\\\@empty\fi
  \noalign{%
    \penalty\postdisplaypenalty\vskip\abovedisplayshortskip
    \vskip-\lineskiplimit
    \vskip\normallineskiplimit
    \vskip\l_MT_above_shortintertext_sep
    %\vbox{%
    \begin{varwidth}{\linewidth}%
      \normalbaselines
      \if_dim:w
        \if_dim:w \@totalleftmargin=\z@
          \linewidth
        \else:
          -\maxdimen
        \fi:
        =\columnwidth
      \else:
        \parshape\@ne \@totalleftmargin \linewidth
      \fi:
      \noindent#1\par
    %}%
    \end{varwidth}%
    \penalty\predisplaypenalty\vskip\abovedisplayshortskip%
    \vskip-\lineskiplimit
    \vskip\normallineskiplimit
    \vskip\l_MT_below_shortintertext_sep
  }%
}
\MHInternalSyntaxOff

然后,重新定义命令:

\let\shortintertext\shortintertext@measuring
\let\intertext@\intertext@measuring

现在对示例的测量进行了改进:

结果

完整示例(仅来自问题的示例,添加了来自此答案的代码):

\documentclass[fleqn]{article}
\usepackage{etoolbox}
\usepackage{mathtools}
\usepackage{varwidth}

\usepackage{printlen}
\uselengthunit{mm}

\makeatletter

\def\intertext@measuring{% see \intertext@ in amsmath
  \def\intertext##1{%
    \ifvmode\else\\\@empty\fi
    \noalign{%
      \penalty\postdisplaypenalty\vskip\belowdisplayskip
      %\vbox{
      \begin{varwidth}{\linewidth}%
        \normalbaselines
        \ifdim\linewidth=\columnwidth
        \else \parshape\@ne \@totalleftmargin \linewidth
        \fi
        \noindent##1\par
      %}%
      \end{varwidth}%
      \penalty\predisplaypenalty\vskip\abovedisplayskip%
    }%
  }%
}

\MHInternalSyntaxOn
\def\shortintertext@measuring#1{% see \MT_shortintertext:n in mathtools
  \ifvmode\else\\\@empty\fi
  \noalign{%
    \penalty\postdisplaypenalty\vskip\abovedisplayshortskip
    \vskip-\lineskiplimit
    \vskip\normallineskiplimit
    \vskip\l_MT_above_shortintertext_sep
    %\vbox{%
    \begin{varwidth}{\linewidth}%
      \normalbaselines
      \if_dim:w
        \if_dim:w \@totalleftmargin=\z@
          \linewidth
        \else:
          -\maxdimen
        \fi:
        =\columnwidth
      \else:
        \parshape\@ne \@totalleftmargin \linewidth
      \fi:
      \noindent#1\par
    %}%
    \end{varwidth}%
    \penalty\predisplaypenalty\vskip\abovedisplayshortskip%
    \vskip-\lineskiplimit
    \vskip\normallineskiplimit
    \vskip\l_MT_below_shortintertext_sep
  }%
}
\MHInternalSyntaxOff

%% Fix for varwidth to work with fleqn option
%% https://tex.stackexchange.com/questions/394778/align-in-varwidth-seems-to-ignore-fleqn-option
\let\@vwid@eqmodetrue\@vwid@eqmodefalse

\newsavebox{\@IntertextSavebox}
\newlength{\@MaxIntertextWidth}
\newcommand{\MeasureIntertext}[1]{%
    \savebox{\@IntertextSavebox}{%
        \begin{varwidth}{\linewidth}
            #1%
        \end{varwidth}%
    }%
    %% Keep track of the maximum width of any \shorintertext and
    %% \intertext within this align* environment.
    \ifdim\wd\@IntertextSavebox>\@MaxIntertextWidth
        \setlength{\@MaxIntertextWidth}{\wd\@IntertextSavebox}%
    \fi
}%
\newsavebox{\@NonIntertextBox}
\newcommand{\GetNaturalVarwidth}[3]{%
    %% #1 = length to contain the width
    %% #2 = title for this test case
    %% #3 = text to measure
    \setlength{\@MaxIntertextWidth}{0pt}%
    \savebox{\@NonIntertextBox}{%
        \begin{varwidth}{\linewidth}
            %% ------------------------------------------------------ Problem Area
            %% This attempt to redefine these two seems to be ignored.
            %\let\shortintertext\MeasureIntertext
            \let\shortintertext\shortintertext@measuring
            %\let\intertext\MeasureIntertext
            \let\intertext@\intertext@measuring
            %% ------------------------------------------------------ 
            #3%
        \end{varwidth}%
    }%
    %% ------------------------------------------
    %% For debugging purposes show the box.
    \medskip\par
    \noindent%
    {\bfseries#2}%
    \par\noindent
    \fboxsep=0pt
    \fbox{%
        \usebox{\@NonIntertextBox}%
    }%
    \ifdim\wd\@IntertextSavebox>\wd\@NonIntertextBox
        \setlength{#1}{\wd\@IntertextSavebox}%
    \else
        \setlength{#1}{\wd\@NonIntertextBox}%
    \fi
    {\par\tiny Natural Width is \printlength{#1}.}%
}%
\makeatother

\newlength{\NaturalWidth}
\begin{document}
\GetNaturalVarwidth{\NaturalWidth}{Small text}{Small text}% Works

%% These two don't work, but right now am just focusing on align*
%\GetNaturalVarwidth{\NaturalWidth}{Single Display Equation}{%
%\[
%    F = ma.
%\]
%}
%
%\GetNaturalVarwidth{\NaturalWidth}{Single display equation with text}{%
%Single display equation
%\[
%    F = ma.
%\]
%and some more text.%
%}

\GetNaturalVarwidth{\NaturalWidth}{Single align*}{%
\begin{align*}
    F &= ma.
\end{align*}%
}

\GetNaturalVarwidth{\NaturalWidth}{Align* with text}{%
Famous Equations:
\begin{align*}
    F &= ma. \\
    E &= mc^2,
\end{align*}%
or at least they should be famous.
}

\GetNaturalVarwidth{\NaturalWidth}{Align* with shortintertext}{%
\begin{align*}
    F &= ma. \\
    \shortintertext{and}
    E &= mc^2,
\end{align*}%
}
This one above should be 23.42914mm.

\GetNaturalVarwidth{\NaturalWidth}{Align* with intertext}{%
\begin{align*}
    F &= ma. \\
    \intertext{with some longer intertext}
    E &= mc^2,
\end{align*}%
}
This one above should be greater than 23.42914mm 
(which is width of just the nonintertext portion).

\end{document}

相关内容