File Coverage

blib/lib/MsOffice/Word/Surgeon/Revision.pm
Criterion Covered Total %
statement 23 41 56.1
branch 0 8 0.0
condition 0 8 0.0
subroutine 8 10 80.0
pod 0 2 0.0
total 31 69 44.9


line stmt bran cond sub pod time code
1             package MsOffice::Word::Surgeon::Revision;
2 4     4   53 use 5.24.0;
  4         15  
3 4     4   21 use Moose;
  4         5  
  4         39  
4 4     4   27702 use MooseX::StrictConstructor;
  4         9  
  4         30  
5 4     4   12430 use Moose::Util::TypeConstraints;
  4         9  
  4         41  
6 4     4   10001 use POSIX qw(strftime);
  4         26309  
  4         28  
7 4     4   5768 use MsOffice::Word::Surgeon::Carp;
  4         7  
  4         32  
8 4     4   2020 use MsOffice::Word::Surgeon::Utils qw(maybe_preserve_spaces encode_entities);
  4         13  
  4         345  
9 4     4   44 use namespace::clean -except => 'meta';
  4         23  
  4         42  
10              
11              
12             subtype 'Date_ISO',
13             as 'Str',
14             where {/\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2})?Z?/},
15             message {"$_ is not a date in ISO format yyyy-mm-ddThh:mm:ss"};
16              
17             #======================================================================
18             # ATTRIBUTES
19             #======================================================================
20              
21             has 'rev_id' => (is => 'ro', isa => 'Num', required => 1);
22             has 'to_delete' => (is => 'ro', isa => 'Str');
23             has 'to_insert' => (is => 'ro', isa => 'Str');
24             has 'author' => (is => 'ro', isa => 'Str', default => 'Word::Surgeon');
25             has 'date' => (is => 'ro', isa => 'Date_ISO', default =>
26             sub {strftime "%Y-%m-%dT%H:%M:%SZ", localtime});
27             has 'run' => (is => 'ro', isa => 'MsOffice::Word::Surgeon::Run');
28             has 'xml_before' => (is => 'ro', isa => 'Str');
29              
30              
31             #======================================================================
32             # INSTANCE CONSTRUCTION
33             #======================================================================
34              
35             sub BUILD {
36 0     0 0   my $self = shift;
37              
38 0 0 0       $self->to_delete || $self->to_insert
39             or croak "attempt to create a Revision object without 'to_delete' nor 'to_insert' args";
40             }
41              
42              
43             #======================================================================
44             # METHODS
45             #======================================================================
46              
47             sub as_xml {
48 0     0 0   my ($self) = @_;
49              
50 0           my $rev_id = $self->rev_id;
51 0           my $date = $self->date;
52 0           my $author = $self->author; encode_entities($author);
  0            
53 0 0 0       my $props = $self->run && $self->run->props ? "<w:rPr>" . $self->run->props . "</w:rPr>"
54             : "";
55              
56 0           my $xml = "";
57              
58 0 0         if (my $to_delete = $self->to_delete) {
59 0           my $space_attr = maybe_preserve_spaces($to_delete);
60 0           encode_entities($to_delete);
61 0           $xml .= qq{<w:del w:id="$rev_id" w:author="$author" w:date="$date">}
62             . qq{<w:r>$props}
63             . qq{<w:delText$space_attr>$to_delete</w:delText>}
64             . qq{</w:r>}
65             . qq{</w:del>};
66             }
67 0 0         if (my $to_insert = $self->to_insert) {
68 0           my $space_attr = maybe_preserve_spaces($to_insert);
69 0           encode_entities($to_insert);
70 0   0       $xml .= qq{<w:ins w:id="$rev_id" w:author="$author" w:date="$date">}
71             . qq{<w:r>$props}
72             . ($self->xml_before // '')
73             . qq{<w:t$space_attr>$to_insert</w:t>}
74             . qq{</w:r>}
75             . qq{</w:ins>};
76             }
77              
78 0           return $xml;
79             }
80              
81             1;
82              
83             __END__
84              
85             =encoding ISO-8859-1
86              
87             =head1 NAME
88              
89             MsOffice::Word::Surgeon::Revision - generate XML markup for MsWord revisions
90              
91             =head1 DESCRIPTION
92              
93             This class implements the XML markup generation algorithm
94             for the method L<MsOffice::Word::Surgeon/new_revision>.
95             See that method for a description of the API.
96              
97             =head1 INTERNALS
98              
99             The constructor requires an integer C<rev_id> argument.
100             The C<rev_id> is fed by the surgeon object which generates a fresh value at each call.
101             This is inserted as C<w:id> attribute to the
102             C<< <w:del> >> and C<< <w:ins> >> nodes -- but I don't really know why,
103             since it doesn't seem to be used for any purpose by MsWord.
104              
105             =head1 COPYRIGHT AND LICENSE
106              
107             Copyright 2019-2024 by Laurent Dami.
108              
109             This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.