blob: da01469950edf99bcc1a4c30744160c8f24ed258 [file] [log] [blame]
Akronedb5f352017-11-18 20:31:50 +01001package Krawfish::Koral::Result::Enrich::Snippet::Markup;
2use strict;
3use warnings;
Akronb7b17de2017-12-29 15:32:22 +01004use Scalar::Util qw/blessed/;
Akronedb5f352017-11-18 20:31:50 +01005use Role::Tiny;
6
7requires qw/start
8 end
9 start_char
Akronb7b17de2017-12-29 15:32:22 +010010 end_char
11 clone/;
Akronedb5f352017-11-18 20:31:50 +010012
13# TODO:
14# Have common methods with
15# Krawfish::Koral::Document::Annotation
16
17# TODO:
18# This is the base class for
19# - hit
20# - highlight
21# - relation
22# - anchor
23# - Annotation
24
25# TODO:
26# All these role may very well
27# be under Koral - as index data types.
28
29sub new {
30 my $class = shift;
31 bless { @_ }, $class;
32};
33
34
35# Start position
36sub start {
37 my $self = shift;
38 if (@_) {
39 $self->{start} = shift;
40 return $self;
41 };
Akronb7b17de2017-12-29 15:32:22 +010042 return $self->{start} // 0;
Akronedb5f352017-11-18 20:31:50 +010043};
44
45
46# End position
47sub end {
48 my $self = shift;
49 if (@_) {
50 $self->{end} = shift;
51 return $self;
52 };
Akronb7b17de2017-12-29 15:32:22 +010053 return $self->{end} // 0;
Akronedb5f352017-11-18 20:31:50 +010054};
55
56
57# Start char
58sub start_char {
59 my $self = shift;
60 if (@_) {
61 $self->{start_char} = shift;
62 return $self;
63 };
Akronb7b17de2017-12-29 15:32:22 +010064 return $self->{start_char} // 0;
Akronedb5f352017-11-18 20:31:50 +010065};
66
67
68# End char
69sub end_char {
70 my $self = shift;
71 if (@_) {
72 $self->{end_char} = shift;
73 return $self;
74 };
Akronb7b17de2017-12-29 15:32:22 +010075 return $self->{end_char} // 0;
Akronedb5f352017-11-18 20:31:50 +010076};
77
78
79# The element occurs as an opening tag
80sub is_opening {
81 my $self = shift;
82 if (@_ > 0) {
Akronb7b17de2017-12-29 15:32:22 +010083 $self->{opening} = shift ? 1 : 0;
Akronedb5f352017-11-18 20:31:50 +010084 return $self;
85 };
Akronb7b17de2017-12-29 15:32:22 +010086 return $self->{opening} // 0;
Akronedb5f352017-11-18 20:31:50 +010087};
88
Akronb7b17de2017-12-29 15:32:22 +010089
90# The element is empty
91sub is_empty {
92 0;
93};
94
95
96# Sort opening tags
97# - by start position
98# - by start character extension
99# - by end position
100# - by class number / depth
101# - by annotation term
102# - by certainty
103sub compare_open {
104 my ($self_a, $self_b) = @_;
105
106 # By start position
107 if ($self_a->start < $self_b->start) {
108 return -1;
109 }
110
111 elsif ($self_a->start > $self_b->start) {
112 return 1;
113 }
114
115 # By start character
116 elsif ($self_a->start_char < $self_b->start_char){
117 return -1;
118 }
119
120 elsif ($self_a->start_char > $self_b->start_char) {
121 return 1;
122 }
123
124 # By end position
125 elsif ($self_a->end < $self_b->end) {
126 return -1;
127 }
128
129 elsif ($self_a->end > $self_b->end) {
130 return -1;
131 }
132
133 # By number
134 elsif ($self_a->number < $self_b->number) {
135 return -1;
136 }
137
138 elsif ($self_a->number > $self_b->number) {
139 return 1;
140 }
141
142 # By depth
143 elsif ($self_a->depth < $self_b->depth) {
144 return -1;
145 }
146
147 elsif ($self_a->depth > $self_b->depth) {
148 return 1;
149 }
150
151 # By annotation term
152 elsif ($self_a->term lt $self_b->term) {
153 return -1;
154 }
155
156 elsif ($self_a->term gt $self_b->term) {
157 return 1;
158 }
159
160 # By certainty
161 elsif ($self_a->certainty < $self_b->certainty) {
162 return -1;
163 }
164
165 elsif ($self_a->certainty > $self_b->certainty) {
166 return 1;
167 };
168
169 return 0;
170};
171
172
173# Sort closing tags
174# - by end position
175# - by end character extension
176# - by start position
177# - by class number /depth
178# - by annotation term
179# - by certainty
180sub compare_close {
181 my ($self_a, $self_b) = @_;
182
183 # By end position
184 if ($self_a->end < $self_b->end) {
185 return -1;
186 }
187
188 elsif ($self_a->end > $self_b->end) {
189 return 1;
190 }
191
192 # By end character
193 elsif ($self_a->end_char < $self_b->end_char){
194 return -1;
195 }
196
197 elsif ($self_a->end_char > $self_b->end_char) {
198 return 1;
199 }
200
201 # By start position
202 elsif ($self_a->start < $self_b->start) {
203 return -1;
204 }
205
206 elsif ($self_a->start > $self_b->start) {
207 return -1;
208 }
209
210 # By number
211 elsif ($self_a->number < $self_b->number) {
212 return 1;
213 }
214
215 elsif ($self_a->number > $self_b->number) {
216 return -1;
217 }
218
219 # By depth
220 elsif ($self_a->depth < $self_b->depth) {
221 return 1;
222 }
223
224 elsif ($self_a->depth > $self_b->depth) {
225 return -1;
226 }
227
228 # By annotation term
229 elsif ($self_a->term lt $self_b->term) {
230 return 1;
231 }
232
233 elsif ($self_a->term gt $self_b->term) {
234 return -1;
235 }
236
237 # By certainty
238 elsif ($self_a->certainty < $self_b->certainty) {
239 return 1;
240 }
241
242 elsif ($self_a->certainty > $self_b->certainty) {
243 return -1;
244 };
245
246 return 0;
247};
248
249# Fake number for comparation
250sub number {
251 -1;
252};
253
254
255# Fake depth for comparation
256sub depth {
257 -1;
258};
259
260
261# Fake certainty for comparation
262sub certainty {
263 0;
264};
265
266sub term {
267 '';
268};
269
270
271# Clone markup
272sub clone {
273 my $self = shift;
274
275 return blessed($self)->new(
Akron23dc34a2017-12-30 16:45:45 +0100276 start => $self->start,
277 end => $self->end,
278 start_char => $self->start_char,
279 end_char => $self->end_char,
280 opening => $self->is_opening
Akronb7b17de2017-12-29 15:32:22 +0100281 );
282};
283
284
285# Stringification
286sub to_string {
287 my $self = shift;
288 my $str = '';
289 $str .= '(' if $self->is_opening;
290 $str .= join(',', map { $_ ? $_ : 0} @{$self}{qw/start start_char end end_char/});
291 $str .= ')' if !$self->is_opening;
292 return $str;
293};
294
295
Akronedb5f352017-11-18 20:31:50 +01002961;