]> git.sur5r.net Git - glabels/blob - glabels1/src/text_node.c
2009-09-22 Jim Evins <evins@snaught.com>
[glabels] / glabels1 / src / text_node.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  text_node.c:  text node module
5  *
6  *  Copyright (C) 2001-2002  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <config.h>
24
25 #include "text_node.h"
26
27 #include "merge.h"
28
29 #include "debug.h"
30
31 /*===========================================*/
32 /* Local function prototypes                 */
33 /*===========================================*/
34
35 static glTextNode *extract_text_node (gchar * text, gint * n);
36
37 \f
38 /*--------------------------------------------------------------------------*/
39 /* Expand single node into representative string.                           */
40 /*--------------------------------------------------------------------------*/
41 gchar *
42 gl_text_node_expand (glTextNode * text_node,
43                      glMergeRecord * record)
44 {
45         gchar *text;
46
47         if (text_node->field_flag) {
48                 text = gl_merge_eval_key (text_node->data, record);
49                 if (text != NULL) {
50                         return text;
51                 } else {
52                         return g_strdup_printf ("FIELD{%s}", text_node->data);
53                 }
54         } else {
55                 return g_strdup (text_node->data);
56         }
57 }
58
59 /*--------------------------------------------------------------------------*/
60 /* Create a single text node from given text.                               */
61 /*--------------------------------------------------------------------------*/
62 glTextNode *
63 gl_text_node_new_from_text (gchar * text)
64 {
65         gint n;
66
67         return extract_text_node (text, &n);
68 }
69
70 /*--------------------------------------------------------------------------*/
71 /* PRIVATE.  Create a single text node from given text. n = characters used */
72 /*--------------------------------------------------------------------------*/
73 static glTextNode *
74 extract_text_node (gchar * text,
75                    gint * n)
76 {
77         glTextNode *text_node;
78         gchar *p;
79         gint m;
80
81         text_node = g_new0 (glTextNode, 1);
82
83         if (strncmp (text, "FIELD{", strlen ("FIELD{")) == 0) {
84                 /* We are at the beginning of a "FIELD" node */
85                 text_node->field_flag = TRUE;
86                 *n = strlen ("FIELD{");
87                 text += *n;
88                 for (p = text, m = 0; *p != 0; p++, m++, (*n)++) {
89                         if (*p == '}') {
90                                 (*n)++;
91                                 break;
92                         }
93                 }
94                 text_node->data = g_strndup (text, m);
95         } else {
96                 /* We are at the beginning of a literal node */
97                 text_node->field_flag = FALSE;
98                 for (p = text, *n = 0; *p != 0; p++, (*n)++) {
99                         if (strncmp (p, "FIELD{", strlen ("FIELD{")) == 0)
100                                 break;
101                         if (*p == '\n')
102                                 break;
103                 }
104                 text_node->data = g_strndup (text, *n);
105         }
106
107         return text_node;
108 }
109
110 /*--------------------------------------------------------------------------*/
111 /* Free a single text node.                                                 */
112 /*--------------------------------------------------------------------------*/
113 void
114 gl_text_node_free (glTextNode ** text_node)
115 {
116         g_free ((*text_node)->data);
117         (*text_node)->data = NULL;
118         g_free (*text_node);
119         *text_node = NULL;
120 }
121
122 /*--------------------------------------------------------------------------*/
123 /* Expand text lines into single string.                                    */
124 /*--------------------------------------------------------------------------*/
125 gchar *
126 gl_text_node_lines_expand (GList * lines,
127                            glMergeRecord * record)
128 {
129         GList *p_line, *p_node;
130         glTextNode *text_node;
131         gchar *text, *old_text, *expanded_node;
132
133         text = g_strdup ("");   /* prime pointer for concatenation */
134         for (p_line = lines; p_line != NULL; p_line = p_line->next) {
135                 for (p_node = (GList *) p_line->data; p_node != NULL;
136                      p_node = p_node->next) {
137                         text_node = (glTextNode *) p_node->data;
138                         old_text = text;
139                         expanded_node = gl_text_node_expand (text_node, record);
140                         text = g_strconcat (text, expanded_node, NULL);
141                         g_free (old_text);
142                         g_free (expanded_node);
143                 }
144                 old_text = text;
145                 text = g_strconcat (text, "\n", NULL);
146                 g_free (old_text);
147         }
148
149         return text;
150 }
151
152 /*--------------------------------------------------------------------------*/
153 /* Parse a string back into text lines.                                     */
154 /*--------------------------------------------------------------------------*/
155 GList *
156 gl_text_node_lines_new_from_text (gchar * text)
157 {
158         GList *lines, *nodes;
159         glTextNode *text_node;
160         gchar *p;
161         gint n;
162
163         lines = NULL;
164         nodes = NULL;
165         for (p = text; *p != 0; p += n) {
166                 if (*p != '\n') {
167                         text_node = extract_text_node (p, &n);
168                         nodes = g_list_append (nodes, text_node);
169                 } else {
170                         n = 1;
171                         lines = g_list_append (lines, nodes);
172                         nodes = NULL;
173                 }
174         }
175         if (*(p - 1) != '\n') {
176                 lines = g_list_append (lines, nodes);
177         }
178
179         return lines;
180 }
181
182 /*--------------------------------------------------------------------------*/
183 /* Free a list of text lines.                                               */
184 /*--------------------------------------------------------------------------*/
185 void
186 gl_text_node_lines_free (GList ** lines)
187 {
188         GList *p_line, *p_node;
189
190         for (p_line = *lines; p_line != NULL; p_line = p_line->next) {
191                 for (p_node = (GList *) p_line->data; p_node != NULL;
192                      p_node = p_node->next) {
193                         gl_text_node_free ( (glTextNode **) &(p_node->data) );
194                 }
195                 g_list_free ((GList *) p_line->data);
196                 p_line->data = NULL;
197         }
198
199         g_list_free (*lines);
200         *lines = NULL;
201 }
202
203 /****************************************************************************/
204 /* For debugging:  descend and print lines list.                            */
205 /****************************************************************************/
206 void
207 gl_text_node_lines_print (GList * lines )
208 {
209         GList *p_line, *p_node;
210         glTextNode *text_node;
211         gint i_line, i_node;
212
213         for (p_line=lines, i_line=0; p_line != NULL; p_line=p_line->next, i_line++) {
214                 for (p_node = (GList *) p_line->data, i_node=0; p_node != NULL;
215                      p_node = p_node->next, i_node++) {
216                         text_node = (glTextNode *) p_node->data;
217                         g_print( "LINE[%d], NODE[%d] = { %d, \"%s\" }\n",
218                                  i_line, i_node,
219                                  text_node->field_flag, text_node->data );
220
221                 }
222         }
223
224 }
225