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->scale($factor) >>
273 Creates a L<LaTeX::TikZ::Mod::Scale> object that scales the sets onto which it apply by the given C<$factor>.
275 my $circle_of_radius_2 = Tikz->circle(0 => 1)
276 ->mod(Tikz->scale(2));
278 =head3 C<< Tikz->width($line_width) >>
280 Creates a L<LaTeX::TikZ::Mod::Width> object that sets the line width to C<$line_width> when applied.
282 my $thick_arrow = Tikz->arrow(0 => 1)
283 ->mod(Tikz->width(5));
285 =head3 C<< Tikz->color($color) >>
287 Creates a L<LaTeX::TikZ::Mod::Color> object that sets the line color to C<$color> (given in the C<xcolor> syntax).
289 # Paint the previous $thick_arrow in red.
290 $thick_arrow->mod(Tikz->color('red'));
292 =head3 C<< Tikz->fill($color) >>
294 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).
296 my $red_box = Tikz->rectangle(0 => { width => 1, height => 1 })
297 ->mod(Tikz->fill('red'));
299 =head3 C<< Tikz->pattern(class => $class, %args) >>
301 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.
302 C<$class> is prepended with C<LaTeX::TikZ::Mod::Pattern> when it doesn't contain C<::>.
303 See L<LaTeX::TikZ::Mod::Pattern::Dots> and L<LaTeX::TikZ::Mod::Pattern::Lines> for two examples of pattern classes.
305 my $hatched_circle = Tikz->circle(0 => 1)
306 ->mod(Tikz->pattern(class => 'Lines'));
308 =head3 C<< Tikz->raw_mod($content) >>
310 Creates a L<LaTeX::TikZ::Mod::Raw> object that will instantiate to the raw TikZ mod code C<$content>.
312 my $homemade_arrow = Tikz->line(0 => 1)
313 ->mod(Tikz->raw_mod('->')) # or just ->mod('->')
317 =head3 C<< Tikz->formatter(%args) >>
319 Creates a L<LaTeX::TikZ::Formatter> object that can render a L<LaTeX::TikZ::Set> tree.
321 my $tikz = Tikz->formatter;
322 my ($header, $declarations, $seq1_body, $seq2_body) = $tikz->render($set1, $set2);
324 =head3 C<< Tikz->functor(@rules) >>
326 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.
327 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.
329 # The default is a clone method
330 my $clone = Tikz->functor;
331 my $dup = $set->$clone;
334 my $translate = Tikz->functor(
335 'LaTeX::TikZ::Set::Point' => sub {
336 my ($functor, $set, $x, $y) = @_;
343 label => $set->label,
348 my $shifted = $set->$translate(1, 1);
351 my $strip = Tikz->functor(
352 '+LaTeX::TikZ::Mod' => sub { return },
354 my $naked = $set->$strip;
358 use LaTeX::TikZ::Interface;
364 my $name = $args{as};
365 $name = 'Tikz' unless defined $name;
366 unless ($name =~ /^[a-z_][a-z0-9_]*$/i) {
368 Carp::confess('Invalid name');
372 my $const = sub () { 'LaTeX::TikZ::Interface' };
375 *{$pkg . '::' . $name} = $const;
378 LaTeX::TikZ::Interface->load;
385 L<Any::Moose> with L<Mouse> 0.80 or greater.
389 L<Math::Complex>, L<Math::Trig>.
391 L<Scalar::Util>, L<List::Util>, L<Task::Weaken>.
395 PGF/TikZ - L<http://pgf.sourceforge.net>.
399 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
401 You can contact me by mail or on C<irc.perl.org> (vincent).
405 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>.
406 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
410 You can find documentation for this module with the perldoc command.
414 =head1 COPYRIGHT & LICENSE
416 Copyright 2010 Vincent Pit, all rights reserved.
418 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
422 1; # End of LaTeX::TikZ