source: trunk/gsdl/perllib/doc.pm@ 1241

Last change on this file since 1241 was 1241, checked in by sjboddie, 24 years ago

merged ascii_doc.pm and doc.pm back together (removing basedoc.pm). To get
the same speed improvements that we used ascii_doc for you now just pass
your plugin a "-input_encoding ascii" option

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 22.1 KB
Line 
1###########################################################################
2#
3# doc.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) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute 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
26# base class to hold documents
27
28package doc;
29
30BEGIN {
31 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
32 unshift (@INC, "$ENV{'GSDLHOME'}/perllib/dynamic/lib/site_perl/5.005/i686-linux");
33}
34
35use unicode;
36use util;
37use ghtml;
38##use hashdoc;
39
40# the document type may be indexed_doc, nonindexed_doc, or
41# classification
42
43sub new {
44 my $class = shift (@_);
45
46 my $self = bless {'associated_files'=>[],
47 'subsection_order'=>[],
48 'next_subsection'=>1,
49 'subsections'=>{},
50 'metadata'=>[],
51 'text'=>""}, $class;
52
53# $self->set_source_filename ($source_filename) if defined $source_filename;
54 push (@{$self->{'metadata'}}, ["gsdlsourcefilename", $source_filename]) if defined $source_filename;
55# $self->set_doc_type ($doc_type) if defined $doc_type;
56 push (@{$self->{'metadata'}}, ["gsdldoctype", $doc_type]) if defined $doc_type;
57
58 return $self;
59}
60
61# clone the $self object
62sub duplicate {
63 my $self = shift (@_);
64
65 my $newobj = {};
66
67 foreach $k (keys %$self) {
68 $newobj->{$k} = &clone ($self->{$k});
69 }
70
71 bless $newobj, ref($self);
72 return $newobj;
73}
74
75sub clone {
76 my ($from) = @_;
77 my $type = ref ($from);
78
79 if ($type eq "HASH") {
80 my $to = {};
81 foreach $key (keys %$from) {
82 $to->{$key} = &clone ($from->{$key});
83 }
84 return $to;
85 } elsif ($type eq "ARRAY") {
86 my $to = [];
87 foreach $v (@$from) {
88 push (@$to, &clone ($v));
89 }
90 return $to;
91 } else {
92 return $from;
93 }
94}
95
96
97sub set_source_filename {
98 my $self = shift (@_);
99 my ($source_filename) = @_;
100
101 $self->set_metadata_element ($self->get_top_section(),
102 "gsdlsourcefilename",
103 $source_filename);
104}
105
106# returns the source_filename as it was provided
107sub get_source_filename {
108 my $self = shift (@_);
109
110 return $self->get_metadata_element ($self->get_top_section(), "gsdlsourcefilename");
111}
112
113sub set_doc_type {
114 my $self = shift (@_);
115 my ($doc_type) = @_;
116
117 $self->set_metadata_element ($self->get_top_section(),
118 "gsdldoctype",
119 $doc_type);
120}
121
122# returns the source_filename as it was provided
123# the default of "indexed_doc" is used if no document
124# type was provided
125sub get_doc_type {
126 my $self = shift (@_);
127
128 my $doc_type = $self->get_metadata_element ($self->get_top_section(), "gsdldoctype");
129 return $doc_type if (defined $doc_type);
130 return "indexed_doc";
131}
132
133sub _escape_text {
134 my ($text) = @_;
135
136 # special characters in the gml encoding
137 $text =~ s/&/&/g; # this has to be first...
138 $text =~ s/</&lt;/g;
139 $text =~ s/>/&gt;/g;
140 $text =~ s/\"/&quot;/g;
141
142 return $text;
143}
144
145
146sub buffer_section {
147 my $self = shift (@_);
148 my ($section, $suppress_subject_info) = @_;
149
150 $suppress_subject_info = 0 unless defined $suppress_subject_info;
151 my ($all_text,$data, $subsection);
152
153 my $section_ptr = $self->_lookup_section ($section);
154 my ($section_num) = $section =~ /(\d+)$/;
155
156 return "" unless defined $section_ptr;
157
158 # output the section header (including the section number
159 # and metadata)
160
161 $all_text = "<gsdlsection";
162 $all_text .= " gsdlnum=\"$section_num\"" if defined $section_num;
163 foreach $data (@{$section_ptr->{'metadata'}}) {
164 $all_text .= " $data->[0]=\"" . &_escape_text($data->[1]) . "\""
165 unless $suppress_subject_info && $data->[0] eq "Subject";
166 }
167 $all_text .= ">";
168
169 # output the text
170 $all_text .= &_escape_text($section_ptr->{'text'});
171
172 # output all the subsections
173 foreach $subsection (@{$section_ptr->{'subsection_order'}}) {
174 $all_text .= $self->buffer_section("$section.$subsection", $suppress_subject_info);
175 }
176
177 # output the closing tag
178 $all_text .= "</gsdlsection>\n";
179
180 return $all_text;
181}
182
183sub output_section {
184 my $self = shift (@_);
185 my ($handle, $section, $suppress_subject_info) = @_;
186
187 my $all_text = $self->buffer_section($section, $suppress_subject_info);
188 print $handle $all_text;
189}
190
191# look up the reference to the a particular section
192sub _lookup_section {
193 my $self = shift (@_);
194 my ($section) = @_;
195
196 my ($num);
197 my $sectionref = $self;
198
199 while (defined $section && $section ne "") {
200 ($num, $section) = $section =~ /^\.?(\d+)(.*)$/;
201 $num =~ s/^0+(\d)/$1/; # remove leading 0s
202 $section = "" unless defined $section;
203
204 if (defined $num && defined $sectionref->{'subsections'}->{$num}) {
205 $sectionref = $sectionref->{'subsections'}->{$num};
206 } else {
207 return undef;
208 }
209 }
210
211 return $sectionref;
212}
213
214sub _calc_OID {
215 my $self = shift (@_);
216 my ($filename) = @_;
217
218 my $osexe = &util::get_os_exe();
219
220 my $hashfile_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",
221 $ENV{'GSDLOS'},"hashfile$osexe");
222 my $result = "NULL";
223
224 if (-e "$hashfile_exe") {
225 $result = `$hashfile_exe \"$filename\"`;
226 ($result) = $result =~ /:\s*([0-9a-f]+)/i;
227
228 } else {
229 print STDERR "doc::_calc_OID $hashfile_exe could not be found\n";
230 }
231
232 return "HASH$result";
233}
234
235# methods dealing with OID, not groups of them.
236
237# if $OID is not provided one is calculated from hashing the
238# current contents of the document
239# An OID are actually stored as metadata of the document
240sub set_OID {
241 my $self = shift (@_);
242 my ($OID) = @_;
243
244 # if an OID wasn't provided then feed this document to
245 # hashfile.exe
246 if (!defined $OID) {
247 $OID = "NULL";
248 my $tmp_filename = &util::get_tmp_filename();
249 if (!open (OUTFILE, ">$tmp_filename")) {
250 print STDERR "doc::set_OID could not write to $tmp_filename\n";
251 } else {
252 $self->output_section('OUTFILE', $self->get_top_section(), 1);
253 close (OUTFILE);
254
255 $OID = $self->_calc_OID ($tmp_filename);
256 &util::rm ($tmp_filename);
257 }
258 }
259
260 $self->set_metadata_element ($self->get_top_section(), "Identifier", $OID);
261}
262
263# this uses hashdoc (embedded c thingy) which is faster but still
264# needs a little work to be suffiently stable
265sub ___set_OID {
266 my $self = shift (@_);
267 my ($OID) = @_;
268
269 # if an OID wasn't provided then calculate hash value based on document
270 if (!defined $OID)
271 {
272 my $hash_text = $self->buffer_section($self->get_top_section(), 1);
273 my $hash_len = length($hash_text);
274
275 $OID = &hashdoc::buffer($hash_text,$hash_len);
276 }
277
278 $self->set_metadata_element ($self->get_top_section(), "Identifier", $OID);
279}
280
281# returns the OID for this document
282sub get_OID {
283 my $self = shift (@_);
284 my $OID = $self->get_metadata_element ($self->get_top_section(), "Identifier");
285 return $OID if (defined $OID);
286 return "NULL";
287}
288
289sub delete_OID {
290 my $self = shift (@_);
291
292 $self->set_metadata_element ($self->get_top_section(), "Identifier", "NULL");
293}
294
295
296# methods for manipulating section names
297
298# returns the name of the top-most section (the top
299# level of the document
300sub get_top_section {
301 my $self = shift (@_);
302
303 return "";
304}
305
306# returns a section
307sub get_parent_section {
308 my $self = shift (@_);
309 my ($section) = @_;
310
311 $section =~ s/(^|\.)\d+$//;
312
313 return $section;
314}
315
316# returns the first child section (or the end child
317# if there isn't any)
318sub get_begin_child {
319 my $self = shift (@_);
320 my ($section) = @_;
321
322 my $section_ptr = $self->_lookup_section($section);
323 return "" unless defined $section_ptr;
324
325 if (defined $section_ptr->{'subsection_order'}->[0]) {
326 return "$section.$section_ptr->{'subsection_order'}->[0]";
327 }
328
329 return $self->get_end_child ($section);
330}
331
332# returns the next child of a parent section
333sub get_next_child {
334 my $self = shift (@_);
335 my ($section) = @_;
336
337 my $parent_section = $self->get_parent_section($section);
338 my $parent_section_ptr = $self->_lookup_section($parent_section);
339 return undef unless defined $parent_section_ptr;
340
341 my ($section_num) = $section =~ /(\d+)$/;
342 return undef unless defined $section_num;
343
344 my $i = 0;
345 my $section_order = $parent_section_ptr->{'subsection_order'};
346 while ($i < scalar(@$section_order)) {
347 last if $section_order->[$i] eq $section_num;
348 $i++;
349 }
350
351 $i++; # the next child
352 if ($i < scalar(@$section_order)) {
353 return $section_order->[$i] if $parent_section eq "";
354 return "$parent_section.$section_order->[$i]";
355 }
356
357 # no more sections in this level
358 return undef;
359}
360
361# returns a reference to a list of children
362sub get_children {
363 my $self = shift (@_);
364 my ($section) = @_;
365
366 my $section_ptr = $self->_lookup_section($section);
367 return [] unless defined $section_ptr;
368
369 my @children = @{$section_ptr->{'subsection_order'}};
370
371 map {$_ = "$section.$_"; $_ =~ s/^\.+//;} @children;
372 return \@children;
373}
374
375# returns the child section one past the last one (which
376# is coded as "0")
377sub get_end_child {
378 my $self = shift (@_);
379 my ($section) = @_;
380
381 return $section . ".0" unless $section eq "";
382 return "0";
383}
384
385# returns the next section in book order
386sub get_next_section {
387 my $self = shift (@_);
388 my ($section) = @_;
389
390 return undef unless defined $section;
391
392 my $section_ptr = $self->_lookup_section($section);
393 return undef unless defined $section_ptr;
394
395 # first try to find first child
396 if (defined $section_ptr->{'subsection_order'}->[0]) {
397 return $section_ptr->{'subsection_order'}->[0] if ($section eq "");
398 return "$section.$section_ptr->{'subsection_order'}->[0]";
399 }
400
401 do {
402 # try to find sibling
403 my $next_child = $self->get_next_child ($section);
404 return $next_child if (defined $next_child);
405
406 # move up one level
407 $section = $self->get_parent_section ($section);
408 } while $section =~ /\d/;
409
410 return undef;
411}
412
413sub is_leaf_section {
414 my $self = shift (@_);
415 my ($section) = @_;
416
417 my $section_ptr = $self->_lookup_section($section);
418 return 1 unless defined $section_ptr;
419
420 return (scalar (@{$section_ptr->{'subsection_order'}}) == 0);
421}
422
423# methods for dealing with sections
424
425# returns the name of the inserted section
426sub insert_section {
427 my $self = shift (@_);
428 my ($before_section) = @_;
429
430 # get the child to insert before and its parent section
431 my $parent_section = "";
432 my $before_child = "0";
433 my @before_section = split (/\./, $before_section);
434 if (scalar(@before_section) > 0) {
435 $before_child = pop (@before_section);
436 $parent_section = join (".", @before_section);
437 }
438
439 my $parent_section_ptr = $self->_lookup_section($parent_section);
440 if (!defined $parent_section_ptr) {
441 print STDERR "doc::insert_section couldn't find parent section " .
442 "$parent_section\n";
443 return;
444 }
445
446 # get the next section number
447 my $section_num = $parent_section_ptr->{'next_subsection'}++;
448
449 my $i = 0;
450 while ($i < scalar(@{$parent_section_ptr->{'subsection_order'}}) &&
451 $parent_section_ptr->{'subsection_order'}->[$i] ne $before_child) {
452 $i++;
453 }
454
455 # insert the section number into the order list
456 splice (@{$parent_section_ptr->{'subsection_order'}}, $i, 0, $section_num);
457
458 # add this section to the parent section
459 my $section_ptr = {'subsection_order'=>[],
460 'next_subsection'=>1,
461 'subsections'=>{},
462 'metadata'=>[],
463 'text'=>""};
464 $parent_section_ptr->{'subsections'}->{$section_num} = $section_ptr;
465
466 # work out the full section number
467 my $section = $parent_section;
468 $section .= "." unless $section eq "";
469 $section .= $section_num;
470
471 return $section;
472}
473
474# creates a pre-named section
475sub create_named_section {
476 my $self = shift (@_);
477 my ($mastersection) = @_;
478
479 my ($num);
480 my $section = $mastersection;
481 my $sectionref = $self;
482
483#### print STDERR "*** mastersection = $mastersection\n";
484
485 while ($section ne "") {
486 ($num, $section) = $section =~ /^\.?(\d+)(.*)$/;
487 $num =~ s/^0+(\d)/$1/; # remove leading 0s
488 $section = "" unless defined $section;
489
490 if (defined $num) {
491 if (!defined $sectionref->{'subsections'}->{$num}) {
492 push (@{$sectionref->{'subsection_order'}}, $num);
493 $sectionref->{'subsections'}->{$num} = {'subsection_order'=>[],
494 'next_subsection'=>1,
495 'subsections'=>{},
496 'metadata'=>[],
497 'text'=>""};
498 if ($num >= $sectionref->{'next_subsection'}) {
499 $sectionref->{'next_subsection'} = $num + 1;
500 }
501 }
502 $sectionref = $sectionref->{'subsections'}->{$num};
503
504 } else {
505 print STDERR "doc::create_named_section couldn't create section ";
506 print STDERR "$mastersection\n";
507 last;
508 }
509 }
510}
511
512# returns a reference to a list of subsections
513sub list_subsections {
514 my $self = shift (@_);
515 my ($section) = @_;
516
517 my $section_ptr = $self->_lookup_section ($section);
518 if (!defined $section_ptr) {
519 print STDERR "doc::list_subsections couldn't find section $section\n";
520 return [];
521 }
522
523 return [@{$section_ptr->{'subsection_order'}}];
524}
525
526sub delete_section {
527 my $self = shift (@_);
528 my ($section) = @_;
529
530# my $section_ptr = {'subsection_order'=>[],
531# 'next_subsection'=>1,
532# 'subsections'=>{},
533# 'metadata'=>[],
534# 'text'=>""};
535
536 # if this is the top section reset everything
537 if ($section eq "") {
538 $self->{'subsection_order'} = [];
539 $self->{'subsections'} = {};
540 $self->{'metadata'} = [];
541 $self->{'text'} = "";
542 return;
543 }
544
545 # find the parent of the section to delete
546 my $parent_section = "";
547 my $child = "0";
548 my @section = split (/\./, $section);
549 if (scalar(@section) > 0) {
550 $child = pop (@section);
551 $parent_section = join (".", @section);
552 }
553
554 my $parent_section_ptr = $self->_lookup_section($parent_section);
555 if (!defined $parent_section_ptr) {
556 print STDERR "doc::delete_section couldn't find parent section " .
557 "$parent_section\n";
558 return;
559 }
560
561 # remove this section from the subsection_order list
562 my $i = 0;
563 while ($i < scalar (@{$parent_section_ptr->{'subsection_order'}})) {
564 if ($parent_section_ptr->{'subsection_order'}->[$i] eq $child) {
565 splice (@{$parent_section_ptr->{'subsection_order'}}, $i, 1);
566 last;
567 }
568 $i++;
569 }
570
571 # remove this section from the subsection hash
572 if (defined ($parent_section_ptr->{'subsections'}->{$child})) {
573 undef $parent_section_ptr->{'subsections'}->{$child};
574 }
575}
576
577#--
578# methods for dealing with metadata
579
580# set_metadata_element and get_metadata_element are for metadata
581# which should only have one value. add_meta_data and get_metadata
582# are for metadata which can have more than one value.
583
584# returns the first metadata value which matches field
585sub get_metadata_element {
586 my $self = shift (@_);
587 my ($section, $field) = @_;
588 my ($data);
589
590 my $section_ptr = $self->_lookup_section($section);
591 if (!defined $section_ptr) {
592 print STDERR "doc::get_metadata_element couldn't find section " .
593 "$section\n";
594 return;
595 }
596
597 foreach $data (@{$section_ptr->{'metadata'}}) {
598 return $data->[1] if (scalar(@$data) >= 2 && $data->[0] eq $field);
599 }
600
601 return undef; # was not found
602}
603
604
605# returns a list of the form [value1, value2, ...]
606sub get_metadata {
607 my $self = shift (@_);
608 my ($section, $field) = @_;
609 my ($data);
610
611 my $section_ptr = $self->_lookup_section($section);
612 if (!defined $section_ptr) {
613 print STDERR "doc::get_metadata couldn't find section " .
614 "$section\n";
615 return;
616 }
617
618 my @metadata = ();
619 foreach $data (@{$section_ptr->{'metadata'}}) {
620 push (@metadata, $data->[1]) if ($data->[0] eq $field);
621 }
622
623 return \@metadata;
624}
625
626# returns a list of the form [[field,value],[field,value],...]
627sub get_all_metadata {
628 my $self = shift (@_);
629 my ($section) = @_;
630
631 my $section_ptr = $self->_lookup_section($section);
632 if (!defined $section_ptr) {
633 print STDERR "doc::get_all_metadata couldn't find section " .
634 "$section\n";
635 return;
636 }
637
638 return $section_ptr->{'metadata'};
639}
640
641# $value is optional
642sub delete_metadata {
643 my $self = shift (@_);
644 my ($section, $field, $value) = @_;
645
646 my $section_ptr = $self->_lookup_section($section);
647 if (!defined $section_ptr) {
648 print STDERR "doc::delete_metadata couldn't find section " .
649 "$section\n";
650 return;
651 }
652
653 my $i = 0;
654 while ($i < scalar (@{$section_ptr->{'metadata'}})) {
655 if (($section_ptr->{'metadata'}->[$i]->[0] eq $field) &&
656 (!defined $value || $section_ptr->{'metadata'}->[$i]->[1] eq $value)) {
657 splice (@{$section_ptr->{'metadata'}}, $i, 1);
658 } else {
659 $i++;
660 }
661 }
662}
663
664sub delete_all_metadata {
665 my $self = shift (@_);
666 my ($section) = @_;
667
668 my $section_ptr = $self->_lookup_section($section);
669 if (!defined $section_ptr) {
670 print STDERR "doc::delete_all_metadata couldn't find section " .
671 "$section\n";
672 return;
673 }
674
675 $section_ptr->{'metadata'} = [];
676}
677
678sub set_metadata_element {
679 my $self = shift (@_);
680 my ($section, $field, $value) = @_;
681
682 $self->set_utf8_metadata_element ($section, $field,
683 &unicode::ascii2utf8($value));
684}
685
686# set_utf8_metadata_element assumes the text has already been
687# converted to the UTF-8 encoding.
688sub set_utf8_metadata_element {
689 my $self = shift (@_);
690 my ($section, $field, $value) = @_;
691
692 $self->delete_metadata ($section, $field);
693 $self->add_utf8_metadata ($section, $field, $value);
694}
695
696
697# add_metadata assumes the text is in (extended) ascii form. For
698# text which hash been already converted to the UTF-8 format use
699# add_utf8_metadata.
700sub add_metadata {
701 my $self = shift (@_);
702 my ($section, $field, $value) = @_;
703
704 $self->add_utf8_metadata ($section, $field,
705 &unicode::ascii2utf8($value));
706}
707
708# add_utf8_metadata assumes the text has already been converted
709# to the UTF-8 encoding.
710sub add_utf8_metadata {
711 my $self = shift (@_);
712 my ($section, $field, $value) = @_;
713
714 my $section_ptr = $self->_lookup_section($section);
715 if (!defined $section_ptr) {
716 print STDERR "doc::add_utf8_metadata couldn't find section " .
717 "$section\n";
718 return;
719 }
720
721 push (@{$section_ptr->{'metadata'}}, [$field, $value]);
722}
723
724
725# methods for dealing with text
726
727# returns the text for a section
728sub get_text {
729 my $self = shift (@_);
730 my ($section) = @_;
731
732 my $section_ptr = $self->_lookup_section($section);
733 if (!defined $section_ptr) {
734 print STDERR "doc::get_text couldn't find section " .
735 "$section\n";
736 return "";
737 }
738
739 return $section_ptr->{'text'};
740}
741
742# returns the (utf-8 encoded) length of the text for a section
743sub get_text_length {
744 my $self = shift (@_);
745 my ($section) = @_;
746
747 my $section_ptr = $self->_lookup_section($section);
748 if (!defined $section_ptr) {
749 print STDERR "doc::get_text_length couldn't find section " .
750 "$section\n";
751 return 0;
752 }
753
754 return length ($section_ptr->{'text'});
755}
756
757sub delete_text {
758 my $self = shift (@_);
759 my ($section) = @_;
760
761 my $section_ptr = $self->_lookup_section($section);
762 if (!defined $section_ptr) {
763 print STDERR "doc::delete_text couldn't find section " .
764 "$section\n";
765 return;
766 }
767
768 $section_ptr->{'text'} = "";
769}
770
771# add_text assumes the text is in (extended) ascii form. For
772# text which has been already converted to the UTF-8 format
773# use add_utf8_text.
774sub add_text {
775 my $self = shift (@_);
776 my ($section, $text) = @_;
777
778 # convert the text to UTF-8 encoded unicode characters
779 # and add the text
780 $self->add_utf8_text($section, &unicode::ascii2utf8($text));
781}
782
783
784# add_utf8_text assumes the text to be added has already
785# been converted to the UTF-8 encoding. For ascii text use
786# add_text
787sub add_utf8_text {
788 my $self = shift (@_);
789 my ($section, $text) = @_;
790
791 my $section_ptr = $self->_lookup_section($section);
792 if (!defined $section_ptr) {
793 print STDERR "doc::add_utf8_text couldn't find section " .
794 "$section\n";
795 return;
796 }
797
798 $section_ptr->{'text'} .= $text;
799}
800
801
802# methods for dealing with associated files
803
804# a file is associated with a document, NOT a section.
805# if section is defined it is noted in the data structure
806# only so that files associated from a particular section
807# may be removed later (using delete_section_assoc_files)
808sub associate_file {
809 my $self = shift (@_);
810 my ($real_filename, $assoc_filename, $mime_type, $section) = @_;
811 $mime_type = &ghtml::guess_mime_type ($real_filename) unless defined $mime_type;
812
813 # remove all associated files with the same name
814 $self->delete_assoc_file ($assoc_filename);
815
816 push (@{$self->{'associated_files'}},
817 [$real_filename, $assoc_filename, $mime_type, $section]);
818}
819
820# returns a list of associated files in the form
821# [[real_filename, assoc_filename, mimetype], ...]
822sub get_assoc_files {
823 my $self = shift (@_);
824
825 return $self->{'associated_files'};
826}
827
828sub delete_section_assoc_files {
829 my $self = shift (@_);
830 my ($section) = @_;
831
832 my $i=0;
833 while ($i < scalar (@{$self->{'associated_files'}})) {
834 if (defined $self->{'associated_files'}->[$i]->[3] &&
835 $self->{'associated_files'}->[$i]->[3] eq $section) {
836 splice (@{$self->{'associated_files'}}, $i, 1);
837 } else {
838 $i++;
839 }
840 }
841}
842
843sub delete_assoc_file {
844 my $self = shift (@_);
845 my ($assoc_filename) = @_;
846
847 my $i=0;
848 while ($i < scalar (@{$self->{'associated_files'}})) {
849 if ($self->{'associated_files'}->[$i]->[1] eq $assoc_filename) {
850 splice (@{$self->{'associated_files'}}, $i, 1);
851 } else {
852 $i++;
853 }
854 }
855}
856
857sub reset_nextsection_ptr {
858 my $self = shift (@_);
859 my ($section) = @_;
860
861 my $section_ptr = $self->_lookup_section($section);
862 $section_ptr->{'next_subsection'} = 1;
863}
864
8651;
Note: See TracBrowser for help on using the repository browser.