1

This question has been edited since the original problems due to errors in my code were fixed.

I tried to use wrapfig to wrap text around a box at the right margin, but the package behaves unpredictably, its interaction with my document makes no sense to me. (For example, enclosing some text in a group {} greatly affects the resulting layout.)

Now I am looking for a simple and predictable solution to wrap a paragraph around a box flushed to the right margin and aligned at the top with the start of the paragraph.

I had created a box and saved is with \sbox under \mybox name. I wrote some code to use the width of that box to reserve free space at the right margin using \parshape.

I would like to know what would be the "standard" or the simplest way to insert the box into the reserved space (with \usebox{\mybox}), aligning it at the top with the top of the paragraph. I think that alignment either with the top of the paragraph box or with the baseline of the first line would be both satisfactory. Here is what I did:

\documentclass{article}
\usepackage{lipsum}

\begin{document}

\newsavebox{\mybox}
\sbox{\mybox}{%
  \raisebox{-\height}{\fbox{\parbox{0.5\textwidth}{Floating\\\\\\frame}}}%
}
\newlength{\myboxwidth}
\setlength{\myboxwidth}{\wd\mybox}

\newlength{\parshapelinelen}
\setlength{\parshapelinelen}{\textwidth}
\addtolength{\parshapelinelen}{-\myboxwidth}
\addtolength{\parshapelinelen}{-\columnsep}

\hbox to \hsize{\hfill\smash{\usebox{\mybox}}}
\vspace*{-\baselineskip}

\parshape=5
0pt \parshapelinelen
0pt \parshapelinelen
0pt \parshapelinelen
0pt \parshapelinelen
0pt \textwidth
\lipsum[1]

\end{document}

How can my code be improved or simplified?

In fact, there is still a problem: I do not want to use \vspace* with negative argument because it can cause wrong spacing after the preceding material.

A more general question: if I reserved an empty space for a box at the right margin from line n to line n+k of a paragraph, how to put the box there?

13
  • 1
    well as your problems with wrapfig should tell you, this is not an easy task. So you should provide a complete example and not expect people to guess what you are doing. Nov 11, 2021 at 17:47
  • @UlrikeFischer, ok, but i though my description was sufficient.
    – Alexey
    Nov 11, 2021 at 17:49
  • 1
    I personally prefer the much simpler insbox over wrapfig.
    – Skillmon
    Nov 11, 2021 at 18:16
  • You can use the \InsertBoxR command, from the insbox plain TeX macros package.
    – Bernard
    Nov 11, 2021 at 18:23
  • @UlrikeFischer, i've fixed some problem with my code, edited my question, and added my code.
    – Alexey
    Nov 11, 2021 at 18:31

1 Answer 1

3

Simple solution to wrap a paragraph around a box flushed to the right (or left) margin, and aligned at the top with the start of the paragraph. No other packages were needed.

To automate the procedure, the command \InsertBox was defined, with 4 parameters.

\InsertBox[<l or r (default} >]{<box content>}{<box width>}{<text to be shaped>}

  1. (optional) where to place the box in the text area: r or l (r,right, is the default);
  2. content of the box (it is not a float!);
  3. desired box width;
  4. paragraph to be shaped.

Everything else follows from them.

The lines to do the formatting of the shape are generated using the macro \newparshape taken from condensed-version-of-parshape

UPDATE After Peter Wilson's comment.

Now \parindent can take any value, so the starting of the paragraphs are clear.

So far it won't behave properly on page breaks.

g

h

j

\documentclass{article}

\usepackage{kantlipsum}% dummy text 
\usepackage{graphicx}% insert figures   

%***************************************************************************************************
\newlength{\AboveSkipbox}
\setlength{\AboveSkipbox}{0.7\baselineskip}  % above space <<<<

\newlength{\Sidesepbox}
\setlength{\Sidesepbox}{1.5em} % side space <<<

\newlength{\BoxHeight}
\newlength{\ParHeight}  
\newlength{\FirstIndent}
\newlength{\FigureBoxWidth}
\newlength{\FigIndent}      
\newsavebox{\mybox} 
\newsavebox{\tmpbox}
%% From https://tex.stackexchange.com/questions/127504/more-condensed-version-of-parshape
\makeatletter
\let\SavedIndent\parindent  
\let\@afterindentfalse\@afterindenttrue
\@afterindenttrue
\def\newparshape{\parshape\@npshape0{}}
\def\@npshape#1#2#3{\ifx\\#3\expandafter\@@@npshape\else\expandafter\@@npshape\fi
    {#1}{#2}{#3}}
\def\@@npshape#1#2#3#4#5{%
    \ifnum#3>\z@\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
    {\expandafter\@@npshape\expandafter{\the\numexpr#1+1\relax}{#2 #4 #5}{\numexpr#3-1\relax}{#4}{#5}}%
    {\@npshape{#1}{#2}}}
\def\@@@npshape#1#2#3{#1 #2}
\def\SetFirstIndent{\if@afterindent\FirstIndent\SavedIndent\else\FirstIndent\z@\fi}
\makeatother
        
\newcommand{\nlines}[1]{\the\numexpr#1/\baselineskip +1 \relax}     
\newcommand{\TypesetBox}[1]{\makebox[\linewidth][#1]{\raisebox{\dimexpr-\ht\mybox-\AboveSkipbox\relax}[0pt][0pt]{\usebox{\mybox}}}}     
\newcommand{\TypesetTextShortLong}[1]{%
    \hspace*{\parindent}
    \ifdim\dimexpr\ht\tmpbox+\dp\tmpbox<\dimexpr\ht\mybox+\dp\mybox+2\baselineskip\relax%short
    \hspace{-\parindent}\usebox{\tmpbox}\vspace{\dimexpr\ht\mybox+\dp\mybox+\AboveSkipbox-\ht\tmpbox-\dp\tmpbox\relax}
    \else%long
    #1\fi
}

\newcommand{\MakeFigureSpace}[1]{%
\ifx#1l% left
\setlength{\FigIndent}{\FigureBoxWidth}
    \else% right
\setlength{\FigIndent}{0pt} 
\fi
}

\newcommand{\InsertBox}[4][r]{%
\SetFirstIndent%    
\setlength{\FigureBoxWidth}{\dimexpr#3+\Sidesepbox\relax}   
\sbox{\tmpbox}{\parbox[t]{\dimexpr\linewidth-\FigureBoxWidth\relax}{\hspace{\FirstIndent}#4}}
\sbox{\mybox}{\fbox{\parbox{#3}{#2}}}%
\MakeFigureSpace{#1}% Figure Indent = \parindent or Fig Box width
\vspace{-\baselineskip} 
\hspace{\dimexpr-\FigIndent-\parindent\relax}\TypesetBox{#1}    
\newparshape% shape paragraph text
{\nlines{\dimexpr\ht\mybox+\dp\mybox+\baselineskip\relax}}{\FigIndent}{\dimexpr\linewidth-\FigureBoxWidth\relax}%
{1}{0pt}{\linewidth}\\
\TypesetTextShortLong{#4} 
}
%***************************************************************************************************

\begin{document}

    \InsertBox{It is not a floating \\ \\ \\ \\ frame}{0.5\textwidth}{\kant[2]}
    
    \kant[9]
    
    \InsertBox{\bfseries \large As I have shown elsewhere, Aristotle tells
    us that the objects in space and time, in the full sense of these
    terms, would be falsified.}{0.4\textwidth}{\kant[4]}
    
    \newpage 
    
    \section*{Right side}
    
    \noindent   \kant[9]
    
    \InsertBox{\centering\includegraphics[scale=0.35]{example-image}}{0.35\textwidth}{\kant[9]}
    
    \section*{Left side}
    
    \InsertBox[l]{\centering\includegraphics[scale=0.4]{example-image}}{0.4\textwidth}{\kant[9]}
        
    \newpage
    
    \section*{Right side, short paragraph}  
    
    \noindent   \kant[9]
    
    \InsertBox{\centering\includegraphics[scale=0.4]{example-image}}{0.4\textwidth}{As any dedicated reader can clearly see, the Ideal of
    practical reason is a representation of, as far as I know, the things
    in themselves; as I have shown elsewhere, the phenomena should only be
    used as a canon for our understanding. }
    
    \kant[9]
    
    \section*{Left side, short paragraph}
    
    \InsertBox[l]{\centering\includegraphics[scale=0.4]{example-image}}{0.4\textwidth}{As any dedicated reader can clearly see, the Ideal of
    practical reason is a representation of, as far as I know, the things
    in themselves; as I have shown elsewhere, the phenomena should only be
    used as a canon for our understanding.}
    
    \kant[9]

\end{document}
3
  • Very impressive. I tried it with a non-zero \parindent and the box extended into the margin. Any chance of the box taking account of the \parindent so as not to extend into the margin? On the other hand as it is set up it looks almost as if the first two boxes are in continuous text instead of separate paragraphs (except for the short lines just before the boxes). It seems that there might be a lot of design options that could be desired but I'm not suggesting that any be implemented as that could be a never-ending task. You could make it into a package but then the OP would not use it! Nov 13, 2021 at 19:39
  • @Peter Wilson Food for (more) thought. Thank you. Nov 13, 2021 at 20:08
  • @Peter Wilson Updated following your suggestion on the \parindent Nov 13, 2021 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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