Ignore:
Timestamp:
2000-07-13T10:21:53+12:00 (24 years ago)
Author:
sjboddie
Message:

merged changes to trunk into New_Config_Format branch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/New_Config_Format-branch/gsdl/perllib/doc.pm

    r846 r1279  
    2424###########################################################################
    2525
    26 # class to hold documents
     26# base class to hold documents
    2727
    2828package doc;
    2929
    30 use basedoc;
    31 
    3230BEGIN {
    33     @ISA = ('basedoc');
    34 }
     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;
    3539
    3640# the document type may be indexed_doc, nonindexed_doc, or
     
    3943sub new {
    4044    my $class = shift (@_);
    41     my ($source_filename, $doc_type) = @_;
    42    
    43     my $self = new basedoc();
     45   
     46    my $self = bless {'associated_files'=>[],
     47              'subsection_order'=>[],
     48              'next_subsection'=>1,
     49              'subsections'=>{},
     50              'metadata'=>[],
     51              'text'=>""}, $class;
    4452
    4553#    $self->set_source_filename ($source_filename) if defined $source_filename;
    46     push (@{$self->{'metadata'}}, ["gsdlsourcefilename", &unicode::ascii2utf8($source_filename)])
    47     if defined $source_filename;
     54    push (@{$self->{'metadata'}}, ["gsdlsourcefilename", $source_filename]) if defined $source_filename;
    4855#    $self->set_doc_type ($doc_type) if defined $doc_type;
    49     push (@{$self->{'metadata'}}, ["gsdldoctype", &unicode::ascii2utf8($doc_type)])
    50     if defined $doc_type;
    51 
    52     bless($self,$class);
     56    push (@{$self->{'metadata'}}, ["gsdldoctype", $doc_type]) if defined $doc_type;
     57
    5358    return $self;
    5459}
    5560
     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#--
    56578# methods for dealing with metadata
    57579
     
    60582# are for metadata which can have more than one value.
    61583
    62 # set_metadata_element assumes the value is in (extended) ascii form.
    63 # For text which hash been already converted to the UTF-8 format use
    64 # set_utf8_metadata_element.
     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
    65678sub set_metadata_element {
    66679    my $self = shift (@_);
     
    112725# methods for dealing with text
    113726
     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
    114771# add_text assumes the text is in (extended) ascii form. For
    115772# text which has been already converted to the UTF-8 format
     
    143800
    144801
     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
    1458651;
Note: See TracChangeset for help on using the changeset viewer.