line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Text::Amuse::Compile; |
2
|
|
|
|
|
|
|
|
3
|
58
|
|
|
58
|
|
2482112
|
use strict; |
|
58
|
|
|
|
|
589
|
|
|
58
|
|
|
|
|
1853
|
|
4
|
58
|
|
|
58
|
|
319
|
use warnings FATAL => 'all'; |
|
58
|
|
|
|
|
121
|
|
|
58
|
|
|
|
|
3352
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
use constant { |
7
|
|
|
|
|
|
|
DEBUG => $ENV{AMW_DEBUG}, |
8
|
58
|
|
|
58
|
|
355
|
}; |
|
58
|
|
|
|
|
143
|
|
|
58
|
|
|
|
|
5784
|
|
9
|
|
|
|
|
|
|
|
10
|
58
|
|
|
58
|
|
414
|
use File::Basename; |
|
58
|
|
|
|
|
110
|
|
|
58
|
|
|
|
|
6667
|
|
11
|
58
|
|
|
58
|
|
34173
|
use File::Temp; |
|
58
|
|
|
|
|
997711
|
|
|
58
|
|
|
|
|
4089
|
|
12
|
58
|
|
|
58
|
|
478
|
use File::Find; |
|
58
|
|
|
|
|
118
|
|
|
58
|
|
|
|
|
3110
|
|
13
|
58
|
|
|
58
|
|
371
|
use File::Spec; |
|
58
|
|
|
|
|
115
|
|
|
58
|
|
|
|
|
1576
|
|
14
|
|
|
|
|
|
|
|
15
|
58
|
|
|
58
|
|
24229
|
use Text::Amuse::Functions qw/muse_fast_scan_header/; |
|
58
|
|
|
|
|
2356620
|
|
|
58
|
|
|
|
|
4582
|
|
16
|
58
|
|
|
58
|
|
34645
|
use Text::Amuse::Compile::File; |
|
58
|
|
|
|
|
226
|
|
|
58
|
|
|
|
|
2392
|
|
17
|
58
|
|
|
58
|
|
28505
|
use Text::Amuse::Compile::Merged; |
|
58
|
|
|
|
|
192
|
|
|
58
|
|
|
|
|
1998
|
|
18
|
58
|
|
|
58
|
|
469
|
use Text::Amuse::Compile::MuseHeader; |
|
58
|
|
|
|
|
171
|
|
|
58
|
|
|
|
|
1339
|
|
19
|
58
|
|
|
58
|
|
23883
|
use Text::Amuse::Compile::FileName; |
|
58
|
|
|
|
|
198
|
|
|
58
|
|
|
|
|
2009
|
|
20
|
58
|
|
|
58
|
|
460
|
use Text::Amuse::Compile::Fonts; |
|
58
|
|
|
|
|
167
|
|
|
58
|
|
|
|
|
1285
|
|
21
|
58
|
|
|
58
|
|
25615
|
use Text::Amuse::Compile::Fonts::Selected; |
|
58
|
|
|
|
|
3458
|
|
|
58
|
|
|
|
|
2122
|
|
22
|
|
|
|
|
|
|
|
23
|
58
|
|
|
58
|
|
421
|
use Cwd; |
|
58
|
|
|
|
|
2587
|
|
|
58
|
|
|
|
|
4651
|
|
24
|
58
|
|
|
58
|
|
412
|
use Fcntl qw/:flock/; |
|
58
|
|
|
|
|
119
|
|
|
58
|
|
|
|
|
7951
|
|
25
|
58
|
|
|
58
|
|
385
|
use Moo; |
|
58
|
|
|
|
|
146
|
|
|
58
|
|
|
|
|
317
|
|
26
|
58
|
|
|
58
|
|
21146
|
use Types::Standard qw/Int Maybe Bool Str HashRef CodeRef Object ArrayRef InstanceOf/; |
|
58
|
|
|
|
|
138
|
|
|
58
|
|
|
|
|
415
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 NAME |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
Text::Amuse::Compile - Compiler for Text::Amuse |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 VERSION |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Version 1.88 |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=cut |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
our $VERSION = '1.88'; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=head1 SYNOPSIS |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
use Text::Amuse::Compile; |
43
|
|
|
|
|
|
|
my $compiler = Text::Amuse::Compile->new; |
44
|
|
|
|
|
|
|
$compiler->compile($file1, $file2, $file3) |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head1 METHODS/ACCESSORS |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head2 CONSTRUCTOR |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=head3 new(ttdir => '.', pdf => 1, ...); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
Constructor. It will accept the following options |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
Format options (by default all of them are activated); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=over 4 |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item cleanup |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
Remove auxiliary files after compilation (.status) |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=item fontspec |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Argument for L constructor. Passing these |
65
|
|
|
|
|
|
|
triggers a new way to select fonts. The validation happens against a |
66
|
|
|
|
|
|
|
list of font you can provide. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=item epub_embed_fonts |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Boolean (default to true) which triggers the epub font embedding. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=item luatex |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
Use lualatex instead of xelatex. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=item tex |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
LaTeX output. Compatible with C and C (see below |
79
|
|
|
|
|
|
|
for the packages needed). |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=item pdf |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
Plain PDF without any imposition. |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=item a4_pdf |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
PDF imposed on A4 paper |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=item lt_pdf |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
PDF imposed on Letter paper |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=item html |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Full HTML output |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item epub |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
The EPUB |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=item bare_html |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
The bare HTML, non |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=item zip |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
The zipped sources |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=item sl_tex |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
The Beamer LaTeX output, if the muse headers say so. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=item sl_pdf |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
The Beamer PDF output, if the muse headers say so. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
If the header has a C<#slides> header with some value (e.g., 1, yes, |
118
|
|
|
|
|
|
|
ok, whatever) and if there some sectioning, create a pdf presentation |
119
|
|
|
|
|
|
|
out of it. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
E.g., the following will not produce slides: |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
#title Foo |
124
|
|
|
|
|
|
|
#slides |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
But this would |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
#title Foo |
129
|
|
|
|
|
|
|
#slides 1 |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
The value of the header is totally insignificant, as long is not |
132
|
|
|
|
|
|
|
C or C or C<0> or empty, which disable them. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Sections which contain the comment C<; noslide> are ignored. LaTeX |
135
|
|
|
|
|
|
|
source is left in the tree with C<.sl.tex> extension, and the output |
136
|
|
|
|
|
|
|
will have C<.sl.pdf> extension. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=item slides |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Alias for sl_pdf. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=item selected_font_main |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
The selected main font (from the C hashref) |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=item selected_font_sans |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
The selected sans font (from the C hashref) |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=item selected_font_mono |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
The selected mono font (from the C hashref) |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=item selected_font_size |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
The selected font size (from the C hashref) |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=item extra_opts |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
An hashref of key/value pairs to pass to each template in the |
161
|
|
|
|
|
|
|
C namespace. This is internal |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=item coverpage_only_if_toc |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
Generate a cover page only if there is a ToC in the document. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
When compiling a virtual file (a collection) the option is ignored, |
168
|
|
|
|
|
|
|
because L C always returns |
169
|
|
|
|
|
|
|
true. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=item include_paths |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
Arrayref of absolute paths to look into for included files. |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=item extra |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
In the constructor arguments, a shallow copy will be stored in |
178
|
|
|
|
|
|
|
C. Using it as an accessor will return an hash with the |
179
|
|
|
|
|
|
|
copy of C |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=item standalone |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Do not force bcor=0 and oneside for plain tex and pdf |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=back |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Template directory: |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=over 4 |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item ttdir |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
The directory where to look for templates, named as format.tt |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=back |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
You can retrieve the value by calling them on the object. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head3 available_methods |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
Return a list of all the available compilation methods |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head3 compile_methods |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Return the list of the methods which are going to be used. |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=cut |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
has sl_tex => (is => 'ro', isa => Bool, default => sub { 0 }); |
210
|
|
|
|
|
|
|
has sl_pdf => (is => 'ro', isa => Bool, default => sub { 0 }); |
211
|
|
|
|
|
|
|
has luatex => (is => 'ro', isa => Bool, default => sub { 0 }); |
212
|
|
|
|
|
|
|
has zip => (is => 'ro', isa => Bool, default => sub { 0 }); |
213
|
|
|
|
|
|
|
has tex => (is => 'ro', isa => Bool, default => sub { 0 }); |
214
|
|
|
|
|
|
|
has pdf => (is => 'ro', isa => Bool, default => sub { 0 }); |
215
|
|
|
|
|
|
|
has a4_pdf => (is => 'ro', isa => Bool, default => sub { 0 }); |
216
|
|
|
|
|
|
|
has lt_pdf => (is => 'ro', isa => Bool, default => sub { 0 }); |
217
|
|
|
|
|
|
|
has epub => (is => 'ro', isa => Bool, default => sub { 0 }); |
218
|
|
|
|
|
|
|
has html => (is => 'ro', isa => Bool, default => sub { 0 }); |
219
|
|
|
|
|
|
|
has bare_html => (is => 'ro', isa => Bool, default => sub { 0 }); |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
has cleanup => (is => 'ro', isa => Bool, default => sub { 0 }); |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
has ttdir => (is => 'ro', isa => Maybe[Str]); |
224
|
|
|
|
|
|
|
has templates => (is => 'lazy', isa => Object); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
has fontspec => (is => 'ro'); |
227
|
|
|
|
|
|
|
has fonts => (is => 'lazy', isa => InstanceOf['Text::Amuse::Compile::Fonts::Selected']); |
228
|
|
|
|
|
|
|
has epub_embed_fonts => (is => 'ro', isa => Bool, default => sub { 1 }); |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
has include_paths => (is => 'ro', |
231
|
|
|
|
|
|
|
default => sub { return [] }, |
232
|
|
|
|
|
|
|
isa => sub { |
233
|
|
|
|
|
|
|
die "include_paths must be an arrayref" unless ref($_[0]) eq 'ARRAY'; |
234
|
|
|
|
|
|
|
foreach my $path (@{$_[0]}) { |
235
|
|
|
|
|
|
|
die "include_paths must be defined" unless defined $path; |
236
|
|
|
|
|
|
|
die "include_paths $path is empty" unless length($path); |
237
|
|
|
|
|
|
|
die "include_paths $path must be absolute" unless File::Spec->file_name_is_absolute($path); |
238
|
|
|
|
|
|
|
die "include_paths $path must exist" unless -d $path; |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
}); |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub _build_fonts { |
243
|
226
|
|
|
226
|
|
14144
|
my $self = shift; |
244
|
226
|
|
|
|
|
943
|
my $specs = $self->fontspec; |
245
|
226
|
|
|
|
|
4960
|
my $fonts = Text::Amuse::Compile::Fonts->new($specs); |
246
|
224
|
|
100
|
|
|
38293
|
my %args = ( |
247
|
|
|
|
|
|
|
size => $self->selected_font_size || 10, |
248
|
|
|
|
|
|
|
all_fonts => $fonts, |
249
|
|
|
|
|
|
|
luatex => $self->luatex, |
250
|
|
|
|
|
|
|
); |
251
|
224
|
|
|
|
|
1510
|
my @all_fonts = $fonts->all_fonts; |
252
|
224
|
|
|
|
|
978
|
foreach my $type (qw/sans mono serif/) { |
253
|
670
|
|
|
|
|
1938
|
my $method = $type . '_fonts'; |
254
|
670
|
|
|
|
|
4347
|
my @all = $fonts->$method; |
255
|
670
|
100
|
|
|
|
2351
|
die "Missing $type font in the specification" unless @all; |
256
|
669
|
100
|
|
|
|
2267
|
my $store = $type eq 'serif' ? 'main' : $type; |
257
|
669
|
|
|
|
|
1624
|
my $smethod = "selected_font_${store}"; |
258
|
669
|
100
|
|
|
|
3373
|
if (my $selected = $self->$smethod) { |
259
|
46
|
|
|
|
|
113
|
my ($got) = grep { $_->name eq $selected } @all_fonts; |
|
1251
|
|
|
|
|
2192
|
|
260
|
46
|
|
|
|
|
149
|
$args{$store} = $got; |
261
|
|
|
|
|
|
|
} |
262
|
669
|
100
|
|
|
|
1929
|
unless ($args{$store}) { |
263
|
625
|
|
|
|
|
14499
|
$self->logger->("$store font not found, using the default\n"); |
264
|
625
|
|
|
|
|
7615
|
$args{$store} = $all[0]; # if everything fails |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
} |
267
|
223
|
|
|
|
|
7195
|
return Text::Amuse::Compile::Fonts::Selected->new(%args); |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
has selected_font_main => (is => 'ro', isa => Maybe[Str]); |
271
|
|
|
|
|
|
|
has selected_font_sans => (is => 'ro', isa => Maybe[Str]); |
272
|
|
|
|
|
|
|
has selected_font_mono => (is => 'ro', isa => Maybe[Str]); |
273
|
|
|
|
|
|
|
has selected_font_size => (is => 'ro', isa => Maybe[Int]); |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
has standalone => (is => 'lazy', isa => Bool); |
276
|
|
|
|
|
|
|
has extra_opts => (is => 'ro', isa => HashRef, default => sub { +{} }); |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub slides { |
279
|
0
|
|
|
0
|
1
|
0
|
return shift->sl_pdf; |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
has coverpage_only_if_toc => (is => 'ro', isa => Bool, default => sub { 0 }); |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub BUILDARGS { |
285
|
247
|
|
|
247
|
1
|
1951782
|
my ($class, %params) = @_; |
286
|
247
|
100
|
|
|
|
796
|
$params{extra_opts} = { %{ delete $params{extra} || {} } }; |
|
247
|
|
|
|
|
2406
|
|
287
|
247
|
|
|
|
|
1008
|
my $all = 1; |
288
|
247
|
100
|
|
|
|
1231
|
if (exists $params{slides}) { |
289
|
15
|
|
|
|
|
36
|
my $slides = delete $params{slides}; |
290
|
15
|
|
100
|
|
|
62
|
$params{sl_pdf} ||= $slides; |
291
|
|
|
|
|
|
|
} |
292
|
247
|
|
|
|
|
1283
|
foreach my $format ($class->available_methods) { |
293
|
1261
|
100
|
|
|
|
3160
|
if (exists $params{$format}) { |
294
|
237
|
|
|
|
|
675
|
$all = 0; |
295
|
237
|
|
|
|
|
705
|
last; |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
} |
298
|
247
|
100
|
|
|
|
1221
|
if ($all) { |
299
|
10
|
|
|
|
|
42
|
foreach my $format ($class->available_methods) { |
300
|
100
|
|
|
|
|
190
|
$params{$format} = 1; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
} |
303
|
247
|
|
|
|
|
794
|
foreach my $dir (qw/ttdir/) { |
304
|
247
|
50
|
66
|
|
|
1489
|
if (exists $params{$dir} and defined $params{$dir} and -d $params{$dir}) { |
|
|
|
66
|
|
|
|
|
305
|
1
|
|
|
|
|
21
|
my $abs = File::Spec->rel2abs($params{$dir}); |
306
|
1
|
|
|
|
|
4
|
$params{$dir} = $abs; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
# take out the fonts from the extra, for backcomp. |
310
|
247
|
|
|
|
|
875
|
foreach my $type (qw/main sans mono/) { |
311
|
741
|
|
|
|
|
2800
|
$params{"selected_font_$type"} = delete $params{extra_opts}{"${type}font"}; |
312
|
|
|
|
|
|
|
} |
313
|
247
|
|
|
|
|
950
|
$params{selected_font_size} = delete $params{extra_opts}{fontsize}; |
314
|
247
|
|
|
|
|
5311
|
return \%params; |
315
|
|
|
|
|
|
|
} |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
sub available_methods { |
318
|
579
|
|
|
579
|
1
|
2837
|
return (qw/bare_html |
319
|
|
|
|
|
|
|
html |
320
|
|
|
|
|
|
|
epub |
321
|
|
|
|
|
|
|
a4_pdf |
322
|
|
|
|
|
|
|
lt_pdf |
323
|
|
|
|
|
|
|
tex |
324
|
|
|
|
|
|
|
zip |
325
|
|
|
|
|
|
|
pdf |
326
|
|
|
|
|
|
|
sl_tex |
327
|
|
|
|
|
|
|
sl_pdf |
328
|
|
|
|
|
|
|
/); |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
sub compile_methods { |
331
|
322
|
|
|
322
|
1
|
996
|
my $self = shift; |
332
|
322
|
|
|
|
|
1113
|
return grep { $self->$_ } $self->available_methods; |
|
3220
|
|
|
|
|
9365
|
|
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
sub extra { |
338
|
304
|
|
|
304
|
1
|
2969
|
return %{ shift->extra_opts }; |
|
304
|
|
|
|
|
9287
|
|
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub _build_standalone { |
343
|
220
|
|
|
220
|
|
7933
|
my $self = shift; |
344
|
220
|
100
|
66
|
|
|
2050
|
if ($self->a4_pdf || $self->lt_pdf) { |
345
|
2
|
|
|
|
|
35
|
return 0; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
else { |
348
|
218
|
|
|
|
|
3925
|
return 1; |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
has logger => (is => 'rw', |
353
|
|
|
|
|
|
|
isa => CodeRef, |
354
|
|
|
|
|
|
|
default => sub { return sub { print @_ }; }); |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
has report_failure_sub => (is => 'rw', |
357
|
|
|
|
|
|
|
isa => CodeRef, |
358
|
|
|
|
|
|
|
default => sub { |
359
|
|
|
|
|
|
|
return sub { |
360
|
|
|
|
|
|
|
print "Failure to compile $_[0]\n"; |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
}); |
363
|
|
|
|
|
|
|
has errors => (is => 'rwp', isa => ArrayRef, default => sub { [] }); |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=head2 BUILDARGS routine |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
The C key is passed instead to C. Directories are |
369
|
|
|
|
|
|
|
made absolute. If no formats are required explicitely, set them all to |
370
|
|
|
|
|
|
|
true. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=cut |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=head2 METHODS |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head3 fonts |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
The L object, constructed from |
379
|
|
|
|
|
|
|
the fontspec argument and eventual C font keys passed. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=head3 version |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
Report version information |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=cut |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
sub version { |
388
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
389
|
0
|
|
|
|
|
0
|
my $musev = $Text::Amuse::VERSION; |
390
|
0
|
|
|
|
|
0
|
my $selfv = $VERSION; |
391
|
0
|
|
|
|
|
0
|
my $pdfv = $PDF::Imposition::VERSION; |
392
|
0
|
|
|
|
|
0
|
return "Using Text::Amuse $musev, Text::Amuse::Compiler $selfv, " . |
393
|
|
|
|
|
|
|
"PDF::Imposition $pdfv\n"; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=head3 logger($sub) |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
Accessor/setter for the subroutine which will handle the logging. |
399
|
|
|
|
|
|
|
Defaults to printing to the standard output. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head3 recursive_compile($directory) |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
Compile recursive a directory, comparing the timestamps of the status |
404
|
|
|
|
|
|
|
file with the muse file. If the status file is newer, the file is |
405
|
|
|
|
|
|
|
ignored. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
Return a list of absolute path to the files processed. To infer the |
408
|
|
|
|
|
|
|
success or the failure of each file look at the status file or at the |
409
|
|
|
|
|
|
|
logs. |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=head3 find_muse_files($directory) |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
Return a sorted list of files with extension .muse excluding illegal |
414
|
|
|
|
|
|
|
names (including hidden files and directories). |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head3 find_new_muse_files($directory) |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
As above, but check the age of the status file and skip already |
419
|
|
|
|
|
|
|
processed files. |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=cut |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
sub find_muse_files { |
424
|
5
|
|
|
5
|
1
|
3222
|
my ($self, $dir) = @_; |
425
|
5
|
|
|
|
|
10
|
my @files; |
426
|
5
|
50
|
33
|
|
|
96
|
die "$dir is not a dir" unless ($dir && -d $dir); |
427
|
|
|
|
|
|
|
find( sub { |
428
|
80
|
|
|
80
|
|
285
|
my $file = $_; |
429
|
|
|
|
|
|
|
# file only |
430
|
80
|
100
|
|
|
|
3597
|
return unless -f $file; |
431
|
40
|
100
|
|
|
|
689
|
return unless $file =~ m/^[0-9a-z][0-9a-z-]+[0-9a-z]+\.muse$/; |
432
|
|
|
|
|
|
|
# exclude hidden directories |
433
|
20
|
100
|
|
|
|
75
|
if ($File::Find::dir =~ m/\./) { |
434
|
8
|
|
|
|
|
66
|
my @dirs = File::Spec->splitdir($File::Find::dir); |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# for the purpose of filtering, the leading . is harmless |
437
|
8
|
100
|
33
|
|
|
55
|
if (@dirs && $dirs[0] && $dirs[0] eq '.') { |
|
|
|
66
|
|
|
|
|
438
|
4
|
|
|
|
|
9
|
shift(@dirs); |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
8
|
|
|
|
|
23
|
my @dots = grep { m/^\./ } @dirs; |
|
24
|
|
|
|
|
68
|
|
442
|
8
|
100
|
|
|
|
150
|
return if @dots; |
443
|
|
|
|
|
|
|
} |
444
|
15
|
|
|
|
|
712
|
push @files, File::Spec->rel2abs($file); |
445
|
5
|
|
|
|
|
367
|
}, $dir); |
446
|
5
|
|
|
|
|
69
|
return sort @files; |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
sub find_new_muse_files { |
450
|
4
|
|
|
4
|
1
|
5630
|
my ($self, $dir) = @_; |
451
|
4
|
|
|
|
|
15
|
my @candidates = $self->find_muse_files($dir); |
452
|
4
|
|
|
|
|
9
|
my @newf; |
453
|
4
|
|
|
|
|
9
|
my $mtime = 9; |
454
|
4
|
|
|
|
|
12
|
while (@candidates) { |
455
|
12
|
|
|
|
|
30
|
my $f = shift(@candidates); |
456
|
12
|
50
|
33
|
|
|
181
|
die "I was expecting a file here" unless $f && -f $f; |
457
|
12
|
|
|
|
|
34
|
my $status = $f; |
458
|
12
|
|
|
|
|
67
|
$status =~ s/\.muse$/.status/; |
459
|
12
|
100
|
|
|
|
271
|
if (! -f $status) { |
|
|
50
|
|
|
|
|
|
460
|
7
|
|
|
|
|
32
|
push @newf, $f; |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
elsif ((stat($f))[$mtime] > (stat($status))[$mtime]) { |
463
|
0
|
|
|
|
|
0
|
push @newf, $f; |
464
|
|
|
|
|
|
|
} |
465
|
|
|
|
|
|
|
} |
466
|
4
|
|
|
|
|
26
|
return @newf; |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
sub recursive_compile { |
470
|
2
|
|
|
2
|
1
|
1977
|
my ($self, $dir) = @_; |
471
|
2
|
|
|
|
|
7
|
return $self->compile($self->find_new_muse_files($dir)); |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
=head3 compile($file1, $file2, ...); |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
Main method to get the job done, passing the list of muse files. You |
478
|
|
|
|
|
|
|
can inspect the errors calling C. It does produce some output. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
The file may also be an hash reference. In this case, the compile will |
481
|
|
|
|
|
|
|
act on a list of files and will merge them. Beware that so far only |
482
|
|
|
|
|
|
|
the C and C options will work, while the other html methods |
483
|
|
|
|
|
|
|
will throw exceptions or (worse probably) produce empty files. This |
484
|
|
|
|
|
|
|
will be fixed soon. This feature is marked as B and |
485
|
|
|
|
|
|
|
could change in the future. |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=head4 virtual file hashref |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
The hash reference should have those mandatory fields: |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=over 4 |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item files |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
An B of filenames without extension. |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=item path |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
A mandatory directory where to find the above files. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=back |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
Optional keys |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
=over 4 |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=item name |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Default to virtual. This is the basename of the files which will be |
510
|
|
|
|
|
|
|
produced. It's up to you to provide a sensible name we don't do any |
511
|
|
|
|
|
|
|
check on that. |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
=item suffix |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
Defaults to '.muse' and you have no reason to change this. |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=back |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
Every other key is the metadata of the new document, so usually you |
520
|
|
|
|
|
|
|
want to set C and optionally C. |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
Example: |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
$c->compile({ |
525
|
|
|
|
|
|
|
# mandatory |
526
|
|
|
|
|
|
|
path => File::Spec->catdir(qw/t merged-dir/), |
527
|
|
|
|
|
|
|
files => [qw/first second/], |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
# recommended |
530
|
|
|
|
|
|
|
name => 'my-new-test', |
531
|
|
|
|
|
|
|
title => 'My new shiny test', |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
# optional |
534
|
|
|
|
|
|
|
subtitle => 'Another one', |
535
|
|
|
|
|
|
|
date => 'Today!', |
536
|
|
|
|
|
|
|
source => 'Text::Amuse::Compile', |
537
|
|
|
|
|
|
|
}); |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
You can pass as many hashref you want. |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
=cut |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
sub compile { |
544
|
299
|
|
|
299
|
1
|
361622
|
my ($self, @files) = @_; |
545
|
299
|
|
|
|
|
1670
|
$self->reset_errors; |
546
|
299
|
|
|
|
|
13240
|
my $cwd = getcwd; |
547
|
299
|
|
|
|
|
1124
|
my @compiled; |
548
|
299
|
|
|
|
|
1063
|
foreach my $file (@files) { |
549
|
301
|
50
|
|
|
|
4320
|
chdir $cwd or die "Couldn't chdir into $cwd $!"; |
550
|
301
|
100
|
|
|
|
1557
|
if (ref($file)) { |
551
|
16
|
|
|
|
|
39
|
eval { $self->_compile_virtual_file($file); }; |
|
16
|
|
|
|
|
80
|
|
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
else { |
554
|
285
|
|
|
|
|
714
|
eval { $self->_compile_file($file); }; |
|
285
|
|
|
|
|
1440
|
|
555
|
|
|
|
|
|
|
} |
556
|
301
|
|
|
|
|
1678
|
my $fatal = $@; |
557
|
301
|
50
|
|
|
|
6172
|
chdir $cwd or die "Couldn't chdir into $cwd $!"; |
558
|
301
|
100
|
|
|
|
1764
|
if ($fatal) { |
559
|
3
|
|
|
|
|
89
|
$self->logger->($fatal); |
560
|
3
|
|
|
|
|
46
|
$self->add_errors("$file $fatal"); |
561
|
3
|
|
|
|
|
70
|
$self->report_failure_sub->($file); |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
else { |
564
|
298
|
|
|
|
|
1865
|
push @compiled, $file; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
} |
567
|
299
|
|
|
|
|
2222
|
return @compiled; |
568
|
|
|
|
|
|
|
} |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
sub _compile_virtual_file { |
571
|
16
|
|
|
16
|
|
57
|
my ($self, $vfile) = @_; |
572
|
|
|
|
|
|
|
# check if the reference is good |
573
|
16
|
50
|
|
|
|
76
|
die "Virtual file is not a hashref" unless ref($vfile) eq 'HASH'; |
574
|
16
|
|
|
|
|
127
|
my %virtual = %$vfile; |
575
|
16
|
|
|
|
|
60
|
my $files = delete $virtual{files}; |
576
|
16
|
50
|
33
|
|
|
122
|
die "No file list found" unless $files && @$files; |
577
|
16
|
|
|
|
|
57
|
my $path = delete $virtual{path}; |
578
|
16
|
50
|
33
|
|
|
316
|
die "No directory path" unless $path && -d $path; |
579
|
16
|
50
|
|
|
|
179
|
chdir $path or die "Couldn't chdir into $path $!"; |
580
|
16
|
|
50
|
|
|
121
|
my $suffix = delete($virtual{suffix}) || '.muse'; |
581
|
16
|
|
50
|
|
|
69
|
my $name = delete($virtual{name}) || 'virtual'; |
582
|
16
|
|
|
|
|
568
|
$self->logger->("Working on virtual file in " . getcwd(). "\n"); |
583
|
16
|
|
|
|
|
114
|
my @filelist = map { Text::Amuse::Compile::FileName->new($_) } @$files; |
|
53
|
|
|
|
|
280
|
|
584
|
|
|
|
|
|
|
my $doc = Text::Amuse::Compile::Merged->new(files => \@filelist, |
585
|
16
|
|
|
|
|
69
|
include_paths => [ @{$self->include_paths} ], |
|
16
|
|
|
|
|
230
|
|
586
|
|
|
|
|
|
|
%virtual); |
587
|
|
|
|
|
|
|
my $muse = Text::Amuse::Compile::File->new( |
588
|
|
|
|
|
|
|
name => $name, |
589
|
|
|
|
|
|
|
suffix => $suffix, |
590
|
|
|
|
|
|
|
luatex => $self->luatex, |
591
|
|
|
|
|
|
|
ttdir => $self->ttdir, |
592
|
|
|
|
|
|
|
options => { $self->extra }, |
593
|
|
|
|
|
|
|
document => $doc, |
594
|
|
|
|
|
|
|
logger => $self->logger, |
595
|
|
|
|
|
|
|
virtual => 1, |
596
|
|
|
|
|
|
|
standalone => $self->standalone, |
597
|
|
|
|
|
|
|
fonts => $self->fonts, |
598
|
|
|
|
|
|
|
epub_embed_fonts => $self->epub_embed_fonts, |
599
|
16
|
|
|
|
|
224
|
include_paths => [ @{$self->include_paths} ], |
|
16
|
|
|
|
|
12148
|
|
600
|
|
|
|
|
|
|
); |
601
|
16
|
|
|
|
|
1620
|
$self->_muse_compile($muse); |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
sub _compile_file { |
606
|
285
|
|
|
285
|
|
1252
|
my ($self, $file) = @_; |
607
|
285
|
|
|
|
|
3346
|
my $fileobj = Text::Amuse::Compile::FileName->new($file); |
608
|
285
|
100
|
66
|
|
|
2951
|
die "$file is not a file" unless $fileobj && -f $fileobj->full_path; |
609
|
|
|
|
|
|
|
|
610
|
284
|
50
|
|
|
|
1742
|
if (my $path = $fileobj->path) { |
611
|
284
|
50
|
|
|
|
3137
|
chdir $path or die "Cannot chdir into $path from " . getcwd() . "\n" ; |
612
|
|
|
|
|
|
|
}; |
613
|
|
|
|
|
|
|
|
614
|
284
|
|
|
|
|
1594
|
my $filename = $fileobj->filename; |
615
|
284
|
|
|
|
|
10258
|
$self->logger->("Working on $filename file in " . getcwd(). "\n"); |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
my %args = ( |
618
|
|
|
|
|
|
|
name => $fileobj->name, |
619
|
|
|
|
|
|
|
suffix => $fileobj->suffix, |
620
|
|
|
|
|
|
|
ttdir => $self->ttdir, |
621
|
|
|
|
|
|
|
options => { $self->extra }, |
622
|
|
|
|
|
|
|
logger => $self->logger, |
623
|
|
|
|
|
|
|
standalone => $self->standalone, |
624
|
|
|
|
|
|
|
fonts => $self->fonts, |
625
|
|
|
|
|
|
|
epub_embed_fonts => $self->epub_embed_fonts, |
626
|
|
|
|
|
|
|
luatex => $self->luatex, |
627
|
|
|
|
|
|
|
fileobj => $fileobj, |
628
|
|
|
|
|
|
|
coverpage_only_if_toc => $self->coverpage_only_if_toc, |
629
|
284
|
|
|
|
|
5102
|
include_paths => [ @{$self->include_paths} ], |
|
283
|
|
|
|
|
226689
|
|
630
|
|
|
|
|
|
|
); |
631
|
|
|
|
|
|
|
|
632
|
283
|
|
|
|
|
7743
|
my $muse = Text::Amuse::Compile::File->new(%args); |
633
|
283
|
|
|
|
|
9893
|
$self->_muse_compile($muse); |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
# write the status file and unlock it after that. |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
sub _write_status_file { |
639
|
299
|
|
|
299
|
|
1490
|
my ($self, $fh, $status, @diagnostics) = @_; |
640
|
299
|
|
|
|
|
12619
|
my $localtime = localtime(); |
641
|
299
|
|
|
|
|
2970
|
my %avail = ( |
642
|
|
|
|
|
|
|
FAILED => 1, |
643
|
|
|
|
|
|
|
DELETED => 1, |
644
|
|
|
|
|
|
|
OK => 1, |
645
|
|
|
|
|
|
|
); |
646
|
299
|
50
|
|
|
|
1882
|
die unless $avail{$status}; |
647
|
299
|
|
|
|
|
4843
|
print $fh "$status $$ $localtime\n"; |
648
|
299
|
100
|
|
|
|
1632
|
if (@diagnostics) { |
649
|
1
|
|
|
|
|
3
|
print $fh "\n"; |
650
|
1
|
|
|
|
|
3
|
foreach my $diag (@diagnostics) { |
651
|
1
|
|
|
|
|
14
|
print $fh "$diag\n"; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
} |
654
|
299
|
50
|
|
|
|
14496
|
flock($fh, LOCK_UN) or die "Cannot unlock status file\n"; |
655
|
299
|
|
|
|
|
12127
|
close $fh; |
656
|
|
|
|
|
|
|
} |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
sub _muse_compile { |
659
|
299
|
|
|
299
|
|
1043
|
my ($self, $muse) = @_; |
660
|
299
|
|
|
|
|
1784
|
my $statusfile = $muse->status_file; |
661
|
299
|
50
|
|
20
|
|
25408
|
open (my $fhlock, '>:encoding(utf-8)', $statusfile) |
|
20
|
|
|
|
|
177
|
|
|
20
|
|
|
|
|
48
|
|
|
20
|
|
|
|
|
169
|
|
662
|
|
|
|
|
|
|
or die "Cannot open $statusfile\n!"; |
663
|
299
|
50
|
|
|
|
55565
|
flock($fhlock, LOCK_EX | LOCK_NB) or die "Cannot acquire lock on $statusfile"; |
664
|
|
|
|
|
|
|
|
665
|
299
|
|
|
|
|
5001145
|
sleep 5 if DEBUG; |
666
|
|
|
|
|
|
|
|
667
|
299
|
|
|
|
|
1025
|
my @fatals; |
668
|
|
|
|
|
|
|
my @warnings; |
669
|
|
|
|
|
|
|
|
670
|
299
|
|
|
|
|
2235
|
$muse->purge_all unless DEBUG; |
671
|
299
|
100
|
|
|
|
10154
|
if ($muse->is_deleted) { |
672
|
1
|
|
|
|
|
72
|
$self->_write_status_file($fhlock, 'DELETED'); |
673
|
1
|
|
|
|
|
29
|
return; |
674
|
|
|
|
|
|
|
} |
675
|
298
|
|
|
|
|
22772
|
foreach my $method ($self->compile_methods) { |
676
|
438
|
100
|
66
|
|
|
3785
|
if ($method eq 'sl_pdf' or $method eq 'sl_tex') { |
677
|
16
|
100
|
|
|
|
343
|
unless ($muse->wants_slides) { |
678
|
7
|
|
|
|
|
492
|
$self->logger->("* Slides not required\n"); |
679
|
7
|
|
|
|
|
38
|
next; |
680
|
|
|
|
|
|
|
} |
681
|
|
|
|
|
|
|
} |
682
|
431
|
|
|
|
|
1625
|
my $output = eval { |
683
|
|
|
|
|
|
|
local $SIG{__WARN__} = sub { |
684
|
1
|
|
|
1
|
|
409
|
push @warnings, @_; |
685
|
431
|
|
|
|
|
4256
|
}; |
686
|
431
|
|
|
|
|
3199
|
$muse->$method |
687
|
|
|
|
|
|
|
}; |
688
|
431
|
100
|
|
|
|
101411
|
if ($@) { |
|
|
50
|
|
|
|
|
|
689
|
1
|
|
|
|
|
5
|
push @fatals, $@; |
690
|
1
|
|
|
|
|
2
|
last; |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
elsif ($output) { |
693
|
430
|
|
|
|
|
20655
|
$self->logger->("* Created $output\n"); |
694
|
|
|
|
|
|
|
} |
695
|
|
|
|
|
|
|
else { |
696
|
0
|
|
|
|
|
0
|
$self->logger->("* $method skipped\n"); |
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
} |
699
|
298
|
100
|
|
|
|
7020
|
if (@fatals) { |
700
|
1
|
|
|
|
|
7
|
$self->_write_status_file($fhlock, 'FAILED', @fatals); |
701
|
1
|
|
|
|
|
182
|
die join(" ", @fatals); |
702
|
|
|
|
|
|
|
} |
703
|
|
|
|
|
|
|
else { |
704
|
297
|
|
|
|
|
1924
|
$self->_write_status_file($fhlock, 'OK'); |
705
|
|
|
|
|
|
|
} |
706
|
297
|
100
|
|
|
|
3219
|
$muse->cleanup if $self->cleanup; |
707
|
297
|
|
|
|
|
124680
|
foreach my $warn (@warnings) { |
708
|
1
|
50
|
|
|
|
33
|
$self->logger->("Warning: $warn") if $warn; |
709
|
|
|
|
|
|
|
} |
710
|
|
|
|
|
|
|
} |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
sub _suffix_for_method { |
713
|
27
|
|
|
27
|
|
66
|
my ($self, $method) = @_; |
714
|
27
|
50
|
|
|
|
68
|
return unless $method; |
715
|
27
|
|
|
|
|
46
|
my $ext = $method; |
716
|
27
|
|
|
|
|
93
|
$ext =~ s/_/./g; |
717
|
27
|
|
|
|
|
66
|
$ext = '.' . $ext; |
718
|
27
|
|
|
|
|
75
|
return $ext; |
719
|
|
|
|
|
|
|
} |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
=head3 file_needs_compilation |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
Returns true if the file has already been compiled, false if some |
724
|
|
|
|
|
|
|
output file is missing or stale. |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=head3 parse_muse_header($file) |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
Return a L object for the given |
729
|
|
|
|
|
|
|
file. |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
=cut |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
sub _check_file_basename { |
734
|
29
|
|
|
29
|
|
61
|
my ($self, $file) = @_; |
735
|
29
|
|
|
|
|
170
|
my $fileobj = Text::Amuse::Compile::FileName->new($file); |
736
|
29
|
|
|
|
|
110
|
return File::Spec->catfile($fileobj->path, $fileobj->name); |
737
|
|
|
|
|
|
|
} |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
sub parse_muse_header { |
740
|
53
|
|
|
53
|
1
|
348
|
my ($self, $file) = @_; |
741
|
53
|
|
|
|
|
364
|
my $path = Text::Amuse::Compile::FileName->new($file)->full_path; |
742
|
53
|
|
|
|
|
257
|
return Text::Amuse::Compile::MuseHeader->new(muse_fast_scan_header($path)); |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
sub file_needs_compilation { |
747
|
16
|
|
|
16
|
1
|
5820
|
my ($self, $file) = @_; |
748
|
16
|
|
|
|
|
34
|
my $need = 0; |
749
|
16
|
|
|
|
|
31
|
my $mtime = 9; |
750
|
16
|
|
|
|
|
44
|
my $basename = $self->_check_file_basename($file); |
751
|
16
|
|
|
|
|
67
|
my $header = $self->parse_muse_header($file); |
752
|
16
|
|
|
|
|
2346
|
foreach my $m ($self->compile_methods) { |
753
|
22
|
|
|
|
|
94
|
my $outsuffix = $self->_suffix_for_method($m); |
754
|
22
|
|
|
|
|
58
|
my $outfile = $basename . $outsuffix; |
755
|
22
|
100
|
66
|
|
|
95
|
if ($m eq 'sl_tex' or $m eq 'sl_pdf') { |
756
|
11
|
100
|
|
|
|
241
|
next unless $header->wants_slides; |
757
|
|
|
|
|
|
|
} |
758
|
15
|
100
|
66
|
|
|
543
|
if (-f $outfile and (stat($outfile))[$mtime] >= (stat($file))[$mtime]) { |
759
|
11
|
|
|
|
|
43
|
print "$outfile is OK\n" if DEBUG; |
760
|
11
|
|
|
|
|
39
|
next; |
761
|
|
|
|
|
|
|
} |
762
|
|
|
|
|
|
|
else { |
763
|
4
|
|
|
|
|
13
|
print "$outfile is NOT OK\n" if DEBUG; |
764
|
4
|
|
|
|
|
10
|
$need = 1; |
765
|
4
|
|
|
|
|
12
|
last; |
766
|
|
|
|
|
|
|
} |
767
|
|
|
|
|
|
|
} |
768
|
16
|
|
|
|
|
360
|
return $need; |
769
|
|
|
|
|
|
|
} |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
=head2 purge(@files) |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
Remove all the files produced by the compilation of the files passed |
774
|
|
|
|
|
|
|
as arguments. |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=cut |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
sub purge { |
779
|
13
|
|
|
13
|
1
|
2696
|
my ($self, @files) = @_; |
780
|
13
|
|
|
|
|
40
|
foreach my $file (@files) { |
781
|
13
|
|
|
|
|
39
|
my $basename = $self->_check_file_basename($file); |
782
|
13
|
|
|
|
|
100
|
foreach my $ext (Text::Amuse::Compile::File->purged_extensions) { |
783
|
351
|
50
|
|
|
|
917
|
die "?" if $ext eq '.muse'; |
784
|
351
|
|
|
|
|
677
|
my $produced = $basename . $ext; |
785
|
351
|
100
|
|
|
|
4719
|
if (-f $produced) { |
786
|
5
|
|
|
|
|
152
|
$self->logger->("Purging $produced\n"); |
787
|
5
|
50
|
|
|
|
342
|
unlink $produced or warn "Cannot unlink $produced $!"; |
788
|
|
|
|
|
|
|
} |
789
|
|
|
|
|
|
|
} |
790
|
|
|
|
|
|
|
} |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=head3 report_failure_sub(sub { push @problems, $_[0] }); |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
You can set the sub to be used to report problems using this accessor. |
797
|
|
|
|
|
|
|
It will receive as first argument the file which led to failure. |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
The actual errors are logged by the C sub. |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
=head3 errors |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
Accessor to the catched errors. It returns a list of strings. |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=head3 add_errors($error1, $error2,...) |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
Add an error. [Internal] |
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
=head3 reset_errors |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
Reset the errors |
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
=head3 has_errors |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
Return the number of errors (handy to use as a boolean). |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
=cut |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
sub add_errors { |
820
|
3
|
|
|
3
|
1
|
13
|
my ($self, @args) = @_; |
821
|
3
|
|
|
|
|
8
|
push @{$self->errors}, @args; |
|
3
|
|
|
|
|
25
|
|
822
|
|
|
|
|
|
|
} |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
sub reset_errors { |
825
|
299
|
|
|
299
|
1
|
844
|
my $self = shift; |
826
|
299
|
|
|
|
|
8411
|
$self->_set_errors([]); |
827
|
|
|
|
|
|
|
} |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
sub has_errors { |
830
|
0
|
|
|
0
|
1
|
0
|
return scalar(@{ shift->errors }); |
|
0
|
|
|
|
|
0
|
|
831
|
|
|
|
|
|
|
} |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
=head1 TeX live packages needed. |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
You need the xetex scheme plus the following packages: fontspec, |
836
|
|
|
|
|
|
|
polyglossia, pzdr, wrapfig, footmisc, ulem, microtype, zapfding. |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
For the luatex options, same as above plus luatex (and the lualatex |
839
|
|
|
|
|
|
|
format), luatexbase, luaotfload. |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
The luatex option could give better microtypography results but is |
842
|
|
|
|
|
|
|
slower (x4) and requires more memory (x2). |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=head1 INTERNAL CONSTANTS |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=head2 DEBUG |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
Set from AMW_DEBUG environment. |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
=head1 AUTHOR |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
Marco Pessotto, C<< >> |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
=head1 BUGS |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
Please mail the author and provide a minimal example to add to the |
857
|
|
|
|
|
|
|
test suite. |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
=head1 SUPPORT |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
perldoc Text::Amuse::Compile |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
=head1 LICENSE |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
868
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
869
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
See L for more information. |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
=cut |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
1; # End of Text::Amuse::Compile |