SVG-Parser

 view release on metacpan or  search on metacpan

lib/SVG/Parser/Base.pm  view on Meta::CPAN

    my ($self,$source)=@_;

    return ARG_IS_INVALID unless $source;

    # assume a string unless we determine differently
    my $type=ARG_IS_STRING;

    # check for various filehandle cases
    if (ref $source) {
        my $class = ref($source);

        if (UNIVERSAL::isa($source,'IO::Handle')) {
            # it's a new-style filehandle
            $type=ARG_IS_HANDLE;
        } elsif (tied($source)) {
            # it's a tied filehandle?
            no strict 'refs'; 
            $type=ARG_IS_HANDLE if defined &{"${class}::TIEHANDLE"};
        }
    } else {
        # it's an old-style filehandle?
        no strict 'refs';
        $type=ARG_IS_HANDLE if eval { *{$source}{IO} };
    }

    # possibly a hash argument is called via parse_file (SAX)
    $type=ARG_IS_HASHRF if ref($source) and $type eq ARG_IS_STRING;

    return $type;
}

#-------------------------------------------------------------------------------
# Additional SVG.pm processing

sub process_attrs ($$) {
    my ($parser,$attrs)=@_;

    if (exists $attrs->{style}) {
        my %styles=split /\s*[:;]\s*/,$attrs->{style};
        $attrs->{style}=\%styles;
    }
}

#---------------------------------------------------------------------------------------
# Shared Expat/SAX Handlers

# create and set SVG document object as root element
sub StartDocument {
    my $parser=shift;

    # gather SVG constuctor attributes
    my %svg_attr;
    %svg_attr=%{delete $parser->{__svg_attr}} if exists $parser->{__svg_attr};
    $svg_attr{-nostub}=1;
    # instantiate SVG document object
    $parser->{__svg}=new SVG(%svg_attr);
    # empty element list
    $parser->{__elements}=[];
    # empty unassigned attlist list (for internal DTD subset handling)
    $parser->{__unassigned_attlists}=[];
    # cdata count
    $parser->{__in_cdata}=0;

    $parser->debug("Start",$parser."/".$parser->{__svg});
}

# handle start of element - extend chain by one
sub StartTag {
    my ($parser,$type,%attrs)=@_;
    my $elements=$parser->{__elements};
    my $svg=$parser->{__svg};

    # some attributes need extra processing
    $parser->process_attrs(\%attrs);

    if (@$elements) {
        my $parent=$elements->[-1];
        push @$elements, $parent->element($type,%attrs);
    } else {
        $svg->{-inline}=1 if $type ne "svg"; #inlined
        my $el=$svg->element($type,%attrs);
        $svg->{-document} = $el;
        push @$elements, $el;
    }

    $parser->debug("Element",$type);
}

# handle end of element - shorten chain by one
sub EndTag {
    my ($parser,$type)=@_;
    my $elements=$parser->{__elements};
    pop @$elements;
}

# handle cannonical data (text)
sub Text {
    my ($parser,$text)=@_;
    my $elements=$parser->{__elements};

    return if $text=~/^\s*$/s; #ignore redundant whitespace
    my $parent=$elements->[-1];

    # are we in a CDATA section? (see CdataStart/End below)
    if ($parser->{__in_cdata}) {
        my $current=$parent->{-CDATA} || '';
        $parent->CDATA($current.$parser->{__svg}{-elsep}.$text);
    } else {
        my $current=$parent->{-cdata} || '';
        $parent->cdata($current.$parser->{__svg}{-elsep}.$text);
    }

    $parser->debug("CDATA","\"$text\"");
}

# handle cannonical data (CDATA sections)
sub CdataStart {
    my $parser=shift;
    $parser->{__in_cdata}++;

    $parser->debug("CDATA","start->");
}

sub CdataEnd {
    my $parser=shift;
    my $elements=$parser->{__elements};
    my $parent=$elements->[-1];

    my $current=$parent->{-CDATA} || '';
    $parent->CDATA($current.$parser->{__svg}{-elsep});
    $parser->{__in_cdata}--;

    $parser->debug("CDATA","<-end");
}

# handle processing instructions
sub PI {
    my ($parser,$target,$data)=@_;
    my $elements=$parser->{__elements};

    if (my $parent=$elements->[-1]) {
        /^<\?(.*)\?>/;
        $parent->pi($1);
    };

    $parser->debug("PI",$_);
}

# handle XML Comments
sub Comment {
    my ($parser,$data)=@_;

    my $elements=$parser->{__elements};
    if (my $parent=$elements->[-1]) {
        # SVG.pm doesn't handle comment prior to document start
        $parent->comment($data);
    }

    $parser->debug("Comment",$data);
}

# return root SVG document object as result of parse()
sub FinishDocument {
    my $parser=shift;
    my $svg=$parser->{__svg};

    # add any attlists that were seen before their element
    if (my $attlists=$parser->{__unassigned_attlists}) {
        foreach my $unassigned_attlist (@$attlists) {
            # if the element is still missing this will complain (if the parser didn't)
            $svg->attlist_decl(@$unassigned_attlist);
        }
    }

    $parser->debug("Done");

    return $parser->{__svg};
}

#---------------------------------------------------------------------------------------

# handle XML declaration, if present
sub XMLDecl {
    my ($parser,$version,$encoding,$standalone)=@_;
    my $svg=$parser->{__svg};

    $svg->{-version}=$version || $parser->SVG_DEFAULT_DECL_VERSION;
    $svg->{-encoding}=$encoding || $parser->SVG_DEFAULT_DECL_ENCODING;
    $svg->{-standalone}=$standalone?"yes":"no";

    $parser->debug("XMLDecl","-version=\"$svg->{-version}\"",



( run in 2.058 seconds using v1.01-cache-2.11-cpan-2398b32b56e )