]> git.sur5r.net Git - glabels/blob - glabels2/libglabels/xml-template.c
2004-01-06 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / libglabels / xml-template.c
1 /*
2  *  (LIBGLABELS) Template library for GLABELS
3  *
4  *  xml-template.c:  template xml module
5  *
6  *  Copyright (C) 2001-2004  Jim Evins <evins@snaught.com>.
7  *
8  *  This file is part of the LIBGLABELS library.
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Library General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Library General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Library General Public
21  *  License along with this library; if not, write to the Free
22  *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23  *  MA 02111-1307, USA
24  */
25
26 #include "libglabels-private.h"
27
28 #include <string.h>
29 #include <libintl.h>
30
31 #include "paper.h"
32 #include "xml.h"
33 #include "xml-template.h"
34
35 /*===========================================*/
36 /* Private types                             */
37 /*===========================================*/
38
39 /*===========================================*/
40 /* Private globals                           */
41 /*===========================================*/
42
43 /*===========================================*/
44 /* Local function prototypes                 */
45 /*===========================================*/
46 static void  xml_parse_label_rectangle_node (xmlNodePtr              label_node,
47                                              glTemplate             *template);
48 static void  xml_parse_label_round_node     (xmlNodePtr              label_node,
49                                              glTemplate             *template);
50 static void  xml_parse_label_cd_node        (xmlNodePtr              label_node,
51                                              glTemplate             *template);
52 static void  xml_parse_layout_node          (xmlNodePtr              layout_node,
53                                              glTemplateLabelType    *label_type);
54 static void  xml_parse_markup_margin_node   (xmlNodePtr              markup_node,
55                                              glTemplateLabelType    *label_type);
56 static void  xml_parse_markup_line_node     (xmlNodePtr              markup_node,
57                                              glTemplateLabelType    *label_type);
58 static void  xml_parse_markup_circle_node   (xmlNodePtr              markup_node,
59                                              glTemplateLabelType    *label_type);
60 static void  xml_parse_alias_node           (xmlNodePtr              alias_node,
61                                              glTemplate             *template);
62
63 static void  xml_create_label_node          (const glTemplateLabelType    *label_type,
64                                              xmlNodePtr                    root,
65                                              const xmlNsPtr                ns);
66 static void  xml_create_layout_node         (const glTemplateLayout       *layout,
67                                              xmlNodePtr                    root,
68                                              const xmlNsPtr                ns);
69 static void  xml_create_markup_margin_node  (const glTemplateMarkup       *margin,
70                                              xmlNodePtr                    root,
71                                              const xmlNsPtr                ns);
72 static void  xml_create_markup_line_node    (const glTemplateMarkup       *line,
73                                              xmlNodePtr                    root,
74                                              const xmlNsPtr                ns);
75 static void  xml_create_markup_circle_node  (const glTemplateMarkup       *circle,
76                                              xmlNodePtr                    root,
77                                              const xmlNsPtr                ns);
78 static void  xml_create_alias_node          (const gchar                  *name,
79                                              xmlNodePtr                    root,
80                                              const xmlNsPtr                ns);
81
82
83 /*****************************************************************************/
84 /* Read templates from template file.                                        */
85 /*****************************************************************************/
86 GList *
87 gl_xml_template_read_templates_from_file (const gchar *utf8_filename)
88 {
89         gchar      *filename;
90         xmlDocPtr   templates_doc;
91         GList      *templates = NULL;
92
93         LIBXML_TEST_VERSION;
94
95         filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
96         if (!filename) {
97                 g_warning ("Utf8 filename conversion error");
98                 return NULL;
99         }
100
101         templates_doc = xmlParseFile (filename);
102         if (!templates_doc) {
103                 g_warning ("\"%s\" is not a glabels template file (not XML)",
104                       filename);
105                 return templates;
106         }
107
108         templates = gl_xml_template_parse_templates_doc (templates_doc);
109
110         g_free (filename);
111         xmlFreeDoc (templates_doc);
112
113         return templates;
114 }
115
116 /*****************************************************************************/
117 /* Read templates from templates xml doc tree.                               */
118 /*****************************************************************************/
119 GList *
120 gl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc)
121 {
122         
123         GList      *templates = NULL;
124         xmlNodePtr  root, node;
125         glTemplate *template;
126
127         LIBXML_TEST_VERSION;
128
129         root = xmlDocGetRootElement (templates_doc);
130         if (!root || !root->name) {
131                 g_warning ("\"%s\" is not a glabels template file (no root node)",
132                            templates_doc->name);
133                 xmlFreeDoc (templates_doc);
134                 return templates;
135         }
136         if (!xmlStrEqual (root->name, "Glabels-templates")) {
137                 g_warning ("\"%s\" is not a glabels template file (wrong root node)",
138                       templates_doc->name);
139                 xmlFreeDoc (templates_doc);
140                 return templates;
141         }
142
143         for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
144
145                 if (xmlStrEqual (node->name, "Template")) {
146                         template = gl_xml_template_parse_template_node (node);
147                         templates = g_list_append (templates, template);
148                 } else {
149                         if ( !xmlNodeIsText(node) ) {
150                                 if (!xmlStrEqual (node->name,"comment")) {
151                                         g_warning ("bad node =  \"%s\"",node->name);
152                                 }
153                         }
154                 }
155         }
156
157         return templates;
158 }
159
160 /*****************************************************************************/
161 /* Parse XML template Node.                                                  */
162 /*****************************************************************************/
163 glTemplate *
164 gl_xml_template_parse_template_node (const xmlNodePtr template_node)
165 {
166         gchar                 *name;
167         gchar                 *description;
168         gchar                 *page_size;
169         gdouble                page_width, page_height;
170         glPaper               *paper = NULL;
171         glTemplate            *template;
172         xmlNodePtr             node;
173
174         name  = xmlGetProp (template_node, "name");
175
176         description = xmlGetProp (template_node, "_description");
177         if (description != NULL) {
178                 description = gettext (description);
179         } else {
180                 description = xmlGetProp (template_node, "description");
181         }
182
183         page_size = xmlGetProp (template_node, "size");
184         if (gl_paper_is_id_other (page_size)) {
185
186                 page_width = gl_xml_get_prop_length (template_node, "width", 0);
187                 page_height = gl_xml_get_prop_length (template_node, "height", 0);
188
189         } else {
190                 paper = gl_paper_from_id (page_size);
191                 if (paper == NULL) {
192                         /* This should always be an id, but just in case a name
193                            slips by! */
194                         g_warning (_("Unknown page size id \"%s\", trying as name"),
195                                    page_size);
196                         paper = gl_paper_from_name (page_size);
197                         g_free (page_size);
198                         page_size = g_strdup (paper->id);
199                 }
200                 if (paper != NULL) {
201                         page_width  = paper->width;
202                         page_height = paper->height;
203                 } else {
204                         g_warning (_("Unknown page size id or name \"%s\""),
205                                    page_size);
206                 }
207                 gl_paper_free (paper);
208                 paper = NULL;
209         }
210
211         template = gl_template_new (name,
212                                     description,
213                                     page_size,
214                                     page_width, page_height);
215
216         for (node = template_node->xmlChildrenNode; node != NULL;
217              node = node->next) {
218                 if (xmlStrEqual (node->name, "Label-rectangle")) {
219                         xml_parse_label_rectangle_node (node, template);
220                 } else if (xmlStrEqual (node->name, "Label-round")) {
221                         xml_parse_label_round_node (node, template);
222                 } else if (xmlStrEqual (node->name, "Label-cd")) {
223                         xml_parse_label_cd_node (node, template);
224                 } else if (xmlStrEqual (node->name, "Alias")) {
225                         xml_parse_alias_node (node, template);
226                 } else {
227                         if (!xmlNodeIsText (node)) {
228                                 if (!xmlStrEqual (node->name,"comment")) {
229                                         g_warning ("bad node =  \"%s\"",node->name);
230                                 }
231                         }
232                 }
233         }
234
235         return template;
236 }
237
238 /*--------------------------------------------------------------------------*/
239 /* PRIVATE.  Parse XML Template->Label-rectangle Node.                      */
240 /*--------------------------------------------------------------------------*/
241 static void
242 xml_parse_label_rectangle_node (xmlNodePtr  label_node,
243                                 glTemplate *template)
244 {
245         gchar               *id;
246         gdouble              waste;
247         gdouble              w, h, r;
248         glTemplateLabelType *label_type;
249         xmlNodePtr           node;
250
251         id    = xmlGetProp (label_node, "id");
252         waste = gl_xml_get_prop_length (label_node, "waste", 0);
253         w     = gl_xml_get_prop_length (label_node, "width", 0);
254         h     = gl_xml_get_prop_length (label_node, "height", 0);
255         r     = gl_xml_get_prop_length (label_node, "round", 0);
256
257         label_type = gl_template_rect_label_type_new (id, w, h, r, waste);
258         gl_template_add_label_type (template, label_type);
259
260         for (node = label_node->xmlChildrenNode; node != NULL;
261              node = node->next) {
262                 if (xmlStrEqual (node->name, "Layout")) {
263                         xml_parse_layout_node (node, label_type);
264                 } else if (xmlStrEqual (node->name, "Markup-margin")) {
265                         xml_parse_markup_margin_node (node, label_type);
266                 } else if (xmlStrEqual (node->name, "Markup-line")) {
267                         xml_parse_markup_line_node (node, label_type);
268                 } else if (xmlStrEqual (node->name, "Markup-circle")) {
269                         xml_parse_markup_circle_node (node, label_type);
270                 } else if (!xmlNodeIsText (node)) {
271                         if (!xmlStrEqual (node->name,"comment")) {
272                                 g_warning ("bad node =  \"%s\"",node->name);
273                         }
274                 }
275         }
276
277 }
278
279 /*--------------------------------------------------------------------------*/
280 /* PRIVATE.  Parse XML Template->Label-round Node.                          */
281 /*--------------------------------------------------------------------------*/
282 static void
283 xml_parse_label_round_node (xmlNodePtr  label_node,
284                             glTemplate *template)
285 {
286         gchar               *id;
287         gdouble              waste;
288         gdouble              r;
289         glTemplateLabelType *label_type;
290         xmlNodePtr           node;
291
292         id    = xmlGetProp (label_node, "id");
293         waste = gl_xml_get_prop_length (label_node, "waste", 0);
294         r     = gl_xml_get_prop_length (label_node, "radius", 0);
295
296         label_type = gl_template_round_label_type_new (id, r, waste);
297         gl_template_add_label_type (template, label_type);
298
299         for (node = label_node->xmlChildrenNode; node != NULL;
300              node = node->next) {
301                 if (xmlStrEqual (node->name, "Layout")) {
302                         xml_parse_layout_node (node, label_type);
303                 } else if (xmlStrEqual (node->name, "Markup-margin")) {
304                         xml_parse_markup_margin_node (node, label_type);
305                 } else if (xmlStrEqual (node->name, "Markup-line")) {
306                         xml_parse_markup_line_node (node, label_type);
307                 } else if (xmlStrEqual (node->name, "Markup-circle")) {
308                         xml_parse_markup_circle_node (node, label_type);
309                 } else if (!xmlNodeIsText (node)) {
310                         if (!xmlStrEqual (node->name,"comment")) {
311                                 g_warning ("bad node =  \"%s\"",node->name);
312                         }
313                 }
314         }
315
316 }
317
318 /*--------------------------------------------------------------------------*/
319 /* PRIVATE.  Parse XML Template->Label-cd Node.                             */
320 /*--------------------------------------------------------------------------*/
321 static void
322 xml_parse_label_cd_node (xmlNodePtr  label_node,
323                          glTemplate *template)
324 {
325         gchar               *id;
326         gdouble              waste;
327         gdouble              r1, r2, w, h;
328         glTemplateLabelType *label_type;
329         xmlNodePtr           node;
330
331         id    = xmlGetProp (label_node, "id");
332         waste = gl_xml_get_prop_length (label_node, "waste", 0);
333         r1    = gl_xml_get_prop_length (label_node, "radius", 0);
334         r2    = gl_xml_get_prop_length (label_node, "hole", 0);
335         w     = gl_xml_get_prop_length (label_node, "width", 0);
336         h     = gl_xml_get_prop_length (label_node, "height", 0);
337
338         label_type = gl_template_cd_label_type_new (id, r1, r2, w, h, waste);
339         gl_template_add_label_type (template, label_type);
340
341         for (node = label_node->xmlChildrenNode; node != NULL;
342              node = node->next) {
343                 if (xmlStrEqual (node->name, "Layout")) {
344                         xml_parse_layout_node (node, label_type);
345                 } else if (xmlStrEqual (node->name, "Markup-margin")) {
346                         xml_parse_markup_margin_node (node, label_type);
347                 } else if (xmlStrEqual (node->name, "Markup-line")) {
348                         xml_parse_markup_line_node (node, label_type);
349                 } else if (xmlStrEqual (node->name, "Markup-circle")) {
350                         xml_parse_markup_circle_node (node, label_type);
351                 } else if (!xmlNodeIsText (node)) {
352                         if (!xmlStrEqual (node->name,"comment")) {
353                                 g_warning ("bad node =  \"%s\"",node->name);
354                         }
355                 }
356         }
357
358 }
359
360 /*--------------------------------------------------------------------------*/
361 /* PRIVATE.  Parse XML Template->Label->Layout Node.                        */
362 /*--------------------------------------------------------------------------*/
363 static void
364 xml_parse_layout_node (xmlNodePtr              layout_node,
365                        glTemplateLabelType    *label_type)
366 {
367         gint        nx, ny;
368         gdouble     x0, y0, dx, dy;
369         xmlNodePtr  node;
370
371         nx = gl_xml_get_prop_int (layout_node, "nx", 1);
372         ny = gl_xml_get_prop_int (layout_node, "ny", 1);
373
374         x0 = gl_xml_get_prop_length (layout_node, "x0", 0);
375         y0 = gl_xml_get_prop_length (layout_node, "y0", 0);
376
377         dx = gl_xml_get_prop_length (layout_node, "dx", 0);
378         dy = gl_xml_get_prop_length (layout_node, "dy", 0);
379
380         gl_template_add_layout (label_type,
381                                 gl_template_layout_new (nx, ny, x0, y0, dx, dy));
382
383         for (node = layout_node->xmlChildrenNode; node != NULL;
384              node = node->next) {
385                 if (!xmlNodeIsText (node)) {
386                         if (!xmlStrEqual (node->name,"comment")) {
387                                 g_warning ("bad node =  \"%s\"",node->name);
388                         }
389                 }
390         }
391
392 }
393
394 /*--------------------------------------------------------------------------*/
395 /* PRIVATE.  Parse XML Template->Label->Markup-margin Node.                 */
396 /*--------------------------------------------------------------------------*/
397 static void
398 xml_parse_markup_margin_node (xmlNodePtr              markup_node,
399                               glTemplateLabelType    *label_type)
400 {
401         gdouble     size;
402         xmlNodePtr  node;
403
404         size = gl_xml_get_prop_length (markup_node, "size", 0);
405
406         gl_template_add_markup (label_type,
407                                 gl_template_markup_margin_new (size));
408
409         for (node = markup_node->xmlChildrenNode; node != NULL;
410              node = node->next) {
411                 if (!xmlNodeIsText (node)) {
412                         if (!xmlStrEqual (node->name,"comment")) {
413                                 g_warning ("bad node =  \"%s\"",node->name);
414                         }
415                 }
416         }
417
418 }
419
420 /*--------------------------------------------------------------------------*/
421 /* PRIVATE.  Parse XML Template->Label->Markup-line Node.                   */
422 /*--------------------------------------------------------------------------*/
423 static void
424 xml_parse_markup_line_node (xmlNodePtr              markup_node,
425                             glTemplateLabelType    *label_type)
426 {
427         gdouble     x1, y1, x2, y2;
428         xmlNodePtr  node;
429
430         x1 = gl_xml_get_prop_length (markup_node, "x1", 0);
431         y1 = gl_xml_get_prop_length (markup_node, "y1", 0);
432         x2 = gl_xml_get_prop_length (markup_node, "x2", 0);
433         y2 = gl_xml_get_prop_length (markup_node, "y2", 0);
434
435         gl_template_add_markup (label_type,
436                                 gl_template_markup_line_new (x1, y1, x2, y2));
437
438         for (node = markup_node->xmlChildrenNode; node != NULL;
439              node = node->next) {
440                 if (!xmlNodeIsText (node)) {
441                         if (!xmlStrEqual (node->name,"comment")) {
442                                 g_warning ("bad node =  \"%s\"",node->name);
443                         }
444                 }
445         }
446
447 }
448
449 /*--------------------------------------------------------------------------*/
450 /* PRIVATE.  Parse XML Template->Label->Markup-circle Node.                 */
451 /*--------------------------------------------------------------------------*/
452 static void
453 xml_parse_markup_circle_node (xmlNodePtr              markup_node,
454                               glTemplateLabelType    *label_type)
455 {
456         gdouble     x0, y0, r;
457         xmlNodePtr  node;
458
459         x0 = gl_xml_get_prop_length (markup_node, "x0", 0);
460         y0 = gl_xml_get_prop_length (markup_node, "y0", 0);
461         r  = gl_xml_get_prop_length (markup_node, "radius", 0);
462
463         gl_template_add_markup (label_type,
464                                 gl_template_markup_circle_new (x0, y0, r));
465
466         for (node = markup_node->xmlChildrenNode; node != NULL;
467              node = node->next) {
468                 if (!xmlNodeIsText (node)) {
469                         if (!xmlStrEqual (node->name,"comment")) {
470                                 g_warning ("bad node =  \"%s\"",node->name);
471                         }
472                 }
473         }
474
475 }
476
477 /*--------------------------------------------------------------------------*/
478 /* PRIVATE.  Parse XML Template->Alias Node.                                */
479 /*--------------------------------------------------------------------------*/
480 static void
481 xml_parse_alias_node (xmlNodePtr  alias_node,
482                       glTemplate *template)
483 {
484         gchar       *name;
485
486         name = xmlGetProp (alias_node, "name");
487
488         gl_template_add_alias (template, name);
489
490         g_free (name);
491 }
492
493 /****************************************************************************/
494 /* Write a list of templates to XML file.                                   */
495 /****************************************************************************/
496 void
497 gl_xml_template_write_templates_to_file (GList       *templates,
498                                          const gchar *utf8_filename)
499 {
500         xmlDocPtr    doc;
501         xmlNsPtr     ns;
502         gint         xml_ret;
503         GList       *p;
504         glTemplate  *template;
505         gchar       *filename;
506
507         doc = xmlNewDoc ("1.0");
508         doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Glabels-templates", NULL);
509
510         ns = xmlNewNs (doc->xmlRootNode, GL_XML_NAME_SPACE, NULL);
511         xmlSetNs (doc->xmlRootNode, ns);
512
513         for (p=templates; p!=NULL; p=p->next) {
514                 template = (glTemplate *)p->data;
515                 gl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
516         }
517
518         filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
519         if (!filename)
520                 g_warning (_("Utf8 conversion error."));
521         else {
522                 xmlSetDocCompressMode (doc, 0);
523                 xml_ret = xmlSaveFormatFile (filename, doc, TRUE);
524                 xmlFreeDoc (doc);
525                 if (xml_ret == -1) {
526
527                         g_warning (_("Problem saving xml file."));
528
529                 }
530                 g_free (filename);
531         }
532
533 }
534
535 /****************************************************************************/
536 /* Write single template to XML file.                                       */
537 /****************************************************************************/
538 void
539 gl_xml_template_write_template_to_file (const glTemplate  *template,
540                                         const gchar       *utf8_filename)
541 {
542         GList     *templates = NULL;
543
544         templates = g_list_append (templates, (gpointer)template);
545
546         gl_xml_template_write_templates_to_file (templates, utf8_filename);
547
548         g_list_free (templates);
549 }
550
551 /****************************************************************************/
552 /* Add XML Template Node                                                    */
553 /****************************************************************************/
554 void
555 gl_xml_template_create_template_node (const glTemplate *template,
556                                       xmlNodePtr        root,
557                                       const xmlNsPtr    ns)
558 {
559         xmlNodePtr              node;
560         GList                  *p;
561         glTemplateLabelType    *label_type;
562
563         node = xmlNewChild (root, ns, "Template", NULL);
564
565         xmlSetProp (node, "name", template->name);
566
567         xmlSetProp (node, "size", template->page_size);
568         if (xmlStrEqual (template->page_size, "Other")) {
569
570                 gl_xml_set_prop_length (node, "width", template->page_width);
571                 gl_xml_set_prop_length (node, "height", template->page_height);
572
573         }
574
575         xmlSetProp (node, "description", template->description);
576
577         for ( p=template->label_types; p != NULL; p=p->next ) {
578                 label_type = (glTemplateLabelType *)p->data;
579                 xml_create_label_node (label_type, node, ns);
580         }
581
582         for ( p=template->aliases; p != NULL; p=p->next ) {
583                 if (!xmlStrEqual (template->name, p->data)) {
584                         xml_create_alias_node ( p->data, node, ns );
585                 }
586         }
587
588 }
589
590 /*--------------------------------------------------------------------------*/
591 /* PRIVATE.  Add XML Template->Label Node.                                  */
592 /*--------------------------------------------------------------------------*/
593 static void
594 xml_create_label_node (const glTemplateLabelType  *label_type,
595                        xmlNodePtr                  root,
596                        const xmlNsPtr              ns)
597 {
598         xmlNodePtr        node;
599         GList            *p;
600         glTemplateMarkup *markup;
601         glTemplateLayout *layout;
602
603         switch (label_type->shape) {
604
605         case GL_TEMPLATE_SHAPE_RECT:
606                 node = xmlNewChild(root, ns, "Label-rectangle", NULL);
607                 xmlSetProp (node, "id", label_type->id);
608                 gl_xml_set_prop_length (node, "width",  label_type->size.rect.w);
609                 gl_xml_set_prop_length (node, "height", label_type->size.rect.h);
610                 gl_xml_set_prop_length (node, "round",  label_type->size.rect.r);
611                 gl_xml_set_prop_length (node, "waste",  label_type->waste);
612                 break;
613
614         case GL_TEMPLATE_SHAPE_ROUND:
615                 node = xmlNewChild(root, ns, "Label-round", NULL);
616                 xmlSetProp (node, "id", label_type->id);
617                 gl_xml_set_prop_length (node, "radius",  label_type->size.round.r);
618                 gl_xml_set_prop_length (node, "waste",   label_type->waste);
619                 break;
620
621         case GL_TEMPLATE_SHAPE_CD:
622                 node = xmlNewChild(root, ns, "Label-cd", NULL);
623                 xmlSetProp (node, "id", label_type->id);
624                 gl_xml_set_prop_length (node, "radius",  label_type->size.cd.r1);
625                 gl_xml_set_prop_length (node, "hole",    label_type->size.cd.r2);
626                 if (label_type->size.cd.w != 0.0) {
627                         gl_xml_set_prop_length (node, "width",  label_type->size.cd.w);
628                 }
629                 if (label_type->size.cd.h != 0.0) {
630                         gl_xml_set_prop_length (node, "height", label_type->size.cd.h);
631                 }
632                 gl_xml_set_prop_length (node, "waste",  label_type->waste);
633                 break;
634
635         default:
636                 g_warning ("Unknown label style");
637                 return;
638                 break;
639
640         }
641
642         for ( p=label_type->layouts; p != NULL; p=p->next ) {
643                 layout = (glTemplateLayout *)p->data;
644                 xml_create_layout_node (layout, node, ns);
645         }
646
647         for ( p=label_type->markups; p != NULL; p=p->next ) {
648                 markup = (glTemplateMarkup *)p->data;
649                 switch (markup->type) {
650                 case GL_TEMPLATE_MARKUP_MARGIN:
651                         xml_create_markup_margin_node (markup, node, ns);
652                         break;
653                 case GL_TEMPLATE_MARKUP_LINE:
654                         xml_create_markup_line_node (markup, node, ns);
655                         break;
656                 case GL_TEMPLATE_MARKUP_CIRCLE:
657                         xml_create_markup_circle_node (markup, node, ns);
658                         break;
659                 default:
660                         g_warning ("Unknown markup type");
661                         break;
662                 }
663         }
664
665 }
666
667 /*--------------------------------------------------------------------------*/
668 /* PRIVATE.  Add XML Template->Label->Layout Node.                          */
669 /*--------------------------------------------------------------------------*/
670 static void
671 xml_create_layout_node (const glTemplateLayout *layout,
672                         xmlNodePtr              root,
673                         const xmlNsPtr          ns)
674 {
675         xmlNodePtr  node;
676
677         node = xmlNewChild(root, ns, "Layout", NULL);
678         gl_xml_set_prop_int (node, "nx", layout->nx);
679         gl_xml_set_prop_int (node, "ny", layout->ny);
680         gl_xml_set_prop_length (node, "x0", layout->x0);
681         gl_xml_set_prop_length (node, "y0", layout->y0);
682         gl_xml_set_prop_length (node, "dx", layout->dx);
683         gl_xml_set_prop_length (node, "dy", layout->dy);
684
685 }
686
687 /*--------------------------------------------------------------------------*/
688 /* PRIVATE.  Add XML Template->Label->Markup-margin Node.                   */
689 /*--------------------------------------------------------------------------*/
690 static void
691 xml_create_markup_margin_node (const glTemplateMarkup  *markup,
692                                xmlNodePtr               root,
693                                const xmlNsPtr           ns)
694 {
695         xmlNodePtr  node;
696
697         node = xmlNewChild(root, ns, "Markup-margin", NULL);
698
699         gl_xml_set_prop_length (node, "size", markup->data.margin.size);
700
701 }
702
703 /*--------------------------------------------------------------------------*/
704 /* PRIVATE.  Add XML Template->Label->Markup-line Node.                     */
705 /*--------------------------------------------------------------------------*/
706 static void
707 xml_create_markup_line_node (const glTemplateMarkup *markup,
708                              xmlNodePtr              root,
709                              const xmlNsPtr          ns)
710 {
711         xmlNodePtr  node;
712
713         node = xmlNewChild(root, ns, "Markup-line", NULL);
714
715         gl_xml_set_prop_length (node, "x1", markup->data.line.x1);
716         gl_xml_set_prop_length (node, "y1", markup->data.line.y1);
717         gl_xml_set_prop_length (node, "x2", markup->data.line.x2);
718         gl_xml_set_prop_length (node, "y2", markup->data.line.y2);
719
720 }
721
722 /*--------------------------------------------------------------------------*/
723 /* PRIVATE.  Add XML Template->Label->Markup-circle Node.                   */
724 /*--------------------------------------------------------------------------*/
725 static void
726 xml_create_markup_circle_node (const glTemplateMarkup *markup,
727                                xmlNodePtr              root,
728                                const xmlNsPtr          ns)
729 {
730         xmlNodePtr  node;
731
732         node = xmlNewChild(root, ns, "Markup-circle", NULL);
733
734         gl_xml_set_prop_length (node, "x0",     markup->data.circle.x0);
735         gl_xml_set_prop_length (node, "y0",     markup->data.circle.y0);
736         gl_xml_set_prop_length (node, "radius", markup->data.circle.r);
737
738 }
739
740 /*--------------------------------------------------------------------------*/
741 /* PRIVATE.  Add XML Template->Alias Node.                                  */
742 /*--------------------------------------------------------------------------*/
743 static void
744 xml_create_alias_node (const gchar      *name,
745                        xmlNodePtr        root,
746                        const xmlNsPtr    ns)
747 {
748         xmlNodePtr node;
749
750         node = xmlNewChild (root, ns, "Alias", NULL);
751         xmlSetProp (node, "name", name);
752
753 }
754