如何在不使用任何包的情况下将文本环绕在框周围?

如何在不使用任何包的情况下将文本环绕在框周围?

自从修复了由于我的代码错误而导致的原始问题以来,这个问题已经被编辑。

我尝试使用wrapfig将文本环绕在右边距的框内,但该包的行为不可预测,它与我的文档的交互对我来说毫无意义。(例如,将一些文本封闭在组中会{}极大地影响最终的布局。)

现在,我正在寻找一个简单且可预测的解决方案,将段落环绕在一个与右边距齐平的框周围,并与段落的开头在顶部对齐。

我创建了一个框,并将其保存为名称\sbox下的\mybox。我编写了一些代码,以使用该框的宽度在右边距保留可用空间\parshape

我想知道将框插入保留空间(使用\usebox{\mybox})的“标准”或最简单的方法是什么,并将其与段落顶部对齐。我认为与段落框顶部对齐或与第一行的基线对齐都可以令人满意。以下是我所做的:

\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}

我的代码怎样才能改进或简化?

事实上,还存在一个问题:我不想使用\vspace*负参数,因为它会导致前面的材料之后出现错误的间距。

一个更普遍的问题:如果我在段落第 n 行到第 n+k 行的右边距为一个框保留一个空白区域,如何将框放在那里?

答案1

简单的解决方案是将段落环绕在与右(或左)边距齐平的框内,并在顶部与段落开头对齐。无需其他软件包。

\InsertBox为了自动化该过程,定义了具有 4 个参数的命令。

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

  1. (可选)在文本区域中放置框的位置:rlr,right, 是默认值);
  2. 盒子的内容(它不是一个浮点数!)
  3. 所需的盒子宽度;
  4. 要成形的段落。

其余一切都由他们决定。

使用宏生成用于格式化形状的行\newparshape从中获取的宏生成的parshape 的精简版本

更新在 Peter Wilson 发表评论之后。

现在\parindent可以取任意值,因此段落的开头很清晰。

到目前为止,它在分页符时还不能正常运行。

G

H

杰

\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}

相关内容