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   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