0

I think I have an idea how to alleviate some of the following problem:

Two floating wrapfigures in a row

but I'm not sure how to implement it. A significant part of the floating issue seems to be related to the insistence of putting the wrapfig in the beginning of a paragraph. How do I relax this restriction?

For example, I put a wrapfig before a paragraph that has a pagebreak in the middle. The wrapfig would float to the next paragraph (which, e.g., may be too small--before the section ends--or used by another wrapfig), ignoring the current paragraph completely. However, if I break the paragraph into a line-size, small paragraphs, then wrap fig would start at the first chance it gets. Instead of splitting into small paragraphs (or manually position wrapfig within a paragraph every time the document changes), I'd like to lift the paragraph restriction.


EDIT

The comments below made me wonder:

Low-level latex--does it need a makeover?

Zohar Levi
  • 1,237
  • 1
    line breaking happens as a least cost optimisation at the end of the paragraph so the adjustment of lines to fit a cut-in figure is necessarily a paragraph-level operation. – David Carlisle Aug 27 '20 at 08:51
  • @David, I'm not following; are you saying my suggested "algorithm" doesn't make sense, or are you saying that latex has limited functionality and it's not possible? – Zohar Levi Aug 27 '20 at 09:28
  • 2
    your suggested algorithm isn't really an algorithm and I can not guess how you would intend to base anything on lines not paragraphs when lines are not known until the end of a paragraph. Adding a comma on the last line can change the place the first linebreak happens. – David Carlisle Aug 27 '20 at 09:44
  • You can take a look at the efforts in xgalley to see how tricky this all – Joseph Wright Aug 27 '20 at 09:59
  • You can pull off one line at a time using \vsplit, but you have to format the text ahead of time. The width of each line can't be changed. – John Kormylo Aug 27 '20 at 14:11
  • I edited the question as a reply. – Zohar Levi Aug 29 '20 at 21:55

1 Answers1

1

You might find this interesting. It was an attempt to apply \parshape to multiple paragraphs and equations.

\documentclass{article}
\usepackage{mwe}
\usepackage{showframe}
\tracingmacros=1

% global varaibles \newtoks\MSeverypar \newcounter{MScount} \newcounter{MSlines} \newlength{\MSleft} \newlength{\MSright} \newlength{\MSvert} \newsavebox{\MSbox} \newif{\ifMSdone} \newif{\ifMSnext} \newcommand{\MSparshape}{}% reserve global name \newcommand{\MSnextshape}{}% reserve gloval name

\newenvironment{minishape}[1]% #1 = shape blocks (left,right,vert) {\MSeverypar=\expandafter{\the\everypar} \def\END{\END}% token only. Do not expand! \setcounter{MScount}{0}% \xdef\MSlastleft{0pt}% \xdef\MSlastright{0pt}% \MSparse#1\empty\END% save instructions as macros \edef\MStotal{\theMScount}% \setcounter{MScount}{0}% \MSnext \everypar{\MSparagraph}}{}

\def\MSparse#1(#2,#3,#4)#5\END{% #1=throwaway #2=left, #3=right, #4=vert, #5=next \ifx!#4\relax \xdef\MSlastleft{#2}% \xdef\MSlastright{#3}%b \else \stepcounter{MScount}% \expandafter\xdef\csname MSleft\theMScount\endcsname{#2}% \expandafter\xdef\csname MSright\theMScount\endcsname{#3}% \expandafter\xdef\csname MSvert\theMScount\endcsname{#4}% \fi \ifx\empty#5\relax\else\expandafter\MSparse#5\END\fi}

\newcommand{\MSmerge}[2]{\edef\MSshape{#1 #2}}

\long\def\MSparagraph#1\par{% \everypar#2) \setcounter{MSlines}{1}% \global\let\MSparshape=\MSnextshape \MSdonefalse \loop \MSmakebox{#1}% \MSsplitbox \ifMSdone\else\repeat \global\advance\MSvert by -\parskip \ifnum\value{MScount}>\MStotal\relax \stepcounter{MSlines}% \MSmerge{\MSparshape}{\MSnextshape}% \global\let\MSparshape=\MSshape \fi \MSmerge{\theMSlines}{\MSparshape}% \parshape=\MSshape #1\par}

\newcommand{\MSmakebox}[1]% #1 = paragraph {\bgroup \clubpenalty=0 \widowpenalty=0 \displaywidowpenalty=0 \predisplaypenalty=0 \postdisplaypenalty=0 \interlinepenalty=0 \everypar=\expandafter{\the\MSeverypar} \MSmerge{\theMSlines}{\MSparshape}% \global\setbox\MSbox=\vbox{\parshape=\MSshape \strut#1\strut}% \egroup}

\newcommand{\MSsplitbox}% extend \MSparshape {\bgroup% local varaibles and loops \countdef\count=1 \dimendef\delta=0 \dimendef\test=1 \count=1 \loop\ifnum\count<\value{MSlines}% \advance\count by 1 \global\setbox0=\vsplit\MSbox to \baselineskip% \repeat \MSnextfalse \loop \delta=\ht\MSbox \advance\delta by \dp\MSbox \ifdim\delta>0pt\relax \global\setbox0=\vsplit\MSbox to \baselineskip% \advance\delta by -\ht\MSbox \advance\delta by -\dp\MSbox \ifdim\delta>\MSvert \count=\value{MScount}% \ifnum\count<\MStotal\relax \advance\count by 1 \ifdim\MSleft<\csname MSleft\the\count\endcsname\relax \MSnext \else \ifdim\MSright<\csname MSright\the\count\endcsname\relax \MSnext\fi \fi \fi \fi \stepcounter{MSlines}% global \MSmerge{\MSparshape}{\MSnextshape}% \global\let\MSparshape=\MSshape \global\advance\MSvert by -\delta \ifdim\MSvert>0pt\relax\else\MSnext\fi \else \global\MSdonetrue \MSnexttrue \fi \ifMSnext\else\repeat \egroup}

\newcommand{\MSnext}{% at end of block \MSnexttrue \ifnum\value{MScount}<\MStotal\relax \stepcounter{MScount}% \global\advance\MSvert by \csname MSvert\theMScount\endcsname\relax% \global\MSleft=\csname MSleft\theMScount\endcsname% \global\MSright=\csname MSright\theMScount\endcsname% \else \stepcounter{MScount}% \global\MSdonetrue \global\MSleft=\MSlastleft\relax \global\MSright=\MSlastright\relax \fi \MSmerge{\the\MSleft}{\the\dimexpr\linewidth-\MSleft-\MSright}% \global\let\MSnextshape=\MSshape }

\begin{document}

\begin{minishape}{(.25in,.25in,1in) (.5in,.5in,1.5in)} Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Curabitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum.

Nam dui ligula, fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi auctor lorem non justo. Nam lacus libero, pretium at, lobortis vitae, ultricies et, tellus. Donec aliquet, tortor sed accumsan bibendum, erat ligula aliquet magna, vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit mollis. Suspendisse ut massa. Cras nec ante. Pellentesque a nulla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam tincidunt urna. Nulla ullamcorper vestibulum turpis. Pellentesque cursus luctus mauris.

\end{minishape}

\end{document}

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • Can you please explain what you did and how it helps with my issue? And I hardly know meta-latex; see my edited question. – Zohar Levi Aug 29 '20 at 21:56
  • wrapfig use \everypar and \parshpae to wrap the text, but it assumes every line is precisely \baselineskip apart. This measures the height of each line instead. – John Kormylo Aug 30 '20 at 16:55
  • I'll need time to look into it, probably read some on tex on the way. However, it would help if you could demonstrate your solution in a full example, e.g. the one I posted in the first link. – Zohar Levi Sep 02 '20 at 10:54
  • if you want to solve the linked question, I would not use this approach. This was intended to handle equations and other nonstandard spacing. – John Kormylo Sep 02 '20 at 15:13
  • I see; thanks for the effort on both threads. – Zohar Levi Sep 02 '20 at 21:22