Re: A perl/Gtk Newbie



john knops writes:
at the tutorial at www.gtk.org but it's a bit light on how to create a canvas 
with text, images and a coloured background. So watch this space for more 
questions over the coming weeks.


Sorry this is late, and doubly sorry that I haven't had time to trim
this down to something more illustrative. This is a cut-and-paste
without much clean-up from a generic XML editor I've been playing
with:

Along with your usual "use"s, you'll want:

use Gtk2::Pango;

And this code depends on:

use XML::Parser;


my $w = $gladexml->get_widget('textview1');
my $b = $w->get_buffer();


my $tagname = 0;
my $ignoreTags = 
{
    'html' => 1,
    'body' => 1,
    'img' => sub
    {
        my ($buffer, $iter, $args) = @_;
        if (defined($args->{src}))
        {
            my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($args->{src});
            $buffer->insert_pixbuf($iter, $pixbuf);
        }
    },
};

my ($attrTags) = 
{
    'i' => [style => 'italic'],
    'cite' => [style => 'italic'],
    'b' => [weight => Gtk2::Pango::PANGO_WEIGHT_BOLD],
    'small' => [scale => Gtk2::Pango::PANGO_SCALE_SMALL],
    'large' => [scale => Gtk2::Pango::PANGO_SCALE_LARGE],
    'h1' => [scale => Gtk2::Pango::PANGO_SCALE_XX_LARGE],
    'h2' => [scale => Gtk2::Pango::PANGO_SCALE_X_LARGE],
    'h3' => [scale => Gtk2::Pango::PANGO_SCALE_X_LARGE],
    'h4' => [scale => Gtk2::Pango::PANGO_SCALE_X_LARGE],
    'h5' => [scale => Gtk2::Pango::PANGO_SCALE_X_LARGE],
    'h6' => [scale => Gtk2::Pango::PANGO_SCALE_X_LARGE],
};

my $followingSpaceTags =
{
    'br' => "\n",
    'p' => "\n\n",
    'h1' => "\n\n",
    'h2' => "\n\n",
    'h3' => "\n\n",
    'h4' => "\n\n",
    'h5' => "\n\n",
    'h6' => "\n\n",
};


sub handle_start()
{
    my ($buffer, $tagstack, $parser, $tag, %attribs) = @_;

    if (defined($ignoreTags->{$tag}))
    {
        if (ref($ignoreTags->{$tag})
            && ref($ignoreTags->{$tag}) eq 'CODE')
        {
            &{$ignoreTags->{$tag}}($buffer,
                                   $buffer->get_end_iter(),
                                   \%attribs);
        }
    }
    else
    {
        my $node = $tagstack->[$#$tagstack];

        my (@args);

        if ($attrTags->{$tag})
        {
            @args = @{$attrTags->{$tag}};
        }
        else
        {
            @args = (editable => '1');
        }
        print "Creating tag for $tag with tagname $tagname and args: ".join(',', @args)."\n";

        my $buftag;
        $buftag = $buffer->create_tag($tagname,@args);
        $node = [$tag, \%attribs, $buftag, $tagname];
        $tagList->{$buftag} = $node;
        $tagname++;

        push @$tagstack, $node;
    }
}
sub handle_end()
{
    my ($buffer, $tagstack, $parser, $tag) = @_;
    if (!defined($ignoreTags->{$tag}))
    {
        pop @$tagstack;
    }
    if (defined($followingSpaceTags->{$tag}))
    {
        $buffer->insert_with_tags($buffer->get_end_iter(),
                                  $followingSpaceTags->{$tag},
                                  $buftagUneditableWhitespace);
    }
}
sub handle_char()
{
    my ($buffer, $tagstack, $parser, $text) = @_;

    my @tags;
    foreach (@$tagstack)
    {
        push @tags, $_->[2]
            if (defined($_->[2]));
    }

    $text =~ s/\s+/ /g;
    $buffer->insert_with_tags($buffer->get_end_iter(), $text, @tags);
}

my $tagstack = [];
my $p = new XML::Parser(Handlers =>
                        {Start => sub { &handle_start($b, $tagstack, @_) },
                         End   => sub { &handle_end($b, $tagstack, @_) },
                         Char  => sub { &handle_char($b, $tagstack, @_) },
                     });
my $t = $p->parsefile($ENV{'HOME'}
                       .'/Projects/xmledit/test.xml');




So you can run it on some valid XML that looks roughly like:

<html>
<body bgcolor="#234567">
<h1>Some test XML text</h1>

<p>Here's some <i>italic</i> and some <b>bold</b> and <img
 src="/home/danlyke/images/elph0100/img_8454.sm.jpg" /> some <b>bold
<i>italic</i></b> and <i>italic <b>bold</b></i> text.</p>

<p>And here's some <small>small</small> and <large>large</large> text.</p>

</body>
</html>





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]