我认为我知道如何缓解以下一些问题:
但我不确定如何实现它。浮动问题的很大一部分似乎与坚持将 wrapfig 放在段落开头有关。我该如何放宽这个限制?
例如,我将一个 wrapfig 放在中间有分页符的段落之前。wrapfig 会浮动到下一个段落(例如,在本节结束之前,该段落可能太小,或者被另一个 wrapfig 使用),完全忽略当前段落。但是,如果我将段落分成一行大小的小段落,则 wrapfig 会一有机会就开始显示。我不想拆分成小段落(或者每次文档更改时手动将 wrapfig 放置在段落内),而是想取消段落限制。
编辑
下面的评论让我疑惑:
答案1
\parshape
你可能会觉得这很有趣。这是将其应用于多个段落和方程式的尝试。
\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}