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