line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Text::Amuse::Functions; |
2
|
20
|
|
|
20
|
|
711578
|
use strict; |
|
20
|
|
|
|
|
130
|
|
|
20
|
|
|
|
|
480
|
|
3
|
20
|
|
|
20
|
|
80
|
use warnings; |
|
20
|
|
|
|
|
30
|
|
|
20
|
|
|
|
|
524
|
|
4
|
20
|
|
|
20
|
|
1351
|
use utf8; |
|
20
|
|
|
|
|
59
|
|
|
20
|
|
|
|
|
82
|
|
5
|
20
|
|
|
20
|
|
10372
|
use File::Temp; |
|
20
|
|
|
|
|
298720
|
|
|
20
|
|
|
|
|
1147
|
|
6
|
20
|
|
|
20
|
|
6819
|
use File::Copy qw/move/; |
|
20
|
|
|
|
|
34167
|
|
|
20
|
|
|
|
|
931
|
|
7
|
20
|
|
|
20
|
|
5340
|
use Text::Amuse; |
|
20
|
|
|
|
|
55
|
|
|
20
|
|
|
|
|
509
|
|
8
|
20
|
|
|
20
|
|
6370
|
use Text::Amuse::String; |
|
20
|
|
|
|
|
46
|
|
|
20
|
|
|
|
|
452
|
|
9
|
20
|
|
|
20
|
|
91
|
use Text::Amuse::Output; |
|
20
|
|
|
|
|
32
|
|
|
20
|
|
|
|
|
393
|
|
10
|
20
|
|
|
20
|
|
71
|
use Text::Amuse::Document; |
|
20
|
|
|
|
|
26
|
|
|
20
|
|
|
|
|
14439
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
require Exporter; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our @EXPORT_OK = qw/muse_format_line |
17
|
|
|
|
|
|
|
muse_fast_scan_header |
18
|
|
|
|
|
|
|
muse_to_html |
19
|
|
|
|
|
|
|
muse_to_tex |
20
|
|
|
|
|
|
|
muse_to_object |
21
|
|
|
|
|
|
|
muse_rewrite_header |
22
|
|
|
|
|
|
|
/; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 NAME |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Text::Amuse::Functions - Exportable functions for L |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 SYNOPSIS |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
This module provides some functions to format strings wrapping the OO |
32
|
|
|
|
|
|
|
interface to function calls. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
use Text::Amuse::Functions qw/muse_format_line/ |
35
|
|
|
|
|
|
|
my $html = muse_format_line(html => "hello 'world'"); |
36
|
|
|
|
|
|
|
my $ltx = muse_format_line(ltx => "hello #world"); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head1 FUNCTIONS |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=over 4 |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=item muse_format_line ($format, $string, [ $lang ]) |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Output the given chunk in the desired format (C or C). |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
Accepts a third parameter with the language code. This is usually not |
47
|
|
|
|
|
|
|
needed unless you're dealing with French. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
This is meant to be used for headers, or for on the fly escaping. So |
50
|
|
|
|
|
|
|
lists, footnotes, tables, blocks, etc. are not supported. Basically, |
51
|
|
|
|
|
|
|
we process only one paragraph, without wrapping it in . |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=cut |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub muse_format_line { |
56
|
29
|
|
|
29
|
1
|
2609
|
my ($format, $line, $lang) = @_; |
57
|
29
|
50
|
|
|
|
69
|
return "" unless defined $line; |
58
|
29
|
50
|
66
|
|
|
91
|
die unless ($format eq 'html' or $format eq 'ltx'); |
59
|
29
|
|
|
|
|
108
|
my $doc = Text::Amuse::String->new($line, $lang); |
60
|
29
|
|
|
|
|
102
|
my $out = Text::Amuse::Output->new(document => $doc, |
61
|
|
|
|
|
|
|
format => $format); |
62
|
29
|
|
|
|
|
36
|
return join("", @{ $out->process }); |
|
29
|
|
|
|
|
67
|
|
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item muse_fast_scan_header($file, $format); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
Open the file $file, which is supposed to be UTF-8 encoded. Decode the |
68
|
|
|
|
|
|
|
content and read its Muse header. |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Returns an hash reference with the metadata. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
If the second argument is set and is C or , filter the |
73
|
|
|
|
|
|
|
hashref values through C. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
It dies if the file doesn't exist or can't be read. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=cut |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub muse_fast_scan_header { |
80
|
18
|
|
|
18
|
1
|
27755
|
my ($file, $format) = @_; |
81
|
18
|
50
|
33
|
|
|
97
|
die "No file provided!" unless defined($file) && length($file); |
82
|
18
|
50
|
|
|
|
233
|
die "$file is not a file!" unless -f $file; |
83
|
18
|
|
|
|
|
123
|
my $doc = Text::Amuse::Document->new(file => $file); |
84
|
18
|
|
|
|
|
54
|
my $directives = $doc->parse_directives; |
85
|
|
|
|
|
|
|
|
86
|
18
|
100
|
|
|
|
41
|
if ($format) { |
87
|
6
|
100
|
100
|
|
|
35
|
die "Wrong format $format" |
88
|
|
|
|
|
|
|
unless ($format eq 'ltx' or $format eq 'html'); |
89
|
5
|
|
|
|
|
14
|
foreach my $k (keys %$directives) { |
90
|
14
|
|
|
|
|
41
|
$directives->{$k} = muse_format_line($format, $directives->{$k}, $doc->language_code); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
} |
93
|
17
|
|
|
|
|
103
|
return $directives; |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item muse_to_html($body); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Format the $body text (assumed to be decoded) as HTML and return it. |
99
|
|
|
|
|
|
|
Header is discarded. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
$body can also be a reference to a scalar to speed up the argument |
102
|
|
|
|
|
|
|
passing. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item muse_to_tex($body); |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Format the $body text (assumed to be decoded) as LaTeX and return it. |
107
|
|
|
|
|
|
|
Header is discarded |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
$body can also be a reference to a scalar to speed up the argument |
110
|
|
|
|
|
|
|
passing. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=item muse_to_object($body); |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Same as above, but returns the L document instead. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub muse_to_html { |
119
|
19
|
|
|
19
|
1
|
20303
|
return _format_on_the_fly(html => @_); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub muse_to_tex { |
123
|
12
|
|
|
12
|
1
|
4474
|
return _format_on_the_fly(ltx => @_); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub muse_to_object { |
127
|
219
|
|
|
219
|
1
|
170139
|
return _format_on_the_fly(obj => @_); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
sub _format_on_the_fly { |
131
|
250
|
|
|
250
|
|
515
|
my ($format, $text, $opts) = @_; |
132
|
250
|
|
|
|
|
309
|
my %opt; |
133
|
250
|
100
|
66
|
|
|
558
|
if ($opts and ref($opts) eq 'HASH') { |
134
|
3
|
|
|
|
|
36
|
%opt = %$opts; |
135
|
|
|
|
|
|
|
} |
136
|
250
|
|
|
|
|
1476
|
my $fh = File::Temp->new(SUFFIX => '.muse'); |
137
|
12
|
|
|
12
|
|
60
|
binmode $fh, ':encoding(utf-8)'; |
|
12
|
|
|
|
|
16
|
|
|
12
|
|
|
|
|
63
|
|
|
250
|
|
|
|
|
78057
|
|
138
|
250
|
100
|
|
|
|
107563
|
if (ref $text) { |
139
|
2
|
|
|
|
|
10
|
print $fh $$text, "\n"; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
else { |
142
|
248
|
|
|
|
|
1320
|
print $fh $text, "\n"; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
# flush the file and close it |
145
|
250
|
|
|
|
|
12722
|
close $fh; |
146
|
250
|
|
|
|
|
1279
|
my $doc = Text::Amuse->new(%opt, file => $fh->filename); |
147
|
250
|
100
|
|
|
|
788
|
if ($format eq 'ltx') { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
148
|
12
|
|
|
|
|
39
|
return $doc->as_latex; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
elsif ($format eq 'html') { |
151
|
19
|
|
|
|
|
61
|
return $doc->as_html; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
elsif ($format eq 'obj') { |
154
|
|
|
|
|
|
|
# dirty trick |
155
|
219
|
|
|
|
|
306
|
$doc->{_private_temp_fh} = $fh; |
156
|
219
|
|
|
|
|
684
|
return $doc; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
else { |
159
|
0
|
|
|
|
|
0
|
die "Wrong usage, format can be only ltx or html!"; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=item muse_rewrite_header($file, { header1 => value, header2 => value2 }) |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
Rewrite the headers of the given file, adding/replacing the header |
166
|
|
|
|
|
|
|
where appropriate. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=cut |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub muse_rewrite_header { |
171
|
2
|
|
|
2
|
1
|
10251
|
my ($file, $pairs) = @_; |
172
|
2
|
|
|
|
|
12
|
my $doc = Text::Amuse::Document->new(file => $file); |
173
|
|
|
|
|
|
|
# do a deep copy |
174
|
2
|
|
|
|
|
6
|
my @directives = map { [ @{$_} ] } $doc->directives_array; |
|
13
|
|
|
|
|
13
|
|
|
13
|
|
|
|
|
22
|
|
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
REWRITE: |
177
|
2
|
|
|
|
|
8
|
foreach my $key (keys %$pairs) { |
178
|
7
|
50
|
|
|
|
17
|
my $value = defined $pairs->{$key} ? $pairs->{$key} . "\n" : "\n"; |
179
|
|
|
|
|
|
|
SEARCH: |
180
|
7
|
|
|
|
|
9
|
foreach my $dir (@directives) { |
181
|
36
|
100
|
|
|
|
43
|
if ($dir->[0] eq $key) { |
182
|
6
|
|
|
|
|
7
|
$dir->[1] = $value; |
183
|
6
|
|
|
|
|
9
|
next REWRITE; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
} |
186
|
1
|
|
|
|
|
3
|
push @directives, [ $key, $value ]; |
187
|
|
|
|
|
|
|
} |
188
|
2
|
|
|
|
|
3
|
my @out; |
189
|
2
|
|
|
|
|
4
|
foreach my $dir (@directives) { |
190
|
14
|
|
|
|
|
27
|
push @out, '#' . $dir->[0] . " " . $dir->[1]; |
191
|
|
|
|
|
|
|
} |
192
|
2
|
|
|
|
|
3
|
my $now = time(); |
193
|
2
|
|
|
|
|
5
|
my $rewritten = $file . '~rw' . $now; |
194
|
2
|
|
|
|
|
3
|
my $backup = $file . '~bk' . $now; |
195
|
2
|
|
|
|
|
97
|
open (my $fh, ">:encoding(UTF-8)", $rewritten); |
196
|
2
|
|
|
|
|
100
|
print $fh @out, "\n", $doc->raw_body; |
197
|
2
|
|
|
|
|
78
|
close $fh; |
198
|
2
|
50
|
|
|
|
11
|
move($file, $backup) or die "Cannot move $file into $backup $!"; |
199
|
2
|
50
|
|
|
|
375
|
move($rewritten, $file) or die "Cannot move $rewritten into $backup $!"; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=back |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=cut |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
1; |
207
|
|
|
|
|
|
|
|