1 /*
2  *  parseMarkup.c
3  *
4  *  See the file "license.terms" for information on usage and redistribution
5  *  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
6  *
7  */
8 
9 /*
10     History:
11 
12     2011-09  began module development
13 
14 */
15 
16 #include <gtk/gtk.h>
17 #include <stdio.h>
18 #include <string.h>
19 
20 /**
21 \brief  delete substring
22         http://www.timeflash.net/tutorials/cc/16-how-to-remove-a-substring-from-a-string-in-c-and-c.html
23 **/
strdstr(char * str,char * substr)24 char* strdstr ( char* str, char* substr )
25 {
26 	int i, j, p, match;
27 
28 	char newstr [strlen ( str ) ];
29 
30 	for ( i = 0 ; i < strlen ( str ) ; ++i )
31 	{
32 		if ( str[i] == substr[j] )
33 		{
34 			match = 1;
35 
36 			for ( j = 1; j < strlen ( substr ); ++j )
37 			{
38 				if ( str[i+j] != substr[j] )
39 				{
40 					j = 0;
41 					match = 0;
42 				}
43 			}
44 
45 			if ( match )
46 			{
47 				i += strlen ( substr ) - 1;
48 				j = 0;
49 			}
50 		}
51 
52 		else
53 		{
54 			newstr[p] = str[i];
55 			++p;
56 		}
57 	}
58 
59 	newstr[p] = '\0';
60 
61 	return newstr;
62 }
63 
64 
65 /**
66     String concatenation
67     http://rosettacode.org/wiki/String_concatenation#C
68 **/
sconcat(const char * s1,const char * s2)69 static char *sconcat ( const char *s1, const char *s2 )
70 {
71 	char *s0 = ( char * ) malloc ( strlen ( s1 ) + strlen ( s2 ) + 1 );
72 	strcpy ( s0, s1 );
73 	strcat ( s0, s2 );
74 	return s0;
75 }
76 
77 /**
78     Strip a set of characters from a string
79     http://rosettacode.org/wiki/Strip_a_set_of_characters_from_a_string#C
80     done
81 **/
82 /* checks if character exists in list */
contains(char character,char * list)83 static int contains ( char character, char * list )
84 {
85 	while ( *list )
86 	{
87 		if ( character == *list )
88 			return 1;
89 
90 
91 		++ list;
92 	}
93 
94 	return 0;
95 }
96 
97 /* removes all chars from string */
_strip_chars(const char * string,const char * chars)98 static char * _strip_chars ( const char * string, const char * chars )
99 {
100 
101 	char * newstr = malloc ( strlen ( string ) );
102 	int counter = 0;
103 
104 	while ( *string )
105 	{
106 		if ( contains ( *string, chars ) != 1 )
107 		{
108 			newstr[ counter ] = *string;
109 			++ counter;
110 		}
111 
112 		++ string;
113 	}
114 
115 	return newstr;
116 }
117 
118 /**
119 \brief
120 **/
strip_chars(char * string,char * chars)121 static int strip_chars ( char * string, char * chars )
122 {
123 
124 	int i = 0;
125 	int j = strlen ( string );
126 	int l = strlen ( chars );
127 
128 	char newstr[strlen ( string ) ];
129 	int c = 0;
130 	int k = 0;
131 
132 	strcpy ( newstr, string );
133 
134 	char *f;
135 	f = string;
136 
137 	/* search through string till match found */
138 	while ( i < j )
139 	{
140 
141 		/* check for chars, in string */
142 		if ( strncmp ( f + i, chars, l ) != -1 )
143 		{
144 			g_print ( "got tag %s\n", chars );
145 			i += l - 1;
146 			/* remove matching tag */
147 		}
148 
149 		else
150 		{
151 			/*
152 			newstr[c] = string[i];
153 			g_print ( "plain text %c\n", newstr[c] );
154 			newstr[c+1] = '\0';
155 			g_print ( "      string = %s\n", newstr );
156 			*/
157 			c++;
158 			i++;
159 
160 		}
161 
162 	}
163 
164 	g_print ( "string = %s : newstr = %s\n", string, newstr );
165 
166 	strcpy ( string, newstr );
167 
168 	string[j] = '\0';
169 
170 	return c;
171 }
172 
173 /**
174     search for first occurance of p in s, starting from i
175     done
176 **/
strnfrst(char * s,char * p,int i)177 static int strnfrst ( char *s, char *p, int i )
178 {
179 	char *f;
180 	int l;
181 
182 	l = strlen ( p ); /* length of search string */
183 	f = s + i;
184 
185 	/* search through string till match found */
186 	while ( *f != '\0' )
187 	{
188 		if ( !strncmp ( f, p, l ) )
189 			return f - s;
190 
191 		f++;
192 	}
193 
194 	return -1;
195 }
196 
197 /**
198     extract a range of characters from string s starting from position a to position b
199     done
200 **/
strrng(char * dest,const char * src,int a,int b)201 static char *strrng ( char *dest, const char *src, int a, int b )
202 {
203 	unsigned i, j;
204 
205 	j = 0;
206 
207 	for ( i = a; i < b; i++ )
208 	{
209 		dest[j++] = src[i];
210 	}
211 
212 	dest[j] = '\0';
213 	return dest;
214 
215 }
216 
217 /*
218 char *strcpy(char *dest, const char *src)
219 {
220   unsigned i;
221   for (i=0; src[i] != '\0'; ++i)
222     dest[i] = src[i];
223   dest[i] = '\0';
224   return dest;
225 }
226 */
227 
228 /**
229     gettag
230     get name of next tag in string, starting at position i
231 **/
_getTag(char * str,char * tag,int i)232 static int _getTag ( char *str, char *tag, int i )
233 {
234 
235 	int a, b;
236 
237 	a = strnfrst ( str, "</", i );
238 
239 	if ( a )
240 		a = strnfrst ( str, "<", i );
241 
242 	b = strnfrst ( str, ">", a + 1 );
243 
244 	strrng ( tag, str, a, b + 1 );
245 
246 	return a;
247 }
248 
249 
250 /**
251     gettag
252     get name of next tag in string, starting at position i
253     return updated value of i
254 
255     test-string = "<b>bold</b>   <i>italic</i>   <u>underline</u>   <s>strikethrough</s>"
256 
257 **/
getTag(char * str,char * tag,int i)258 static int getTag ( char *str, char *tag, int i )
259 {
260 
261 	int j;
262 
263 	if ( strcmp ( str + i, "<" ) )
264 	{
265 		/* handle a tag */
266 		j = strnfrst ( str, ">", i );
267 		//strrng ( tag, str, ++i, j );
268 		strrng ( tag, str, i, ++j );
269 		return j;
270 	}
271 
272 	return ++i;
273 }
274 
275 /**
276 \brief
277 **/
getText(char * str,char * txt,int i)278 static int getText ( char *str, char *txt, int i )
279 {
280 
281 	int j;
282 
283 	j = strnfrst ( str, "<", i );
284 	strrng ( txt, str, i, j );
285 	return j;
286 }
287 
288 /**
289 \brief
290 **/
gnoclParseMarkup(GtkTextBuffer * buffer,GtkTextIter * iter,char * markup_text)291 int gnoclParseMarkup ( GtkTextBuffer *buffer, GtkTextIter *iter, char *markup_text )
292 {
293 
294 	/* interate through pango string, determine, text or markup */
295 	int iter, start, end;
296 	start = 0;
297 	end = strlen ( markup_text );
298 
299 	const char tag[256];
300 	char txt[end];
301 
302 	const char *tags = " ";
303 
304 	iter = start;
305 
306 	while ( iter <= end )
307 	{
308 		iter = getTag ( markup_text, tag, iter );
309 		g_print ( "tag  = '%s'\n", tag );
310 
311 		/* tagoff? */
312 		if ( strstr ( tag, "/" ) != NULL  )
313 		{
314 			g_print ( "tagOff %s\n", tag );
315 			/* remove matching tag from the list */
316 			//strip_chars ( tag, "/" );
317 			strip_chars ( tags, tag );
318 		}
319 
320 		else
321 		{
322 			g_print ( "tagOn %s\n", tag );
323 			/* add new tag to the list */
324 			tags = sconcat ( tags, tag );
325 			tags = sconcat ( tags, " " );
326 		}
327 
328 		if ( iter == end ) break; /* prevent error */
329 
330 		iter = getText ( markup_text, txt, iter );
331 		g_print ( "text = '%s'\n", txt );
332 
333 		gtk_text_buffer_insert_with_tags_by_name ( buffer, &iter, gnoclGetString ( objv[cmdNo+1] ), -1, "b i" );
334 
335 	}
336 
337 	g_print ( "taglist= %s\n", tags );
338 
339 	return 0;
340 }
341