我需要tabular
环境中的元素来设置一些长度,并能够在同一张表的另一行中访问这些长度。但似乎在and\global
前面添加是不够的。\settoheight
\settowidth
以下 MWEMeasureFigureAndPlaceFigure
测量传递给它的参数的高度和宽度,并尝试全局设置长度。这会在 之后报告零长度和宽度tabular
,但在 之外报告正确的长度(忽略轻微的舍入)。
\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{printlen}
\uselengthunit{cm}
\newlength{\FigureHeight}
\newlength{\FigureWidth}
\newcommand{\MeasureFigureAndPlaceFigure}[1]{%
\global\settoheight{\FigureHeight}{#1}%
\global\settowidth{\FigureWidth}{#1}%
#1%
}%
\newcommand{\ReportHeightAndLength}{%
Height=\printlength{\FigureHeight}\quad%
Width=\printlength{\FigureHeight}%
}%
\def\FigA{\includegraphics[width=2.0cm,height=1.0cm]{myimage}}
\begin{document}
\noindent% This reports 0 lengths
\begin{tabular}{@{}l@{}}
\MeasureFigureAndPlaceFigure{\FigA}
\end{tabular}
\ReportHeightAndLength
\noindent % This works just fine
\MeasureFigureAndPlaceFigure{\FigA}
\ReportHeightAndLength
\end{document}
答案1
\settowidth
,\settoheight
并\settodepth
通过辅助宏定义\@settodim
:
\def\settoheight{\@settodim\ht}
\def\settodepth {\@settodim\dp}
\def\settowidth {\@settodim\wd}
\def\@settodim#1#2#3{\setbox\@tempboxa\hbox{{#3}}#2#1\@tempboxa
\setbox\@tempboxa\box\voidb@x}
因此,\settowidth{\mylen}{Hello}
翻译成
\@settodim\wd{\mylen}{Hello}
进而变成
\setbox\@tempboxa\hbox{{Hello}}\mylen\wd\@tempboxa\setbox\@tempboxa\voidb@x
这样,在设置框后,TeX 就会执行赋值
\mylen=\wd\@tempboxa
并清除\@tempboxa
(对另外两个宏执行类似操作)。
从宏的定义方式我们可以推断出
\settowidth{\global\mylen}{Hello}
将执行
\global\mylen=\wd\@tempboxa
它可以满足您的要求。
如果需要进行多次黑客攻击,最好定义四个“全局”宏:
\makeatletter
\def\globalsettoheight{\@gsettodim\ht}
\def\globalsettodepth {\@gsettodim\dp}
\def\globalsettowidth {\@gsettodim\wd}
\def\@gsettodim#1#2#3{%
\setbox\@tempboxa\hbox{{#3}}\global#2#1\@tempboxa
\setbox\@tempboxa\box\voidb@x}
\makeatother
这样就\globalsettowidth{\mylen}{Hello}
可以用更自然的语法来完成工作。
对于您的特定应用程序,您可以按照这些行定义新的宏,但要避免排版两次框(如 David Carlisle 所建议的):
\newlength{\FigureHeight}
\newlength{\FigureWidth}
\newcommand{\MeasureFigureAndPlaceFigure}[1]{%
\setbox\@tempboxa\hbox{{#1}}%
\global\FigureHeight=\ht\@tempboxa
\global\FigureWidth\wd\@tempboxa
\box\@tempboxa
}