Friday, September 30, 2011

Return to coding!

Its been almost a month since a last posting. How time flies. Most of my time has been taken up between making some final adjustments to my Ph.D thesis prior to submission and chasing up a whole pile of work related matters. But now, for a while at least, I can give some more attention to Gnocl. The last issue that I was working was inserting/retrieving Pango markup strings with a GtkTextBuffer. After solving something of a glitch in adding tags to single characters (I'd completely forgotten that iters are invalid after changes to the content of text buffer. Resolved the problem through the use of markers as in function that I've just added to the code:

        GtkTextMark *tagStart, *tagEnd;
        GtkTextIter start, end;
       
        tagStart  = gtk_text_buffer_create_mark (buffer,"tagStart", iter, 1);           
                
        gtk_text_buffer_insert  (buffer, iter, txt, -1);

        tagEnd = gtk_text_buffer_get_insert(buffer);

        applyTags (buffer, tag, tagStart, tagEnd);



Where:

void applyTags (GtkTextBuffer *buffer, gchar *tag, GtkTextMark *tagStart, GtkTextMark *tagEnd) {
   
        GtkTextIter start, end;
   
        gtk_text_buffer_get_iter_at_mark(buffer,&start,tagStart);
        gtk_text_buffer_get_iter_at_mark(buffer,&end,tagEnd);
        gtk_text_buffer_apply_tag_by_name  (buffer,tag, &start,&end);
   
}


At the moment single tags are fine, ie bold but it might be necessary to nest tags, ie bold-underline. The next question is, should I pass a string of tag names, or a linked-list? I'll think about this one tomorrow!



Thursday, September 01, 2011

More on generating pango strings...

This is not so easy a 'nut to crack'. I've noticed that the solution that I've come up with so far fails to implement nested markup, ie <b> <s> text </s></b>. Conversely, getting the <span> </span> block is an issue too! Clearly there is a need for this functionality, but there is no clear solution that I can find. The Gimp developers are working on something similar but I notice that they have problems with <span> too!

So, I've gone back to basics. Rather than relying the pango string parser, I'll put something together of my own. Today I've been working on some extra string funcs. Here's what I've produced so far:

/*
gcc -o first first.c
*/

#include <stdio.h>
#include <string.h>
 
/**
    search for first occurance of p in s, starting from i
    done
**/
int strnfrst(char *s, char *p, int i)
{
        char *f;
        int l;
       
        l = strlen(p);  /* length of search string */
        f = s+i;
 
        /* search through string till match found */
        while (*f != '\0') {
                if ( !strncmp(f, p, l) ) {
                    return f-s;
                }
                f++;
        }
        return -1;
}

/**
    extract a range of characters from string s starting from position a to position b
    done
**/
char *strrng (char *dest, const char *src, int a, int b) {
  unsigned i,j;
 
  j=0;
  for (i=a; i<b; i++)
  {
    dest[j++] = src[i];
  }
  dest[j] = '\0';
  return dest;

}

/*
char *strcpy(char *dest, const char *src)
{
  unsigned i;
  for (i=0; src[i] != '\0'; ++i)
    dest[i] = src[i];
  dest[i] = '\0';
  return dest;
}
*/

/**
    gettag
    get name of next tag in string, starting at position i
**/
int getTag (char *str, char *tag, int i) {

        int a,b;
       
        a = strnfrst(str,"</",i);
       
        if (a) {
            a = strnfrst(str,"<",i);
        }
       
        b = strnfrst(str,">",a+1);

        strrng(tag,str,a,b+1);
       
        return a;
}


/**
    test
**/
int main()
{

        // p in s, starting from i
        char str1[] = "abCdefC";
       
        int i = strnfrst(str1, "C", 0);
        int j = strnfrst(str1, "C", i+1);
        printf("locations %d %d in %s\n",i,j,str1);

        char buf[32];

        /* get the characters between the Cs */
        printf("'%s' lies between chars %d and %d\n",strrng (buf,str1, i+1,j),i+1,j);

        char str2[] = "<b>bold</b>   <i>italic</i>   <u>underline</u>   <s>strikethrough</s>";

        printf("text range 3 thro' 8 = '%s'\n", strrng (buf, str2, 3, 8));

        /* get the next tag in the string */
        i= getTag (str2, buf, 3);
        printf("next tag %s at pos %d\n", buf, i);
       
        i=getTag (str2, buf, i+1);
        printf("next tag %s at pos %d\n", buf, i);

        /* parse the whole string */
        // get the position of the first tag toggle
        i = getTag (str2, buf, 0);
        printf("%d %s\n",i,buf);
       
        // parse the remainder of the string
        while ( i < strlen(str2) ) {
            i=getTag (str2, buf, i+1);
            printf("%d %s\n",i,buf);
           
        }

        return 0;

}