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