refactor GraphML write/parse to use Moose introspection
[scpubgit/stemmatology.git] / lib / Text / Tradition / Collation / Relationship.pm
1 package Text::Tradition::Collation::Relationship;
2
3 use Moose;
4 use Moose::Util::TypeConstraints;
5
6 enum 'RelationshipType' => qw( spelling orthographic grammatical meaning lexical
7                                                            collated repetition transposition );
8
9 enum 'RelationshipScope' => qw( local document global );
10
11 no Moose::Util::TypeConstraints;
12
13 =head1 NAME
14
15 Text::Tradition::Collation::Relationship - represents a syntactic or semantic
16 relationship between two readings
17     
18 =head1 DESCRIPTION
19
20 Text::Tradition is a library for representation and analysis of collated
21 texts, particularly medieval ones.  A relationship connects two readings
22 within a collation, usually when they appear in the same place in different
23 texts.
24
25 =head1 CONSTRUCTOR
26
27 =head2 new
28
29 Creates a new relationship. Usually called via $collation->add_relationship.
30 Options include:
31
32 =over 4
33
34 =item * type - Can be one of spelling, orthographic, grammatical, meaning, lexical, collated, repetition, transposition.  All but the last two are only valid relationships between readings that occur at the same point in the text.
35
36 =item * displayform - (Optional) The reading that should be displayed if the related nodes are treated as one.
37
38 =item * scope - (Optional) A meta-attribute.  Can be one of 'local', 'document', or 'global'. Denotes whether the relationship between the two readings holds always, independent of context, either within this tradition or across all traditions.
39
40 =item * anotation - (Optional) A freeform note to attach to the relationship.
41
42 =item * non_correctable - (Optional) True if the reading would not have been corrected independently.
43
44 =item * non_independent - (Optional) True if the variant is unlikely to have occurred independently in unrelated witnesses.
45
46 =back
47
48 =head1 ACCESSORS
49
50 =head2 type
51
52 =head2 displayform
53
54 =head2 scope
55
56 =head2 annotation
57
58 =head2 non_correctable
59
60 =head2 non_independent
61
62 See the option descriptions above.
63
64 =cut
65
66 has 'type' => (
67         is => 'ro',
68         isa => 'RelationshipType',
69         required => 1,
70         );
71
72 has 'reading_a' => (
73         is => 'ro',
74         isa => 'Str',
75         required => 1,
76         );
77
78 has 'reading_b' => (
79         is => 'ro',
80         isa => 'Str',
81         required => 1,
82         );
83
84 has 'displayform' => (
85         is => 'ro',
86         isa => 'Str',
87         predicate => 'has_displayform',
88         );
89
90 has 'scope' => (
91         is => 'ro',
92         isa => 'RelationshipScope', 
93         default => 'local',
94         );
95         
96 has 'annotation' => (
97         is => 'ro',
98         isa => 'Str',
99         predicate => 'has_annotation',
100         );
101
102 has 'non_correctable' => (
103         is => 'ro',
104         isa => 'Bool',
105         );
106
107 has 'non_independent' => (
108         is => 'ro',
109         isa => 'Bool',
110         );
111         
112 # A read-only meta-Boolean attribute.
113
114 =head2 colocated
115
116 Returns true if the relationship type is one that requires that its readings
117 occupy the same place in the collation.
118
119 =cut
120
121 sub colocated {
122         my $self = shift;
123         return $self->type !~ /^(repetition|transposition)$/;
124 }
125
126 =head2 nonlocal
127
128 Returns true if the relationship scope is anything other than 'local'.
129
130 =cut
131
132 sub nonlocal {
133         my $self = shift;
134         return $self->scope ne 'local';
135 }
136
137 no Moose;
138 __PACKAGE__->meta->make_immutable;
139
140 1;