8 LaTeX::TikZ - Perl object model for generating PGF/TikZ code.
16 our $VERSION = '0.02';
23 my $hline = Tikz->line(-1 => 1);
24 my $vline = Tikz->line([ 0, -1 ] => [ 0, 1 ]);
27 $_->mod(Tikz->color('red')) for $hline, $vline;
31 my $octo = Tikz->closed_polyline(
32 map Math::Complex->emake(1, ($_ * pi)/4), 0 .. 7
35 # Only keep a portion of it
36 $octo->clip(Tikz->rectangle(-0.5*(1+i), 2*(1+i)));
39 $octo->mod(Tikz->pattern(class => 'Dots'));
41 # Create a formatter object
42 my $tikz = Tikz->formatter(scale => 5);
44 # Put those objects all together and print them
45 my $seq = Tikz->seq($octo, $hline, $vline);
46 my ($head, $decl, $body) = $tikz->render($seq);
47 print "$_\n" for map @$_, $head, $decl, $body;
51 This module provides an object model for TikZ, a graphical toolkit for LaTeX.
52 It allows you to build structures representing geometrical figures, apply a wide set of modifiers on them, transform them globally with functors, and print them in the context of an existing TeX document.
56 Traditionally, in TikZ, there are two ways of grouping paths together :
62 either as a I<sequence>, where each path is drawn in its own line :
64 \draw (0cm,0cm) -- (0cm,1cm) ;
65 \draw (0cm,0cm) -- (1cm,0cm) ;
69 or as an I<union>, where paths are all drawn as one line :
71 \draw (0cm,0cm) -- (0cm,1cm) (0cm,0cm) -- (1cm,0cm) ;
75 This distinction is important because there are some primitives that only apply to paths but not to sequences, and vice versa.
77 Figures are made of path or sequence I<sets> assembled together in a tree.
79 I<Modifiers> can be applied onto any set to alter the way in which it is generated.
80 The two TikZ concepts of I<clips> and I<layers> have been unified with the modifiers.
86 =head3 C<< Tikz->union(@seq) >>
88 Creates a L<LaTeX::TikZ::Set::Union> object out of the paths C<@kids>.
90 # A path made of two circles
100 =head3 C<< Tikz->join($connector, @kids) >>
102 Creates a L<LaTeX::TikZ::Set::Chain> object that joins the paths C<@kinds> with the given C<$connector> which can be, according to L<LaTeX::TikZ::Set::Chain/connector>, a string, an array reference or a code reference.
105 Tikz->join('-|', map [ $_, $_ ], 0 .. 5);
107 =head3 C<< Tikz->chain($kid0, $link0, $kid1, $link1, ... $kidn) >>
109 Creates a L<LaTeX::TikZ::Set::Chain> object that chains C<$kid0> to C<$kid1> with the string C<$link0>, C<$kid1> to C<$kid2> with C<$link1>, and so on.
111 # An heart-like shape
113 => '.. controls (-1, 1.5) and (-0.75, 0.25) ..' => [ 0, 0 ]
114 => '.. controls (0.75, 0.25) and (1, 1.5) ..' => [ 0, 1 ]
117 =head3 C<< Tikz->seq(@kids) >>
119 Creates a L<LaTeX::TikZ::Set::Sequence> object out of the sequences or paths C<@kids>.
121 my $bag = Tikz->seq($sequence, $path, $circle, $raw, $point);
125 Those are the building blocks of your geometrical figure.
127 =head3 C<< Tikz->point($point) >>
129 Creates a L<LaTeX::TikZ::Set::Point> object by coercing C<$point> into a L<LaTeX::TikZ::Point>.
130 The following rules are available :
136 If C<$point> isn't given, the point defaults to C<(0, 0)>.
138 my $origin = Tikz->point;
142 If C<$point> is a numish Perl scalar, it is treated as C<($point, 0)>.
144 my $unit = Tikz->point(1);
148 If two numish scalars C<$x> and C<$y> are given, they result in the point C<($x, $y)>.
150 my $one_plus_i = Tikz->point(1, 1);
154 If C<$point> is an array reference, it is parsed as C<< ($point->[0], $point->[1]) >>.
156 my $i = Tikz->point([ 0, 1 ]);
160 If C<$point> is a L<Math::Complex> object, the L<LaTeX::TikZ::Point::Math::Complex> class is automatically loaded and the point is coerced into C<< ($point->Re, $point->Im) >>.
162 my $j = Tikz->point(Math::Complex->emake(1, 2*pi/3));
166 You can define automatic coercions from your user point types to L<LaTeX::TikZ::Point> by writing your own C<LaTeX::TikZ::Point::My::User::Point> class.
167 See L<LaTeX::TikZ::Meta::TypeConstraint::Autocoerce> for the rationale and L<LaTeX::TikZ::Point::Math::Complex> for an example.
169 =head3 C<< Tikz->line($from => $to) >>
171 Creates a L<LaTeX::TikZ::Set::Line> object between the points C<$from> and C<$to>.
173 my $x_axis = Tikz->line(-5 => 5);
174 my $y_axis = Tikz->line([ 0, -5 ] => [ 0, 5 ]);
176 =head3 C<< Tikz->polyline(@points) >>
178 Creates a L<LaTeX::TikZ::Set::Polyline> object that links the successive elements of C<@points> by segments.
180 my $U = Tikz->polyline(
187 =head3 C<< Tikz->closed_polyline(@points) >>
189 Creates a L<LaTeX::TikZ::Set::Polyline> object that cycles through successive elements of C<@points>.
191 my $diamond = Tikz->closed_polyline(
198 =head3 C<< Tikz->rectangle($from => $to), Tikz->rectangle($from => { width => $width, height => $height }) >>
200 Creates a L<LaTeX::TikZ::Set::Rectangle> object with opposite corners C<$from> and C<$to>, or with anchor point C<$from> and dimensions C<$width> and C<$height>.
202 my $square = Tikz->rectangle(
207 =head3 C<< Tikz->circle($center, $radius) >>
209 Creates a L<LaTeX::TikZ::Set::Circle> object of center C<$center> and radius C<$radius>.
211 my $unit_circle = Tikz->circle(0, 1);
213 =head3 C<< Tikz->arc($from => $to, $center) >>
215 Creates a L<LaTeX::TikZ::Set> structure that represents an arc going from C<$from> to C<$to> with center C<$center>.
217 # An arc. The points are automatically coerced into LaTeX::TikZ::Set::Point objects
218 my $quarter = Tikz->arc(
219 [ 1, 0 ] => [ 0, 1 ],
223 =head3 C<< Tikz->arrow($from => $to), Tikz->arrow($from => dir => $dir) >>
225 Creates a L<LaTeX::TikZ::Set> structure that represents an arrow going from C<$from> towards C<$to>, or starting at C<$from> in direction C<$dir>.
227 # An horizontal arrow
228 my $arrow = Tikz->arrow(0 => 1);
230 =head3 C<< Tikz->raw($content) >>
232 Creates a L<LaTeX::TikZ::Set::Raw> object that will instantiate to the raw TikZ code C<$content>.
236 Modifiers are applied onto sets by calling the C<< ->mod >> method, like in C<< $set->mod($mod) >>.
237 This method returns the C<$set> object, so it can be chained.
239 =head3 C<< Tikz->clip($path) >>
241 Creates a L<LaTeX::TikZ::Mod::Clip> object that can be used to clip a given sequence by the (closed) path C<$path>.
243 my $box = Tikz->clip(
244 Tikz->rectangle(0 => [ 1, 1 ]),
247 Clips can also be directly applied to sets with the C<< ->clip >> method.
249 my $set = Tikz->circle(0, 1.5)
250 ->clip(Tikz->rectangle([-1, -1] => [1, 1]));
252 =head3 C<< Tikz->layer($name, above => \@above, below => \@below) >>
254 Creates a L<LaTeX::TikZ::Mod::Layer> object with name C<$name> and optional relative positions C<@above> and C<@below>.
256 my $layer = Tikz->layer(
261 The default layer is C<main>.
263 Layers are stored into a global hash, so that when you refer to them by their name, you get the existing layer object.
265 Layers can also be directly applied to sets with the C<< ->layer >> method.
267 my $dots = Tikz->rectangle(0 => [ 1, 1 ])
268 ->mod(Tikz->pattern(class => 'Dots'))
271 =head3 C<< Tikz->width($line_width) >>
273 Creates a L<LaTeX::TikZ::Mod::Width> object that sets the line width to C<$line_width> when applied.
275 my $thick_arrow = Tikz->arrow(0 => 1)
276 ->mod(Tikz->width(5));
278 =head3 C<< Tikz->color($color) >>
280 Creates a L<LaTeX::TikZ::Mod::Color> object that sets the line color to C<$color> (given in the C<xcolor> syntax).
282 # Paint the previous $thick_arrow in red.
283 $thick_arrow->mod(Tikz->color('red'));
285 =head3 C<< Tikz->fill($color) >>
287 Creates a L<LaTeX::TikZ::Mod::Fill> object that fills the interior of a path with the solid color C<$color> (given in the C<xcolor> syntax).
289 my $red_box = Tikz->rectangle(0 => { width => 1, height => 1 })
290 ->mod(Tikz->fill('red'));
292 =head3 C<< Tikz->pattern(class => $class, %args) >>
294 Creates a L<LaTeX::TikZ::Mod::Pattern> object of class C<$class> and arguments C<%args> that fills the interior of a path with the specified pattern.
295 C<$class> is prepended with C<LaTeX::TikZ::Mod::Pattern> when it doesn't contain C<::>.
296 See L<LaTeX::TikZ::Mod::Pattern::Dots> and L<LaTeX::TikZ::Mod::Pattern::Lines> for two examples of pattern classes.
298 my $hatched_circle = Tikz->circle(0 => 1)
299 ->mod(Tikz->pattern(class => 'Lines'));
301 =head3 C<< Tikz->raw_mod($content) >>
303 Creates a L<LaTeX::TikZ::Mod::Raw> object that will instantiate to the raw TikZ mod code C<$content>.
305 my $homemade_arrow = Tikz->line(0 => 1)
306 ->mod(Tikz->raw_mod('->')) # or just ->mod('->')
310 =head3 C<< Tikz->formatter(%args) >>
312 Creates a L<LaTeX::TikZ::Formatter> object that can render a L<LaTeX::TikZ::Set> tree.
314 my $tikz = Tikz->formatter;
315 my ($header, $declarations, $seq1_body, $seq2_body) = $tikz->render($set1, $set2);
317 =head3 C<< Tikz->functor(@rules) >>
319 Creates a L<LaTeX::TikZ::Functor> anonymous subroutine that can be called against L<LaTeX::TikZ::Set> trees to clone them according to the given rules.
320 C<@rules> should be a list of array references whose first element is the class/role to match against and the second the handler to execute.
322 # The default is a clone method
323 my $clone = Tikz->functor;
324 my $dup = $set->$clone;
327 my $translate = Tikz->functor(
328 'LaTeX::TikZ::Set::Point' => sub {
329 my ($functor, $set, $x, $y) = @_;
336 label => $set->label,
341 my $shifted = $set->$translate(1, 1);
344 my $strip = Tikz->functor(
345 '+LaTeX::TikZ::Mod' => sub { return },
347 my $naked = $set->$strip;
351 use LaTeX::TikZ::Interface;
357 my $name = $args{as};
358 $name = 'Tikz' unless defined $name;
359 unless ($name =~ /^[a-z_][a-z0-9_]*$/i) {
361 Carp::confess('Invalid name');
365 my $const = sub () { 'LaTeX::TikZ::Interface' };
368 *{$pkg . '::' . $name} = $const;
371 LaTeX::TikZ::Interface->load;
378 L<Any::Moose> with L<Mouse> 0.80 or greater.
384 L<Math::Complex>, L<Math::Trig>.
386 L<Scalar::Util>, L<List::Util>, L<Task::Weaken>.
390 PGF/TikZ - L<http://pgf.sourceforge.net>.
394 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
396 You can contact me by mail or on C<irc.perl.org> (vincent).
400 Please report any bugs or feature requests to C<bug-latex-tikz at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=LaTeX-TikZ>.
401 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
405 You can find documentation for this module with the perldoc command.
409 =head1 COPYRIGHT & LICENSE
411 Copyright 2010 Vincent Pit, all rights reserved.
413 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
417 1; # End of LaTeX::TikZ