]> Pileus Git - ~andy/gtk/blob - tests/testtextbuffer.c
change demo install dir to datadir/gtk+-2.0/demo
[~andy/gtk] / tests / testtextbuffer.c
1 /* Simplistic test suite */
2
3 #include <stdio.h>
4
5 #include <gtk/gtk.h>
6 #include "gtktextbtree.h"
7
8 static void fill_buffer (GtkTextBuffer *buffer);
9
10 static void run_tests (GtkTextBuffer *buffer);
11
12 int
13 main (int argc, char** argv)
14 {
15   GtkTextBuffer *buffer;
16   int n;
17   gunichar ch;
18   GtkTextIter start, end;
19
20   gtk_init (&argc, &argv);
21
22   /* Check UTF8 unknown char thing */
23   g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
24   ch = g_utf8_get_char (gtk_text_unknown_char_utf8);
25   g_assert (ch == gtk_text_unknown_char);
26
27   /* First, we turn on btree debugging. */
28   gtk_debug_flags |= GTK_DEBUG_TEXT;
29
30   /* Create a buffer */
31   buffer = gtk_text_buffer_new (NULL);
32
33   /* Check that buffer starts with one empty line and zero chars */
34
35   n = gtk_text_buffer_get_line_count (buffer);
36   if (n != 1)
37     g_error ("%d lines, expected 1", n);
38
39   n = gtk_text_buffer_get_char_count (buffer);
40   if (n != 1)
41     g_error ("%d chars, expected 1", n);
42
43   /* Run gruesome alien test suite on buffer */
44   run_tests (buffer);
45
46   /* Put stuff in the buffer */
47
48   fill_buffer (buffer);
49
50   /* Subject stuff-bloated buffer to further torment */
51   run_tests (buffer);
52
53   /* Delete all stuff from the buffer */
54   gtk_text_buffer_get_bounds (buffer, &start, &end);
55   gtk_text_buffer_delete (buffer, &start, &end);
56
57   /* Check buffer for emptiness (note that a single
58      empty line always remains in the buffer) */
59   n = gtk_text_buffer_get_line_count (buffer);
60   if (n != 1)
61     g_error ("%d lines, expected 1", n);
62
63   n = gtk_text_buffer_get_char_count (buffer);
64   if (n != 1)
65     g_error ("%d chars, expected 1", n);
66
67   run_tests (buffer);
68
69   g_object_unref (G_OBJECT (buffer));
70   
71   g_print ("All tests passed.\n");
72
73   return 0;
74 }
75
76 static gint
77 count_toggles_at_iter (GtkTextIter *iter,
78                        GtkTextTag  *of_tag)
79 {
80   GSList *tags;
81   GSList *tmp;
82   gint count = 0;
83   
84   /* get toggle-ons and toggle-offs */
85   tags = gtk_text_iter_get_toggled_tags (iter, TRUE);
86   tags = g_slist_concat (tags,
87                          gtk_text_iter_get_toggled_tags (iter, FALSE));
88   
89   tmp = tags;
90   while (tmp != NULL)
91     {
92       if (of_tag == NULL)
93         ++count;
94       else if (of_tag == tmp->data)
95         ++count;
96       
97       tmp = g_slist_next (tmp);
98     }
99   
100   g_slist_free (tags);
101
102   return count;
103 }
104      
105 static gint
106 count_toggles_in_buffer (GtkTextBuffer *buffer,
107                          GtkTextTag    *of_tag)
108 {
109   GtkTextIter iter;
110   gint count = 0;
111   
112   gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
113   do
114     {
115       count += count_toggles_at_iter (&iter, of_tag);
116     }
117   while (gtk_text_iter_next_char (&iter));
118
119   /* Do the end iterator, because forward_char won't return TRUE
120    * on it.
121    */
122   count += count_toggles_at_iter (&iter, of_tag);
123   
124   return count;
125 }
126
127 static void
128 check_specific_tag (GtkTextBuffer *buffer,
129                     const gchar   *tag_name)
130 {
131   GtkTextIter iter;
132   GtkTextTag *tag;
133   gboolean state;
134   gint count;
135   gint buffer_count;
136   gint last_offset;
137   
138   tag = gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table (buffer),
139                                    tag_name);
140
141   buffer_count = count_toggles_in_buffer (buffer, tag);
142   
143   state = FALSE;
144   count = 0;
145
146   last_offset = -1;
147   gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
148   if (gtk_text_iter_toggles_tag (&iter, tag) ||
149       gtk_text_iter_forward_to_tag_toggle (&iter, tag))
150     {
151       do
152         {
153           gint this_offset;
154           
155           ++count;
156
157           this_offset = gtk_text_iter_get_offset (&iter);
158
159           if (this_offset <= last_offset)
160             g_error ("forward_to_tag_toggle moved in wrong direction");
161
162           last_offset = this_offset;
163           
164           if (gtk_text_iter_begins_tag (&iter, tag))
165             {
166               if (state)
167                 g_error ("Tag %p is already on, and was toggled on?", tag);
168               state = TRUE;
169             }          
170           else if (gtk_text_iter_ends_tag (&iter, tag))
171             {
172               if (!state)
173                 g_error ("Tag %p toggled off, but wasn't toggled on?", tag);
174               state = FALSE;
175             }
176           else
177             g_error ("forward_to_tag_toggle went to a location without a toggle");
178         }
179       while (gtk_text_iter_forward_to_tag_toggle (&iter, tag));
180     }
181
182   if (count != buffer_count)
183     g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
184              buffer_count, count);
185   
186   state = FALSE;
187   count = 0;
188   
189   gtk_text_buffer_get_last_iter (buffer, &iter);
190   last_offset = gtk_text_iter_get_offset (&iter);
191   if (gtk_text_iter_toggles_tag (&iter, tag) ||
192       gtk_text_iter_backward_to_tag_toggle (&iter, tag))
193     {
194       do
195         {
196           gint this_offset;
197           
198           ++count;
199
200           this_offset = gtk_text_iter_get_offset (&iter);
201           
202           if (this_offset >= last_offset)
203             g_error ("backward_to_tag_toggle moved in wrong direction");
204           
205           last_offset = this_offset;
206
207           if (gtk_text_iter_begins_tag (&iter, tag))
208             {
209               if (!state)
210                 g_error ("Tag %p wasn't on when we got to the on toggle going backward?", tag);
211               state = FALSE;
212             }
213           else if (gtk_text_iter_ends_tag (&iter, tag))
214             {
215               if (state)
216                 g_error ("Tag %p off toggle, but we were already inside a tag?", tag);
217               state = TRUE;
218             }
219           else
220             g_error ("backward_to_tag_toggle went to a location without a toggle");
221         }
222       while (gtk_text_iter_backward_to_tag_toggle (&iter, tag));
223     }
224
225   if (count != buffer_count)
226     g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
227              buffer_count, count);
228
229 }
230
231 static void
232 run_tests (GtkTextBuffer *buffer)
233 {
234   GtkTextIter iter;
235   GtkTextIter start;
236   GtkTextIter end;
237   GtkTextIter mark;
238   gint i, j;
239   gint num_chars;
240   GtkTextMark *bar_mark;
241   GtkTextTag *tag;
242   GHashTable *tag_states;
243   gint count;
244   gint buffer_count;
245   
246   gtk_text_buffer_get_bounds (buffer, &start, &end);
247
248   /* Check that walking the tree via chars and via iterators produces
249    * the same number of indexable locations.
250    */
251   num_chars = gtk_text_buffer_get_char_count (buffer);
252   iter = start;
253   bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
254   i = 0;
255   while (i < num_chars)
256     {
257       GtkTextIter current;
258       GtkTextMark *foo_mark;
259
260       gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
261
262       if (!gtk_text_iter_equal (&iter, &current))
263         {
264           g_error ("get_char_index didn't return current iter");
265         }
266
267       j = gtk_text_iter_get_offset (&iter);
268
269       if (i != j)
270         {
271           g_error ("iter converted to %d not %d", j, i);
272         }
273
274       /* get/set mark */
275       gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
276
277       if (!gtk_text_iter_equal (&iter, &mark))
278         {
279           gtk_text_iter_spew (&iter, "iter");
280           gtk_text_iter_spew (&mark, "mark");
281           g_error ("Mark not moved to the right place.");
282         }
283
284       foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
285       gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
286       gtk_text_buffer_delete_mark (buffer, foo_mark);
287
288       if (!gtk_text_iter_equal (&iter, &mark))
289         {
290           gtk_text_iter_spew (&iter, "iter");
291           gtk_text_iter_spew (&mark, "mark");
292           g_error ("Mark not created in the right place.");
293         }
294
295       if (gtk_text_iter_is_last (&iter))
296         g_error ("iterators ran out before chars (offset %d of %d)",
297                  i, num_chars);
298
299       gtk_text_iter_next_char (&iter);
300
301       gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
302
303       ++i;
304     }
305
306   if (!gtk_text_iter_equal (&iter, &end))
307     g_error ("Iterating over all chars didn't end with the end iter");
308
309   /* Do the tree-walk backward
310    */
311   num_chars = gtk_text_buffer_get_char_count (buffer);
312   gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
313
314   gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
315
316   i = num_chars;
317
318   if (!gtk_text_iter_equal (&iter, &end))
319     g_error ("iter at char -1 is not equal to the end iterator");
320
321   while (i >= 0)
322     {
323       GtkTextIter current;
324       GtkTextMark *foo_mark;
325
326       gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
327
328       if (!gtk_text_iter_equal (&iter, &current))
329         {
330           g_error ("get_char_index didn't return current iter while going backward");
331         }
332       j = gtk_text_iter_get_offset (&iter);
333
334       if (i != j)
335         {
336           g_error ("going backward, iter converted to %d not %d", j, i);
337         }
338
339       /* get/set mark */
340       gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
341
342       if (!gtk_text_iter_equal (&iter, &mark))
343         {
344           gtk_text_iter_spew (&iter, "iter");
345           gtk_text_iter_spew (&mark, "mark");
346           g_error ("Mark not moved to the right place.");
347         }
348
349       foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
350       gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
351       gtk_text_buffer_delete_mark (buffer, foo_mark);
352
353       if (!gtk_text_iter_equal (&iter, &mark))
354         {
355           gtk_text_iter_spew (&iter, "iter");
356           gtk_text_iter_spew (&mark, "mark");
357           g_error ("Mark not created in the right place.");
358         }
359
360       if (i > 0)
361         {
362           if (!gtk_text_iter_prev_char (&iter))
363             g_error ("iterators ran out before char indexes");
364
365           gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
366         }
367       else
368         {
369           if (gtk_text_iter_prev_char (&iter))
370             g_error ("went backward from 0?");
371         }
372
373       --i;
374     }
375
376   if (!gtk_text_iter_equal (&iter, &start))
377     g_error ("Iterating backward over all chars didn't end with the start iter");
378
379   /*
380    * Check that get_line_count returns the same number of lines
381    * as walking the tree by line
382    */
383   i = 1; /* include current (first) line */
384   gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
385   while (gtk_text_iter_forward_line (&iter))
386     ++i;
387
388   if (i != gtk_text_buffer_get_line_count (buffer))
389     g_error ("Counted %d lines, buffer has %d", i,
390              gtk_text_buffer_get_line_count (buffer));
391
392   /*
393    * Check that moving over tag toggles thinks about working.
394    */
395
396   buffer_count = count_toggles_in_buffer (buffer, NULL);
397   
398   tag_states = g_hash_table_new (NULL, NULL);
399   count = 0;
400   
401   gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
402   if (gtk_text_iter_toggles_tag (&iter, NULL) ||
403       gtk_text_iter_forward_to_tag_toggle (&iter, NULL))
404     {
405       do
406         {
407           GSList *tags;
408           GSList *tmp;
409           gboolean found_some = FALSE;
410           
411           /* get toggled-on tags */
412           tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
413
414           if (tags)
415             found_some = TRUE;
416           
417           tmp = tags;
418           while (tmp != NULL)
419             {
420               ++count;
421               
422               tag = tmp->data;
423               
424               if (g_hash_table_lookup (tag_states, tag))
425                 g_error ("Tag %p is already on, and was toggled on?", tag);
426
427               g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
428           
429               tmp = g_slist_next (tmp);
430             }
431
432           g_slist_free (tags);
433       
434           /* get toggled-off tags */
435           tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
436
437           if (tags)
438             found_some = TRUE;
439           
440           tmp = tags;
441           while (tmp != NULL)
442             {
443               ++count;
444               
445               tag = tmp->data;
446
447               if (!g_hash_table_lookup (tag_states, tag))
448                 g_error ("Tag %p is already off, and was toggled off?", tag);
449
450               g_hash_table_remove (tag_states, tag);
451           
452               tmp = g_slist_next (tmp);
453             }
454
455           g_slist_free (tags);
456
457           if (!found_some)
458             g_error ("No tags found going forward to tag toggle.");
459
460         }
461       while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL));
462     }
463   
464   g_hash_table_destroy (tag_states);
465
466   if (count != buffer_count)
467     g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
468              buffer_count, count);
469   
470   /* Go backward; here TRUE in the hash means we saw
471    * an off toggle last.
472    */
473   
474   tag_states = g_hash_table_new (NULL, NULL);
475   count = 0;
476   
477   gtk_text_buffer_get_last_iter (buffer, &iter);
478   if (gtk_text_iter_toggles_tag (&iter, NULL) ||
479       gtk_text_iter_backward_to_tag_toggle (&iter, NULL))
480     {
481       do
482         {
483           GSList *tags;
484           GSList *tmp;
485           gboolean found_some = FALSE;
486           
487           /* get toggled-off tags */
488           tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
489
490           if (tags)
491             found_some = TRUE;
492           
493           tmp = tags;
494           while (tmp != NULL)
495             {
496               ++count;
497               
498               tag = tmp->data;
499
500               if (g_hash_table_lookup (tag_states, tag))
501                 g_error ("Tag %p has two off-toggles in a row?", tag);
502           
503               g_hash_table_insert (tag_states, tag, GINT_TO_POINTER (TRUE));
504           
505               tmp = g_slist_next (tmp);
506             }
507
508           g_slist_free (tags);
509       
510           /* get toggled-on tags */
511           tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
512
513           if (tags)
514             found_some = TRUE;
515           
516           tmp = tags;
517           while (tmp != NULL)
518             {
519               ++count;
520               
521               tag = tmp->data;
522
523               if (!g_hash_table_lookup (tag_states, tag))
524                 g_error ("Tag %p was toggled on, but saw no off-toggle?", tag);
525
526               g_hash_table_remove (tag_states, tag);
527           
528               tmp = g_slist_next (tmp);
529             }
530
531           g_slist_free (tags);
532
533           if (!found_some)
534             g_error ("No tags found going backward to tag toggle.");
535         }
536       while (gtk_text_iter_backward_to_tag_toggle (&iter, NULL));
537     }
538   
539   g_hash_table_destroy (tag_states);
540
541   if (count != buffer_count)
542     g_error ("Counted %d tags iterating by char, %d iterating by tag toggle\n",
543              buffer_count, count);
544
545   check_specific_tag (buffer, "fg_red");
546   check_specific_tag (buffer, "bg_green");
547   check_specific_tag (buffer, "front_tag");
548   check_specific_tag (buffer, "center_tag");
549   check_specific_tag (buffer, "end_tag");
550 }
551
552
553 static char  *book_closed_xpm[] = {
554 "16 16 6 1",
555 "       c None s None",
556 ".      c black",
557 "X      c red",
558 "o      c yellow",
559 "O      c #808080",
560 "#      c white",
561 "                ",
562 "       ..       ",
563 "     ..XX.      ",
564 "   ..XXXXX.     ",
565 " ..XXXXXXXX.    ",
566 ".ooXXXXXXXXX.   ",
567 "..ooXXXXXXXXX.  ",
568 ".X.ooXXXXXXXXX. ",
569 ".XX.ooXXXXXX..  ",
570 " .XX.ooXXX..#O  ",
571 "  .XX.oo..##OO. ",
572 "   .XX..##OO..  ",
573 "    .X.#OO..    ",
574 "     ..O..      ",
575 "      ..        ",
576 "                "};
577
578 static void
579 fill_buffer (GtkTextBuffer *buffer)
580 {
581   GtkTextTag *tag;
582   GdkColor color, color2;
583   GtkTextIter iter;
584   GtkTextIter iter2;
585   GdkPixbuf *pixbuf;
586   int i;
587
588   tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
589
590   color.red = color.green = 0;
591   color.blue = 0xffff;
592   color2.red = 0xfff;
593   color2.blue = 0x0;
594   color2.green = 0;
595   gtk_object_set (GTK_OBJECT (tag),
596                  "foreground_gdk", &color,
597                  "background_gdk", &color2,
598                  "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
599                  NULL);
600
601   tag = gtk_text_buffer_create_tag (buffer, "fg_red");
602
603   color.blue = color.green = 0;
604   color.red = 0xffff;
605   gtk_object_set (GTK_OBJECT (tag),
606                  "offset", -4,
607                  "foreground_gdk", &color,
608                  NULL);
609
610   tag = gtk_text_buffer_create_tag (buffer, "bg_green");
611
612   color.blue = color.red = 0;
613   color.green = 0xffff;
614   gtk_object_set (GTK_OBJECT (tag),
615                  "background_gdk", &color,
616                  "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
617                  NULL);
618
619   pixbuf = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
620
621   g_assert (pixbuf != NULL);
622
623   i = 0;
624   while (i < 10)
625     {
626       gchar *str;
627
628       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
629
630       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
631
632       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
633
634       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
635
636       str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
637                             i);
638
639       gtk_text_buffer_insert (buffer, &iter, str, -1);
640
641       g_free (str);
642
643       gtk_text_buffer_insert (buffer, &iter,
644                               "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
645                               /* This is UTF8 stuff, Emacs doesn't
646                                  really know how to display it */
647                               "Spanish (Español) ¡Hola! / French (Français) Bonjour, Salut / German (Deutsch Süd) Grüß Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash)  (ภาษาไทย)  สวัสดีครับ, สวัสดีค่ะ\n",
648                               -1);
649
650       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
651       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
652
653       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
654
655       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
656
657       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
658
659       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
660
661       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
662
663       gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf);
664
665       gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
666       iter2 = iter;
667       gtk_text_iter_forward_chars (&iter2, 10);
668
669       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
670
671       gtk_text_iter_forward_chars (&iter, 7);
672       gtk_text_iter_forward_chars (&iter2, 10);
673
674       gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
675
676       gtk_text_iter_forward_chars (&iter, 12);
677       gtk_text_iter_forward_chars (&iter2, 10);
678
679       gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
680
681       gtk_text_iter_forward_chars (&iter, 10);
682       gtk_text_iter_forward_chars (&iter2, 15);
683
684       gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
685       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
686
687       gtk_text_iter_forward_chars (&iter, 20);
688       gtk_text_iter_forward_chars (&iter2, 20);
689
690       gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
691       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
692
693       gtk_text_iter_backward_chars (&iter, 25);
694       gtk_text_iter_forward_chars (&iter2, 5);
695
696       gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
697       gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
698
699       gtk_text_iter_forward_chars (&iter, 15);
700       gtk_text_iter_backward_chars (&iter2, 10);
701
702       gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
703       gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);
704
705       ++i;
706     }
707
708   /* Put in tags that are just at the beginning, and just near the end,
709    * and just near the middle.
710    */
711   tag = gtk_text_buffer_create_tag (buffer, "front_tag");
712   gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3);
713   gtk_text_buffer_get_iter_at_offset (buffer, &iter2, 300);
714
715   gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
716   
717   tag = gtk_text_buffer_create_tag (buffer, "end_tag");
718   gtk_text_buffer_get_last_iter (buffer, &iter2);
719   gtk_text_iter_backward_chars (&iter2, 12);
720   iter = iter2;
721   gtk_text_iter_backward_chars (&iter, 157);
722
723   gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);
724   
725   tag = gtk_text_buffer_create_tag (buffer, "center_tag");
726   gtk_text_buffer_get_iter_at_offset (buffer, &iter,
727                                       gtk_text_buffer_get_char_count (buffer)/2);
728   gtk_text_iter_backward_chars (&iter, 37);
729   iter2 = iter;
730   gtk_text_iter_forward_chars (&iter2, 57);
731
732   gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2);  
733
734   gdk_pixbuf_unref (pixbuf);
735 }