Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

i would like to obtain this effect

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
\clip (-1ex,-12pt) rectangle (1ex,12pt);
\node [align=center] (text) {A \\ B \\ C};
\end{tikzpicture}
\end{document}

but i cannot find a way to clip the node that is still to be drawn, something like

\clip ($(text.south west) + (0,6pt)$) rectangle ($(text.north east) - (0,6pt)$);

how can i achieve it without explicit use of the position to clip?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

Ah, this looks like a job for \pgfpositionnodelater! If you call this command in a local scope, subsequently defined nodes won't be typeset straight away, but their content will be saved into a box and the edge coordinates can be saved to macros. You can then use the node alias not yet positioned@<node name> to set up your clip path, and then load the edge coordinates and typeset the node using \pgfpositionnodenow.

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\newbox\mybox
\def\mysaver{
\global\setbox\mybox=\box\pgfpositionnodelaterbox
\global\let\myname=\pgfpositionnodelatername
\global\let\myminx=\pgfpositionnodelaterminx
\global\let\myminy=\pgfpositionnodelaterminy
\global\let\mymaxx=\pgfpositionnodelatermaxx
\global\let\mymaxy=\pgfpositionnodelatermaxy
}

\newcommand{\loadnode}{
\let\pgfpositionnodelatername=\myname
\let\pgfpositionnodelaterminx=\myminx
\let\pgfpositionnodelaterminy=\myminy
\let\pgfpositionnodelatermaxx=\mymaxx
\let\pgfpositionnodelatermaxy=\mymaxy
\setbox\pgfpositionnodelaterbox=\box\mybox
}

\begin{document}
\begin{tikzpicture}
{
\pgfpositionnodelater{\mysaver}
\node [align=center] (text) {A \\ B \\ C \\ ABCDEF};
}
\clip ($(not yet positioned@text.south west) + (0,6pt)$) rectangle ($(not yet positioned@text.north east) - (0,6pt)$);
\loadnode
\pgfpositionnodenow{\pgfqpoint{0pt}{0pt}
}

\end{tikzpicture}
\end{document}

EDIT by percusse

If you want to use the TikZ frontend for a similar effect, you can use append after command key as follows:

\begin{tikzpicture} 
\clip node [append after command={%
        ($(text.south west) + (0,6pt)$) rectangle ($(text.north east) - (0,6pt)$)%
        },%
    align=center] (text) {TOP TEXT\\ A \\ B \\ C \\ LONGER}; 
\end{tikzpicture}

Roughly speaking, it nests the path construction and node placement in the desired order. The counterpart in terms of the order is given by the prefix after command. This allows us to use the name of the node to-be-created in advance. However, its use is quite limited as stated in the manual. You can not change the structural properties such as shape,color etc of the node.

share|improve this answer
    
I think the TikZ version is append after command/prefix after command. But I'm not sure. –  percusse Feb 18 '12 at 0:14
    
Great, so that's how it's called. I couldn't find it in the manual myself (was expecting something like \save...). –  Frg Feb 18 '12 at 0:59
    
@percusse i've been trying to achieve it with append after command/prefix after command with no luck... can you expand on it? –  capitalaslash Feb 18 '12 at 17:16
2  
@capitalaslash Try the following :\begin{tikzpicture} \clip node [append after command={($(text.south west) + (0,6pt)$) rectangle ($(text.north east) - (0,6pt)$)} ,align=center] (text) {TOP TEXT\\ A \\ B \\ C \\ LONGER}; \end{tikzpicture} . I just combined your commands, and that key allows you to use the node name in advance... –  percusse Feb 19 '12 at 3:58
    
@percusse: Oh wow, that should be a separate answer. That's much better than all that work with \pgfpositionnodelater. –  Jake Feb 19 '12 at 6:33

You can first create an invisible node, just to catch the dimensions, then clip and finally draw the text, like so (this is just the inside of tikzpicture):

\node [transparent, align=center] (text) {A \\ B \\ C};
\clip ($(text.south west) + (0,6pt)$) rectangle ($(text.north east) - (0,6pt)$);
\draw (text) node [align=center] {A \\ B \\ C};

Full example with longer text (put in a macro to remove text repetition):

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\def\longText{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. 
Faucibus, tortor lacus vestibulum sapien, tempus tellus. Praesent a leo ac diam. 
Pellentesque facilisis hendrerit. Maecenas interdum eu, ullamcorper ut, 
pulvinar vitae, vestibulum varius. In hac habitasse platea dictumst. 
Aenean tincidunt enim. Mauris at magna. Donec vitae ornare elementum congue, 
lorem pretium sit amet felis non odio. Nam non nulla.}
\begin{tikzpicture}
\node [transparent, align=justify, text width=10cm] (text) {\longText};
\clip ($(text.south west) + (0,6pt)$) rectangle ($(text.north east) - (0,6pt)$);
\draw (text) node [align=justify, text width=10cm] {\longText};
\end{tikzpicture}
\end{document}
share|improve this answer
    
i like this approach, but the real text in the box is gonna be several lines... would like to find a solution that does not require to type it twice. thanks! –  capitalaslash Feb 17 '12 at 22:33
    
For a longer text a simple def outside of the drawing will be a good idea, as to not repeat oneself. –  Frg Feb 17 '12 at 22:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.