0

I've drawn a multi-line box around a text in a paragraph using the code at multi-line-box-around-a-sentence-in-a-paragraph For simplicity, let's call this multi-line boxed text as highlighted text.

Now I'd like to draw a line from this highlighted text to a TikZ node I've formed. Here is the MWE:

% The code must be run at least 2 times!
% The code from here until the begin{document} is taken from:
% https://tex.stackexchange.com/questions/116900/multi-line-box-around-a-sentence-in-a-paragraph
% with minor additions / modifications
\documentclass{article}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother

\newcommand\BoxedText[4][]{%
\begin{tikzpicture}[remember picture,overlay]
\draw[#1]
  let \p1=(pic cs:#2), \p2=(pic cs:#3) in
  ([yshift=-0.8ex]\p1) --
  ([yshift=2ex]\p1) -- 
  ([xshift=3pt,yshift=2ex]\p1-|current page text area.east) -- 
  ([xshift=3pt,yshift=2ex]\p2-|current page text area.east) --
  ([yshift=2ex]\p2) --
  ([yshift=-0.8ex]\p2) --
  ([xshift=-3pt,yshift=-0.8ex]\p2-|current page text area.west) --
  ([xshift=-3pt,yshift=-0.8ex]\p1-|current page text area.west) --
  cycle node (#4) {}
; % (#4) is added in order to name the node 
\end{tikzpicture}%
}
\usepackage{blindtext}
\begin{document}

\BoxedText[]{start1}{end1}{MYPARAGRAPH}

% \blindtext[100] Nope, this doesn't work in this particular case.
Some text goes here. I have to add some text manually here. blindtext[100] doesn't work here. Sorry. Some text goes here. Some text goes here.Some text goes here.Some text goes here. Some text goes here. 
\tikzmark{start1} Some text goes here. Some text goes here. Some text goes here. Some text goes here.Some text goes here.Some text goes here. Some text goes here. Some text goes here. Some text goes here. Some text Some text goes here \tikzmark{end1} Some text goes here. Some text goes here. Some text goes here. Some text goes here.Some text goes here. Some text goes here. Some text goes here. Some text goes here. Some text goes here. Some text Some text goes here

\begin{tikzpicture}[]
  \node[rectangle,
    below=0.5cm of MYPARAGRAPH,
    draw=blue,]
  (MYNOTE){\footnotesize Here is my note};
  \draw[very thick,blue] 
  (MYPARAGRAPH) -| (MYNOTE);
\end{tikzpicture}     

\end{document}

The \drawed line seems to end at the region where the paragraph ends. I'd like to extend the \draw 'ed line up to the border of the highlighted text like this:

node to node line

How to do it?

1 Answer 1

3

One way to do that is to place a coordinate when drawing your box around the text. Here I did coordinate[midway](leftside) to place this coordinate in the middle of the left side of your box.

Then, instead of trying to draw from a node to this place, I found it easier to do the opposite: drawing from the left side of the box to somewhere below the text and placing your node at the end.

draw from text to node

Obviously, the distances can be adjusted as you wish.

% The code must be run at least 2 times!
% The code from here until the begin{document} is taken from:
% https://tex.stackexchange.com/questions/116900/multi-line-box-around-a-sentence-in-a-paragraph
% with minor additions / modifications
\documentclass{article}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] #1;}
\makeatother

\newcommand\BoxedText[4][]{%
\begin{tikzpicture}[remember picture,overlay]
\draw[#1]
  let \p1=(pic cs:#2), \p2=(pic cs:#3) in
  ([yshift=-0.8ex]\p1) --
  ([yshift=2ex]\p1) -- 
  ([xshift=3pt,yshift=2ex]\p1-|current page text area.east) -- 
  ([xshift=3pt,yshift=2ex]\p2-|current page text area.east) --
  ([yshift=2ex]\p2) --
  ([yshift=-0.8ex]\p2) --
  ([xshift=-3pt,yshift=-0.8ex]\p2-|current page text area.west) --
  ([xshift=-3pt,yshift=-0.8ex]\p1-|current page text area.west) coordinate[midway](leftside) --
  cycle node (#4) {}
; % (#4) is added in order to name the node 
\end{tikzpicture}%
}
\usepackage{blindtext}
\begin{document}

\BoxedText[]{start1}{end1}{MYPARAGRAPH}

% \blindtext[100] Nope, this doesn't work in this particular case.
Some text goes here. I have to add some text manually here. \blindtext[1]

Some text goes here. Some text goes here.Some text goes here.Some text goes here. Some text goes here. \tikzmark{start1} Some text goes here. Some text goes here. Some text goes here. Some text goes here.Some text goes here.Some text goes here. Some text goes here. Some text goes here. Some text goes here. Some text Some text goes here \tikzmark{end1} Some text goes here. Some text goes here. Some text goes here. Some text goes here.Some text goes here. Some text goes here. Some text goes here. Some text goes here. Some text goes here. Some text Some text goes here

\begin{tikzpicture}[remember picture, overlay]
    \draw[very thick,blue]  (leftside) -|++ (-0.5,-2.2) -|++ (2,-.5) node [below,draw=blue,text=black] {\footnotesize Here is my note};
\end{tikzpicture}     

\end{document}
2
  • Thank you for the answer. That worked it out in a heartbeat. Plus, drawing from the highlighted text box to somewhere below the text and placing an unnamed node on the fly looks good too. However, there's one detail I couldn't understand: How did you know/ensure that the \draw would start from the BoxedText named MYPARAGRAPH without giving it the name MYPARAGRAPH? (My guess) Is it achieved by the [remember picture, overlay] options? Jan 4 at 19:18
  • 1
    Like I said in my answer, I added a coordinate while drawing the BoxedText. Search coordinate[midway](leftside) into the code. This places a coordinate in the middle of the left vertical line of your BoxedText that you can access later in another tikzpicture, thanks to the [remember picture, overlay] option.
    – SebGlav
    Jan 5 at 18:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .