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 21     21   1035687 use strict;
  21         170  
  21         610  
3 21     21   112 use warnings;
  21         42  
  21         566  
4 21     21   1970 use utf8;
  21         92  
  21         157  
5 21     21   16167 use File::Temp;
  21         444319  
  21         1756  
6 21     21   10194 use File::Copy qw/move/;
  21         50187  
  21         1252  
7 21     21   7303 use Text::Amuse;
  21         86  
  21         740  
8 21     21   9144 use Text::Amuse::String;
  21         68  
  21         661  
9 21     21   181 use Text::Amuse::Output;
  21         48  
  21         629  
10 21     21   117 use Text::Amuse::Document;
  21         94  
  21         22376  
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 30     30 1 1966 my ($format, $line, $lang) = @_;
57 30 50       79 return "" unless defined $line;
58 30 50 66     112 die unless ($format eq 'html' or $format eq 'ltx');
59 30         120 my $doc = Text::Amuse::String->new($line, $lang);
60 30         111 my $out = Text::Amuse::Output->new(document => $doc,
61             format => $format);
62 30         47 return join("", @{ $out->process });
  30         70  
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 40271 my ($file, $format) = @_;
81 18 50 33     127 die "No file provided!" unless defined($file) && length($file);
82 18 50       294 die "$file is not a file!" unless -f $file;
83 18         156 my $doc = Text::Amuse::Document->new(file => $file);
84 18         81 my $directives = $doc->parse_directives;
85              
86 18 100       67 if ($format) {
87 6 100 100     46 die "Wrong format $format"
88             unless ($format eq 'ltx' or $format eq 'html');
89 5         19 foreach my $k (keys %$directives) {
90 14         54 $directives->{$k} = muse_format_line($format, $directives->{$k}, $doc->language_code);
91             }
92             }
93 17         145 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 30400 return _format_on_the_fly(html => @_);
120             }
121              
122             sub muse_to_tex {
123 12     12 1 81878 return _format_on_the_fly(ltx => @_);
124             }
125              
126             sub muse_to_object {
127 219     219 1 211316 return _format_on_the_fly(obj => @_);
128             }
129              
130             sub _format_on_the_fly {
131 250     250   676 my ($format, $text, $opts) = @_;
132 250         423 my %opt;
133 250 100 66     757 if ($opts and ref($opts) eq 'HASH') {
134 3         63 %opt = %$opts;
135             }
136 250         1890 my $fh = File::Temp->new(SUFFIX => '.muse');
137 12     12   82 binmode $fh, ':encoding(utf-8)';
  12         25  
  12         98  
  250         106663  
138 250 100       154684 if (ref $text) {
139 2         17 print $fh $$text, "\n";
140             }
141             else {
142 248         1757 print $fh $text, "\n";
143             }
144             # flush the file and close it
145 250         13040 close $fh;
146 250         1844 my $doc = Text::Amuse->new(%opt, file => $fh->filename);
147 250 100       1001 if ($format eq 'ltx') {
    100          
    50          
148 12         57 return $doc->as_latex;
149             }
150             elsif ($format eq 'html') {
151 19         87 return $doc->as_html;
152             }
153             elsif ($format eq 'obj') {
154             # dirty trick
155 219         426 $doc->{_private_temp_fh} = $fh;
156 219         936 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 13957 my ($file, $pairs) = @_;
172 2         17 my $doc = Text::Amuse::Document->new(file => $file);
173             # do a deep copy
174 2         9 my @directives = map { [ @{$_} ] } $doc->directives_array;
  13         16  
  13         36  
175              
176             REWRITE:
177 2         9 foreach my $key (keys %$pairs) {
178 7 50       24 my $value = defined $pairs->{$key} ? $pairs->{$key} . "\n" : "\n";
179             SEARCH:
180 7         10 foreach my $dir (@directives) {
181 36 100       66 if ($dir->[0] eq $key) {
182 6         8 $dir->[1] = $value;
183 6         16 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         51 push @out, '#' . $dir->[0] . " " . $dir->[1];
191             }
192 2         6 my $now = time();
193 2         6 my $rewritten = $file . '~rw' . $now;
194 2         4 my $backup = $file . '~bk' . $now;
195 2         133 open (my $fh, ">:encoding(UTF-8)", $rewritten);
196 2         141 print $fh @out, "\n", $doc->raw_body;
197 2         112 close $fh;
198 2 50       14 move($file, $backup) or die "Cannot move $file into $backup $!";
199 2 50       303 move($rewritten, $file) or die "Cannot move $rewritten into $backup $!";
200             }
201              
202             =back
203              
204             =cut
205              
206             1;
207