59

wrapfig is incompatible with the enumerate and itemize environments. Is there a typographical reason not to wrap a list around a figure or is it a technical limitation of LaTeX? If it is a technical limitation, is there any work (new packages or changes to LaTeX) currently being done to eliminate the limitation in the future?

Edit: To respond to some of the comments: I realize that there are "gymnastics" which can make this work. I do not have an example of the problem. Whenever I run into a problem with wrapfig because it is near an enumerate or itemize environment, I search for an easy solution, find none, and move the figure elsewhere. In the vast majority of cases, the cost of learning the complex solutions isn't worth the benefit of keeping the figure where I want it.

  • 5
    I have some thoughts for LaTeX3: currently we still need to do work on this, but I would expect 13galley to eventually cover this. – Joseph Wright Jun 8 '12 at 19:04
  • 1
    Another solution to having cutouts in latex lists is given here tex.stackexchange.com/questions/53702/… – David Carlisle Jun 8 '12 at 20:45
  • 1
    @JosephWright Your first comment that 13galley would eventually help is from 2012. Is there any progress since then regarding the question? Or even better a production ready solution? – student Sep 10 '15 at 21:37
  • 1
    @JosephWright What do you mean by "new format" in this case? – student Sep 11 '15 at 6:28
  • 2
    @JosephWright I’m also curious about how this is progressing. I like to let text wrap around figures, and wrapfigure is far too inflexible for this purpose. My tests of xgalley were very promising until I realized it created wrong vertical spacing around lists. Is there any hope this can be fixed to make the package useful within LaTeX2e? – Gaussler May 12 '16 at 8:48
25

The cutwin package (and some \parshape gymnastics) can be used here:

\documentclass{article}
\usepackage{cutwin}
\usepackage{caption}
\usepackage{graphicx}
\usepackage{lipsum}

\begin{document}
\renewcommand\windowpagestuff{%
  \hspace*{25pt}\includegraphics[height=4cm]{ctanlion}
  \captionof{figure}{A test figure.}
}
\opencutleft

\begin{cutout}{2}{10pt}{0.5\linewidth}{12}
\begin{enumerate}
{%
\parshape 15 26pt \linewidth 26pt \linewidth 0.5\linewidth 0.5\linewidth
  0.5\linewidth 0.5\linewidth  0.5\linewidth 0.5\linewidth  0.5\linewidth 0.5\linewidth
  0.5\linewidth 0.5\linewidth   0.5\linewidth 0.5\linewidth   0.5\linewidth 0.5\linewidth 
  0.5\linewidth 0.5\linewidth   0.5\linewidth 0.5\linewidth   0.5\linewidth 0.5\linewidth
  0.5\linewidth 0.5\linewidth   0.5\linewidth 0.5\linewidth 26 pt \linewidth
\item \lipsum[1]
}%
\item \lipsum[2]
\item \lipsum[2]
\end{enumerate}
\end{cutout}

\end{document}

enter image description here

CTAN lion drawing by Duane Bibby.

  • 1
    This should even work if you want to put the picture at the start of the numbering. I didn't try it with cutwin, but just an ordinary \parshape. – Werner Jun 8 '12 at 19:05
  • @Werner you're probably right; I used cutwin to put the figure after some lines of the numbering; right now I have to leave, but I will do some tests later and post some code if no one else has done it. – Gonzalo Medina Jun 8 '12 at 19:09
  • If this is a good, general solution to the problem, would it be possible to develop a package which makes it possible to do this as few of lines of code as wrapfig? Could wrapfig be modified to use this alternative approach when used in a list? – ScottKu Jun 8 '12 at 20:01
  • Your minimal working example (cut win package) fails if one uses a different font, say \usepackage{palatino}. – Vafa Khalighi Jun 9 '12 at 3:18
  • 1
    what if you want to add two different figures inside the same itemize? – glS Dec 4 '15 at 11:18
22

FWIW, wrapfigure works out of the box in ConTeXt. So, it is clearly not a limitation of TeX.

\setuppapersize[A5]

\useexternalfigure[ctanlion][http://www.ctan.org/lion/ctan_lion_350x350.png][width=3cm]


\starttext

\placefigure[left,2*hang]{Test}
  {\externalfigure[ctanlion]}

\startitemize[n]
  \item \input ward
  \item \input ward
  \item \input ward
\stopitemize

\stoptext

which gives:

enter image description here

Removing 2*hang from \placefigure gives:

enter image description here

  • 4
    +1: This is a really nice example for ConTeXt's simplicity. – Henri Menke May 22 '15 at 13:54
6

It is possible by putting the wrapfigure into a parbox or minipage as is mentioned in some of the duplicates of this question. However those methods usually fix vertical spacing issues by manually inserting \vspace with hand picked values. This solution works automatically by using a strut. The strut places the baseline of the first text line at a specified distance from the top of the minipage. Then adjustbox is used to place the top of the minipage exactly that amount above the outer baseline.

\documentclass{article}

\usepackage{calc}
\usepackage{adjustbox}
\usepackage{lipsum}
\usepackage{wrapfig}

\begin{document}

\newlength{\strutheight}
\settoheight{\strutheight}{\strut}
\begin{enumerate}
  \item \lipsum[1]
  \item
    \begin{adjustbox}{valign=T,raise=\strutheight,minipage={\linewidth}}
      \begin{wrapfigure}{l}{0pt}
        \includegraphics[width=3cm]{example-image-a}
      \end{wrapfigure}
    \strut{}\lipsum[2]
    \end{adjustbox}
\end{enumerate}

\end{document}
4

Here's a kluge. It replaces itemize with a lookalike, instead of trying to fiddle around with wrapfig.

\documentclass{article}

%put this code in preamble
\newlength{\bulletwidth}\settowidth{\bulletwidth}{$\bullet$}
\newcommand{\mitem}{\setlength{\leftskip}{\leftmargin}\hspace*{-\labelsep}\hspace*{-\bulletwidth}$\bullet$\hspace*{\labelsep}}
\newcommand{\mend}{\setlength{\leftskip}{0cm}}

\begin{document}

Some text.

\mitem This is an example of a list item.

\mitem Second item in list.

\mend

Some more text.

\end{document}

Each \mitem in the list must be preceded by a blank line. The list ends with \mend (also preceded by a blank line). There's no command to begin the list. This works for simple text items; I haven't tried it with anything more complicated.

Someone who knows more about how itemize works (and why it conflicts with wrapfig) might be able to make an even better imitation. It would also be fairly easy to generalize this to enumerate'd lists if necessary.

  • 1
    If each \mitem must start with a new paragraph, why not simply put a \par into its definition? – Skillmon May 15 at 19:39
1

You can create a new wrap enviroment. In the following MWE my wrapr env. places the image in the right side of the page while wrapl place it in the left. Both enviroments have the same structure:

wrapr{vertical adjustment of text}{number of lines}{horizontal space needed for the image}{vertical adjustment of image}{IMAGE}{TEXT}

We can see here both enviroments in use

\documentclass[a4paper,11pt]{article}
\usepackage{graphicx}
\usepackage{tikz,pgfplots,tkz-euclide}
\tkzSetUpPoint[size=7,fill=white]
\usepackage{wrapfig}


\newenvironment{WrapText1}[3][r]
{\wrapfigure[#2]{#1}{#3}}
{\endwrapfigure}
\newenvironment{WrapText2}[3][l]
{\wrapfigure[#2]{#1}{#3}}
{\endwrapfigure}
\newcommand{\wrapr}[6]{
\begin{minipage}{\linewidth}\mbox{}\\
\vspace{#1}
\begin{WrapText1}{#2}{#3}
\vspace{#4}#5\end{WrapText1}#6
\end{minipage}}

\newcommand{\wrapl}[6]{
\begin{minipage}{\linewidth}\mbox{}\\
\vspace{#1}
\begin{WrapText2}{#2}{#3}
\vspace{#4}#5\end{WrapText2}#6
\end{minipage}}
\usepackage{lipsum}


\begin{document}
\wrapr{-4mm}{8}{4cm}{5mm}{\begin{tikzpicture}
\tkzDefPoint(3,0){C}
\tkzDefPoint(0,0){B}
\tkzDefPoint(1,2){A}
\tkzDefPoint(1.33,.66){G}
\tkzDefPoint(1.5,0){M}
\tkzDefPoint(.5,1){N}
\tkzDefPoint(2,1){P}
\draw(A)--(B)--(C)-- cycle;
\draw(A)--(M);
\draw(B)--(P);
\draw(C)--(N);
\tkzLabelPoint[left](B){$B$}
\tkzLabelPoint[below](M){$D$}
\tkzLabelPoint[right](P){$E$}
\tkzLabelPoint[left](N){$Z$}
\tkzLabelPoint[right](C){$C$}
\tkzLabelPoint[above](A){$A$}
\tkzLabelPoint[left,yshift=-3mm,xshift=1.7mm](G){$G$}
\tkzDrawPoints(A,B,C,M,N,P,G)
\end{tikzpicture}}{\begin{enumerate}
\item \lipsum[1]
\end{enumerate}}
\vspace{2cm}
\wrapl{-4mm}{8}{3cm}{5mm}{\begin{tikzpicture}
\tkzDefPoint(3,0){C}
\tkzDefPoint(0,0){B}
\tkzDefPoint(1,2){A}
\tkzDefPoint(1.33,.66){G}
\tkzDefPoint(1.5,0){M}
\tkzDefPoint(.5,1){N}
\tkzDefPoint(2,1){P}
\draw(A)--(B)--(C)-- cycle;
\draw(A)--(M);
\draw(B)--(P);
\draw(C)--(N);
\tkzLabelPoint[left](B){$B$}
\tkzLabelPoint[below](M){$D$}
\tkzLabelPoint[right](P){$E$}
\tkzLabelPoint[left](N){$Z$}
\tkzLabelPoint[right](C){$C$}
\tkzLabelPoint[above](A){$A$}
\tkzLabelPoint[left,yshift=-3mm,xshift=1.7mm](G){$G$}
\tkzDrawPoints(A,B,C,M,N,P,G)
\end{tikzpicture}}{\begin{enumerate}
\item \lipsum[1]
\end{enumerate}}
\end{document}

enter image description here

protected by Joseph Wright Mar 13 '15 at 14:26

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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