为了解决部分这个问题,我想在排版之前测量标题的大小,然后用它来计算节点矩阵的大小。
我能看到的第一个问题是它\caption
有一个不同的定义,取决于(至少)是否{caption}
使用了包,或者只是普通的 Latex:
$ texdef -t latex \@caption
\@caption:
\long macro:#1[#2]#3->\par \addcontentsline {\csname ext@#1\endcsname }{#1}{\protect \numberline {\csname the#1\endcsname }{\ignorespaces #2}}\begingroup \@parboxrestore \if@minipage \@setminipage \fi \normalsize \@makecaption {\csname fnum@#1\endcsname }{\ignorespaces #3}\par \endgroup
$ texdef -t latex -p caption \@caption
\@caption:
\long macro:#1[#2]#3->\ifcaption@star \else \caption@prepareanchor {#1}{#2}\memcaptioninfo {#1}{\csname the#1\endcsname }{#2}{#3}\@nameuse {nag@hascaptiontrue}\fi \par \caption@beginex {#1}{#2}{#3}\caption@setfloatcapt {\caption@boxrestore \if@minipage \@setminipage \fi \caption@normalsize \ifcaption@star \let \caption@makeanchor \@firstofone \fi \@makecaption {\csname fnum@#1\endcsname }{\ignorespaces \caption@makeanchor {#3}}\par \caption@if@minipage \@minipagetrue \@minipagefalse }\caption@end
更糟糕的是,我想要旋转标题后的尺寸;下面是基于另一个问题:
% modified from: https://tex.stackexchange.com/questions/44427/rotate-picture-with-caption
\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{adjustbox}
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\begin{figure}[ht]
\begin{adjustbox}{addcode={\begin{minipage}{\width}}{%
\caption{%
Here is a caption of the figure which is so long that
it has to be wrapped over multiple lines, but should
not exceed the width (height after the rotation) of the image.
}%
\makeatletter%
\ifx\caption@@make\undefined%
\typeout{\string\caption@@make is undefined, prob. not using \{caption\}}%
\else%
\typeout{\string\caption@@make is defined, prob. using \{caption\}}%
\typeout{\string\caption@box is: \meaning\caption@box}%
\fi%
\typeout{\string\@makecaption is: \meaning\@makecaption}%
\makeatother%
\end{minipage}},rotate=90,center}
\includegraphics[width=0.6\textwidth,height=0.4\textwidth]{demo}%
\end{adjustbox}
\end{figure}
\lipsum[2]
\end{document}
我基本上希望通过阅读的定义\caption
,找到一个排版标题的框,并测量其宽度/高度/深度;但不幸的是,这取决于是否加载{caption}
,以及标题的样式(例如,使用什么大小的字体) - 并且在排版标题后它仍然是信息。
顺便说一下,MWE 输出以下内容:
...并打印出:
\caption@@make is defined, prob. using \{caption\}
\caption@box is: macro:->\ifx \@captype \@undefined \@latex@error {\noexpand \caption outside float}\@ehd \expandafter \@gobble \else \refstepcounter \@captype \expandafter \@firstofone \fi {\@dblarg {\@caption \@captype }}@box
\@makecaption is: macro:->\spacefactor \@m makecaption
...这似乎表明该错误,请参见在下面评论(此外,我在这里得到的定义与提供的定义有点不同{caption}
包被使用,即使没有明确指定texdef
,但没关系)。
所以我的问题是 - 如何从 MWE 获取图像上旋转标题的大小,以便我可以使用它进行计算(例如,旋转图像的高度=原始图像的宽度)?
答案1
好的,我想我明白了一些,但不确定它是否正确。本质上:
- 我们可以使用
\savebox
预先将标题排版到框中;但是:- (
\caption
和\savebox
)必须位于 内{figure}
;并且: - 必须有一个
\parbox
或{minipage}
包装\caption
在里面\savebox
- 否则不会应用换行
- (
事实证明,需要使用某种换行符( \break
、\linebreak
或)来将 定位在图像下方,就像正常情况一样 - 否则,由于某种原因,它会粘在图像的右侧。以下 MWE 结果具有此输出(单击可查看完整分辨率):\\
\newline
\usebox
\caption
第一个图是OP中的正常用法。
第二幅图使用\savebox{ \parbox{ ... \caption...
和\break \usebox{...
,只是为了确认它相对于第一幅图是否正确。一般来说是正确的,除了标题有点偏离,我用红色虚线(放置在gimp
)来表示。
第三个图是预先计算标题的大小,并用它来调整图像大小(新高度 = 原始高度 - 标题高度的一半)。现在这里有一些技巧,需要小心:
- 的
addcode=
实际上\adjustbox
由两部分组成;代码前(或precode=
)和代码后(或appcode=
);我在用空格标记的地方标明了 - 对于最后一个图,我明确使用了precode=
,appcode=
有了这个,人们可能会认为最终的构造将是这样的:
from \adjustbox:precode -> \begin{minipage}{\width} inside -> \includegraphics{...} from \adjustbox:appcode -> \end{minipage}
...这通常是正确的 - 除了在执行方面,“内部”的代码首先执行,甚至在之前
precode=
!它是:inside -> \includegraphics{...} from \adjustbox:precode -> \begin{minipage}{\width} from \adjustbox:appcode -> \end{minipage}
类似地,该
\width
参数仅存在于 pre/appcode 中 - 不存在于“内部”代码中- 因此,即使你可以在预编码中,并在应用程序代码中
\savebox
使用它 - 也没关系,到那时图像已经排版,并且其大小已固定 - 所以我们无法根据这些点的标题大小修改其大小\caption
\usebox
因此,唯一的解决方案是预先知道/设置图像的至少一个维度 - 此处为宽度(未旋转),该维度由图像和标题共享(无论如何都需要它来打破文本行)。如果人们接受这是不可避免的,那么人们可以:
- 将 排版
\caption
在 中\savebox
,在 内{figure}
,但在{adjustbox}
之前 - 然后,在“内部”代码中,当
\includegraphics
排版时,保存的框和它的先验尺寸都是已知的 - 因此可以及时计算出修改后的尺寸; - 最后,
\usebox
可以在这里 - 或者像下面的 MWE 一样,在的appcode=
(\adjustbox
的precode
只\adjustbox
需要打开\begin{minipage}{\width}
MWE 代码:
% modified from: http://tex.stackexchange.com/questions/44427/rotate-picture-with-caption
\documentclass{article}
\usepackage[demo]{graphicx}
\usepackage{adjustbox}
%\usepackage{lipsum}
\usepackage{lua-visual-debug} % compile with lualatex test.tex, for visual indication of margins
% "The text in a \savebox is typeset all on one line. You need to use a \parbox inside \savebox."
% http://tex.stackexchange.com/questions/194811/how-to-measure-the-height-and-width-of-several-lines-paragraph
% "'Missing \endgroup inserted' errors - a horizontal (LR) box which can not directly contain vertical (par) mode display material, you need a minipage to get into vertical mode"
% http://tex.stackexchange.com/questions/74896/using-align-within-savebox
% http://tex.stackexchange.com/questions/60491/latex-tracing
\def\tracingboxes{\showboxbreadth = \maxdimen
\showboxdepth = \maxdimen}%
% must have \tracingboxes here before \tracingoutput,
% else nothing will be printed
\tracingboxes
\tracingoutput1
\begin{document}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum ...
\begin{figure}[ht]
\begin{adjustbox}{addcode={\begin{minipage}{\width}} {%
\caption{%
Here is a caption of the figure which is so long that
it has to be wrapped over multiple lines, but should
not exceed the width (height after the rotation) of the image.
}%
\end{minipage}},rotate=90,center}
\includegraphics[width=0.4\textwidth,height=0.3\textwidth]{demo}%
\end{adjustbox}
\end{figure}
\begin{figure}[ht]
\newsavebox{\boxcapt}% is allocated (though not set) globally now, http://tex.stackexchange.com/questions/7134/making-register-declarations-local-undef
\begin{adjustbox}{addcode={\begin{minipage}{\width}} {%
\savebox{\boxcapt}{%
\parbox{\width}{%
\caption{%
Here is a caption of the figure which is so long that
it has to be wrapped over multiple lines, but should
not exceed the width (height after the rotation) of the image.
}%
}% %end \parbox%
}% %end \savebox%
\typeout{boxcapt: wd is: \the\wd\boxcapt, ht is: \the\ht\boxcapt, dp is: \the\dp\boxcapt}%
%\break\fbox{\usebox{\boxcapt}}% fbox will mess up spacing
\break% same w/ \linebreak, \\ or \newline
\usebox{\boxcapt}%
\end{minipage}},rotate=90,center}
\includegraphics[width=0.4\textwidth,height=0.3\textwidth]{demo}%
\end{adjustbox}
\end{figure}
Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ...
% http://tex.stackexchange.com/questions/45396/is-it-possible-to-remove-length-counter-dim-etc-that-have-been-declared
% No, it's not possible: \newlength allocates a register and this allocation is permanent. If you do the \newlength inside a group, you'll lose the register name at group end, but the register will not be reusable.
\newlength{\globimw}
\newlength{\globimh}
% %%%%%%%%%%%%% nowork like this: %%%%%%%%%%%%%
% \begin{figure}[!h]
% \begin{adjustbox}{addcode={\begin{minipage}{\width}%
% \savebox{\boxcapt}{%
% \parbox{\width}{%
% \caption{%
% Here is a caption of the figure which is so long that
% it has to be wrapped over multiple lines, but should
% not exceed the width (height after the rotation) of the image.
% }%
% }% %end \parbox%
% }% %end \savebox%
% \setlength{\skip0}{\ht\boxcapt}%
% \global\setlength{\skip1}{\ht\boxcapt}% nope
% \global\skip1=\skip0% nope
% \global\setlength{\globimw}{\ht\boxcapt}% nope
% \global\globimw=\globimw%
% \typeout{boxcapt in: wd is: \the\wd\boxcapt, ht is: \the\ht\boxcapt, dp is: \the\dp\boxcapt ; skip0: \the\skip0; skip1: \the\skip1; glp: \the\globimw}% ok here! but runs after boxcapt out?
% } {% addcode= code after:
% \break% same w/ \linebreak, \\ or \newline
% \usebox{\boxcapt}%
% \end{minipage}},rotate=90,center}
% % use temp "scratch" register to calculate new height (rotated: width) of image, to its original height minus half height of caption
% \typeout{boxcapt out: wd is: \the\wd\boxcapt, ht is: \the\ht\boxcapt, dp is: \the\dp\boxcapt ; skip0: \the\skip0; skip1: \the\skip1; glp: \the\globimw}% all are zeroes!
% \setlength{\skip0}{\dimexpr 0.3\textwidth-\expandafter\ht\boxcapt}
% \includegraphics[width=0.4\textwidth,height=\skip0]{demo}%
% \end{adjustbox}
% \end{figure}
\begin{figure}[!h]
\setlength{\globimw}{0.4\textwidth}%
\setlength{\globimh}{0.3\textwidth}%
\global\globimw=\globimw% % must have, to propagate
\global\globimh=\globimh%
\savebox{\boxcapt}{%
\parbox{\globimw}{% \width here is undefined (\adjustbox is below)
\caption{%
Here is a caption of the figure which is so long that
it has to be wrapped over multiple lines, but should
not exceed the width (height after the rotation) of the image.
}%
}% %end \parbox%
}% %end \savebox%
\begin{adjustbox}{
precode={\begin{minipage}{\width}},
appcode={% addcode= code after:
\typeout{boxcapt out: wd is: \the\wd\boxcapt, ht is: \the\ht\boxcapt, dp is: \the\dp\boxcapt ; skip1: \the\skip1; skip3: \the\skip3; glw,h: \the\globimw, \the\globimh; tw \the\textwidth}% all are here
\break% same w/ \linebreak, \\ or \newline
\usebox{\boxcapt}% place the caption, finally
\vspace{\skip3}% this just to push everything "up" (i.e. left in rotated perspective), so "top" (left) edge of this figure aligns with the others - since \adjustbox does the rotation centered.
\end{minipage}%
},
rotate=90,center%
}% %closing of \begin{adjustbox}%
%\includegraphics[width=\globimw,height=\globimh]{demo}% ok
%\includegraphics[width=0.4\textwidth,height=0.3\textwidth]{demo}% ok
% use temp "scratch" register to calculate new height (rotated: width) of image, to its original height minus half height of caption
% skip1, 3 should be \global % http://tex.stackexchange.com/questions/29950/is-there-a-way-of-limiting-the-scope-of-newlength
%\typeout{\width} % \width ! Undefined control sequence.
\setlength{\skip3}{\dimexpr 0.5\dimexpr(\ht\boxcapt+\dp\boxcapt)}%
\setlength{\skip1}{\dimexpr 0.3\textwidth-\skip3}%
\global\skip1=\skip1% w. \global keeps val until next step
\global\skip3=\skip3%
\typeout{boxcapt inside: wd is: \the\wd\boxcapt, ht is: \the\ht\boxcapt, dp is: \the\dp\boxcapt ; skip1: \the\skip1; skip3: \the\skip3; glw: \the\globimw}% boxcapt is now known
\includegraphics[width=0.4\textwidth,height=\skip1]{demo}%
\end{adjustbox}
\end{figure}
\end{document}