File Coverage

blib/lib/Text/Amuse/Output/Image.pm
Criterion Covered Total %
statement 100 103 97.0
branch 45 48 93.7
condition 20 25 80.0
subroutine 15 15 100.0
pod 12 12 100.0
total 192 203 94.5


line stmt bran cond sub pod time code
1             package Text::Amuse::Output::Image;
2 44     44   49189 use strict;
  44         1313  
  44         921  
3 44     44   440 use warnings;
  44         77  
  44         740  
4 44     44   164 use utf8;
  44         63  
  44         165  
5              
6             =head1 NAME
7              
8             Text::Amuse::Output::Image -- class to manage images
9              
10             =head1 SYNOPSIS
11              
12             The module is used internally by L, so everything here is
13             pretty much internal only (and underdocumented).
14              
15             =head1 CONSTRUCTORS
16              
17             =over 4
18              
19             =item new(filename => "hello.png", width => 50, wrap => 'l')
20              
21             Constructor. Accepts three options: C, C, as a
22             integer in percent, and C, as a string denoting the position.
23             C is mandatory.
24              
25             These arguments are saved in the objects and can be accessed with:
26             =cut
27              
28             =back
29              
30             =head1 METHODS
31              
32             =over 4
33              
34             =item filename
35              
36             =item rotate
37              
38             Allowed values are 90 180 270. Rotation happens around the image
39             figure and before the scaling.
40              
41             =item width
42              
43             =item wrap
44              
45             If 'l', the float will wrap on the left, if 'r' will wrap on the
46             right, if 'f' it's not floating, but it's intended as fullpage (will
47             insert a clearpage after the image). This is handy if there is some
48             long series of images without text.
49              
50             =item fmt
51              
52             =item desc
53              
54             Please note that we concatenate the caption as is. It's up to the
55             caller to pass an escaped string.
56              
57             =cut
58              
59             sub new {
60 442     442 1 2680 my $class = shift;
61 442         986 my $self = {
62             width => 1,
63             wrap => 0,
64             };
65 442         1516 my %opts = @_;
66              
67 442 50       855 if (my $f = $opts{filename}) {
68 442         641 $self->{filename} = $f;
69             # just to be sure
70 442 100       1619 unless ($f =~ m{^[0-9A-Za-z][0-9A-Za-z/-]+\.(png|jpe?g)}s) {
71 2         16 die "Illegal filename $f!";
72             }
73             }
74             else {
75 0         0 die "Missing filename argument!";
76             }
77              
78 440 100       922 if (my $wrap = $opts{wrap}) {
79 309 50 100     1329 if ($wrap eq 'l' or $wrap eq 'r' or $wrap eq 'f') {
      66        
80 309         520 $self->{wrap} = $wrap;
81             }
82             else {
83 0         0 die "Wrong wrapping option";
84             }
85 309 100 100     897 if ($wrap eq 'l' or $wrap eq 'r') {
86 70   100     179 $opts{width} ||= 50;
87             }
88             }
89              
90 440 100       739 if (my $w = $opts{width}) {
91 87 100       281 if ($w =~ m/^[0-9]+$/s) {
92 86         826 $self->{width} = sprintf('%.2f', $w / 100);
93             }
94             else {
95 1         8 die "Wrong width $w passed!";
96             }
97             }
98 439 100       756 if (my $r = $opts{rotate}) {
99 37         83 my %angles = (90 => 90, 180 => 180, 270 => 270);
100 37   50     111 $self->{rotate} = $angles{$r} || 0;
101             }
102 439         659 foreach my $k (qw/desc fmt/) {
103 878 100 66     2116 if (exists $opts{$k} and defined $opts{$k}) {
104 432         768 $self->{$k} = $opts{$k};
105             }
106             }
107              
108 439         2318 bless $self, $class;
109             }
110              
111             sub rotate {
112 458     458 1 860 return shift->{rotate};
113             }
114              
115             sub width {
116 556     556 1 965 return shift->{width};
117             }
118              
119             sub wrap {
120 447     447 1 718 return shift->{wrap};
121             }
122              
123             sub filename {
124 859     859 1 1620 return shift->{filename};
125             }
126              
127             sub fmt {
128 629     629 1 1238 return shift->{fmt};
129             }
130              
131             sub desc {
132 539     539 1 826 my ($self, @args) = @_;
133 539 100       914 if (@args) {
134 100         198 $self->{desc} = shift(@args);
135             }
136 539         886 return shift->{desc};
137             }
138              
139             =back
140              
141             =head2 Formatters
142              
143             =over 4
144              
145             =item width_html
146              
147             Width in percent
148              
149             =item width_latex
150              
151             Width as '0.25\textwidth'
152              
153             =cut
154              
155             sub width_html {
156 51     51 1 77 my $self = shift;
157 51         88 my $width = $self->width;
158 51         198 my $width_in_pc = sprintf('%d', $width * 100);
159 51         160 return $width_in_pc . '%';
160             }
161              
162             sub width_latex {
163 229     229 1 264 my $self = shift;
164 229         361 my $width = $self->width;
165 229 100       427 if ($width == 1) {
166 179         288 return "\\textwidth";
167             }
168             else {
169 50         86 return $self->width . "\\textwidth"; # a float
170             }
171             }
172              
173             =item as_latex
174              
175             The LaTeX code for the image. Right and left floats uses the
176             wrapfigure packages. To full page floats a \clearpage is appended.
177              
178             =item as_html
179              
180             The HTML code for the image. Classes used:
181              
182             img.embedimg {
183             margin: 1em;
184             }
185              
186             div.image, div.float_image_f {
187             margin: 1em;
188             text-align: center;
189             padding: 3px;
190             background-color: white;
191             }
192              
193             div.float_image_r {
194             float: right;
195             }
196              
197             div.float_image_l {
198             float: left;
199             }
200              
201             div.float_image_f {
202             clear: both;
203             margin-left: auto;
204             margin-right: auto;
205             }
206              
207              
208             =item output
209              
210             Given that we know the format, just return the right one, using
211             C or C.
212              
213             =back
214              
215              
216             =cut
217              
218              
219              
220             sub as_latex {
221 221     221 1 260 my $self = shift;
222 221         357 my $wrap = $self->wrap;
223 221         342 my $width = $self->width_latex;
224 221         280 my $desc = "";
225 221         328 my $realdesc = $self->desc;
226 221 100 66     573 if (defined($realdesc) && length($realdesc)) {
227             # the \noindent here is harmless if you still want the label,
228             # commenting out the \renewcommand*
229 52         129 $desc = "\n\\caption[]{\\noindent $realdesc}";
230             }
231 221         314 my $src = $self->filename;
232 221         286 my $open;
233             my $close;
234 221 100 100     725 if ($wrap eq 'r' or $wrap eq 'l') {
    100          
235 36         98 $open = "\\begin{wrapfigure}{$wrap}{$width}";
236 36         55 $close = "\\end{wrapfigure}";
237             }
238             elsif ($wrap eq 'f') {
239 119         152 $open = "\\begin{figure}[p]";
240 119         136 $close = "\\end{figure}\n\\clearpage";
241             }
242             else {
243 66         85 $open = "\\begin{figure}[htbp!]";
244 66         82 $close = "\\end{figure}";
245             }
246 221 100       358 my $rotation = $self->rotate ? "origin=c,angle=" . $self->rotate . ',' : '';
247 221 100       313 my $heightratio = $desc ? '0.85' : "";
248 221         844 my $out = <<"EOF";
249              
250             $open
251             \\centering
252             \\includegraphics[${rotation}keepaspectratio=true,height=$heightratio\\textheight,width=$width]{$src}$desc
253             $close
254             EOF
255 221         926 return $out;
256             }
257              
258             sub as_html {
259 218     218 1 258 my $self = shift;
260 218         338 my $wrap = $self->wrap;
261 218         283 my $width = "";
262 218         223 my $desc;
263 218         257 my $class = "image";
264 218         227 my $out;
265 218 100       354 if ($wrap) {
266 154         255 $class = "float_image_$wrap";
267             }
268              
269 218         387 my $src = $self->filename;
270 218         314 my $realdesc = $self->desc;
271 218 100 66     560 if (defined($realdesc) && length($realdesc)) {
272 51         131 $desc = <<"EOF";
273            
$realdesc
274             EOF
275             }
276              
277 218         241 my @styles;
278 218 100       367 if ($self->width != 1) {
279 43         110 push @styles, "width:" . $self->width_html . ";";
280             }
281 218 100       367 if (my $rotate = $self->rotate) {
282 19         36 push @styles, "transform:rotate(${rotate}deg);";
283 19         25 push @styles, "background: transparent;";
284             }
285 218         284 my $style_html = "";
286 218 100       329 if (@styles) {
287 55         132 $style_html = q{ style="} . join(' ', @styles) . q{"};
288             }
289 218         673 $out = qq{\n
\n} .
290             qq{$src\n};
291 218 100       395 if (defined $desc) {
292 51         82 $out .= $desc;
293             }
294 218         320 $out .= "\n";
295 218         840 return $out;
296             }
297              
298             sub output {
299 420     420 1 564 my $self = shift;
300 420 100       664 if ($self->fmt eq 'ltx') {
    50          
301 211         324 return $self->as_latex;
302             }
303             elsif ($self->fmt eq 'html') {
304 209         356 return $self->as_html;
305             }
306             else {
307 0           die "Bad format ". $self->fmt;
308             }
309             }
310              
311             1;
312