PHP-GTK2 Newsletter

PHP-GTK2 Tips & Techniques
FREE Newsletter
by kksou



Sample Code 155: How to highlight matching html tags in GtkTextView?
Written by kksou   
Monday, 29 January 2007
Problem

You want to highlight enclosing html tags in a GtkTextView as shown below:

How to highlight matching html tags in GtkTextView?


Solution

Sample Code
1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
81   
82   
83   
84   
85   
86   
87   
88   
89   
90   
91   
92   
93   
94   
95   
96   
97   
98   
99   
100   
101   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 240);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Highlight matching HTML tags");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 20);
$title->set_justify(Gtk::JUSTIFY_CENTER);
$alignment = new GtkAlignment(0.5, 0.5, 0, 0);
$alignment->add($title);
$vbox->pack_start($alignment);

$left_start_iter = $left_end_iter = null;
$right_start_iter = $right_end_iter = null;

// Create a new buffer and a new view to show the buffer.
$buffer = new GtkTextBuffer();
$buffer->set_text('<p>This is a test</p>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>');
$view = new GtkTextView();
$view->set_buffer($buffer);
$view->modify_font(new PangoFontDescription("Arial 10"));
$view->set_wrap_mode(Gtk::WRAP_WORD);
$view->connect('button-press-event', 'on_button_press_in_textview');
$view->connect('key-press-event', 'on_key_press_in_textview');

$hbox = new GtkHBox();
$hbox->pack_start($button = new GtkButton('Find enclosing tags'), 0);
$vbox->pack_start($hbox, 0);
$button->connect('clicked', 'on_button', $buffer);

$scrolled_win = new GtkScrolledWindow();
$scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
$vbox->pack_start($scrolled_win);
$scrolled_win->add($view);

$tag_table = $buffer->get_tag_table();
$tag['highlight'] = new GtkTextTag();
$tag['highlight']->set_property('background', "#ffff00");
$tag_table->add($tag['highlight']);

$window->show_all();
Gtk::main();

function find_left_tag($iter, $buffer) {
    global $tag;

    $match_start = $iter->copy();
    $match_end = $iter->copy();

    // check left { first
    $found = $iter->backward_search('<', 0, $match_start,  // note 1
        $match_end, null); 
    if (!$found) return null;

    // check if there's a } on the left
    $iter2 = $match_end->copy();
    $match_start2 = $iter2->copy();
    $match_end2 = $iter2->copy();

    $found2 = $iter2->forward_search('>', 0, $match_start2, // note 2
        $match_end2, null); 

    if ($found2 && $match_start->compare($match_start2)!=-1) return null;

    $buffer->apply_tag($tag['highlight'], $match_start, $match_end2); // note 3
    return array($match_start, $match_end2);
}

function find_right_tag($current_iter, $buffer) {
    global $tag;
    $iter = $current_iter->copy();
    $match_start = $iter->copy();
    $match_end = $iter->copy();

    // check right } first
    $found = $iter->forward_search('<', 0, $match_start, // note 4
        $match_end, null); 
    if (!$found) return null;

    // check if there's a { on the left
    $iter2 = $match_end->copy();
    $match_start2 = $iter2->copy();
    $match_end2 = $iter2->copy();

    $found2 = $iter2->forward_search('>', 0, $match_start2, // note 5
        $match_end2, null); 

    if ($found2 && $match_start->compare($match_start2)!=-1) return null;

    $buffer->apply_tag($tag['highlight'], $match_start, $match_end2); // note 6
    return array($match_start, $match_end2);
}
  • Note that this is only 70% of the sample code. You have to be a registered member to see the entire sample code. Please login or register.
  • Registration is free and immediate.
  • Have some doubt about the registration? Please read this forum article.
Explanation
  1. Search for start of left tag.
  2. Search for end of left tag.
  3. Highlight the left tag.
  4. Search for start of right tag.
  5. Search for end of right tag.
  6. Highlight the right tag.

Note

To make the code easier to understand, I did not put in any error checking here. In your actual implementation, you should check that the start and end tags are matching, otherwise the following might occur:


Related Links

User reviews

There are no user reviews yet.

Note: You have to be a registered member to leave a comment. Free registration here.

 
< Prev   Next >

Copyright © 2006-2008. kksou.com. All Rights Reserved