我正在尝试测量自然宽度align*
(使用documentclass选项fleqn
),并在评论中被告知
确定 align* 的自然宽度:varwidth 使用 \linewidth,即使显示正确\intertext
使用整个\linewidth
。因此,解决方案声音简单,重新定义\intertext
(\shortintertext
并通过 分别测量它们\varwidth
。
问题在于重新定义这两个宏似乎有些棘手,因为\let
似乎忽略了使用。MWE 旨在通过测量和的宽度\intertext
与\shorintertext
其余部分分开来解决最后两个测试用例align*
。
参考:
- 确定 align* 的自然宽度:varwidth 使用 \linewidth,即使显示正确
- varwidth 中的 align* 似乎忽略了 fleqn 选项
- 这是一个相关问题,但答案并不涉及重新定义
\intertext
:在 \intertext 和 \shortintertext 周围应用条件会留下多余的垂直空间。
代码:
\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}