1

Some text in a paragraph may need frame out of them, and this framed text may cross lines. \framebox seems not be able to do that. How to get this effect as shown on the attached figure which is clipped in Microsoft Word?enter image description here

  • There are tons of ways. See e.g. this post, which does more fancy stuff, but one can always downgrade. – user121799 May 20 '18 at 1:51
2

Here is some code that I almost entirely stole from gusbrs's brilliant answer, which to the best of my knowledge is the only reliable code that is very flexible and deals with page breaks.

\documentclass[12pt,DIV=8]{scrartcl}
\usepackage{soulutf8}
\usepackage{atbegshi}
\usepackage{etoolbox}
\usepackage{tikz} % from https://tex.stackexchange.com/a/429389/121799
\usetikzlibrary{tikzmark,calc,decorations.pathmorphing}


\colorlet{tdcolor}{yellow!35}

\makeatletter

\newlength{\txtdec@depth}
\setlength{\txtdec@depth}{.5ex}
\newlength{\txtdec@height}
\setlength{\txtdec@height}{\f@size pt} % sensible default

\newcounter{txtdec@hyphmark}
\newcounter{txtdec@decormark}
\newcounter{txtdec@hyphdraw}
\setcounter{txtdec@hyphdraw}{1}
\newcounter{txtdec@decordraw}
\setcounter{txtdec@decordraw}{1}

\newcounter{txtdec@thenextpage}

\newtoggle{txtdec@unfinisheddecor}
\newtoggle{txtdec@stayonpage}
\newtoggle{txtdec@stayondecor}
\newtoggle{txtdec@stayonline}

% from https://tex.stackexchange.com/a/33765/105447
\newcommand{\gettikzxy}[3]{%
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \edef#2{\the\pgf@x}%
  \edef#3{\the\pgf@y}%
}

% the drawing macros

\newcommand{\txtdec@draw@all}{%
%   \fill[tdcolor, decoration = {random steps, amplitude=1pt, segment length=10pt},
%         outer sep = -15pt, inner sep = 0pt, decorate] 
 \draw      ($(\Xbegin,\Ybegin)+(0,-\txtdec@depth)$) rectangle ($(\Xend,\Yend)+(0,\txtdec@height-\txtdec@depth)$) ;
}

\newcommand{\txtdec@draw@begin}{%
%   \fill[tdcolor, decoration = {random steps, amplitude=1pt, segment length=10pt},
%         outer sep = -15pt, inner sep = 0pt, decorate] 
\draw
        ($(\Xbegin,\Ybegin)+(0,-\txtdec@depth)$) rectangle ($(\Xlineend,\Ylineend)+(0,\txtdec@height-\txtdec@depth)$) ;
}

\newcommand{\txtdec@draw@middle}{%
%   \fill[tdcolor, decoration = {random steps, amplitude=1pt, segment length=10pt},
%         outer sep = -15pt, inner sep = 0pt, decorate] 
\draw       ($(\Xlinebegin,\Ylinebegin)+(0,-\txtdec@depth)$) rectangle ($(\Xlineend,\Ylineend)+(0,\txtdec@height-\txtdec@depth)$) ;
}

\newcommand{\txtdec@draw@end}{%
%   \fill[tdcolor, decoration = {random steps, amplitude=1pt, segment length=10pt},
%         outer sep = -15pt, inner sep = 0pt, decorate] 
\draw       ($(\Xlinebegin,\Ylinebegin)+(0,-\txtdec@depth)$) rectangle ($(\Xend,\Yend)+(0,\txtdec@height-\txtdec@depth)$) ;
}

% using soul to set tikzmarks

\def\SOUL@tdleaders{%
  \stepcounter{txtdec@hyphmark}%
  \tikzmark{p\thepage.d\arabic{txtdec@decormark}.\arabic{txtdec@hyphmark}}%
  \leaders\hrule\@depth\z@\@height\z@\relax
}

\def\SOUL@tdunderline#1{{%
    \setbox\z@\hbox{#1}%
    \dimen@=\wd\z@
    \dimen@i=\SOUL@uloverlap
    \advance\dimen@2\dimen@i
    \rlap{%
      \null
      \kern-\dimen@i
      \SOUL@ulcolor{\SOUL@tdleaders\hskip\dimen@}%
      \hskip\dimen@
    }%
    \unhcopy\z@
  }}

\def\SOUL@tdpreamble{%
  \spaceskip\SOUL@spaceskip
  \stepcounter{txtdec@decormark}%
  \setcounter{txtdec@hyphmark}{0}%
  \tikzmark{p\thepage.d\arabic{txtdec@decormark}.begin}%
}
\def\SOUL@tdeverysyllable{%
  \SOUL@tdunderline{%
    \the\SOUL@syllable
    \SOUL@setkern\SOUL@charkern
  }%
  \stepcounter{txtdec@hyphmark}%
  \tikzmark{p\thepage.d\arabic{txtdec@decormark}.\arabic{txtdec@hyphmark}}%
}
\def\SOUL@tdeveryhyphen{%
  \discretionary{%
    \unkern
    \SOUL@tdunderline{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
    }%
    \stepcounter{txtdec@hyphmark}%
    \tikzmark{p\thepage.d\arabic{txtdec@decormark}.\arabic{txtdec@hyphmark}}%
  }{}{}%
}
\def\SOUL@tdeveryexhyphen#1{%
  \SOUL@setkern\SOUL@hyphkern
  \SOUL@tdunderline{#1}%
  \stepcounter{txtdec@hyphmark}%
  \tikzmark{p\thepage.d\arabic{txtdec@decormark}.\arabic{txtdec@hyphmark}}%
  \discretionary{}{}{%
    \SOUL@setkern\SOUL@charkern
  }%
}
\def\SOUL@tdpostamble{%
  % create an extra mark, vertically displaced, to create an exit condition for the last line
  \stepcounter{txtdec@hyphmark}%
  \raisebox{-5pt}{\tikzmark{p\thepage.d\arabic{txtdec@decormark}.\arabic{txtdec@hyphmark}}}%
  \tikzmark{p\thepage.d\arabic{txtdec@decormark}.end}%
}
\def\SOUL@tdsetup{%
  \SOUL@setup
  \let\SOUL@preamble\SOUL@tdpreamble
  \let\SOUL@everysyllable\SOUL@tdeverysyllable
  \let\SOUL@everyhyphen\SOUL@tdeveryhyphen
  \let\SOUL@everyexhyphen\SOUL@tdeveryexhyphen
  \let\SOUL@postamble\SOUL@tdpostamble
}
\DeclareRobustCommand*\textdecor{\SOUL@tdsetup\SOUL@}

% get the drawing done AtBeginShipout

\AtBeginShipout{%
  \AtBeginShipoutUpperLeft{%
    % getting the number of the next page
    \setcounter{txtdec@thenextpage}{\thepage}%
    \stepcounter{txtdec@thenextpage}%
    % if the current decoration occurs on this page, stay on it
    \iftikzmark{p\thepage.d\arabic{txtdec@decordraw}.\arabic{txtdec@hyphdraw}}{%
      \toggletrue{txtdec@stayonpage}}{}%
    \whileboolexpr{togl {txtdec@stayonpage}}{%
      \begin{tikzpicture}[remember picture, overlay]
        \iftikzmark{p\thepage.d\arabic{txtdec@decordraw}.begin}{%
          % if current decor begins in current page, get coordinates
          \gettikzxy{(pic cs:p\thepage.d\arabic{txtdec@decordraw}.begin)}{\Xbegin}{\Ybegin}}{%
          % if current decor begins in previous page, set to top left of the page
          \gettikzxy{(current page.north west)}{\Xbegin}{\Ybegin}}%
        \iftikzmark{p\thepage.d\arabic{txtdec@decordraw}.end}{%
          % if current decor ends in current page, get coordinates
          \gettikzxy{(pic cs:p\thepage.d\arabic{txtdec@decordraw}.end)}{\Xend}{\Yend}}{%
          % if current decor ends in future page, set to bottom right of the page
          \gettikzxy{(current page.south east)}{\Xend}{\Yend}}%
        \ifdim\Ybegin=\Yend % the simplest case, a single line
          \txtdec@draw@all
          \stepcounter{txtdec@decordraw}%
        \else % current textdecor has a line break          
          \toggletrue{txtdec@stayondecor}%
          \whileboolexpr{togl {txtdec@stayondecor}}{%
            \gettikzxy{(pic cs:p\thepage.d\arabic{txtdec@decordraw}.\arabic{txtdec@hyphdraw})}{\Xlinebegin}{\Ylinebegin}%
            \edef\Xcurrent{\Xlinebegin}%
            \edef\Ycurrent{\Ylinebegin}%
            \edef\Xnext{\Xcurrent}%
            \edef\Ynext{\Ycurrent}%
            \toggletrue{txtdec@stayonline}%
            \whileboolexpr{togl {txtdec@stayonline}}{%
              \ifdim\Ycurrent=\Ynext
                \stepcounter{txtdec@hyphdraw}%
                % if the following tikzmark exists, we are at a page break
                \iftikzmark{p\arabic{txtdec@thenextpage}.d\arabic{txtdec@decordraw}.\arabic{txtdec@hyphdraw}}{%
                  \edef\Xcurrent{\Xnext}%
                  \edef\Ycurrent{\Ynext}%
                  \gettikzxy{(current page.south east)}{\Xnext}{\Ynext}
                  \togglefalse{txtdec@stayondecor}%
                }{% else, we remain on the same page
                  \iftikzmark{p\thepage.d\arabic{txtdec@decordraw}.\arabic{txtdec@hyphdraw}}{%
                    \edef\Xcurrent{\Xnext}%
                    \edef\Ycurrent{\Ynext}%
                    \gettikzxy{(pic cs:p\thepage.d\arabic{txtdec@decordraw}.\arabic{txtdec@hyphdraw})}{\Xnext}{\Ynext}}{}%
                }%
              \else
                \edef\Xlineend{\Xcurrent}%
                \edef\Ylineend{\Ycurrent}%
                % if we are on the first line of the current decoration
                \ifdim\Ylinebegin=\Ybegin
                  \txtdec@draw@begin
                \else
                  % if we are on the last line of the current decoration
                  \ifdim\Ycurrent=\Yend
                    \txtdec@draw@end
                    \stepcounter{txtdec@decordraw}%
                    \setcounter{txtdec@hyphdraw}{1}%
                    \togglefalse{txtdec@stayondecor}%
                  % if we are in a middle line of the decoration
                  \else
                    \txtdec@draw@middle
                  \fi
                \fi
                \togglefalse{txtdec@stayonline}%  
              \fi
            }%
          }%
        \fi
      \end{tikzpicture}%
      % if the beginning of the next decor does not exist in this page, leave this page
      \iftikzmark{p\thepage.d\arabic{txtdec@decordraw}.begin}{}{%
        \togglefalse{txtdec@stayonpage}}%
      % if the continuation of the current decor exists in the next page, leave this page
      \iftikzmark{p\arabic{txtdec@thenextpage}.d\arabic{txtdec@decordraw}.\arabic{txtdec@hyphdraw}}{%
        \togglefalse{txtdec@stayonpage}}{}% 
    }%
  }%
}

\makeatother

\begin{document}

\vspace*{5cm}

Lorem ipsum \textdecor{dolor sit amet, consectetuer adipiscing}
elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae,
felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget,
consectetuer id, vulputate a, magna.  \textdecor{Donec vehicula augue
  eu neque. Pellentesque habitant morbi tristi-que senectus et netus
  et malesuada fames ac -- turpis --- egestas. Mauris ut leo. Cras
  viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla
  ultrices.} Phasellus eu tellus sit amet tortor gravida
placerat. Integer sapien est, iaculis in, pretium quis, viverra ac,
nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac,
nulla. Curabitur auctor semper nulla. Donec varius orci eget
risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis,
diam. Duis eget orci sit amet orci dignissim rutrum.  Nam dui ligula,
fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi auctor
lorem non justo. Nam lacus libero, pretium at, lobortis vitae,
ultricies et, tellus. Donec aliquet, tortor sed accumsan bibendum,
erat ligula aliquet magna, vitae ornare odio metus a mi.  Morbi ac
orci et nisl hendrerit mollis. Suspendisse ut massa.  Nam dui ligula,
fringilla a, euismod sodales, sollicitudin vel, wisi. Morbi auctor
lorem non justo. Nam lacus libero, pretium at, lobortis vitae,
ultricies et, tellus. Donec aliquet, tortor sed accumsan bibendum,
erat ligula aliquet magna, vitae ornare odio metus a mi.  Morbi ac
orci et nisl hendrerit mollis. Suspendisse ut massa.  \textdecor{Nam
  dui ligula, fringilla a, euismod sodales, sollicitudin vel,
  wisi. Morbi auctor lorem non justo. Nam lacus libero, pretium at,
  lobortis vitae, ultricies et, tellus. Donec aliquet, tortor sed
  accumsan bibendum, erat ligula aliquet magna, vitae ornare odio
  metus a mi.  Morbi ac orci et nisl hendrerit mollis. Suspendisse ut
  massa.  Nam dui ligula, fringilla a, euismod sodales, sollicitudin
  vel, wisi. Morbi auctor lorem non justo. Nam lacus libero, pretium
  at, lobortis vitae, ultricies et, tellus. Donec aliquet, tortor sed
  accumsan bibendum, erat ligula aliquet magna, vitae ornare odio
  metus a mi.  Morbi ac orci et nisl hendrerit mollis. Suspendisse ut
  massa.  Cras nec ante. Pellentesque a nulla.} Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus.
Aliquam tincidunt urna. Nulla ullamcorper vestibulum
turpis. Pellentesque cursus luctus mauris.

\begin{quotation}
  Lorem ipsum \textdecor{dolor sit amet, consectetuer adipiscing}
  elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae,
  felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy
  eget, consectetuer id, vulputate a, magna.  \textdecor{Donec
    vehicula augue eu neque. Pellentesque habitant morbi tristi-que
    senectus et netus et malesuada fames ac -- turpis ---
    egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et
    lectus vestibulum urna fringilla ultrices.} Phasellus eu tellus
  sit amet tortor gravida placerat.
\end{quotation}

\begin{itemize}
\item Lorem ipsum \textdecor{dolor sit amet, consectetuer adipiscing}
  elit.
\item Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae,
  felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy
  eget, consectetuer id, vulputate a, magna. \textdecor{Donec vehicula
    augue eu neque. Pellentesque habitant morbi tristi-que senectus et
    netus et malesuada fames ac -- turpis --- egestas. Mauris ut leo.}
\end{itemize}

\end{document}

All I did is to replace some \fill commands by \draw commands. All credits go to gusbrs.

  • @lyl Yes, I know, it looks complicated, but I think sooner or later this will become a package. If you scroll through the list of linked posts of this post, you will certainly find something simpler. – user121799 May 20 '18 at 3:21
  • a package to solve it is a good idea. I hope it appears soon. And thanks again. – lyl May 20 '18 at 7:11
  • It can get somewhat prettified with tex.stackexchange.com/a/429498/105447. Or somewhat less code heavy with tex.stackexchange.com/a/427130/105447. – gusbrs May 21 '18 at 14:59

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.