3

Too Long; Didn't Read

See the figure. The yellow blocks are actually three nodes.

  • How to improve anchor border?
  • How to place such a node inline?
  • Or, overall, any better mechanism to do so?

Explanation

I started with this octagon. The black rays are there to illustrate the \anchorborder, which depict a rectangle as it is inherited from rectangle.

\documentclass{article}
\usepackage{tikz}
\begin{document}

\makeatletter
\pgfset{
  left indent/.initial  =\parindent,
  right indent/.initial =\parindent,
  top indent/.initial   =\baselineskip,
  bottom indent/.initial=\baselineskip,
}
\pgfdeclareshape{html span}
{
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchorborder[from=rectangle]
  \savedanchor\preindent{
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/left indent}}
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/top indent}}
  }
  \savedanchor\postindent{
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/right indent}}
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/bottom indent}}
  }
  \anchor{north west inner}{
    \southwest
    \pgf@xa=\pgf@x
    \northeast
    \pgf@ya=\pgf@y
    \preindent
    \advance\pgf@xa+\pgf@x \pgf@x=\pgf@xa
    \advance\pgf@ya-\pgf@y \pgf@y=\pgf@ya
  }
  \anchor{south east inner}{
    \southwest
    \pgf@ya=\pgf@y
    \northeast
    \pgf@xa=\pgf@x
    \postindent
    \advance\pgf@xa-\pgf@x \pgf@x=\pgf@xa
    \advance\pgf@ya+\pgf@y \pgf@y=\pgf@ya
  }
  \anchor{begin}{
    \southwest
    \pgf@xa=\pgf@x
    \northeast
    \pgf@ya=\pgf@y
    \preindent
    \advance\pgf@xa+  \pgf@x \pgf@x=\pgf@xa
    \advance\pgf@ya-.5\pgf@y \pgf@y=\pgf@ya
  }
  \anchor{end}{
    \southwest
    \pgf@ya=\pgf@y
    \northeast
    \pgf@xa=\pgf@x
    \postindent
    \advance\pgf@xa-  \pgf@x \pgf@x=\pgf@xa
    \advance\pgf@ya+.5\pgf@y \pgf@y=\pgf@ya
  }
  \backgroundpath{
    \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \preindent \pgf@xc=\pgf@x \pgf@yc=\pgf@y
    \pgfpathmoveto{\pgfqpoint{\pgf@xb        }{\pgf@yb        }}
    \pgfpathlineto{\pgfpoint {\pgf@xa+\pgf@xc}{\pgf@yb        }}
    \pgfpathlineto{\pgfpoint {\pgf@xa+\pgf@xc}{\pgf@yb-\pgf@yc}}
    \pgfpathlineto{\pgfpoint {\pgf@xa        }{\pgf@yb-\pgf@yc}}
    \postindent \pgf@xc=\pgf@x \pgf@yc=\pgf@y
    \pgfpathlineto{\pgfqpoint{\pgf@xa        }{\pgf@ya        }}
    \pgfpathlineto{\pgfpoint {\pgf@xb-\pgf@xc}{\pgf@ya        }}
    \pgfpathlineto{\pgfpoint {\pgf@xb-\pgf@xc}{\pgf@ya+\pgf@yc}}
    \pgfpathlineto{\pgfpoint {\pgf@xb        }{\pgf@ya+\pgf@yc}}
    \pgfpathclose
    \pgfsetarrowsstart{}
    \pgfsetarrowsend{}
 }
}

Now we can image some baby usage.

\begin{tikzpicture}[remember picture]
    \node[fill=yellow,shape=html span,minimum width=5cm,minimum height=3\baselineskip,left indent=8em,right indent=6em](B){Bravo};
    \tiny\path(B.north west inner)node{$\times$\rlap{nw}}(B.south east inner)node{\llap{se}$\times$};
\end{tikzpicture}

\bigskip

\begin{tikzpicture}[remember picture]
    \node[fill=yellow,shape=html span,minimum width=5cm,minimum height=2\baselineskip,left indent=4.5cm,right indent=3.5cm](C){Charlie};
    \tiny\path(C.north west inner)node{$\times$\rlap{nw}}(C.south east inner)node{\llap{se}$\times$};
\end{tikzpicture}

\bigskip

\begin{tikzpicture}[remember picture,overlay]
    \draw[red,->](B.end)to[out=0,in=180](C.begin);
\end{tikzpicture}

As to place it properly, I need four supporting nodes.

\newdimen\pgf@xd\newdimen\pgf@yd
\pgfset{
  inner sep=0pt,
  outer sep=0pt,
  html span over/.code args={(#1)(#2)(#3)(#4)}{
    \tikz@scan@one@point\pgfutil@firstofone(#1.north)
    \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone(#2)
    \pgf@xb=\pgf@x \pgf@yb=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone(#3)
    \pgf@xc=\pgf@x \pgf@yc=\pgf@y
    \tikz@scan@one@point\pgfutil@firstofone(#4.south)
    \pgf@xd=\pgf@x \pgf@yd=\pgf@y
    \pgfset{
      left indent/.expanded  =\pgf@xa-\pgf@xb,
      right indent/.expanded =\pgf@xc-\pgf@xd,
      /tikz/shape=html span,
      /tikz/anchor=center,
      /tikz/text width/.expanded =\pgf@xc-\pgf@xb,
      /tikz/text height/.expanded=\pgf@ya-\pgf@yd,
      /tikz/text depth/.expanded =0
    }
    \edef\tikz@node@at{\noexpand\pgfpoint{.5\pgf@xb+.5\pgf@xc}{.5\pgf@ya+.5\pgf@yd}}%
  }
}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    \tikz[overlay,remember picture]\node[anchor=base,red](D1){D1\strut};%
    \vadjust{\noindent\tikz[overlay,remember picture,red]\node(D2){D2};\hfill\tikz[overlay,remember picture,red]\node(D3){D3};}%
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.%
    \tikz[overlay,remember picture,red]\node[anchor=base](D4){D4\strut};
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \tikz[overlay,remember picture]\node[fill=yellow,opacity=.3,html span over=(D1)(D2)(D3)(D4)]{};

Finally I can pack them into two commands: \nodehighlight(#1) and \endnodehighlight(#1).

\def\nodehighlight(#1){%
    \tikz[overlay,remember picture]\node[anchor=base](#11){\strut};%
    \vadjust{\noindent\tikz[overlay,remember picture]\node(#12){};\hfill\tikz[overlay,remember picture]\node(#13){};}%
}
\def\endnodehighlight(#1){%
    \tikz[overlay,remember picture]\node[anchor=base](#14){\strut};%
    \tikz[overlay,remember picture]\node[fill=yellow,opacity=.3,html span over=(#11)(#12)(#13)(#14)](#1){};%
}
    Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. 
    \nodehighlight(E)%
    Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.%
    \endnodehighlight(E)
    Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante.
    \nodehighlight(F)%
    Etiam sit amet orci eget eros faucibus tincidunt.%
    \endnodehighlight(F)
    Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. 
    \nodehighlight(G)%
    Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla.%
    \endnodehighlight(G)
    Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.
    \tikz[remember picture,overlay]\draw[red](E.end)to[out=0,in=180](F.begin)(F.end)to[out=0,in=180](G.begin);

Problem(s)

  • How to improve anchor border? I have no reasonable idea concerning three cases in the last figure. (Namely: staying in a single line, broken into two pieces, and spanning over lines.)
  • How to place such a node properly? In my approach I assume every line is of (total)height \baselineskip, so I did not change top indent and bottom indent.
  • Minor issues:
    • fill the background, not foreground.
    • exceed the right border in case it spans to the next line.
    • what kind of anchor are useful in this case? How to name them to be self-explaining?
    • span over pages?
    • ...

Your Answer

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

Browse other questions tagged or ask your own question.