1

I had this question about a feature that would make my life much much easier. Is it possible to take a paragraph, have TeX break it into lines, and then have tikz access the individual lines and place them at different positions on the page? So, for example, I have a paragraph of 10 lines (but I don't know necessarily in advance that there will be 9 or 10 or 11 lines), and I want tikz to take the individual lines and place them on different locations, for example so that their origins are points of a cicle.

(I guess this would use \unvbox, a command that is still mysterious to me, and some kind of loop to access the individual hboxes contained in the vbox, would this be a TeX loop or a tikz loop?)

After the demand by user202729 to give an explicit example, here we are:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit, positioning}
\usepackage{lipsum}

\begin{document}
\begin{tikzpicture}[remember picture,overlay,shift=(current page.south west)]

\node[align=left,text width=4cm] at (1in,1in) {some text spanning three lines with very nice automatic line breaks};

\end{tikzpicture}

\end{document}

Using this code I get

enter image description here

where the center of the text box is located at coordinates (1in,1in) (with the bottom left corner of the page being (0,0)).

First (minor) question: how can I refer to the point which is here:

enter image description here

that is the left boundary of the baseline of the first line of text? (I call this the origin of the line)

Second (major) question: how can I break this text into lines and have tikz place these lines at different locations? For example, I want the (origin of the) first line to be at coordinates (2in,2in), the (origin of the) second line to be at coordinates (3.5in,0.75in) and the (origin of the) third line to be at some other given location?

Indeed there is an answer to the question "how do I frame every second line of a text" and indeed this is a step in the right direction, but how can I have \lastbox interact with tikz?

Ideally, what I need is the possibility to tell tikz "take this paragraph and place its individual lines at locations (2in,2in),(3in,50pt),(11bp,22345sp)… etc."

2

1 Answer 1

0

This prototype answers the main question(s) and the minor question. It will capture each line of a paragraph, one at the time, and loads them into tikz nodes.

The capture is done using Werner's command which uses \lastbox.

The command \TypesetLines{<text>} will display the lines using the x and y offsets, and an optional rotation, using the commands generated by

\RotateAndGo[<optional rotation angle>]{<consecutive number id>}{<x offset from corner>}{<y offset from corner>}

There are two modes of operation:

(1) With the manual mode you choose the rotation and position of each line with a \RotateAndGo per line. The number of \RotateAndGo required is at least equal as the number of lines.

(2) In automatic mode the parameters needed for \RotateAndGo are dynamically generated based on the number id (or other variable) by including its execution in the \makenodes command.

Each line is added to the tikz node together with a tikzmark with the same number id as the line. This allows an arrow to be drawn from anywhere on the page to the baseline at the beginning of any line.

a

Manual mode

b

Automatic mode: the starting points of the lines follow a quadratic curve.

c

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{tikzmark} % needed <<<<<<<<<<   

\usepackage[showframe]{geometry}
    
\newsavebox{\singleline}
\newcounter{xcount}\setcounter{xcount}{0}
\newcounter{xlinecount}

% From https://tex.stackexchange.com/a/57140/161015
\newcommand{\getlines}{% capture all  lines of a paragraph and puts them in their place
    \setbox\singleline\lastbox%
    \ifvoid\singleline%
    \noindent\ignorespaces%
    \else
    \unskip\unpenalty%
    \begingroup\getlines\endgroup
    \stepcounter{xcount}\setcounter{xlinecount}{\value{xcount}}\par
    \makenodes
    \fi}

\newcommand{\makenodes}{}

\newcommand{\TypesetLines}[1]{\parindent0pt\vbox{#1\par\getlines}} % load the paragraph  and display the lines

%\RotateAndGo[<optional rotation angle>]{<number ID >}{<x shift from corner>}{<y shift from corner>}
\newcommand{\RotateAndGo}[4][0]{% save rotation and shifts
    \expandafter\expandafter\expandafter\newcommand \csname  R#2\endcsname{#1}%
    \expandafter\expandafter\expandafter\newcommand \csname  Cx#2\endcsname{#3}%
    \expandafter\expandafter\expandafter\newcommand \csname  Cy#2\endcsname{#4}%
}

\begin{document}
\pagestyle{empty}   

% First example ********************************************
\newgeometry{textwidth=4.0cm}

\renewcommand{\makenodes}{%put the lines in their place, automatic mode
\RotateAndGo{\thexcount}{1cm}{-0.5in*\thexcount} % only y-shift
\tikz\node[inner sep=0pt,rotate=\expandafter\csname R\thexcount\endcsname,  remember picture, overlay, anchor= west ,draw] 
at ([xshift=\expandafter\csname Cx\thexcount\endcsname, yshift=\expandafter\csname Cy\thexcount\endcsname] current page.south west) 
{\tikzmark{\thexcount}\usebox{\singleline}}; % typeset  
}

\noindent Some text spanning three lines with very nice automatic line breaks \bigskip

From \tikzmarknode{here}~HERE to the first line baseline

\TypesetLines{Some text spanning three lines with very nice automatic line breaks}

\tikz[remember picture,overlay] \draw[->,red, very thick] (here) -- (pic cs:1); % the arrow to the baseline of the first line (# 1)

\newpage

% Second example ********************************************
\newgeometry{textwidth=4in}

\renewcommand{\makenodes}{%put the lines in their place, manual mode <<<<<<<<<<<<<<<<<<<<
    \tikz\node[inner sep=0pt,rotate=\expandafter\csname R\thexcount\endcsname,  remember picture, overlay, anchor= west ,draw] 
    at ([xshift=\expandafter\csname Cx\thexcount\endcsname, yshift=\expandafter\csname Cy\thexcount\endcsname] current page.south west) 
    {\tikzmark{\thexcount}\usebox{\singleline}}; % typeset  
}

\noindent 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.The paralogisms of practical
reason are what first give rise to the architectonic of practical
reason.

\bigskip

Arrow to the \tikzmarknode{last}~LAST line (\# \verb|\thexlinecount|) 

Last used line= \thexlinecount  

\newcounter{ctrx}\setcounter{ctrx}{\value{xlinecount}}
    
\addtocounter{ctrx}{1}
\RotateAndGo[0]{\thectrx}{0in}{-1in} % first line here is # 4
\addtocounter{ctrx}{1}
\RotateAndGo[-90]{\thectrx}{0in}{-1in}
\addtocounter{ctrx}{1}
\RotateAndGo[-90]{\thectrx}{2in}{-1in+\baselineskip}
\addtocounter{ctrx}{1}
\RotateAndGo[-90]{\thectrx}{4in}{-1in+2\baselineskip}
\addtocounter{ctrx}{1}
\RotateAndGo{\thectrx}{0.in}{-4.7in}

\TypesetLines{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.The paralogisms of practical
    reason are what first give rise to the architectonic of practical
    reason.}

\tikz[remember picture,overlay] \draw[->,red, very thick] (last) -- (pic cs:\thexlinecount); % the arrow to the baseline of the last line

\newpage

% Third example********************************************
\newgeometry{textwidth=3in,showframe=false}

\renewcommand{\makenodes}{%put the lines in their place
    \RotateAndGo{\thexcount}{-10pt*(\thexcount-9)*(\thexcount-9)+4in}{-1ex*\thexcount-1in} %changed <<<<<
    \tikz\node[blue, inner sep=0pt,rotate=\expandafter\csname R\thexcount\endcsname,    remember picture, overlay] %changed <<<<<
    at ([xshift=\expandafter\csname Cx\thexcount\endcsname, yshift=\expandafter\csname Cy\thexcount\endcsname] current page.south west) 
    {\tikzmark{\thexcount}\usebox{\singleline}}; % typeset  
}   

\TypesetLines{\raggedright 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.The paralogisms of practical
    reason are what first give rise to the architectonic of practical
    reason.}

\end{document}

This is a "light" version, to be used only in automatic mode (that is, without prior individual assignments to each line).

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{tikzmark} % needed <<<<<<<<<<   

\usepackage{calc}% needed <<<<<<<<<<

\usepackage[showframe]{geometry}
    
\newsavebox{\singleline}
\newcounter{xcount}\setcounter{xcount}{0}
\newcounter{xlinecount}

% From https://tex.stackexchange.com/a/57140/161015
\newcommand{\getlines}{% capture all  lines of a paragraph and puts them in their place
    \setbox\singleline\lastbox%
    \ifvoid\singleline%
    \noindent\ignorespaces%
    \else
    \unskip\unpenalty%
    \begingroup\getlines\endgroup
    \stepcounter{xcount}\setcounter{xlinecount}{\value{xcount}}\par
    \makenodes
    \fi}

\newcommand{\makenodes}{}

\newcommand{\TypesetLines}[1]{\parindent0pt\vbox{#1\par\getlines}} % load the paragraph  and display the lines

\newcounter{anglex} \newlength{\Cx}\newlength{\Cy}
\newcommand{\RotateAndGo}[3][0]{% save rotation and shifts changed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        \setcounter{anglex}{#1}\setlength{\Cx}{#2}\setlength{\Cy}{#3}
}

\begin{document}
\pagestyle{empty}   

% First example ********************************************
\newgeometry{textwidth=4.0cm}

\renewcommand{\makenodes}{%put the lines in their place, automatic mode
\RotateAndGo{1cm}{-0.5in*\thexcount} % only y-shift
\tikz\node[inner sep=0pt,rotate=\theanglex, remember picture, overlay, anchor= west ,draw] 
at ([xshift=\the\Cx, yshift=\the\Cy] current page.south west)   
{\tikzmark{\thexcount}\usebox{\singleline}}; % typeset  
}

\noindent Some text spanning three lines with very nice automatic line breaks \bigskip

From \tikzmarknode{here}~HERE to the first line baseline

\TypesetLines{Some text spanning three lines with very nice automatic line breaks}

\tikz[remember picture,overlay] \draw[->,red, very thick] (here) -- (pic cs:1); % the arrow to the baseline of the first line (# 1)

\newpage

% Fourth example ********************************************
\newgeometry{textwidth=2in,showframe=false}

\renewcommand{\makenodes}{%put the lines in their place
    \RotateAndGo{-10pt*(\thexcount-9)*(\thexcount-9)+3in}{-1ex*\thexcount-1in} %changed <<<<<
    \tikz\node[blue, inner sep=0pt,rotate=\theanglex,   remember picture, overlay] %changed <<<<<
    at ([xshift=\the\Cx, yshift=\the\Cy] current page.south west)   
    {\tikzmark{\thexcount}\usebox{\singleline}}; % typeset  
}   

\TypesetLines{\raggedright 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.The paralogisms of practical
    reason are what first give rise to the architectonic of practical
    reason.}

\end{document}

d

You must log in to answer this question.

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