Markup-Tree

 view release on metacpan or  search on metacpan

lib/Markup/Tree.pm  view on Meta::CPAN

sub foreach_node {
	my ($self, $start_callback, $end_callback, $start_from) = @_;
	my $walk_tree;

	if (!$start_from) {
		if ($end_callback && UNIVERSAL::isa($end_callback, 'Markup::TreeNode')) {
			$start_from = $end_callback;
			$end_callback = undef;
		}
		else {
			$start_from = $self->{'_tree'};
		}
	}

	if (!($start_callback || (ref($start_callback) ne 'CODE'))) {
		Carp::croak ("parameter 0 is not a CODE reference");
	}

	$walk_tree = sub {
		my $tree = shift();

		if (ref($tree) eq 'ARRAY') {
			for (my $i = 0; $i < scalar(@{ $tree }); $i++) {
				$walk_tree->($tree->[$i]);
			}
		}
		elsif ($tree->isa('Markup::TreeNode')) {
			if ($tree->{'element_type'} eq '-->ignore') {
				$walk_tree->($tree->{'children'});
				return;
			}
			return if (!$start_callback->($tree));
			$walk_tree->($tree->{'children'});
			if ($end_callback && ref($end_callback) eq 'CODE') {
				return if (!$end_callback->($tree));
			}
		}
	};

	$walk_tree->($start_from);
}

sub save_as {
	my ($self, $file, $file_type) = @_;

	if (!$file_type) {
		if ($file =~ m/\.xml$/i) {
			$file_type = 'xml';
		}
		else {
			$file_type = 'html';
		}
	}

	$file_type = lc $file_type;

	$file = _mk_filehandle_write($file);

	print $file '<?xml version = "1.0" encoding = "iso-8859-1"?>'."\n";
	if ($file_type =~ '(?:x)?html') {
		print $file '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ';
		print $file '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'."\n";
	}

	$self->foreach_node(
		sub {
			my $node = shift();

			return 1 if ($node->{'element_type'} eq '-->root');
			return 1 if ($node->{'element_type'} eq '-->declaration');

			print $file '<!-- '.$node->{'text'}." -->\n" and return 1
				if ($node->{'element_type'} eq '-->comment');

			print $file $self->_rindent($node);
			unless ($node->{'element_type'} eq '-->text') {
				print $file "<".$node->{'tagname'};
				foreach (keys %{ $node->{'attr'} }) {
					print $file " $_ = \"".$node->{'attr'}->{$_}."\"";
				}
				if (!scalar(@{$node->{'children'} || []})) {
					print $file ' /';
				}
			}
			print $file (($node->{'element_type'} eq '-->text') ? $node->{'text'} : ">")."\n";
			return 1;
		},
		sub {
			my $node = shift();

			return 1 if ($node->{'element_type'} eq '-->root');
			return 1 if ($node->{'element_type'} eq '-->declaration');
			return 1 if (!scalar(@{$node->{'children'} || []}));
			return 1 if ($node->{'element_type'} eq '-->text');

			print $file $self->_rindent($node);
			print $file '</'.$node->{'tagname'}.">\n";

			return 1;
		}
	);

	close ($file) or Carp::croak ("Could not close file - $!");
}

sub _rindent {
	my ($self, $node) = @_;
	my $ident = $node->{'level'};
	my $buf = "";

	if ($self->{'no_indent'}) {
		return if (ref($self->{'no_indent'}) ne 'ARRAY');
		my $indent = 1;
		foreach (@{ $self->{'no_indent'} }) {
			if ($_ eq $node->{'tagname'}) { $indent = 0; last; }
		}

		return if (!$indent);
	}

	while ($ident--) {



( run in 1.427 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )