File Coverage

blib/lib/Text/Amuse/Functions.pm
Criterion Covered Total %
statement 89 90 98.8
branch 22 30 73.3
condition 8 12 66.6
subroutine 17 17 100.0
pod 6 6 100.0
total 142 155 91.6


line stmt bran cond sub pod time code
1             package Text::Amuse::Functions;
2 20     20   798429 use strict;
  20         128  
  20         499  
3 20     20   88 use warnings;
  20         30  
  20         480  
4 20     20   1533 use utf8;
  20         63  
  20         134  
5 20     20   12415 use File::Temp;
  20         342289  
  20         1306  
6 20     20   8026 use File::Copy qw/move/;
  20         39710  
  20         1013  
7 20     20   5977 use Text::Amuse;
  20         58  
  20         549  
8 20     20   6976 use Text::Amuse::String;
  20         50  
  20         515  
9 20     20   109 use Text::Amuse::Output;
  20         33  
  20         435  
10 20     20   85 use Text::Amuse::Document;
  20         31  
  20         16732  
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 1567 my ($format, $line, $lang) = @_;
57 29 50       60 return "" unless defined $line;
58 29 50 66     86 die unless ($format eq 'html' or $format eq 'ltx');
59 29         90 my $doc = Text::Amuse::String->new($line, $lang);
60 29         83 my $out = Text::Amuse::Output->new(document => $doc,
61             format => $format);
62 29         40 return join("", @{ $out->process });
  29         59  
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 25623 my ($file, $format) = @_;
81 18 50 33     90 die "No file provided!" unless defined($file) && length($file);
82 18 50       247 die "$file is not a file!" unless -f $file;
83 18         120 my $doc = Text::Amuse::Document->new(file => $file);
84 18         52 my $directives = $doc->parse_directives;
85              
86 18 100       45 if ($format) {
87 6 100 100     36 die "Wrong format $format"
88             unless ($format eq 'ltx' or $format eq 'html');
89 5         14 foreach my $k (keys %$directives) {
90 14         50 $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 20798 return _format_on_the_fly(html => @_);
120             }
121              
122             sub muse_to_tex {
123 12     12 1 4299 return _format_on_the_fly(ltx => @_);
124             }
125              
126             sub muse_to_object {
127 219     219 1 296004 return _format_on_the_fly(obj => @_);
128             }
129              
130             sub _format_on_the_fly {
131 250     250   924 my ($format, $text, $opts) = @_;
132 250         475 my %opt;
133 250 100 66     1267 if ($opts and ref($opts) eq 'HASH') {
134 3         40 %opt = %$opts;
135             }
136 250         3179 my $fh = File::Temp->new(SUFFIX => '.muse');
137 12     12   72 binmode $fh, ':encoding(utf-8)';
  12         20  
  12         67  
  250         135825  
138 250 100       133945 if (ref $text) {
139 2         13 print $fh $$text, "\n";
140             }
141             else {
142 248         1986 print $fh $text, "\n";
143             }
144             # flush the file and close it
145 250         20492 close $fh;
146 250         2086 my $doc = Text::Amuse->new(%opt, file => $fh->filename);
147 250 100       1516 if ($format eq 'ltx') {
    100          
    50          
148 12         38 return $doc->as_latex;
149             }
150             elsif ($format eq 'html') {
151 19         66 return $doc->as_html;
152             }
153             elsif ($format eq 'obj') {
154             # dirty trick
155 219         545 $doc->{_private_temp_fh} = $fh;
156 219         1285 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 11667 my ($file, $pairs) = @_;
172 2         11 my $doc = Text::Amuse::Document->new(file => $file);
173             # do a deep copy
174 2         5 my @directives = map { [ @{$_} ] } $doc->directives_array;
  13         15  
  13         26  
175              
176             REWRITE:
177 2         7 foreach my $key (keys %$pairs) {
178 7 50       19 my $value = defined $pairs->{$key} ? $pairs->{$key} . "\n" : "\n";
179             SEARCH:
180 7         8 foreach my $dir (@directives) {
181 36 100       54 if ($dir->[0] eq $key) {
182 6         6 $dir->[1] = $value;
183 6         11 next REWRITE;
184             }
185             }
186 1         4 push @directives, [ $key, $value ];
187             }
188 2         3 my @out;
189 2         5 foreach my $dir (@directives) {
190 14         31 push @out, '#' . $dir->[0] . " " . $dir->[1];
191             }
192 2         4 my $now = time();
193 2         3 my $rewritten = $file . '~rw' . $now;
194 2         3 my $backup = $file . '~bk' . $now;
195 2         110 open (my $fh, ">:encoding(UTF-8)", $rewritten);
196 2         116 print $fh @out, "\n", $doc->raw_body;
197 2         89 close $fh;
198 2 50       11 move($file, $backup) or die "Cannot move $file into $backup $!";
199 2 50       261 move($rewritten, $file) or die "Cannot move $rewritten into $backup $!";
200             }
201              
202             =back
203              
204             =cut
205              
206             1;
207