Text-Restructured

 view release on metacpan or  search on metacpan

lib/Text/Restructured/DOM.pm  view on Meta::CPAN

# Returns: None
sub substitute : method {
    my($dom, @new_doms) = @_;

    my $parent = $dom->parent;
    return unless $parent;
    my $index = $parent->index($dom);
    return if $index < 0;
    splice @{$parent->{content}}, $index, 1, @new_doms;
    delete $PARENT{$dom};
    @PARENT{@new_doms} = ($parent) x @new_doms;
}

# INSTANCE METHOD.
# Returns the tag of a DOM object
# Arguments: Optional new tag value
# Returns: Tag
sub tag : method {
    my($dom, $new_tag) = @_;

    $dom->{tag} = $new_tag if defined $new_tag;
    return $dom->{tag};
}

# Parses text that is in DOM (pseudo-XML) format.
# Arguments: Text, reference to hash of command-line options
# Returns: DOM object
# Uses globals: None
sub Parse {
    my ($text, $opt) = @_;
    my $last_indent = -1;
    my @stack;
    my @indents;
    my $tos;	# top of stack
    my $main;
    my @text = split /\n/, $text;
    foreach (@text) {
	my ($spaces) = /^(\s*)/;
	my $indent = length($spaces);
	if (@stack > 0) {
	    my $i;
	    for ($i=0; $i < @indents; $i++) {
		last if $indent <= $indents[$i]+1;
	    }
	    splice(@stack, $i);
	    splice(@indents, $i);
	    $tos = $stack[-1];
	}

	if (/^(\s*)<(\w+)\s*([^>]*)>\s*$/) {
	    my ($spaces, $tag, $attrlist) = ($1, $2, $3);
	    my $dom = new Text::Restructured::DOM($tag);
	    while ($attrlist ne '') {
		if ($attrlist =~ s/^([\w:]+)=([\"\'])([^\"]*)\2\s*//) {
		    $dom->{attr}{$1} = $3;
		}
		elsif ($attrlist =~ s/^(\w+)\s*//) {
		    $dom->{attr}{$1} = undef;
		}
		else {
		    goto pcdata;
		}
	    }
	    $tos->append($dom) if $tos;
	    if (@stack > 0) {
		$tos = $dom;
	    }
	    else {
		$main = $dom;
	    }
	    push (@stack, $dom);
	    push (@indents, $indent);
	    $tos = $dom;
	}
	else {
	  pcdata:
	    substr($_,0,$indents[-1]+4) = "";
	    chomp;
	    my $text = $_;
	    my $ncontent = @{$tos->{content}};
	    if ($ncontent > 0 &&
		$tos->{content}[$ncontent-1]{tag} eq '#PCDATA') {
		$tos->{content}[$ncontent-1]{text} .= "$text\n";
	    }
	    else {
		my $dom = newPCDATA Text::Restructured::DOM("$text\n");
		$tos->append($dom);
	    }
	}
    };

    $main->{attr}{source} = $opt->{D}{source} || $ARGV;
    return $main;
}

# Methods relating to the DTD

BEGIN {
# These are computed from the docutils.dtd using XML::Smart::DTD
my @takes_body_elts =
    qw(admonition attention block_quote caution citation compound
       container danger definition description document error
       field_body footer footnote header hint important legend
       list_item note section sidebar system_message tip topic
       warning);
my @takes_inline_elts =
    qw(abbreviation acronym address attribution author caption
       classifier contact copyright date doctest_block emphasis
       field_name generated inline line literal_block organization
       paragraph problematic raw reference revision rubric status
       strong subscript substitution_definition substitution_reference
       subtitle superscript target term title title_reference
       version);
my @is_body_elt =
    qw(admonition attention block_quote bullet_list caution citation
       comment compound container danger definition_list doctest_block
       enumerated_list error field_list figure footnote hint image
       important line_block literal_block note option_list paragraph
       pending raw reference rubric substitution_definition
       system_message table target tip warning);
my @is_inline_elt =
    qw(emphasis strong literal reference footnote_reference
       citation_reference substitution_reference title_reference
       abbreviation acronym subscript superscript inline problematic
       generated target image raw);
my (%takes_body_elts, %takes_inline_elts, %is_body_elt, %is_inline_elt);
@takes_body_elts{@takes_body_elts}     = (1) x @takes_body_elts;
@takes_inline_elts{@takes_inline_elts} = (1) x @takes_inline_elts;
@is_body_elt{@is_body_elt}             = (1) x @is_body_elt;
@is_inline_elt{@is_inline_elt}         = (1) x @is_inline_elt;

# INSTANCE METHOD.
# Arguments: None
# Returns: True if the DOM object can take body elements in its contents
sub takes_body_elts : method {
    my ($dom) = @_;



( run in 1.308 second using v1.01-cache-2.11-cpan-39bf76dae61 )