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?

Schweinebacke
  • 26,336
fauve
  • 2,501
  • see https://tex.stackexchange.com/a/406009/2388 – Ulrike Fischer Dec 21 '18 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 Dec 21 '18 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. – Ulrike Fischer Dec 21 '18 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 Dec 21 '18 at 20:11
  • You could measure the side boxes and calculate the needed parshape. – Ulrike Fischer Dec 21 '18 at 20:20
  • Note that parshape only does one paragraph at a time. – John Kormylo Dec 30 '18 at 16:28

1 Answers1

1

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}

Vincent
  • 20,157
  • 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 May 17 '20 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 May 17 '20 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 May 17 '20 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 May 17 '20 at 15:17
  • It work fine, I just edit your code to add \usepackage{xparse} for \NewDocumentCommand’s support. – fauve May 17 '20 at 17:11
  • @fauve Good point. At first I did not load it separately in the example since \lipsum already loads it. – Vincent May 17 '20 at 21:22