First crack at a constructor
[scpubgit/stemmatology.git] / lib / Text / Tradition.pm
1 #!/usr/bin/env perl
2
3 package Text::Tradition;
4
5 use Text::Tradition::Witness;
6 use Text::Tradition::Collation;
7 use Moose;
8
9 has 'collation' => (
10                     is => 'ro',
11                     isa => 'Text::Tradition::Collation',
12                     );
13
14 has 'witnesses' => (
15                     traits => ['Array'],
16                     is => 'rw',
17                     isa => 'ArrayRef[Text::Tradition::Witness]',
18                     handles => {
19                         all_options    => 'elements',
20                         add_option     => 'push',
21                         map_options    => 'map',
22                         option_count   => 'count',
23                         sorted_options => 'sort',
24                     },
25                     );
26
27 around BUILDARGS => sub {
28     my $orig = shift;
29     my $class = shift;
30
31     # Now @_ contains the original constructor args.  Make a
32     # collation argument and a witnesses argument.
33     my %init_args = @_;
34     my %member_objects = { 'collation' => undef,
35                            'witnesses' => [] };
36
37     if( exists $init_args{'witnesses'} ) {
38         # We got passed an uncollated list of witnesses.  Make a
39         # witness object for each witness, and then send them to the
40         # collator.
41         my $autosigil = 0;
42         foreach my $wit ( %{$init_args{'witnesses'}} ) {
43             # Each item in the list is either a string or an arrayref.
44             # If it's a string, it is a filename; if it's an arrayref,
45             # it is a tuple of 'sigil, file'.  Handle either case.
46             my $args;
47             if( ref( $wit ) eq 'ARRAY' ) {
48                 $args = { 'sigil' => $wit->[0],
49                           'file' => $wit->[1] };
50             } else {
51                 $args = { 'sigil' => chr( $autosigil+65 ),
52                           'file' => $wit };
53                 $autosigil++;
54             }
55             push( @{$member_objects{'witnesses'}},
56                   Text::Tradition::Witness->new( $args ) );
57             # Now how to collate these?
58         }
59     } else {
60         $member_objects{'collation'} = 
61             Text::Tradition::Collation->new( %init_args );
62         @{$member_objects{'witnesses'}} = 
63             $member_objects->{'collation'}->create_witnesses();
64     }
65
66     return $class->$orig( %member_objects );
67 };
68
69 # The user will usually be instantiating a Tradition object, and
70 # examining its collation.  The information about the tradition can
71 # come via several routes:
72 # - graphML from CollateX or elsewhere, standalone
73 # - TEI parallel segmentation
74 # - Leuven-style spreadsheet of variants, converted to CSV, plus base text
75 # - apparatus pulled from CTE, plus base text
76 # From this we should be able to get basic witness information.
77
78 # Alternatively the user can just give us the uncollated texts.  Then
79 # instead of passing a collation, s/he is passing a set of witnesses
80 # from which we will generate a collation.  Those witnesses can be in
81 # plaintext or in TEI with certain constraints adopted.
82
83 # So the constructor for a tradition needs to take one of these infosets,
84 # and construct the collation and the witness objects.
85
86 no Moose;
87 __PACKAGE__->meta->make_immutable;