5

The following code wraps the body text around a picture and its accompanying text. Set this way (with the \vfills) picture and text are centered vertically in the recess.

What I want to achieve is aligning the text under the picture to the baseline grid (by lowering both). If I omit the last \vfill within the third parameter to \figflow the text is set too low.

Resources: I'm using XeTeX (to include the picture), figflow.tex, greybox.png and background grid taken from this answer.

\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

UPDATE:

In this case, where \baselineskip and the font size in the text under the figure is the same as those of the body text, I managed to align the baselines by changing the \figflow line to

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

Why does inserting an empty \vskip work? Note that it doesn't work with other font sizes, nor with other \baselineskips, even not when inserting \struts within or outside of the group within box 1.

UPDATE 2:

Thanks to wipet's answer I created yet another MWE with a not so uncommon case: when picture and caption should be in the lower right (or left) corner of a page:

\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

The problem is (I think) that somewhere a \baselineskip is inserted which is being undone using the \vskip-\baselineskip at the end of the macro. That \baselineskip makes the whole picture and text next to the picture appear of the next page. When moving the call to \includegraphics one line up (before Especially …), the picture appears on the first page, but with one line of body text below the picture and caption text.

UPDATE 3:

The page ejection was done when inserting the picture in figflow.tex. I added a \nobreak at one point (marked with ^^^) and the ejection was gone:

% 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

The only problem that now exists is that the last two lines on the page are moved over to the next one (including the shortening). I think it has something to do with \widowpenalty and \clubpenalty, but tinkering with those variables didn't solve the issue.

Any better solutions to the aforementioned problems are also appreciated.

UPDATE 4:

Manually adding a \nobreak\̺ after the last word in the body text on the first page (i.e., after a variety of important) indeed solves the issue mentioned in update 3, but now a line break is also prohibited at this point, resulting in a (too) tight line and unnecessary hyphenation. How to solve this and, of course, how to automate this?

UPDATE 5:

When doing some kind of stress test I encountered another issue. I added two macros \toppicture and \midpicture to respectively add an \eject or a \par before starting \includegraphics (please don't shy away from this code by its length, most of it is dummy text):

\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

First, comment the second \midpicture out (it should be on line 169) and run XeTeX. One way or another, I can now leave out the changes I made in update 3 (adding \nobreak to figflow.tex) and update 4 (adding \nobreak\ to the source copy) and everything is typeset fine. This is very strange, as I didn't change anything else, as far as I know. The text flows correctly around the picture and the picture caption.

Please, now uncomment the \midpicture call you just commented out and run TeX again. Now it complains about inserting a } just before an \endgroup. That sounds strange to me. What happens here?

Third, comment that line out again and uncomment the \midpicture on line 149. Now figflow.tex will complain about a figure collission, probably because it's not done processing the lines beside the first picture, although I called the \midpicture macro after the last word in the row. This implies that one cannot place two pictures immediately beneath eachother (they shouldn't collide). How to avoid this collission?

Fourth, comment line 149 out again and uncomment the only \toppicture, on line 178. Strangely enough, this time TeX doesn't choke on a second call to \figflow like when line 169 was uncommented. The result is two correctly typeset pages and a new page with the picture in the top left. Only now everything (body text, picture and picture caption) is slightly off-grid. What's wrong here?

7
  • why do you use a space delimited argument for #4 ? – David Carlisle Dec 21 '14 at 17:04
  • @DavidCarlisle To eat the space after the command, otherwise I would have to type Especially immediately after the closing brace. If you know a better way to eat that space, I'm willing to improve my code. – Marcel Korpel Dec 21 '14 at 17:09
  • 1
    @MarcelKorpel Avoid using odd numbered scratch registers for local assignments. – egreg Dec 23 '14 at 10:10
  • 1
    @egreg Why? The TeXbook only states that "[t]he first ten \count registers […] are reserved for a special purpose" (p. 119). It says nothing about other registers, or am I wrong? – Marcel Korpel Dec 23 '14 at 20:45
  • 2
    @MarcelKorpel Page 346, item 2 (Allocation of registers): ‘All assignments to the scratch registers whose numbers are 1, 3, 5, 7, and 9 should be \global; all assignments to the other scratch registers (0, 2, 4, 6, 8, 255) should be non-\global. (This prevents the phenomenon of “save stack buildup” discussed in Chapter 27.)’ The phenomenon is described on page 301. – egreg Dec 23 '14 at 20:52
5
+150

I suggest to use the \figflow only for creating appropriate space for the picture and to do the picture placing under our control.

\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}

If you set \kern-\baselineskip instead of \kern0pt inside \vtop then you will have the picture placed by one line up.

Edit: considering to the comment I added second version of the code, where the \baselineskip of the text under picture can be arbitrary and the first parameter of the \includegraphics macro can be negative. Then the \dimen0 is absolute value of this parameter and the \dimen2 is newly introduces as #1 plus or minus 1pc (adds the margin in dependency of the sign of the #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}

Edit2: Considering to your updates of your question I decided that you can try the macro \oblom from my book TeXbook naruby (pages 236 and 237). The full PDF version of this book is available but only in Czech language.

The name of the macro \oblom is derived from Czech word "do typesetting around something". This macro creates white rectangular space in next paragraph (or more paragraphs). My next code here uses this macro (but renames the separator words). The usage of this macro is:

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

where <width> is the width of the rectangular space, <linenum1> is the first line number which is indented and <linenum2> is the number of indented lines. If the <width> is negative then the rectangular space will be at the right side. For example:

\oblom 5cm from 3 indent 5

means that five lines will be indented by 5cm from third line (including this one). First two lines are not indented and they are in their normal width.

The macro \oblom have to be used between paragraphs and it influences the shape of next one or more paragraphs. The main advantage is that you needn't to stop the paragraph exactly in the place where indentation starts. Note your previous examples where you must do {\parfillskip=0pt\par} which brings complications.

My next code uses \oblom and defines the macro \flowpic:

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

For example

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

inserts the picture greybox.png with the given caption from third line of the next paragraph at the right side. The width of the picture will be 7cm minus 1pc because 1pc is the margin between the picture and the text. You needn't to use the pckage figflow.

The code consists from three parts. First part is the definition of the \oblom macro copied from TeXbook naruby. This macro caclulates\parshape parameters and uses \parshape. The second part defines the macro \pic for insertion of pictures with given width. The definitions depends on the fact that XeTeX is or isn't used. The third part declares \flowpic which uses \oblom and \pic. The flowpic macro inserts the picture at the same page where it is used if there is enough place. If not then flowpic inserts the picture to the next page, where the last paragraphs with modified shape ends.

\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

The limitation of this macro is: you cannot place the picture at the "edge" of the page where is the pagebreak. Only before or after such pagebreak. You cannot insert two pictures into one paragraph. The next usage of \flowpic is permited only before the paragraph where are no lines indented by previous \flowpic. If you have very long paragraph and you need to place two \flowpics here then you need to use the known trick by {\parfillskip=0pt\par} in order to close the previous "invisible" paragraph.

6
  • Thanks! Works with same-size and smaller font, but not with smaller \baselineskip (within the group within box 1). Any solution for this (not so uncommon) case? And how to put the contents of box 2 at the right side? Using only \figflow, one could use a negative width and all is done. – Marcel Korpel Dec 23 '14 at 20:08
  • Thank you again. There still remains another not so uncommon edge case where the picture and caption text should appear at the bottom of a page, see my update above. – Marcel Korpel Dec 23 '14 at 23:13
  • This is great! The only limitation is, as you wrote, that a picture included at the end of a page will result in a line transported to the next page. A \nobreak solves this issue. Another edge case is that when a heading (within a box with a different \baselineskip) is inserted, the counting of line numbers will fail, but I'll fix that myself when such a case occurs. BTW, you wrote that TeXbook naruby could be translated to English. I'd love to buy a copy when this work is finished, if ever. Please let me know. In the mean time, I'll have to learn Czech. ;) – Marcel Korpel Dec 29 '14 at 16:26
  • FYI, I added another parameter to \flowpic which indicates the number of lines at the end that should not be indented. Now I can say \flowpic from 3 minus 9 width -7cm {greybox.png}{Lorem ipsum…} to reflow the last 9 lines around the picture (e.g., when there are 9\baselineskips extra within a paragraph due to a heading left (or right) to the picture). You can see the improved version on Pastebin. – Marcel Korpel Dec 29 '14 at 18:20
  • I have a followup question about a picture which is moved to the left when using Minion, but not with Computer Modern Roman. Can you have a look at it? Thanks in advance. – Marcel Korpel Dec 29 '14 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.