source: gs3-extensions/html-to-expeditee/trunk/src/perllib/ExpediteeFrameIO.pm@ 26730

Last change on this file since 26730 was 26730, checked in by davidb, 8 years ago

Tidying up file

File size: 13.9 KB
Line 
1###########################################################################
2#
3# ExpediteeFrameIO.pm --
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 2009 New Zealand Digital Library Project
9#
10# This program is free software; you can redistr te it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26package ExpediteeFrameIO;
27
28use strict;
29
30use CssStyleToExpAttr;
31
32sub new
33{
34 my $class = shift(@_);
35 my $output_dir = shift(@_);
36 my $username = shift(@_) || "greenstone";
37
38 my $self = { 'items' => [], 'lines' => [], 'constraints' => [] };
39
40 $self->{'output_dir'} = $output_dir;
41 $self->{'username'} = $username;
42
43 return bless $self, $class;
44}
45
46sub getFormattedDate
47{
48 my ($opt_mode) = @_;
49
50 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
51
52 my @mabbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
53
54 $year += 1900;
55
56 my $fdate;
57
58 if ((defined $opt_mode) && ($opt_mode eq "highPrecision")) {
59 $fdate = sprintf("%02d%s%04d[%02d:%0d2.%02d]",
60 $mday, $mabbr[$mon],$year,$hour,$min,$sec);
61 }
62 else {
63 $fdate = sprintf("%02d%s%04d[%02d:%0d2]",
64 $mday, $mabbr[$mon],$year,$hour,$min);
65 }
66
67 return $fdate;
68}
69
70sub convertStyleToAttr
71{
72 my ($css_attr) = @_;
73
74 my $exp_attr = {};
75
76 # load up some defaults for font information
77 my $exp_font_family = "s"; # t
78 my $exp_font_face = "r";
79 my $exp_font_size = "18";
80
81# if (defined $css_attr->{'font-family'}) {
82# $font_family = $font_family_lookup->[$css_attr->{'font-family'}];
83# }
84
85 if (defined $css_attr->{'font-size'}) {
86
87 my $css_font_size = $css_attr->{'font-size'};
88 $exp_font_size = CssStyleToExpAttr::convert_font_size($css_font_size);
89
90 }
91
92 if(defined $css_attr->{'font-family'}){
93 my $obtain_font_family = $css_attr->{'font-family'};
94 my $new_exp_font_family = CssStyleToExpAttr::convert_font_family($obtain_font_family);
95
96 if(defined $new_exp_font_family){
97 $exp_font_family = $new_exp_font_family;
98 }
99 }
100
101 my $css_font_style;
102 my $css_font_face;
103
104 if(defined $css_attr->{'font-style'}){
105 $css_font_style = $css_attr->{'font-style'};
106 $exp_font_face = CssStyleToExpAttr::convert_font_face($css_font_style);
107 }
108
109 if(defined $css_attr->{'font-weight'}){
110 $css_font_face = $css_attr->{'font-weight'};
111 $exp_font_face = CssStyleToExpAttr::convert_font_face($css_font_face);
112 }
113
114 if(defined $css_attr->{'font-style'} && defined $css_attr->{'font-weight'}){
115 my $font_face_param = $css_attr->{'font-weight'}.'-'.$css_attr->{'font-style'};
116 $exp_font_face = CssStyleToExpAttr::convert_font_face($font_face_param);
117 }
118
119 $exp_attr->{'f'} = $exp_font_family.$exp_font_face.$exp_font_size;
120
121 # background color
122
123
124 if (defined $css_attr->{'background-color'}) {
125 my $css_color = $css_attr->{'background-color'};
126
127 my $exp_color = CssStyleToExpAttr::convert_color($css_color);
128
129 $exp_attr->{'e'} = $exp_color;
130 }
131
132 return $exp_attr;
133}
134
135
136sub _nextFreeId
137{
138 my $self = shift @_;
139
140 my $items = $self->{'items'};
141 my $lines = $self->{'lines'};
142 my $constraints = $self->{'constraints'};
143
144 # Ids start at base of 1
145 return 1+(scalar(@$items) + scalar(@$lines) + scalar(@$constraints));
146}
147
148
149sub _addItem
150{
151 my $self = shift @_;
152 my ($type,$attr) = @_;
153
154 # By this point 'attr' is synonymous with being an item
155
156 my $items = $self->{'items'};
157
158 my $next_free_id = $self->_nextFreeId();
159
160 $attr->{'_type'} = $type;
161 $attr->{'_id'} = $next_free_id;
162
163 push(@$items,$attr);
164
165 return ($attr,$next_free_id);
166}
167
168
169
170sub _setBaseDefaultAttributes
171{
172 my $self = shift @_;
173 my ($attr) = @_;
174
175 $attr->{'o'} = $self->{'username'};
176 $attr->{'s'} = getFormattedDate("highPrecision");
177 $attr->{'Q'} = "0"; # gradient
178 $attr->{'v'} = "S"; # dot type
179}
180
181
182sub setPointDefaultAttributes
183{
184 my $self = shift @_;
185 my ($attr) = @_;
186
187 $self->_setBaseDefaultAttributes($attr);
188}
189
190sub setTextDefaultAttributes
191{
192 my $self = shift @_;
193 my ($attr) = @_;
194
195 $self->_setBaseDefaultAttributes($attr);
196
197 if(defined $attr->{'d'}){
198
199 }
200 else {
201 $attr->{'d'} = "0 0 0"; # black color
202 }
203
204}
205
206
207sub setRectPointDefaultAttributes
208{
209 my $self = shift @_;
210 my ($attr) = @_;
211
212
213 $self->setPointDefaultAttributes($attr);
214
215 if((defined $attr->{'d'}) && (defined $attr->{'h'})){
216
217 }
218 else {
219 $attr->{'d'} = "80 80 80"; # grey color for rect lines
220 $attr->{'h'} = "1.0"; # line thickness
221 }
222}
223
224
225sub addRectPoint
226{
227 my $self = shift @_;
228 my ($x, $y, $attr) = @_;
229
230 my %attr_copy = %$attr; # make a private copy of 'attr'
231
232 $self->setRectPointDefaultAttributes(\%attr_copy);
233
234 my $items = $self->{'items'};
235
236 $attr_copy{'P'} = "$x $y";
237
238 return $self->_addItem("P",\%attr_copy);
239}
240
241sub addText
242{
243 my $self = shift @_;
244 my ($x,$y,$text,$w,$attr) = @_;
245
246 my %attr_copy = %$attr; #make a private copy of 'attr'
247
248 $self->setTextDefaultAttributes(\%attr_copy);
249 my $items = $self->{'items'};
250
251 $attr_copy{'P'} = "$x $y";
252 $attr_copy{'T'} = $text;
253 $attr_copy{'w'} = "-$w" if (defined $w);
254
255 return $self->_addItem("T",\%attr_copy);
256}
257
258sub addLine
259{
260 my $self = shift @_;
261
262 my ($item_id1,$item_id2) = @_;
263
264 my $lines = $self->{'lines'};
265 my $line_type = 1;
266
267 my $next_free_id = $self->_nextFreeId();
268
269 my $attr = { 'L' => "$next_free_id $line_type" };
270
271 $attr->{'s'} = "$item_id1 $item_id2";
272
273 push(@$lines,$attr);
274
275 return ($attr,$next_free_id);
276}
277
278
279sub addConstraint
280{
281 my $self = shift @_;
282
283 my ($orientation,$item_id1,$item_id2) = @_;
284
285 my $constraints = $self->{'constraints'};
286
287 my $orientation_type = undef;
288 if ($orientation eq "vertical") {
289 $orientation_type = 2;
290 }
291 else {
292 # assume horizontal for now
293 $orientation_type = 3;
294 }
295
296 my $next_free_id = $self->_nextFreeId();
297
298 my $attr = { 'C' => "$next_free_id $orientation_type" };
299
300 $attr->{'s'} = "$item_id1 $item_id2";
301
302 push(@$constraints,$attr);
303
304 return ($attr,$next_free_id);
305}
306
307
308sub addRect
309{
310 my $self = shift @_;
311
312 my ($xl, $yt, $xr, $yb, $attr) = @_;
313
314 # do point in same order Expeditee puts them in
315 my ($p_tr,$p_tr_id) = $self->addRectPoint($xr,$yt,$attr);
316 my ($p_tl,$p_tl_id) = $self->addRectPoint($xl,$yt,$attr);
317 my ($p_bl,$p_bl_id) = $self->addRectPoint($xl,$yb,$attr);
318 my ($p_br,$p_br_id) = $self->addRectPoint($xr,$yb,$attr);
319
320 my ($l_t,$l_t_id) = $self->addLine($p_tr_id,$p_tl_id);
321 my ($l_l,$l_l_id) = $self->addLine($p_tl_id,$p_bl_id);
322 my ($l_b,$l_b_id) = $self->addLine($p_bl_id,$p_br_id);
323 my ($l_r,$l_r_id) = $self->addLine($p_br_id,$p_tr_id);
324
325 my ($c_t,$c_t_id) = $self->addConstraint("horizontal",$p_tr_id,$p_tl_id);
326 my ($c_l,$c_l_id) = $self->addConstraint("vertical" ,$p_tl_id,$p_bl_id);
327 my ($c_b,$c_b_id) = $self->addConstraint("horizontal",$p_bl_id,$p_br_id);
328 my ($c_r,$c_r_id) = $self->addConstraint("vertical" ,$p_br_id,$p_tr_id);
329
330 $p_tr->{'l'} = "$l_t_id $l_r_id";
331 $p_tl->{'l'} = "$l_t_id $l_l_id";
332 $p_bl->{'l'} = "$l_l_id $l_b_id";
333 $p_br->{'l'} = "$l_b_id $l_r_id";
334
335 $p_tr->{'c'} = "$c_t_id $c_r_id";
336 $p_tl->{'c'} = "$c_t_id $c_l_id";
337 $p_bl->{'c'} = "$c_l_id $c_b_id";
338 $p_br->{'c'} = "$c_b_id $c_r_id";
339
340}
341
342sub writeHeaderSection
343{
344 my $self = shift @_;
345
346 # Example header:
347 # V 1
348 # p 4
349 # U davidb
350 # D 09Jan2012[13:33]
351 # M davidb
352 # d 09Jan2012[13:33]
353 # Z
354 #
355
356 # Legend:
357 # V = version
358 # p = permision level
359 # U = username (owner)
360 # M = last modified by
361 # D, d = date information
362 # Z => end of section
363
364
365 my $username = $self->{'username'};
366
367 my $fdate = getFormattedDate();
368
369 print FOUT "V 1\n";
370 print FOUT "p 4\n";
371 print FOUT "U $username\n";
372 print FOUT "D $fdate\n";
373 print FOUT "M $username\n";
374 print FOUT "d $fdate\n";
375 print FOUT "Z\n\n";
376
377}
378
379
380sub writeItemsSection
381{
382 my $self = shift @_;
383
384 my $items = $self->{'items'};
385
386 foreach my $item (@$items) {
387
388 my $type = delete $item->{'_type'};
389 my $id = delete $item->{'_id'};
390
391 if(defined($type) && defined($id)) {
392
393 print FOUT "S $type $id\n";
394
395 foreach my $a (keys %$item) {
396 print FOUT "$a ", $item->{$a}, "\n";
397 }
398
399 print FOUT "\n";
400
401 }
402
403 }
404
405 print FOUT "Z\n\n";
406}
407
408sub writeLinesSection
409{
410 my $self = shift @_;
411
412 my $lines = $self->{'lines'};
413
414 foreach my $line (@$lines) {
415
416 print FOUT "L ", $line->{'L'}, "\n";
417 print FOUT "s ", $line->{'s'}, "\n";
418
419 print FOUT "\n";
420 }
421
422 print FOUT "Z\n\n";
423
424}
425
426sub writeConstraintsSection
427{
428 my $self = shift @_;
429
430 my $constraints = $self->{'constraints'};
431
432 foreach my $constraint (@$constraints) {
433 print FOUT "C ", $constraint->{'C'}, "\n";
434 print FOUT "s ", $constraint->{'s'}, "\n";
435
436 print FOUT "\n";
437 }
438
439 print FOUT "Z\n\n";
440}
441
442sub writeStatisticsSection
443{
444 my $self = shift @_;
445
446 # Currently do nothing
447}
448
449sub saveZeroFrame
450{
451 my $self = shift @_;
452 my $file = "0.exp";
453
454 my $filename = &util::filename_cat($self->{'output_dir'},$file);
455
456 my $status = undef;
457
458 my $username = $self->{'username'};
459 my $fdate = getFormattedDate();
460
461 if (open(FOUT,">$filename")) {
462 binmode(FOUT,":utf8");
463
464 print FOUT <<EOT;
465
466V 1
467p 4
468U $username
469D $fdate
470M $username
471d $fdate
472Z
473
474Z
475
476Z
477
478Z
479
480EOT
481
482 close(FOUT);
483 $status = 1;
484 }
485 else {
486 print STDERR "ExpediteeFrameIO::saveZeroFrame() Failed to open $filename for output\n";
487 $status = 0;
488 }
489
490 return $status;
491}
492
493sub writeAssocFilePath
494{
495 my $self = shift @_;
496 my ($assoc) = @_;
497
498 my $x = 318;
499 my $y = 123;
500 my $text = "\@assocfilepath: $assoc";
501
502 my $attr = {};
503
504 #add data: gsdl.Metadata: assocfilepath to this piece of text.
505 $attr->{'D'} = "gsdl.Metadata: assocfilepath";
506
507 $self->addText($x,$y,$text,undef,$attr);
508}
509
510sub saveFrame
511{
512 my $self = shift @_;
513 my ($file,$assoc) = @_;
514
515 if ($file eq "1.exp") {
516 $self->saveZeroFrame();
517 }
518
519 my $filename = &util::filename_cat($self->{'output_dir'},$file);
520
521 my $status = undef;
522
523 if (open(FOUT,">$filename")) {
524 binmode(FOUT,":utf8");
525
526 if(defined $assoc){
527 $self->writeAssocFilePath($assoc); #write assocfilepath out to frame.
528 }
529
530 $self->writeHeaderSection();
531 $self->writeItemsSection();
532 $self->writeLinesSection();
533 $self->writeConstraintsSection();
534 $self->writeStatisticsSection();
535
536
537
538 close(FOUT);
539 $status = 1;
540 }
541 else {
542 print STDERR "ExpediteeFrameIO::saveFrame() Failed to open $filename for output\n";
543 $status = 0;
544 }
545
546 return $status;
547}
548
549sub buildFrame
550{
551 my $self = shift @_;
552 my ($html_node) = @_;
553
554 my $type = $html_node->{'type'};
555
556 if ($type eq "rect") {
557
558 my $rect = $html_node->{'rect'};
559 my $xl = $rect->{'xl'};
560 my $xr = $rect->{'xr'};
561 my $yt = $rect->{'yt'};
562 my $yb = $rect->{'yb'};
563
564 my $attr = convertStyleToAttr($html_node->{'style'});
565
566 if (defined $html_node->{'attr'}) {
567 # values provided in 'attr' explicitly overwrite any values
568 # derived from CSS style
569
570 my $direct_attr_str = $html_node->{'attr'};
571 my @direct_attr_array = split(/\s*;\s*/,$direct_attr_str);
572 foreach my $da (@direct_attr_array) {
573 my ($key,$val) = ($da =~ m/^(.)\s*(.*)$/);
574 $attr->{$key} = $val;
575 }
576 }
577
578 #don't want to add font information to non-text items!
579 my $deleted = delete $attr->{'f'};
580
581 $self->addRect($xl,$yt,$xr,$yb,$attr);
582
583 if (defined $html_node->{'img'}) {
584
585 my $img_url = $html_node->{'img'};
586 $img_url =~ s/^http:\/\/(.*?)\/greenstone3(.*?)\///;
587 if ($img_url =~ m/^interfaces\//) {
588 $img_url = "greenstone3-svn/web/$img_url";
589 }
590 elsif ($img_url =~ m/^sites\//) {
591# if ($img_url =~ m/^sites\//) {
592# $img_url =~ s/^sites\/(.*?)\//images\//;
593 $img_url = "greenstone3-svn/web/$img_url";
594 }
595
596 my $x = $xl;
597 my $y = $yt;
598
599 my $attr = {};
600
601 my $img_text = "\@i: $img_url";
602
603 $self->addText($x,$y,$img_text,undef,$attr);
604 }
605
606 }
607 elsif ($type eq "text") {
608
609 my $text = $html_node->{'text'};
610
611 my $x = $html_node->{'xl'};
612 my $y = $html_node->{'yt'};
613 my $w = $html_node->{'xr'} - $x +1;
614
615 my $attr = convertStyleToAttr($html_node->{'style'});
616
617 # fudge factor for now (based on default font size used)
618 $y += 16; # y-value of text item in Expeditee is it's base line
619 $x += 4;
620
621 my $data = $html_node->{'data'};
622 $attr->{'D'} = $data if defined $data;
623
624 $self->addText($x,$y,$text,$w,$attr);
625 }
626 else {
627 print STDERR "ExpediteeFrameIO::buildFrame(): Warning, unrecognized type '$type'\n";
628 }
629
630 my $childNodes = $html_node->{'childNodes'};
631 foreach my $child_node (@$childNodes) {
632 $self->buildFrame($child_node);
633 }
634}
635
636
637sub saveLastFrameNumber
638{
639 my $self = shift @_;
640 my ($last_frame_number,$collect) = @_;
641
642 my $filename = &util::filename_cat($self->{'output_dir'},"frame.inf");
643
644 my $status = undef;
645
646 if (open(FNOUT,">$filename")) {
647 binmode(FNOUT,":utf8");
648
649 #writes frameset name concatenated with last frame number in the set to the frame.inf file.
650 # my $getFramesetName = $self->{'output_dir'};
651
652 #use collection name rather than the directory name where the frameset is stored, when saving the last frame name/number to the frame.inf file.
653 print FNOUT "$collect"."$last_frame_number";
654
655 close(FNOUT);
656 $status = 1;
657 }
658 else {
659 print STDERR "ExpediteeFrameIO::saveLastFrameNumber() Failed to open $filename for output\n";
660
661 $status = 0;
662 }
663
664 return $status;
665
666}
667
6681;
Note: See TracBrowser for help on using the repository browser.