65

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.

ScottKu
  • 846
  • 1
  • 6
  • 7
  • 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 08 '12 at 19:04
  • 1
    Another solution to having cutouts in latex lists is given here

    http://tex.stackexchange.com/questions/53702/wrapping-text-in-enumeration-environment-around-a-table/53715#53715

    – David Carlisle Jun 08 '12 at 20:45
  • @JosephWright Do you have a link with more information about 13galley? – student Jan 01 '15 at 12:16
  • @student http://texdoc.net/pkg/xgalley and http://texdoc.net/pkg/l3galley would be a start – Joseph Wright Jan 01 '15 at 15:15
  • 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
  • @student l3galley can only really work as part of a new format: whilst it will help at the present that's only in carefully set-up tests. Bruno Le Floch is intending to see if we can 'force' the code to work with existing formats but I'm doubtful. – Joseph Wright Sep 11 '15 at 05:17
  • 1
    @JosephWright What do you mean by "new format" in this case? – student Sep 11 '15 at 06: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 08:48

5 Answers5

26

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

Aditya
  • 62,301
24

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.

Gonzalo Medina
  • 505,128
  • 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 08 '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 08 '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 08 '12 at 20:01
  • Your minimal working example (cut win package) fails if one uses a different font, say \usepackage{palatino}. – Vafa Khalighi Jun 09 '12 at 03:18
  • @VafaKhalighi yes, obviously it fails, because wrapping is related to font dimensions, that's why the packages like cutwin and wrapfig do exist, but in some cases, they cannot be used. The same problem can arise if the text contains inline math which changes the real baseline distance... – yo' Jun 09 '12 at 06:36
  • @tohecs:unliike cutwin, wrapfig does not fail. – Vafa Khalighi Jun 09 '12 at 08:07
  • cutwin doesn't seem to come with ubuntu, any way I can install it? – Ricky Robinson Dec 04 '12 at 17:10
  • @RickyRobinson You can download the files from CTAN: http://www.ctan.org/tex-archive/macros/latex/contrib/cutwin then you can extract the .sty file and place it somewhere TeX can find it. In this site there's some question/answers addressing manual installation of packages. You should consider installing a complete TeX Live system from TUG: http://www.tug.org/texlive/ – Gonzalo Medina Dec 04 '12 at 17:16
  • 1
    what if you want to add two different figures inside the same itemize? – glS Dec 04 '15 at 11:18
7

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}
Sunday
  • 592
5

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.

Mike
  • 59
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

mac
  • 1,479