Как выровнять базовые линии текста изображения и основного текста?

Как выровнять базовые линии текста изображения и основного текста?

Следующий код оборачивает основной текст вокруг изображения и его сопровождающего текста. Установленный таким образом (с \vfills) изображение и текст центрируются вертикально в углублении.

Я хочу добиться выравнивания текста под изображением по базовой сетке (опуская оба). Если я опускаю последний \vfillв третьем параметре, \figflowтекст устанавливается слишком низко.

Ресурсы: Я использую XeTeX (чтобы вставить картинку),figflow.tex,серый ящик.pngи фоновая сетка взята изэтот ответ.

\newbox\gridbox
\setbox\gridbox\line{%
  \special{color push rgb .8 .8 1}%
  \vrule height\baselineskip width0pt \hrulefill
  \special{color pop}}
\def\grid{\vtop to0pt{\hrule height0pt\kern-\dimexpr\baselineskip-\topskip\topskip=10pt\relax
    \vbox to\dimexpr\vsize+2pt\relax{\leaders\copy\gridbox\vfil}\vss}}
\def\pagebody{\vbox to\vsize{\boxmaxdepth=\maxdepth \grid\pagecontents}}

\input figflow
\parskip=0pt \frenchspacing \raggedbottom
\font\smallrm=cmr8

\def\includegraphics#1#2#3#4{
{\parfillskip=0pt\par}\dimen0=#1
\dimen1=#2
\advance\dimen0 by 1pc
\setbox0=\vbox to #2{\hsize=#1
\XeTeXpicfile #3 width #1 height #2}
\setbox1=\vbox{\hsize=#1{\noindent\it #4\par}}
\advance\dimen1 by \ht1
\divide\dimen1 by \baselineskip
\multiply\dimen1 by \baselineskip
\advance\dimen1 by \baselineskip
\setbox2=\vbox to \dimen1{\vfil\box0\vskip2mm\box1}
\figflow{\dimen0}{\dimen1}{\vfill\box2\vfill}\noindent\ignorespaces}

\noindent
A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more.%
\includegraphics{7cm}{7cm}{greybox.png}{Lorem ipsum dolor sit
amet, consectetur adipiscing elit. Donec a diam lectus.}
Especially pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.
\bye

ОБНОВЛЯТЬ:

Вэтотслучае, когда \baselineskipи размер шрифта в тексте под рисунком такой же, как и в основном тексте, мне удалось выровнять базовые линии, изменив линию \figflowна

\figflow{\dimen0}{\dimen1}{\vfill\box2\vskip0pt}\noindent\ignorespaces}

Почему работает вставка пустого элемента \vskip? Обратите внимание, что это не работает с другими размерами шрифта, с другими \baselineskips, даже при вставке \struts внутри или за пределами группы в поле 1.

ОБНОВЛЕНИЕ 2:

Благодаря ответу Wipet я создал еще один MWE с не таким уж редким случаем: когда изображение и подпись должны находиться в правом нижнем (или левом) углу страницы:

\newbox\gridbox
\setbox\gridbox\line{%
  \special{color push rgb .8 .8 1}%
  \vrule height\baselineskip width0pt \hrulefill
  \special{color pop}}
\def\grid{\vtop to0pt{\hrule height0pt\kern-\dimexpr\baselineskip-\topskip\topskip=10pt\relax
    \vbox to\dimexpr\vsize+2pt\relax{\leaders\copy\gridbox\vfil}\vss}}
\def\pagebody{\vbox to\vsize{\boxmaxdepth=\maxdepth \grid\pagecontents}}

\input figflow
\parskip=0pt \frenchspacing \raggedbottom
\font\smallrm=cmr8

\def\includegraphics#1#2#3#4{%
   {\parfillskip=0pt\par}
   \dimen0=#1 \ifdim#1<0pt \dimen0=-\dimen0 \fi
   \dimen1=#2 
   \dimen2=#1 \advance\dimen2 by \ifdim#1<0pt-\fi 1pc
   \setbox0=\vbox {\XeTeXpicfile #3 width\dimen0 height #2}
   \setbox1=\vbox{\hsize=\dimen0 \baselineskip=9.5pt\noindent\smallrm #4\par} 
   \advance\dimen1 by \ht1
   \divide\dimen1 by \baselineskip
   \multiply\dimen1 by \baselineskip
   \advance\dimen1 by 1\baselineskip
   \setbox2=\vbox to\dimen1{\vss\box0\vskip2mm\box1}
   \figflow{\dimen2}{\dimen1}{}%
   \line{\ifdim#1<0pt\hfill\fi\vtop to0pt{\kern0pt\box2\vss}\hfil}
   \nobreak\vskip-\baselineskip
   \noindent\ignorespaces}

\noindent
A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more.
Especially pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages%
\includegraphics{-7cm}{7cm}{greybox.png}{Lorem ipsum dolor sit
amet, consectetur adipiscing elit. Donec a diam lectus.}
can optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.
\bye

Проблема в том (я думаю), что где-то \baselineskipвставлено a, которое отменяется с помощью \vskip-\baselineskipв конце макроса. Это \baselineskipзаставляет всю картинку и текст рядом с картинкой появляться на следующей странице. При перемещении вызова на \includegraphicsодну строку вверх (до Especially …), картинка появляется на первой странице, но с одной строкой основного текста под картинкой и текстом подписи.

ОБНОВЛЕНИЕ 3:

Выброс страницы произошел при вставке картинки в figflow.tex. Я добавил a \nobreakв одной точке (отмечено ^^^), и выброс исчез:

% FIGFLOW:  plain TEX macro by Ian Hutchinson, 21 Oct 95.
% Copyright 1995 Ian Hutchinson.
% You may freely use, modify, and/or distribute this file, without limitation.
% Make text flow round figure.
% Usage: \figflow{<width>}{<height>}{<[Figure+][Caption]>}
% at start of new paragraph. Figure top starts at insert.
% #1 figure width dimen. If negative, fig on right, else left.
% #2 figure height (including caption) dimen. (E.g.: 4 truein)
% #3 \special for figure if desired, then \vfill caption. (Both optional).
% Example: figflow{4 truein}{5 truein}{\epsfbox{figure.ps}\vfill Figure 1.}
% User is responsible for the figure fitting within the space defined.
% If figure won't fit on page, it is moved over the page break.
% If a new figflow starts before the old one is finished, a message is given
% and the second figure is skipped. Fix manually.
% Does not work for Latex.

\newdimen\pageremains\newdimen\pdepth
\newdimen\figwidth
\newdimen\figheight
\newcount\figlines
\newcount\flevel

\def\figflow#1#2#3{
\ifnum\flevel>0
\message{******Figure collision. Ignoring second figure.******}
\else
\figwidth=#1
\figheight=#2
\def\contents{#3}
% Put figure contents in an appropriate box.
\def\figure{\let\temp=\par \let\par=\plainpar
  \line{\overfullrule=0pt%  Avoid black box.
   \ifdim \figwidth<0pt \hsize=-\figwidth \hss\else \hsize=\figwidth\fi
   \advance \hsize by -10pt% Give a little extra hspace.
   \vbox to \figheight{\vfil\noindent\contents}
   \ifdim \figwidth>0pt \hss\fi
  }\nobreak\vskip-\figheight
%  ^^^^^^^^ inserted by MK
  \let\par=\temp%
}
% […] remainder of file is the same

Единственная проблема, которая сейчас существует, заключается в том, что последние две строки на странице перемещены на следующую (включая сокращение). Я думаю, что это как-то связано с \widowpenaltyи \clubpenalty, но манипуляции с этими переменными не решили проблему.

Любые лучшие решения вышеупомянутых проблем также приветствуются.

ОБНОВЛЕНИЕ 4:

Ручное добавление a \nobreak\̺после последнего слова в тексте на первой странице (т. е. после a variety of important) действительно решает проблему, упомянутую в обновлении 3, но теперь перенос строки также запрещен в этой точке, что приводит к (слишком) плотной строке и ненужным переносам. Как это решить и, конечно, как это автоматизировать?

ОБНОВЛЕНИЕ 5:

При выполнении какого-то стресс-теста я столкнулся с другой проблемой. Я добавил два макроса \toppictureи , \midpictureчтобы соответственно добавить \ejectили \parперед началом \includegraphics(пожалуйста, не пугайтесь этого кода из-за его длины, большая его часть — пустой текст):

\newbox\gridbox
\setbox\gridbox\line{%
  \special{color push rgb .8 .8 1}%
  \vrule height\baselineskip width0pt \hrulefill
  \special{color pop}}
\def\grid{\vtop to0pt{\hrule height0pt\kern-\dimexpr\baselineskip-\topskip\topskip=10pt\relax
    \vbox to\dimexpr\vsize+2pt\relax{\leaders\copy\gridbox\vfil}\vss}}
\def\pagebody{\vbox to\vsize{\boxmaxdepth=\maxdepth \grid\pagecontents}}

\input figflow
\parskip=0pt \frenchspacing \raggedbottom
\widowpenalty=10000 \clubpenalty=10000
\font\smallrm=cmr8

%\toppicture params:
%  #1 <dimen>  width of picture
%  #2 <dimen>  height of picture
%  #3 <string> file name
%  #4 <string> caption text
\def\toppicture#1#2#3#4{%
   {\parfillskip=0pt\par}\eject%
   \includegraphics{#1}{#2}{#3}{#4}
}

%\midpicture params:
%  #1 <dimen>  width of picture
%  #2 <dimen>  height of picture
%  #3 <string> file name
%  #4 <string> caption text
\def\midpicture#1#2#3#4{%
   {\parfillskip=0pt\par}
   \includegraphics{#1}{#2}{#3}{#4}
}

\def\includegraphics#1#2#3#4{%
   \dimen0=#1 \ifdim#1<0pt \dimen0=-\dimen0 \fi
   \dimen2=#2 
   \dimen4=#1 \advance\dimen4 by \ifdim#1<0pt-\fi 1pc
   \setbox0=\vbox {\XeTeXpicfile #3 width\dimen0 height #2}
   \setbox2=\vbox{\hsize=\dimen0 \baselineskip=9.5pt\noindent\smallrm #4\par} 
   \advance\dimen2 by \ht2
   \divide\dimen2 by \baselineskip
   \multiply\dimen2 by \baselineskip
   \advance\dimen2 by \baselineskip
   \setbox4=\vbox to\dimen2{\vss\box0\vskip2mm\box2}
   \figflow{\dimen4}{\dimen2}{}
   \line{\ifdim#1<0pt\hfill\fi\vtop to0pt{\kern0pt\box4\vss}\hfil}
   \nobreak\vskip-\baselineskip
   \noindent\ignorespaces}

\noindent
A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more.
Especially pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more.
Especially pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages
\midpicture{-7cm}{7cm}{greybox.png}{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.}
can optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode,
%\midpicture{7cm}{7cm}{greybox.png}{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.}
namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. 
These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI 
\midpicture{7cm}{7cm}{greybox.png}{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.}
or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.

%\toppicture{7cm}{7cm}{greybox.png}{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.}
A work in progress, {\tt JSBox} is a self-contained
library---written in portable C---that instantiates sandbox-able,
\TeX-language interpreters within the memory space
of any C, Objective-C, or C++ 32- or 64-bit client
program. Built and documented anew, {\tt JSBox}
is faithful to the \TeX\ language's primitives,
syntax, typesetting algorithms, measurements, data
structures, and speed. At the same time, it fixes---in an
upwardly compatible manner---a variety of important %\nobreak\
problems with or lacun\ae\ in the current \TeX\ engine's
implementation. These include integral support for
21-bit Unicode, namespaces, OpenType font tables
and metrics, job-specific 8-bit to 21-bit Unicode
mapping, run-time settable compatibility levels,
full 32-bit fixed-point math, and more. Especially
pertinent to interactive applications---such as an
eBook reader---is that all of a document's pages can
optionally be kept as \TeX\ data structures in memory
after a job is done, with direct random access of any
requested page exported to the client program's screen
without file I/O or DVI or PDF conversion if unneeded.
Tracing (including recursive expansion, re-tracing
interrupted commands, alignments, math, etc.) and
all error messages have been significantly improved
over what \TeX\ does. The author will demo what
{\tt JSBox} can do now, and discuss what it
could do in the future.
\bye

Сначала закомментируйте вторую \midpicture(она должна быть на строке 169) и запустите XeTeX. Так или иначе, теперь я могу не учитывать изменения, которые я сделал в обновлении 3 (добавление \nobreakв figflow.tex) и обновлении 4 (добавление \nobreak\в исходную копию), и все будет набрано нормально. Это очень странно, поскольку я больше ничего не менял, насколько мне известно. Текст правильно обтекает картинку и подпись к ней.

Пожалуйста, теперь раскомментируйте \midpictureвызов, который вы только что закомментировали, и запустите TeX снова. Теперь он жалуется на вставку a }непосредственно перед \endgroup. Это звучит странно для меня. Что здесь происходит?

В-третьих, снова закомментируйте эту строку и раскомментируйте \midpictureстроку 149. Теперь figflow.tex будет жаловаться на столкновение фигур, вероятно, потому, что он не закончил обработку строк рядом с первой картинкой, хотя я вызвал макрос \midpictureпосле последнего слова в строке. Это означает, что нельзя размещать две картинки сразу друг под другом (они не должны сталкиваться). Как избежать этого столкновения?

В-четвертых, снова закомментируйте строку 149 и раскомментируйте единственный \toppicture, в строке 178. Как ни странно, на этот раз TeX не подавился вторым вызовом \figflowlike, когда строка 169 была раскомментирована. Результат — две правильно набранные страницы и новая страница с изображением в левом верхнем углу. Только теперь все (основной текст, изображение и подпись к изображению) немного не вписывается в сетку. Что здесь не так?

решение1

Я предлагаю использовать \figflowтолько его для создания подходящего пространства для картины и контролировать размещение картины.

\def\includegraphics#1#2#3#4{
{\parfillskip=0pt\par}\dimen0=#1
\dimen1=#2
\advance\dimen0 by 1pc
\setbox0=\vbox to #2{\hsize=#1
\XeTeXpicfile #3 width #1 height #2}
\setbox1=\vbox{\hsize=#1{\noindent\it #4\par}}
\advance\dimen1 by \ht1
\divide\dimen1 by \baselineskip
\multiply\dimen1 by \baselineskip
\advance\dimen1 by 1\baselineskip
\setbox2=\vbox to \dimen1{\vfil\box0\vskip2mm\box1}
   % PO changes in OP's code: 
  \figflow{\dimen0}{\dimen1}{}%
  \vtop to0pt{\kern0pt\box2\vss}\nobreak\vskip-\baselineskip
\noindent\ignorespaces}

Если вы установите \kern-\baselineskipвместо « \kern0ptвнутри» \vtop, то изображение будет размещено на одну строку выше.

Редактировать: учитывая комментарий, я добавил вторую версию кода, где текст \baselineskipпод картинкой может быть произвольным, а первый параметр макроса \includegraphicsможет быть отрицательным. Тогда \dimen0это абсолютное значение этого параметра, а \dimen2это новое вводится как #1плюс или минус 1pc (добавляет поле в зависимости от знака #1).

\def\includegraphics#1#2#3#4{%
   {\parfillskip=0pt\par}
   \dimen0=#1 \ifdim#1<0pt \dimen0=-\dimen0 \fi
   \dimen1=#2 
   \dimen2=#1 \advance\dimen2 by \ifdim#1<0pt-\fi 1pc
   \setbox0=\vbox {\XeTeXpicfile #3 width\dimen0 height #2}
   \setbox1=\vbox{\hsize=\dimen0 \noindent\it #4\par} 
   \advance\dimen1 by \ht1
   \divide\dimen1 by \baselineskip
   \multiply\dimen1 by \baselineskip
   \advance\dimen1 by 1\baselineskip
   \setbox2=\vbox to\dimen1{\vss\box0\vskip2mm\box1}
   \figflow{\dimen2}{\dimen1}{}%
   \line{\ifdim#1<0pt\hfill\fi\vtop to0pt{\kern0pt\box2\vss}\hfil}
   \nobreak\vskip-\baselineskip
   \noindent\ignorespaces}

Редактировать2:Учитывая ваши обновления вашего вопроса, я решил, что вы можете попробовать макрос \oblomиз моей книги.TeXbook наруби(страницы 236 и 237). Полная версия этой книги в формате PDF доступна, но только на чешском языке.

Название макроса \oblomпроисходит от чешского слова "делать набор текста вокруг чего-либо". Этот макрос создает белое прямоугольное пространство в следующем абзаце (или нескольких абзацах). Мой следующий код здесь использует этот макрос (но переименовывает разделительные слова). Использование этого макроса следующее:

\oblom <width> from <linenum1> indent <linenum2>

где <width>— ширина прямоугольного пространства, <linenum1>— номер первой строки, которая отступает, <linenum2>— количество строк с отступом. Если отрицательно, <width>то прямоугольное пространство будет справа. Например:

\oblom 5cm from 3 indent 5

означает, что пять строк будут отступлены на 5 см от третьей строки (включая эту). Первые две строки не отступают и имеют обычную ширину.

Макрос \oblomдолжен использоваться между абзацами и влияет на форму следующего одного или нескольких абзацев. Главное преимущество в том, что вам не нужно останавливать абзац точно в том месте, где начинается отступ. Обратите внимание на ваши предыдущие примеры, где вы должны были это сделать, {\parfillskip=0pt\par}что приводит к осложнениям.

Мой следующий код использует \oblomи определяет макрос \flowpic:

\flowpic from <linenum> width <width> {<picfile>} {<caption>}

Например

\flowpic from 3 width -7cm {greybox.png}
    {Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus.}

вставляет картинку greybox.pngс заданной подписью с третьей строки следующего абзаца с правой стороны. Ширина картинки будет 7 см минус 1pc, так как 1pc — это поле между картинкой и текстом. Вам не нужно использовать pckage figflow.

Код состоит из трех частей. Первая часть — определение макроса, \oblomскопированного изTeXbook наруби. Этот макрос вычисляет \parshapeпараметры и использует \parshape. Вторая часть определяет макрос \picдля вставки изображений заданной ширины. Определения зависят от того, используется XeTeX или нет. Третья часть объявляет, \flowpicкакие используют \oblomи \pic. Макрос flowpic вставляет изображение на ту же страницу, где оно используется, если там достаточно места. Если нет, то flowpic вставляет изображение на следующую страницу, где заканчиваются последние абзацы с измененной формой.

\newcount\shapenum \newcount\tempnum \newcount\globpar
\newdimen\ii \newdimen\ww
\newdimen\picwidth  \newbox\picbox
\catcode`\@=11  
\def\oblom #1 from #2 indent #3 {\par \ii=#1 \ww=\hsize
   \ifdim\ii>\z@ \advance\ww by-\ii      
   \else \advance\ww by\ii \ii=\z@ \fi
   \shapenum=1 \tempnum=0 \def\shapelist{}
   \loop \ifnum\shapenum<#2 \edef\shapelist{\shapelist\z@\hsize}
      \advance\shapenum by1 \repeat
   \loop \edef\shapelist{\shapelist\ii\ww}
      \advance\tempnum by1 \ifnum\tempnum<#3 \repeat
   \advance\shapenum by#3 \edef\shapelist{\shapelist\z@\hsize}
   \doshape}  
\catcode`\@=12
\def\doshape{\globpar=0 \def\par{\ifhmode\shapepar\fi}}
\def\shapepar{\prevgraf=\globpar \parshape\shapenum\shapelist
   \endgraf \globpar=\prevgraf
   \ifnum \prevgraf<\shapenum\else \global\let\par=\endgraf \doshapeA \fi}

\ifx\XeTeXpicfile\undefined 
   \def\pic #1{\hbox{\pdfximage width\picwidth {#1}\pdfrefximage\pdflastximage}}
\else
   \def\pic #1{\hbox{\XeTeXpicfile #1 width\picwidth}}
\fi

\def\flowpic from #1 width #2 #3#4{\par
   \dimen0=#2 \ifdim\dimen0<0pt \dimen0=-\dimen0 \fi
   \advance\dimen0 by -1pc %(margin around picture)
   \picwidth=\dimen0
   \setbox0=\vbox{\hsize\dimen0 \pic{#3}\kern 2mm 
                  \emergencystretch=2em \noindent\it #4}
   \dimen0=\ht0 
   \divide\dimen0 by\baselineskip \advance\dimen0 by1sp
   \oblom #2 from #1 indent \dimen0 
   \multiply\dimen0  by\baselineskip
   \setbox\picbox=\vbox to\dimen0{\vss\box0}
   \dimen0=\pagegoal \ifdim\pagegoal=\maxdimen \dimen0=\vsize\fi   
   \advance\dimen0 by-\pagetotal \advance\dimen0 by-#1\baselineskip
   \ifdim\dimen0<0pt 
      \def\doshapeA{\tempnum=\prevgraf \advance\tempnum by-#1 \advance\tempnum by2
         \line{\ifdim#2<0pt \hfill\fi \vbox to0pt{\vss\vtop to0pt{\kern0pt\box\picbox\vss}%
                   \kern\the\tempnum\baselineskip}\hfil}
         \nobreak\vskip-\baselineskip
      }
   \else \def\doshapeA{}
      \line{\ifdim#2<0pt \hfill\fi 
            \vtop to0pt{\kern-2\baselineskip\kern#1\baselineskip\box\picbox\vss}\hfil}
      \nobreak\vskip-\baselineskip
   \fi
}
\parindent=0pt \raggedbottom % we need the grid

Ограничение этого макроса: вы не можете разместить изображение на «краю» страницы, где находится разрыв страницы. Только до или после такого разрыва страницы. Вы не можете вставить два изображения в один абзац. Следующее использование \flowpicразрешено только перед абзацем, где нет строк с отступом от предыдущего \flowpic. Если у вас очень длинный абзац и вам нужно разместить \flowpicздесь два s, то вам нужно использовать известный трюк by {\parfillskip=0pt\par}, чтобы закрыть предыдущий «невидимый» абзац.

Связанный контент