File Coverage

blib/lib/TEI/Lite/Header.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package TEI::Lite::Header;
2              
3             ##==================================================================##
4             ## Libraries and Variables ##
5             ##==================================================================##
6              
7             require 5.006;
8              
9 6     6   3694 use strict;
  6         11  
  6         195  
10 6     6   38 use warnings;
  6         9  
  6         135  
11              
12 6     6   2336 use Date::Calc;
  0            
  0            
13             use XML::LibXML;
14             use TEI::Lite::Element;
15              
16             our @ISA = qw( XML::LibXML::Element );
17              
18             our $VERSION = "0.60";
19              
20             our %METHOD = (
21             'setAuthor' => '//teiHeader/fileDesc/titleStmt/author',
22             'setAuthority' => '//teiHeader/fileDesc/publicationStmt' .
23             '/authority',
24             'setBibliographicCitation' => '//teiHeader/fileDesc/sourceDesc/bibl',
25             'setDistributor' => '//teiHeader/fileDesc/publicationStmt' .
26             '/distributor',
27             'setFunder' => '//teiHeader/fileDesc/titleStmt/funder',
28             'setPrincipalResearcher' => '//teiHeader/fileDesc/titleStmt/principal',
29             'setPublisher' => '//teiHeader/fileDesc/publicationStmt' .
30             '/publisher',
31             'setSponsor' => '//teiHeader/fileDesc/titleStmt/sponsor',
32             'setTitle' => '//teiHeader/fileDesc/titleStmt/title'
33             );
34              
35             no strict "refs";
36              
37             ## Loop through each element in the common method hash and build the
38             ## associated methods. Not all methods are of the cookie cutter variety,
39             ## so we define those methods down below.
40             foreach my $method ( keys( %METHOD ) )
41             {
42             *{ $method } = sub {
43             my( $self, @data ) = @_;
44              
45             ## Use XPath to search for the node that we need.
46             my( $node ) = $self->_ensure_xpath( $METHOD{ $method } );
47              
48             ## Grab the last part of the XPath expression.
49             $METHOD{ $method } =~ /\/(\w+)$/;
50              
51             ## Generate the correct function name ....
52             my $tei_function = "tei_$1";
53            
54             ## Generate the element.
55             my $element = &$tei_function( {}, @data );
56              
57             ## Replace the node.
58             $node->replaceNode( $element );
59            
60             return( $node );
61             }
62             }
63              
64             use strict "refs";
65              
66             ##==================================================================##
67             ## Constructor(s)/Deconstructor(s) ##
68             ##==================================================================##
69              
70             ##----------------------------------------------##
71             ## new ##
72             ##----------------------------------------------##
73             sub new
74             {
75             ## Pull in what type of an object we will be.
76             my $type = shift;
77             ## We will use an anonymous hash as the base of the object.
78             my $self = _generate_header_template( @_ );
79             ## Determine what exact class we will be blessing this instance into.
80             my $class = ref( $type ) || $type;
81             ## Bless the class for it is good [tm].
82             bless( $self, $class );
83             ## Send it back to the caller all happy like.
84             return( $self );
85             }
86              
87             ##----------------------------------------------##
88             ## DESTROY ##
89             ##----------------------------------------------##
90             sub DESTROY
91             {
92             ## This is mainly a placeholder to keep things like mod_perl happy.
93             return;
94             }
95              
96             ##==================================================================##
97             ## Method(s) ##
98             ##==================================================================##
99              
100             ##----------------------------------------------##
101             ## appendRevisionEntry ##
102             ##----------------------------------------------##
103             sub appendRevisionEntry
104             {
105             my( $self, $date, $name, $title, @data ) = @_;
106            
107             ## Attempt to decode the date ...
108             my( $year, $month, $day ) = Decode_Date_US( $date );
109            
110             ## Use XPath to search for the node that we need.
111             my( $node ) = $self->_ensure_xpath( '//teiHeader/revisionDesc/' );
112              
113             my $element = tei_change( tei_date( { value => "$year-$month-$day" },
114             Date_to_Text( $year, $month, $day ) ),
115             tei_respStmt( {}, tei_name( {}, $name ),
116             tei_resp( {}, $title ) ),
117             map( tei_item( {}, $_ ), @data ) );
118              
119             if( $node->hasChildNodes() )
120             {
121             ## We want our latest changes to be at the top.
122             $node->insertBefore( $element, $node->firstChild );
123             }
124             else
125             {
126             ## No children exist, so just append it.
127             $node->appendChild( $element );
128             }
129            
130             return( $node );
131             }
132              
133             ##----------------------------------------------##
134             ## setDatePublished ##
135             ##----------------------------------------------##
136             sub setDatePublished
137             {
138             my( $self, $date ) = @_;
139              
140             ## Attempt to decode the data ...
141             my( $year, $month, $day ) = Decode_Date_US( $date );
142            
143             ## Use XPath to search for the node that we need.
144             my( $node ) =
145             $self->_ensure_xpath( '//teiHeader/fileDesc/publicationStmt/date' );
146              
147             my $element = tei_date( { value => "$year-$month-$day" },
148             Date_to_Text( $year, $month, $day ) );
149            
150             $node->replaceNode( $element );
151            
152             return( $node );
153             }
154              
155             ##----------------------------------------------##
156             ## setDocumentAvailability ##
157             ##----------------------------------------------##
158             sub setDocumentAvailability
159             {
160             my( $self, $status, $copyright ) = @_;
161            
162             ## If we don't have a status provided, set it to unknown.
163             $status = "unknown" if !defined( $status );
164            
165             ## Use XPath to search for the node that we need.
166             my( $node ) =
167             $self->_ensure_xpath( '//teiHeader/fileDesc/publicationStmt/idno' );
168            
169             my $element = tei_availability( { status => $status }, $copyright );
170              
171             $node->replaceNode( $element );
172            
173             return( $node );
174             }
175              
176             ##----------------------------------------------##
177             ## setIdentificationNumber ##
178             ##----------------------------------------------##
179             sub setIdentificationNumber
180             {
181             my( $self, $type, $number ) = @_;
182            
183             ## If we don't provide a specific type, then set it to unknown.
184             $type = "unknown" if !defined( $type );
185            
186             ## Use XPath to search for the node that we need.
187             my( $node ) =
188             $self->_ensure_xpath( '//teiHeader/fileDesc/publicationStmt/idno' );
189            
190             my $element = tei_idno( { type => $type }, $number );
191              
192             $node->replaceNode( $element );
193            
194             return( $node );
195             }
196              
197             ##----------------------------------------------##
198             ## setKeywords ##
199             ##----------------------------------------------##
200             sub setKeywords
201             {
202             my( $self, @data ) = @_;
203            
204             ## Create a variable to temporarily hold our keywords.
205             my @keywords;
206            
207             ## Use XPath to search for the node that we need.
208             my( $node ) =
209             $self->_ensure_xpath( '//teiHeader/profileDesc/textClass/keywords' );
210              
211             ## We need to generate *.
212             my $element = tei_keywords( {},
213             tei_list( {},
214             map( tei_item( {}, $_ ), @data ) ) );
215              
216             $node->replaceNode( $element );
217            
218             return( $node );
219             }
220              
221             ##==================================================================##
222             ## Internal Function(s) ##
223             ##==================================================================##
224              
225             ##----------------------------------------------##
226             ## _ensure_xpath ##
227             ##----------------------------------------------##
228             ## Recursive function that will build up the ##
229             ## path that is required by an element. ##
230             ##----------------------------------------------##
231             sub _ensure_xpath
232             {
233             my( $self, $xpath ) = @_;
234              
235             ## Variable that will hold our search patch after we build it and
236             ## also a temp variable for a loop down below.
237             my( @search, $last );
238            
239             $xpath =~ s/^\/\///g;
240            
241             ## Break up the XPath statement.
242             my @path = split( /\//, $xpath );
243              
244             for( my $loop = 0; $loop < scalar( @path ); $loop++ )
245             {
246             $search[ $loop ] = "/";
247              
248             foreach( my $loop2 = 0; $loop2 <= $loop; $loop2++ )
249             {
250             $search[ $loop ] .= "/" . $path[ $loop2 ];
251             }
252             }
253              
254             foreach( @search )
255             {
256             my( $node ) = $self->findnodes( $_ );
257              
258             ## If it is defined then that is a good thing, but if it isn't
259             ## we need to create it.
260             if( defined( $node ) )
261             {
262             $last = $node;
263             }
264             else
265             {
266             ## Grab the last part of the XPath expression.
267             $_ =~ /\/(\w+)$/;
268            
269             ## Create an element ... add it to the node tree.
270             $last = $last->appendChild( XML::LibXML::Element->new( $1 ) );
271             }
272             }
273              
274             return( $last );
275             }
276              
277             ##----------------------------------------------##
278             ## _generate_header_template ##
279             ##----------------------------------------------##
280             ## Function to generate the most basic header ##
281             ## that doesn't contain any "preset" data, yet ##
282             ## still be valid when validated. ##
283             ##----------------------------------------------##
284             sub _generate_header_template
285             {
286             my( $self, %params ) = @_;
287              
288             ##
289             ##
290             ##</titleStmt> </td> </tr> <tr> <td class="h" > <a name="291">291</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##<publicationStmt><publisher/><date/></publicationStmt> </td> </tr> <tr> <td class="h" > <a name="292">292</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##<sourceDesc><p/></sourceDesc> </td> </tr> <tr> <td class="h" > <a name="293">293</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##</fileDesc> </td> </tr> <tr> <td class="h" > <a name="294">294</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##</teiHeader> </td> </tr> <tr> <td class="h" > <a name="295">295</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> my $header = tei_teiHeader( {}, tei_fileDesc( {}, </td> </tr> <tr> <td class="h" > <a name="296">296</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> tei_titleStmt( {}, </td> </tr> <tr> <td class="h" > <a name="297">297</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> tei_title() ), </td> </tr> <tr> <td class="h" > <a name="298">298</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> tei_publicationStmt( {}, </td> </tr> <tr> <td class="h" > <a name="299">299</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> tei_publisher(), </td> </tr> <tr> <td class="h" > <a name="300">300</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> tei_date() ), </td> </tr> <tr> <td class="h" > <a name="301">301</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> tei_sourceDesc( {}, tei_bibl() ) ) ); </td> </tr> <tr> <td class="h" > <a name="302">302</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> </td> </tr> <tr> <td class="h" > <a name="303">303</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> return( $header ); </td> </tr> <tr> <td class="h" > <a name="304">304</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> } </td> </tr> <tr> <td class="h" > <a name="305">305</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="306">306</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##==================================================================## </td> </tr> <tr> <td class="h" > <a name="307">307</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ## End of Code ## </td> </tr> <tr> <td class="h" > <a name="308">308</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##==================================================================## </td> </tr> <tr> <td class="h" > <a name="309">309</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> 1; </td> </tr> <tr> <td class="h" > <a name="310">310</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="311">311</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##==================================================================## </td> </tr> <tr> <td class="h" > <a name="312">312</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ## Plain Old Documentation (POD) ## </td> </tr> <tr> <td class="h" > <a name="313">313</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> ##==================================================================## </td> </tr> <tr> <td class="h" > <a name="314">314</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s">   </td> </tr> <tr> <td class="h" > <a name="315">315</a> </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td >   </td> <td class="s"> __END__ </td> </tr> </table> </body> </html>