File Coverage

blib/lib/LaTeX/TikZ.pm
Criterion Covered Total %
statement 26 26 100.0
branch 4 4 100.0
condition n/a
subroutine 5 5 100.0
pod n/a
total 35 35 100.0


line stmt bran cond sub pod time code
1             package LaTeX::TikZ;
2              
3 10     10   157856 use strict;
  10         17  
  10         321  
4 10     10   37 use warnings;
  10         10  
  10         922  
5              
6             =head1 NAME
7              
8             LaTeX::TikZ - Perl object model for generating PGF/TikZ code.
9              
10             =head1 VERSION
11              
12             Version 0.03
13              
14             =cut
15              
16             our $VERSION = '0.03';
17              
18             =head1 SYNOPSIS
19              
20             use LaTeX::TikZ;
21              
22             # A couple of lines
23             my $hline = Tikz->line(-1 => 1);
24             my $vline = Tikz->line([ 0, -1 ] => [ 0, 1 ]);
25              
26             # Paint them in red
27             $_->mod(Tikz->color('red')) for $hline, $vline;
28              
29             # An octogon
30             use Math::Complex;
31             my $octo = Tikz->closed_polyline(
32             map Math::Complex->emake(1, ($_ * pi)/4), 0 .. 7
33             );
34              
35             # Only keep a portion of it
36             $octo->clip(Tikz->rectangle(-0.5*(1+i), 2*(1+i)));
37              
38             # Fill it with dots
39             $octo->mod(Tikz->pattern(class => 'Dots'));
40              
41             # Create a formatter object
42             my $tikz = Tikz->formatter(scale => 5);
43              
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;
48              
49             =head1 DESCRIPTION
50              
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.
53              
54             =head1 CONCEPTS
55              
56             Traditionally, in TikZ, there are two ways of grouping paths together :
57              
58             =over 4
59              
60             =item *
61              
62             either as a I, where each path is drawn in its own line :
63              
64             \draw (0cm,0cm) -- (0cm,1cm) ;
65             \draw (0cm,0cm) -- (1cm,0cm) ;
66              
67             =item *
68              
69             or as an I, where paths are all drawn as one line :
70              
71             \draw (0cm,0cm) -- (0cm,1cm) (0cm,0cm) -- (1cm,0cm) ;
72              
73             =back
74              
75             This distinction is important because there are some primitives that only apply to paths but not to sequences, and vice versa.
76              
77             Figures are made of path or sequence I assembled together in a tree.
78              
79             I can be applied onto any set to alter the way in which it is generated.
80             The two TikZ concepts of I and I have been unified with the modifiers.
81              
82             =head1 INTERFACE
83              
84             =head2 Containers
85              
86             =head3 C
87              
88             Tikz->union(@kids)
89              
90             Creates a L object out of the paths C<@kids>.
91              
92             # A path made of two circles
93             Tikz->union(
94             Tikz->circle(0, 1),
95             Tikz->circle(1, 1),
96             )
97             ->mod(
98             Tikz->fill('red'),
99             'even odd rule',
100             );
101              
102             =head3 C
103              
104             Tikz->path(@kids)
105              
106             A synonym for L.
107              
108             =head3 C
109              
110             Tikz->join($connector, @kids)
111              
112             Creates a L object that joins the paths C<@kinds> with the given C<$connector> which can be, according to L, a string, an array reference or a code reference.
113              
114             # A stair
115             Tikz->join('-|', map [ $_, $_ ], 0 .. 5);
116              
117             =head3 C
118              
119             Tikz->chain($kid0, $link0, $kid1, $link1, ... $kidn)
120              
121             Creates a L object that chains C<$kid0> to C<$kid1> with the string C<$link0>, C<$kid1> to C<$kid2> with C<$link1>, and so on.
122              
123             # An heart-like shape
124             Tikz->chain([ 0, 1 ]
125             => '.. controls (-1, 1.5) and (-0.75, 0.25) ..' => [ 0, 0 ]
126             => '.. controls (0.75, 0.25) and (1, 1.5) ..' => [ 0, 1 ]
127             );
128              
129             =head3 C
130              
131             Tikz->seq(@kids)
132              
133             Creates a L object out of the sequences or paths C<@kids>.
134              
135             my $bag = Tikz->seq($sequence, $path, $circle, $raw, $point);
136              
137             =head2 Elements
138              
139             Those are the building blocks of your geometrical figure.
140              
141             =head3 C
142              
143             Tikz->point($point)
144              
145             Creates a L object by coercing C<$point> into a L.
146             The following rules are available :
147              
148             =over 4
149              
150             =item *
151              
152             If C<$point> isn't given, the point defaults to C<(0, 0)>.
153              
154             my $origin = Tikz->point;
155              
156             =item *
157              
158             If C<$point> is a numish Perl scalar, it is treated as C<($point, 0)>.
159              
160             my $unit = Tikz->point(1);
161              
162             =item *
163              
164             If two numish scalars C<$x> and C<$y> are given, they result in the point C<($x, $y)>.
165              
166             my $one_plus_i = Tikz->point(1, 1);
167              
168             =item *
169              
170             If C<$point> is an array reference, it is parsed as C<< ($point->[0], $point->[1]) >>.
171              
172             my $i = Tikz->point([ 0, 1 ]);
173              
174             =item *
175              
176             If C<$point> is a L object, the L class is automatically loaded and the point is coerced into C<< ($point->Re, $point->Im) >>.
177              
178             my $j = Tikz->point(Math::Complex->emake(1, 2*pi/3));
179              
180             =back
181              
182             You can define automatic coercions from your user point types to L by writing your own C class.
183             See L for the rationale and L for an example.
184              
185             =head3 C
186              
187             Tikz->line($from => $to)
188              
189             Creates a L object between the points C<$from> and C<$to>.
190              
191             my $x_axis = Tikz->line(-5 => 5);
192             my $y_axis = Tikz->line([ 0, -5 ] => [ 0, 5 ]);
193              
194             =head3 C
195              
196             Tikz->polyline(@points)
197              
198             Creates a L object that links the successive elements of C<@points> by segments.
199              
200             my $U = Tikz->polyline(
201             Tikz->point(0, 1),
202             Tikz->point(0, 0),
203             Tikz->point(1, 0),
204             Tikz->point(1, 1),
205             );
206              
207             =head3 C
208              
209             Tikz->closed_polyline(@points)
210              
211             Creates a L object that cycles through successive elements of C<@points>.
212              
213             my $diamond = Tikz->closed_polyline(
214             Tikz->point(0, 1),
215             Tikz->point(-1, 0),
216             Tikz->point(0, -2),
217             Tikz->point(1, 0),
218             );
219              
220             =head3 C
221              
222             Tikz->rectangle($from => $to)
223             Tikz->rectangle($from => { width => $width, height => $height })
224              
225             Creates a L object with opposite corners C<$from> and C<$to>, or with anchor point C<$from> and dimensions C<$width> and C<$height>.
226              
227             my $square = Tikz->rectangle(
228             Tikz->point,
229             Tikz->point(2, 1),
230             );
231              
232             =head3 C
233              
234             Tikz->circle($center, $radius)
235              
236             Creates a L object of center C<$center> and radius C<$radius>.
237              
238             my $unit_circle = Tikz->circle(0, 1);
239              
240             =head3 C
241              
242             Tikz->arc($from => $to, $center)
243              
244             Creates a L structure that represents an arc going from C<$from> to C<$to> with center C<$center>.
245              
246             # An arc. The points are automatically coerced into LaTeX::TikZ::Set::Point objects
247             my $quarter = Tikz->arc(
248             [ 1, 0 ] => [ 0, 1 ],
249             [ 0, 0 ]
250             );
251              
252             =head3 C
253              
254             Tikz->arrow($from => $to)
255             Tikz->arrow($from => dir => $dir)
256              
257             Creates a L structure that represents an arrow going from C<$from> towards C<$to>, or starting at C<$from> in direction C<$dir>.
258              
259             # An horizontal arrow
260             my $arrow = Tikz->arrow(0 => 1);
261              
262             =head3 C
263              
264             Tikz->raw($content)
265              
266             Creates a L object that will instantiate to the raw TikZ code C<$content>.
267              
268             =head2 Modifiers
269              
270             Modifiers are applied onto sets by calling the C<< ->mod >> method, like in C<< $set->mod($mod) >>.
271             This method returns the C<$set> object, so it can be chained.
272              
273             =head3 C
274              
275             Tikz->clip($path)
276              
277             Creates a L object that can be used to clip a given sequence by the (closed) path C<$path>.
278              
279             my $box = Tikz->clip(
280             Tikz->rectangle(0 => [ 1, 1 ]),
281             );
282              
283             Clips can also be directly applied to sets with the C<< ->clip >> method.
284              
285             my $set = Tikz->circle(0, 1.5)
286             ->clip(Tikz->rectangle([-1, -1] => [1, 1]));
287              
288             =head3 C
289              
290             Tikz->layer($name, above => \@above, below => \@below)
291              
292             Creates a L object with name C<$name> and optional relative positions C<@above> and C<@below>.
293              
294             my $layer = Tikz->layer(
295             'top'
296             above => [ 'main' ],
297             );
298              
299             The default layer is C
.
300              
301             Layers are stored into a global hash, so that when you refer to them by their name, you get the existing layer object.
302              
303             Layers can also be directly applied to sets with the C<< ->layer >> method.
304              
305             my $dots = Tikz->rectangle(0 => [ 1, 1 ])
306             ->mod(Tikz->pattern(class => 'Dots'))
307             ->layer('top');
308              
309             =head3 C
310              
311             Tikz->scale($factor)
312              
313             Creates a L object that scales the sets onto which it apply by the given C<$factor>.
314              
315             my $circle_of_radius_2 = Tikz->circle(0 => 1)
316             ->mod(Tikz->scale(2));
317              
318             =head3 C
319              
320             Tikz->width($line_width)
321              
322             Creates a L object that sets the line width to C<$line_width> when applied.
323              
324             my $thick_arrow = Tikz->arrow(0 => 1)
325             ->mod(Tikz->width(5));
326              
327             =head3 C
328              
329             Tikz->color($color)
330              
331             Creates a L object that sets the line color to C<$color> (given in the C syntax).
332              
333             # Paint the previous $thick_arrow in red.
334             $thick_arrow->mod(Tikz->color('red'));
335              
336             =head3 C
337              
338             Tikz->fill($color)
339              
340             Creates a L object that fills the interior of a path with the solid color C<$color> (given in the C syntax).
341              
342             my $red_box = Tikz->rectangle(0 => { width => 1, height => 1 })
343             ->mod(Tikz->fill('red'));
344              
345             =head3 C
346              
347             Tikz->pattern(class => $class, %args)
348              
349             Creates a L object of class C<$class> and arguments C<%args> that fills the interior of a path with the specified pattern.
350             C<$class> is prepended with C when it doesn't contain C<::>.
351             See L and L for two examples of pattern classes.
352              
353             my $hatched_circle = Tikz->circle(0 => 1)
354             ->mod(Tikz->pattern(class => 'Lines'));
355              
356             =head3 C
357              
358             Tikz->raw_mod($content)
359              
360             Creates a L object that will instantiate to the raw TikZ mod code C<$content>.
361              
362             my $homemade_arrow = Tikz->line(0 => 1)
363             ->mod(Tikz->raw_mod('->')) # or just ->mod('->')
364              
365             =head2 Helpers
366              
367             =head3 C
368              
369             Tikz->formatter(%args)
370              
371             Creates a L object that can render a L tree.
372              
373             my $tikz = Tikz->formatter;
374             my ($header, $declarations, $seq1_body, $seq2_body) = $tikz->render($set1, $set2);
375              
376             =head3 C
377              
378             Tikz->functor(@rules)
379              
380             Creates a L anonymous subroutine that can be called against L trees to clone them according to the given rules.
381             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.
382              
383             # The default is a clone method
384             my $clone = Tikz->functor;
385             my $dup = $set->$clone;
386              
387             # A translator
388             my $translate = Tikz->functor(
389             'LaTeX::TikZ::Set::Point' => sub {
390             my ($functor, $set, $x, $y) = @_;
391              
392             $set->new(
393             point => [
394             $set->x + $x,
395             $set->y + $y,
396             ],
397             label => $set->label,
398             pos => $set->pos,
399             );
400             },
401             );
402             my $shifted = $set->$translate(1, 1);
403              
404             # A mod stripper
405             my $strip = Tikz->functor(
406             '+LaTeX::TikZ::Mod' => sub { return },
407             );
408             my $naked = $set->$strip;
409              
410             =cut
411              
412 10     10   2945 use LaTeX::TikZ::Interface;
  10         14  
  10         982  
413              
414             sub import {
415 12     12   1083 shift;
416              
417 12         23 my %args = @_;
418 12         18 my $name = $args{as};
419 12 100       44 $name = 'Tikz' unless defined $name;
420 12 100       66 unless ($name =~ /^[a-z_][a-z0-9_]*$/i) {
421 1         6 require Carp;
422 1         167 Carp::confess('Invalid name');
423             }
424              
425 11         19 my $pkg = caller;
426 11         14 my $const = sub () { 'LaTeX::TikZ::Interface' };
427             {
428 10     10   43 no strict 'refs';
  10         74  
  10         620  
  11         13  
429 11         16 *{$pkg . '::' . $name} = $const;
  11         45  
430             }
431              
432 11         29 LaTeX::TikZ::Interface->load;
433              
434 11         2009 return;
435             }
436              
437             =head1 DEPENDENCIES
438              
439             L 0.80 or greater.
440              
441             L.
442              
443             L, L.
444              
445             L, L, L.
446              
447             =head1 SEE ALSO
448              
449             PGF/TikZ - L.
450              
451             =head1 AUTHOR
452              
453             Vincent Pit, C<< >>, L.
454              
455             You can contact me by mail or on C (vincent).
456              
457             =head1 BUGS
458              
459             Please report any bugs or feature requests to C, or through the web interface at L.
460             I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
461              
462             =head1 SUPPORT
463              
464             You can find documentation for this module with the perldoc command.
465              
466             perldoc LaTeX::TikZ
467              
468             =head1 COPYRIGHT & LICENSE
469              
470             Copyright 2010,2011,2012,2013,2014,2015 Vincent Pit, all rights reserved.
471              
472             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
473              
474             =cut
475              
476             1; # End of LaTeX::TikZ