start using witness->text and ->layertext for consistency checking
[scpubgit/stemmatology.git] / lib / Text / Tradition / Witness.pm
1 package Text::Tradition::Witness;
2 use Moose;
3 use Moose::Util::TypeConstraints;
4
5 =head1 NAME
6
7 Text::Tradition::Witness - a manuscript witness to a text tradition
8
9 =head1 SYNOPSIS
10
11   use Text::Tradition::Witness;
12   my $w = Text::Tradition::Witness->new( 
13     'sigil' => 'A',
14     'identifier' => 'Oxford MS Ex.1932',
15     );  
16     
17 =head1 DESCRIPTION
18
19 Text::Tradition::Witness is an object representation of a manuscript
20 witness to a text tradition.  A manuscript has a sigil (a short code that
21 represents it in the wider tradition), an identifier (e.g. the library ID),
22 and probably a text.
23
24 =head1 METHODS
25
26 =head2 new
27
28 Create a new witness.  Options include:
29
30 =over
31
32 =item * sigil - A short code to represent the manuscript.  Required.
33
34 =item * text - An array of strings (words) that contains the text of the
35 manuscript.
36
37 =item * source - A reference to the text, such as a filename, if it is not
38 given in the 'text' option.
39
40 =item * identifier - The recognized name of the manuscript, e.g. a library
41 identifier.
42
43 =item * other_info - A freeform string for any other description of the
44 manuscript.
45
46 =back
47
48 =head2 sigil
49
50 Accessor method for the witness sigil.
51
52 =head2 text
53
54 Accessor method to get and set the text array.
55
56 =head2 source
57
58 Accessor method to get and set the text source.
59
60 =head2 identifier
61
62 Accessor method for the witness identifier.
63
64 =head2 other_info
65
66 Accessor method for the general witness description.
67
68 =head2 is_layered
69
70 Boolean method to note whether the witness has layers (e.g. pre-correction 
71 readings) in the collation.
72
73 =begin testing
74
75 use_ok( 'Text::Tradition::Witness', "can use module" );
76
77 my @text = qw( This is a line of text );
78 my $wit = Text::Tradition::Witness->new( 
79     'sigil' => 'A',
80     'text' => \@text,
81      );
82 is( ref( $wit ), 'Text::Tradition::Witness', 'Created a witness' );
83 if( $wit ) {
84     is( $wit->sigil, 'A', "Witness has correct sigil" );
85     is( join( ' ', @{$wit->text} ), join( ' ', @text ), "Witness has correct text" );
86 }
87
88 =end testing 
89
90 =cut
91
92 # Sigil. Required identifier for a witness.
93 has 'sigil' => (
94         is => 'ro',
95         isa => 'Str',
96         required => 1,
97         );
98
99 # Text.  This is an array of strings (i.e. word tokens).
100 # TODO Think about how to handle this for the case of pre-prepared
101 # collations, where the tokens are in the graph already.
102 has 'text' => (
103         is => 'rw',
104         isa => 'ArrayRef[Str]',
105         predicate => 'has_text',
106         );
107         
108 has 'layertext' => (
109         is => 'rw',
110         isa => 'ArrayRef[Str]',
111         predicate => 'has_layertext',
112         );
113
114 # Source.  This is where we read in the witness, if not from a
115 # pre-prepared collation.  It is probably a filename.
116 has 'source' => (
117         is => 'ro',
118         isa => 'Str',
119         predicate => 'has_source',
120         );
121
122 # Path.  This is an array of Reading nodes that can be saved during
123 # initialization, but should be cleared before saving in a DB.
124 has 'path' => (
125         is => 'rw',
126         isa => 'ArrayRef[Text::Tradition::Collation::Reading]',
127         predicate => 'has_path',
128         clearer => 'clear_path',
129         );                 
130
131 has 'uncorrected_path' => (
132         is => 'rw',
133         isa => 'ArrayRef[Text::Tradition::Collation::Reading]',
134         clearer => 'clear_uncorrected_path',
135         );
136         
137 has 'is_layered' => (
138         is => 'rw',
139         isa => 'Bool',
140         );
141
142 # Manuscript name or similar
143 has 'identifier' => (
144         is => 'ro',
145         isa => 'Str',
146         );
147
148 # Any other info we have
149 has 'other_info' => (
150         is => 'ro',
151         isa => 'Str',
152         );
153         
154 # If we set an uncorrected path, ever, remember that we did so.
155 around 'uncorrected_path' => sub {
156         my $orig = shift;
157         my $self = shift;
158         
159         $self->is_layered( 1 );
160         $self->$orig( @_ );
161 };
162
163 sub BUILD {
164         my $self = shift;
165         if( $self->has_source ) {
166                 # Read the file and initialize the text.
167                 my $rc;
168                 eval { no warnings; $rc = open( WITNESS, $self->source ); };
169                 # If we didn't open a file, assume it is a string.
170                 if( $rc ) {
171                         my @words;
172                         while(<WITNESS>) {
173                                 chomp;
174                                 push( @words, split( /\s+/, $_ ) );
175                         }
176                         close WITNESS;
177                         $self->text( \@words );
178                 } # else the text is in the source string, probably
179                   # XML, and we are doing nothing with it.
180         }
181 }
182
183 no Moose;
184 __PACKAGE__->meta->make_immutable;
185
186 =head1 BUGS / TODO
187
188 =over
189
190 =item * Get rid of either text or path, as they are redundant.
191
192 =item * Re-think the mechanism for pre-correction readings etc.
193
194 =back
195
196 =head1 LICENSE
197
198 This package is free software and is provided "as is" without express
199 or implied warranty.  You can redistribute it and/or modify it under
200 the same terms as Perl itself.
201
202 =head1 AUTHOR
203
204 Tara L Andrews E<lt>aurum@cpan.orgE<gt>