87892706a4427512232896ca3c8baa141d32b0bc
[yaz-moved-to-github.git] / retrieval / d1_write.c
1 /*
2  * Copyright (c) 1995-2002, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Id: d1_write.c,v 1.13 2002-07-03 10:04:04 adam Exp $
7  */
8
9 #include <string.h>
10
11 #include <yaz/data1.h>
12 #include <yaz/wrbuf.h>
13
14 #define IDSGML_MARGIN 75
15
16 static int wordlen(char *b, int max)
17 {
18     int l = 0;
19
20     while (l < max && !d1_isspace(*b))
21         l++, b++;
22     return l;
23 }
24
25 static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
26 {
27     data1_node *c;
28     char line[1024];
29
30     for (c = n->child; c; c = c->next)
31     {
32         char *tag;
33
34         if (c->which == DATA1N_preprocess)
35         {
36             data1_xattr *p;
37             
38             sprintf (line, "%*s<?", col, "");
39             wrbuf_puts (b, line);
40             wrbuf_puts (b, c->u.preprocess.target);
41             for (p = c->u.preprocess.attributes; p; p = p->next)
42             {
43                 wrbuf_putc (b, ' ');
44                 wrbuf_puts (b, p->name);
45                 wrbuf_putc (b, '=');
46                 wrbuf_putc (b, '"');
47                 wrbuf_puts (b, p->value);
48                 wrbuf_putc (b, '"');
49             }
50             if (c->child)
51                 wrbuf_puts(b, " ");
52             if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
53                 return -1;
54             wrbuf_puts (b, "?>\n");
55         }
56         else if (c->which == DATA1N_tag)
57         {
58             if (select && c->u.tag.node_selected)
59                 continue;
60             tag = c->u.tag.tag;
61             if (!data1_matchstr(tag, "wellknown")) /* skip wellknown */
62             {
63                 if (nodetoidsgml(c, select, b, col) < 0)
64                     return -1;
65             }
66             else
67             {
68                 data1_xattr *p;
69
70                 sprintf (line, "%*s<", col, "");
71                 wrbuf_puts (b, line);
72                 wrbuf_puts (b, tag);
73                 for (p = c->u.tag.attributes; p; p = p->next)
74                 {
75                     wrbuf_putc (b, ' ');
76                     wrbuf_puts (b, p->name);
77                     wrbuf_putc (b, '=');
78                     wrbuf_putc (b, '"');
79                     wrbuf_puts (b, p->value);
80                     wrbuf_putc (b, '"');
81                 }
82                 wrbuf_puts(b, ">\n");
83                 if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
84                     return -1;
85                 sprintf (line, "%*s</%s>\n", col, "", tag);
86                 wrbuf_write(b, line, strlen(line));
87             }
88         }
89         else if (c->which == DATA1N_data || c->which == DATA1N_comment)
90         {
91             char *p = c->u.data.data;
92             int l = c->u.data.len;
93             int first = 1;
94             int lcol = col;
95
96             if (!c->u.data.formatted_text)
97             {
98                 sprintf(line, "%*s", col, "");
99                 wrbuf_write(b, line, strlen(line));
100             }
101             if (c->which == DATA1N_comment)
102             {
103                 wrbuf_write (b, "<!--", 4);
104             }
105             switch (c->u.data.what)
106             {
107             case DATA1I_text:
108                 if (c->u.data.formatted_text)
109                 {
110                     wrbuf_write (b, p, l);
111                 }
112                 else
113                 {
114                     while (l)
115                     {
116                         int wlen;
117                         
118                         while (l && d1_isspace(*p))
119                             p++, l--;
120                         if (!l)
121                             break;
122                         /* break if we cross margin and word is not too long */
123                         if (lcol + (wlen = wordlen(p, l)) > IDSGML_MARGIN &&
124                             wlen < IDSGML_MARGIN)
125                         {
126                             sprintf(line, "\n%*s", col, "");
127                             lcol = col;
128                             wrbuf_write(b, line, strlen(line));
129                             first = 1;
130                         }
131                         if (!first)
132                         {
133                             wrbuf_putc(b, ' ');
134                             lcol++;
135                         }
136                         while (l && !d1_isspace(*p))
137                         {
138                             wrbuf_putc(b, *p);
139                             p++;
140                             l--;
141                             lcol++;
142                         }
143                         first = 0;
144                     }
145                     wrbuf_write(b, "\n", 1);
146                 }
147                 break;
148             case DATA1I_num:
149                 wrbuf_write(b, c->u.data.data, c->u.data.len);
150                 wrbuf_write(b, "\n", 1);
151                 break;
152             case DATA1I_oid:
153                 wrbuf_write(b, c->u.data.data, c->u.data.len);
154                 wrbuf_write(b, "\n", 1);
155             }
156             if (c->which == DATA1N_comment)
157             {
158                 wrbuf_write (b, "-->\n", 4);
159             }
160         }
161     }
162     return 0;
163 }
164
165 char *data1_nodetoidsgml (data1_handle dh, data1_node *n, int select, int *len)
166 {
167     WRBUF b = data1_get_wrbuf (dh);
168     
169     wrbuf_rewind(b);
170     
171     if (nodetoidsgml(n, select, b, 0))
172         return 0;
173     *len = wrbuf_len(b);
174     return wrbuf_buf(b);
175 }