我编写了一个宏,用于计算用 s 分隔的线条\measureHbox{}
的高度和宽度:\hbox
\break
\long\def\measureHbox#1{%
\begingroup
\def\break{\noexpand\my@cr}%
\protected@edef\@argi{#1}%
\@tempdima\z@%% width
\@tempdimb\z@%% height+depth
\long\def\mesure@line ##1\my@cr##2\@nil{%
\if!##1!\else
\setbox\@tempboxa\hbox{##1}%
\ifdim\wd\@tempboxa>\@tempdima\relax
\@tempdima=\wd\@tempboxa
\fi
\advance\@tempdimb\ht\@tempboxa
\advance\@tempdimb\dp\@tempboxa
\if!##2!\else
\mesure@line##2\@nil
\fi
\fi
}%
\expandafter\mesure@line\@argi\my@cr\@nil
\edef\mytemp{%
\noexpand\setDimension{Width}{\the\@tempdima}%
\noexpand\setDimension{Height}{\the\@tempdimb}%
}%
\message{^^J==DEBUG>\meaning\mytemp}%
\expandafter\mytemp
\endgroup
}
该宏\setDimension
定义如下:
\def\setDimension#1#2{\expandafter\edef\csname my#1\endcsname{#2}}
这一切都很好,除了我需要改变 measureHbox 定义中使用的所有宏本地(例如\break
)但我需要半群“之外”的结果,例如:
\documentclass[english]{minimal}
\makeatletter
%% definition of \measureHbox here
\parindent\z@
\parskip\z@
\rightskip\@flushglue
%% definition of \setDimension here
\def\mytemp{DO NOT CHANGE ME GLOBALLY!!}
\makeatother
\setDimension{Width}{5pt}
\setDimension{Height}{5pt}
\begin{document}
{\bfseries Before group:}\par
Original width: \myWidth\par % is: 5pt
Original height: \myHeight\par % is: 5pt
\mytemp % original definition
\vskip\baselineskip
\bgroup
{\bfseries In group:}\par
\measureHbox{This is a\break breaking box}\par
Measured width: \myWidth\par % should be: 56.6946pt
Measured height: \myHeight\par % should be: 15.83333pt
\mytemp\par\vskip\baselineskip % should print nothing inside this group
\egroup
{\bfseries After group:}\par
Original width: \myWidth\par % should be 5pt again
Original height: \myHeight\par % should be 5pt again
\mytemp % original definition again
\end{document}
对于嵌入宏的代码来说,重要的是,此宏定义中使用的所有宏都不会全局更改。我的天真方法是在定义的最后两行\mytemp
之后展开宏:\endgroup
\measureHbox
\expandafter\mytemp
\endgroup
但那不管用,也不管用
\aftergroup\mytemp
\endgroup
我的问题是:
有没有办法\mytemp
在 的定义中将 的展开式“移”到半群之外\measureHbox
?
为了完整起见,这里是粘合在一起的完整“最小”示例:
\documentclass[english]{minimal}
\makeatletter
\long\def\measureHbox#1{%
Original Box:\par\vskip\baselineskip#1\par\vskip\baselineskip
\begingroup
\def\break{\noexpand\my@cr}%
\protected@edef\@argi{#1}%
\@tempdima\z@%% width
\@tempdimb\z@%% height+depth
\long\def\mesure@line ##1\my@cr##2\@nil{%
\if!##1!\else
\setbox\@tempboxa\hbox{##1}%
\ifdim\wd\@tempboxa>\@tempdima\relax
\@tempdima=\wd\@tempboxa
\fi
\advance\@tempdimb\ht\@tempboxa
\advance\@tempdimb\dp\@tempboxa
\if!##2!\else
\mesure@line##2\@nil
\fi
\fi
}%
\expandafter\mesure@line\@argi\my@cr\@nil
\edef\mytemp{%
\noexpand\setDimension{Width}{\the\@tempdima}%
\noexpand\setDimension{Height}{\the\@tempdimb}%
}%
\message{^^J==DEBUG>\meaning\mytemp}%
\expandafter\mytemp
\endgroup
}
\parindent\z@
\parskip\z@
\rightskip\@flushglue
\def\setDimension#1#2{\expandafter\edef\csname my#1\endcsname{#2}}
\def\mytemp{DO NOT CHANGE ME GLOBALLY!!}
\makeatother
\setDimension{Width}{5pt}
\setDimension{Height}{5pt}
\begin{document}
{\bfseries Before group:}\par
Original width: \myWidth\par
Original height: \myHeight\par
\mytemp
\vskip\baselineskip
\bgroup
{\bfseries In group:}\par
\measureHbox{This is a\break breaking box}\par
Measured width: \myWidth\par
Measured height: \myHeight\par
\mytemp\par\vskip\baselineskip
\egroup
{\bfseries After group:}\par
Original width: \myWidth\par
Original height: \myHeight\par
\mytemp
\end{document}
答案1
\edef\mytemp{%
\noexpand\setDimension{Width}{\the\@tempdima}%
\noexpand\setDimension{Height}{\the\@tempdimb}%
}%
\message{^^J==DEBUG>\meaning\mytemp}%
\expandafter\mytemp
\endgroup
由于不可扩展,\expandafter
因此不执行任何操作,但你可以执行\endgroup
\edef\mytemp{\endgroup
\noexpand\setDimension{Width}{\the\@tempdima}%
\noexpand\setDimension{Height}{\the\@tempdimb}%
}%
\message{^^J==DEBUG>\meaning\mytemp}%
\mytemp
因此您的寄存器在组内得到扩展,但组在替换文本的开头结束。
或者
\edef\mytemp{%
\noexpand\setDimension{Width}{\the\@tempdima}%
\noexpand\setDimension{Height}{\the\@tempdimb}%
}%
\message{^^J==DEBUG>\meaning\mytemp}%
\expandafter\endgroup
\mytemp
所以\mytemp
在组结束之前就扩大了。