1

I try to do someting like in Margin notes on both left and right? but with wrapfig (or another package which permits it).

The goal is to get two margin notes witch overlap a little bit the main text zone with the text warped around. But the two margin notes have to be in the same line like in this mokup : enter image description here

The gray zones represent the notes. So, as you see, the notes could have a different size content.

So, for this a made the following MWE:

\documentclass[a4paper,12pt,oneside,french]{article}
\usepackage{wrapfig,graphicx,lipsum}


\begin{document}

\begin{wrapfigure}{l}[2cm]{0.3\textwidth}
    \includegraphics[width=\linewidth,height=80pt]{example-image}
\end{wrapfigure}
\begin{wrapfigure}{r}[2cm]{0.3\textwidth}
    \includegraphics[width=\linewidth,height=200pt]{example-image}
\end{wrapfigure}
\lipsum[1-4]
\end{document}

But, then, I get a wrong rendering as you can see:

enter image description here

So, how can we get a two margin note overlapping the text zone in one line?

6
  • see tex.stackexchange.com/a/406009/2388 Commented Dec 21, 2018 at 15:46
  • 1
    Yes we was in this tread, we can merge this new tread with the old one. But the problem in the answer of the old one is that it assume the two image have the same height, when it’s probable that the two images have a completely different height (the width is always the same).
    – fauve
    Commented Dec 21, 2018 at 15:54
  • 2
    The parshape doesn't need to be symmetric, for every line you can decide if and how much you want to cut out on each side. Commented Dec 21, 2018 at 16:01
  • Yes, so it need to be set manually. It isn’t possible to detect the height of each side’s box and adapt the parshape setting?
    – fauve
    Commented Dec 21, 2018 at 20:11
  • You could measure the side boxes and calculate the needed parshape. Commented Dec 21, 2018 at 20:20

1 Answer 1

1
+50

Here's a solution based on @UlrikeFischer's answer here, using \parshape instead of warpfigure. It also relies on the \replicate command defined by @JosephWright here.

I defined a new command \doublewrap which takes six arguments:

  1. (mandatory) The width of the left margin note,
  2. (optional) The number of lines that the left margin note should span,
  3. (mandatory) The content of the left margin note,

and 4, 5, and 6 are the same as 1, 2 and 3 respectively, but for the right margin note instead of the left one. \doublewrap outputs both margin notes halfway overlapped in the margin. It should be used just before a paragraph, which should be long enough to span the full height of margin notes. The number of lines (arguments 2 and 5) that the notes should span are calculated automatically if not given, but I strongly suspect that it would be better to set them manually in the cases where the following paragraph contains lines which modify the lines' height, such as display math environments.

Here's the definition of this command along with two examples, the first with images as margin notes and the second with text.

\documentclass{article}
\usepackage{xparse}
\usepackage{graphicx}
\usepackage{calc}
\usepackage{calculator}
\usepackage{lipsum}

\makeatletter
\newcommand*\replicate[1]{%
  \expandafter\replicate@aux\romannumeral\number\numexpr #1\relax000Q{}
}
\newcommand*\replicate@aux[1]{\csname replicate@aux@#1\endcsname}
\newcommand\replicate@aux@m{}
\long\def\replicate@aux@m#1Q#2#3{\replicate@aux#1Q{#2#3}{#3}}
\newcommand\replicate@aux@Q[2]{#1}
\makeatother

\newlength{\betweenwidth}
\newlength{\betweenpluswidth}
\newlength{\leftnotewidth}
\newlength{\rightnotewidth}
\newlength{\leftnotetotalheight}
\newlength{\rightnotetotalheight}
\newlength{\leftraise}
\newlength{\rightraise}
\newcounter{leftlines}
\newcounter{rightlines}
\newcounter{totallines}
\newsavebox{\leftbox}
\newsavebox{\rightbox}
\NewDocumentCommand{\doublewrap}{m o m m o m}{%
    \setlength{\leftnotewidth}{#1}
    \setlength{\rightnotewidth}{#4}
    \savebox{\leftbox}{\parbox{.9\leftnotewidth}{#3}}
    \savebox{\rightbox}{\parbox{.9\rightnotewidth}{#6}}
    \setlength{\leftnotetotalheight}{\ht\leftbox+\dp\leftbox}
    \setlength{\rightnotetotalheight}{\ht\rightbox+\dp\rightbox}
    \setlength{\betweenwidth}{\textwidth - .5\leftnotewidth - .5\rightnotewidth}
    \IfNoValueTF{#2}
        {\LENGTHDIVIDE{\leftnotetotalheight}{\baselineskip}{\divsol}%
         \INTEGERPART{\divsol}{\roundsol}%
         \setcounter{leftlines}{\roundsol+1}}
        {\setcounter{leftlines}{#2}}
    \IfNoValueTF{#5}
        {\LENGTHDIVIDE{\rightnotetotalheight}{\baselineskip}{\divsol}%
         \INTEGERPART{\divsol}{\roundsol}%
         \setcounter{rightlines}{\roundsol+1}}
        {\setcounter{rightlines}{#5}}
    \setcounter{totallines}{\maxof{\theleftlines}{\therightlines} + 2}
    \ifdim \leftnotetotalheight > \rightnotetotalheight
        \setlength{\rightraise}{\ht\leftbox - \ht\rightbox}
        \setlength{\leftraise}{0pt}
        \setlength{\betweenpluswidth}{\betweenwidth + .5\rightnotewidth}
        \parshape \thetotallines %
                                                    -.5\leftnotewidth \betweenwidth
            \replicate{              \therightlines}{.5\leftnotewidth \betweenwidth}
            \replicate{\theleftlines-\therightlines}{.5\leftnotewidth \betweenpluswidth}
                                                                  0pt \textwidth
    \else
        \setlength{\leftraise}{\ht\rightbox - \ht\leftbox}
        \setlength{\rightraise}{0pt}
        \setlength{\betweenpluswidth}{\betweenwidth + .5\leftnotewidth}
        \parshape \thetotallines %
                                                    -.5\leftnotewidth \betweenwidth
            \replicate{               \theleftlines}{.5\leftnotewidth \betweenwidth}
            \replicate{\therightlines-\theleftlines}{             0pt \betweenpluswidth}
                                                                  0pt \textwidth
    \fi
    \noindent\raisebox{-\height}[0pt][0pt]{%
        \makebox[\textwidth + .5\leftnotewidth + .5\rightnotewidth]{%
            \raisebox{\leftraise}{\usebox{\leftbox}}%
            \hfill%
            \raisebox{\rightraise}{\usebox{\rightbox}}%
        }%
    }%
}

\begin{document}

\doublewrap{.3\textwidth}{%
    \includegraphics[width=.27\textwidth, height=3cm]{example-image-a}%
}{.3\textwidth}{%
    \includegraphics[width=.27\textwidth, height=5cm]{example-image-b}%
}
\lipsum*[1-2]

\doublewrap{.4\textwidth}{%
    \LipsumPar{4}
}{.22\textwidth}{%
    \lipsum[1][1]
}
\lipsum*[8-9]

\end{document}

6
  • Honestly it answer a real large part of the problem. But there is no way to automatically detect the number of lines needed in parameters 2 and 5?
    – fauve
    Commented May 17, 2020 at 10:20
  • @fauve Yes, I also thought it would be better to set them automatically, or at least to set default values. I'll look into it.
    – Vincent
    Commented May 17, 2020 at 13:31
  • The two solutions are both interesting. So, is it possible for you to make another answer with automatic number of line if you could please? So I will make this message unsolved and mark the new one as solved.
    – fauve
    Commented May 17, 2020 at 13:35
  • @fauve I changed the definition of \doublewrap to make parameters 2 and 5 optional. Now they are automatically calculated by default, but they can still be specified manually if needed.
    – Vincent
    Commented May 17, 2020 at 15:17
  • It work fine, I just edit your code to add \usepackage{xparse} for \NewDocumentCommand’s support.
    – fauve
    Commented May 17, 2020 at 17:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .