#!/usr/local/bin/perl -w
# POD docs at end
use strict;
use Data::Stag qw(:all);
use Getopt::Long;
use FileHandle;
use GD;
my $e = "";
my $fmt = 'png';
my $out;
my $parser;
my $fontchoice;
GetOptions("element|e=s"=>\$e,
"out|o=s"=>\$out,
"parser|format|p=s" => \$parser,
"font=s"=>\$fontchoice,
"help|h"=>sub { system("perldoc $0"); exit },
);
my $fn = shift @ARGV;
my $fh;
if ($fn eq '-') {
$fh = \*STDIN;
}
else {
$fh = FileHandle->new($fn) || die $fn;
}
my $tab = 4;
my $stag = Data::Stag->parse(-file=>$fn, -format=>$parser);
my $box = box($stag, 0, 0);
my $FONT = gdLargeFont;
if ($fontchoice) {
if ($fontchoice eq 'gdMediumBoldFont') {
$FONT = gdMediumBoldFont;
}
}
my $CW = $FONT->width;
my $CH = $FONT->height;
my $width = $CW * $box->{x2};
my $height = $CH * $box->{y2};
my $im = new GD::Image($width, $height);
my $bgcol = $im->colorAllocate(255, 255, 255);
my $fgcol = $im->colorAllocate(0, 0, 0);
my $linecol = $im->colorAllocate(0, 0, 0);
my $namecol = $im->colorAllocate(0, 0, 0);
my $datacol = $im->colorAllocate(255, 0, 0);
#$im->transparent($bgcol);
$im->interlaced('true');
drawbox($im, $box);
if ($out) {
open(F, ">$out") || die($out);
print F $im->$fmt();
close(F);
}
else {
print $im->$fmt();
}
sub box {
my $stag = shift;
my ($x, $y)= @_;
my $y1 = $y;
my $x2 = $x;
my @kids = $stag->kids;
my @subboxes = ();
my $data;
if ($stag->isterminal) {
$data = $stag->data;
$x2 += length($data) + length($stag->element) + 1;
@kids = ();
}
$y++;
foreach my $kid (@kids) {
my $subbox = box($kid, $x + $tab, $y);
push(@subboxes, $subbox);
$y = $subbox->{y2};
if ($subbox->{x2} > $x2) {
$x2 = $subbox->{x2};
}
}
return
{boxes=>\@subboxes,
name=>$stag->element,
data=>$data,
x1=>$x,
x2=>$x2,
y1=>$y1,
y2=>$y,
};
}
sub drawbox {
my $im = shift;
my $box = shift;
my $sx1 = $box->{x1} * $CW;
my $sy1 = $box->{y1} * $CH;
my $name = $box->{name};
my $data = $box->{data};
$im->string($FONT,
$sx1,
$sy1,
$name,
$namecol);
if ($data) {
$im->string($FONT,
$sx1 + length($name) * $CW + 1 * $CW,
$sy1,
$data,
$datacol);
}
my $subboxes = $box->{boxes};
my $XOFF = int($CW / 2);
my $YOFF = int($CH / 2);
foreach (@$subboxes) {
drawbox($im, $_);
my $ix = $sx1 + $XOFF;
my $iy = $_->{y1} * $CH + $YOFF;
my $jx = $_->{x1} * $CW;
$im->line($ix, $sy1 + $CH, $ix, $iy, $linecol);
$im->line($ix, $iy, $jx, $iy, $linecol);
}
}
exit 0;
__END__
=head1 NAME
stag-drawtree.pl - draws a stag file (xml, itext, sxpr) as a PNG diagram
=head1 SYNOPSIS
stag-drawtree.pl -o my.png myfile.xml
stag-drawtree.pl -p My::MyFormatParser -o my.png myfile.myfmt
=head1 DESCRIPTION
requires GD library and GD perl module
=head1 ARGUMENTS
=over
=item -p|parser FORMAT
FORMAT is one of xml, sxpr or itext, or the name of a perl module
xml assumed as default
=back
=head1 SEE ALSO
L<Data::Stag>
=cut
syntax highlighted by Code2HTML, v. 0.9.1