use strict; use warnings;
use utf8; use open qw(:std :utf8);
use XML::LibXML;
use Getopt::Std;

my $lx = new XML::LibXML ();
$lx->recover(2);

getopts('vtP', \my %opts);

unless (@ARGV) {
	print "syntax: $0 [-vtP] location xpath-expr [xpath-expr...]\n";
	exit
}

my $dom = $lx->load_html(location => +shift, suppress_errors => 1);

sub maxlen {
	my $len = shift;
	for (@_) {
		if (length $_ > $len) {
			$_ = (substr $_, 0, $len);
			$_ .= "\e[27m" if $_ =~ /\e\[7m/ && $_ !~ /\e\[27m/;
			$_ .= '…';
		}
	}
}

for (@ARGV) {
	print "--[ $_ ]--\n\n";
	if ($opts{v}) {
		print "\t",$dom->findvalue($_),"\n\n";
		next;
	}
	my $c = 0;
	for ($dom->findnodes($_)) {
		my $xml = $_->toString;
		$xml = $_->textContent if $opts{t};
		my $lit = $_->to_literal;
		my $hl = $xml =~ s/\Q$lit\E/\e[7m$lit\e[27m/g;
		maxlen(160, $xml);  maxlen(160, $lit);
		my @path_info;
		my @path2 = split '/', $_->nodePath;
		for (my $n = $_; $n; $n = $n->parentNode) {
			my $id = $n->findvalue('@id');
			my $class = $n->findvalue('@class');
			my $name = $n->findvalue('@name');
			unshift @path_info, (length $id ? "#$id" : '')
				. (length $name ? "^$name" : '')
				. (length $class ? ".$class" : '');
		}
		print ++$c;
		for (my $i = 1; $i < @path_info; ++$i) {
			print "\t".(' 'x$i)."$path2[$i]$path_info[$i]\n" unless $opts{P};
		}
		print "\t$xml\n";
		print "\t$lit\n" unless $hl && $xml =~ /\e\[7m/;
		print "\n";
	}
}
