1e80c6b2400768d85c9970f80ad30356198dbd96
[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.14 2002-07-05 12:42:52 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 #define PRETTY_FORMAT 0
17
18 static int wordlen(char *b, int max)
19 {
20     int l = 0;
21
22     while (l < max && !d1_isspace(*b))
23         l++, b++;
24     return l;
25 }
26
27 static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
28 {
29     data1_node *c;
30     char line[1024];
31
32     for (c = n->child; c; c = c->next)
33     {
34         char *tag;
35
36         if (c->which == DATA1N_preprocess)
37         {
38             data1_xattr *p;
39            
40 #if PRETTY_FORMAT
41             sprintf (line, "%*s", col, "");
42             wrbuf_puts (b, line);
43 #endif
44             wrbuf_puts (b, "<?");
45             wrbuf_puts (b, c->u.preprocess.target);
46             for (p = c->u.preprocess.attributes; p; p = p->next)
47             {
48                 wrbuf_putc (b, ' ');
49                 wrbuf_puts (b, p->name);
50                 wrbuf_putc (b, '=');
51                 wrbuf_putc (b, '"');
52                 wrbuf_puts (b, p->value);
53                 wrbuf_putc (b, '"');
54             }
55             if (c->child)
56                 wrbuf_puts(b, " ");
57             if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
58                 return -1;
59             wrbuf_puts (b, "?>\n");
60         }
61         else if (c->which == DATA1N_tag)
62         {
63             if (select && c->u.tag.node_selected)
64                 continue;
65             tag = c->u.tag.tag;
66             if (!data1_matchstr(tag, "wellknown")) /* skip wellknown */
67             {
68                 if (nodetoidsgml(c, select, b, col) < 0)
69                     return -1;
70             }
71             else
72             {
73                 data1_xattr *p;
74
75 #if PRETTY_FORMAT
76                 sprintf (line, "%*s", col, "");
77                 wrbuf_puts (b, line);
78 #endif
79                 wrbuf_puts (b, "<");    
80                 wrbuf_puts (b, tag);
81                 for (p = c->u.tag.attributes; p; p = p->next)
82                 {
83                     wrbuf_putc (b, ' ');
84                     wrbuf_puts (b, p->name);
85                     wrbuf_putc (b, '=');
86                     wrbuf_putc (b, '"');
87                     wrbuf_puts (b, p->value);
88                     wrbuf_putc (b, '"');
89                 }
90                 wrbuf_puts(b, ">");
91 #if PRETTY_FORMAT
92                 wrbuf_puts(b, "\n");
93 #endif
94                 if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
95                     return -1;
96 #if PRETTY_FORMAT
97                 sprintf (line, "%*s", col);
98                 wrbuf_puts(b, line);
99 #endif
100                 wrbuf_puts(b, "</");
101                 wrbuf_puts(b, tag);
102                 wrbuf_puts(b, ">");
103 #if PRETTY_FORMAT
104                 wrbuf_puts (b, "\n");
105 #endif
106             }
107         }
108         else if (c->which == DATA1N_data || c->which == DATA1N_comment)
109         {
110             char *p = c->u.data.data;
111             int l = c->u.data.len;
112             int first = 1;
113             int lcol = col;
114
115 #if PRETTY_FORMAT
116             if (!c->u.data.formatted_text)
117             {
118                 sprintf(line, "%*s", col, "");
119                 wrbuf_write(b, line, strlen(line));
120             }
121 #endif
122             if (c->which == DATA1N_comment)
123             {
124                 wrbuf_write (b, "<!--", 4);
125             }
126             switch (c->u.data.what)
127             {
128             case DATA1I_text:
129 #if PRETTY_FORMAT
130                 if (c->u.data.formatted_text)
131                 {
132                     wrbuf_write (b, p, l);
133                 }
134                 else
135                 {
136                     while (l)
137                     {
138                         int wlen;
139                         
140                         while (l && d1_isspace(*p))
141                             p++, l--;
142                         if (!l)
143                             break;
144                         /* break if we cross margin and word is not too long */
145                         if (lcol + (wlen = wordlen(p, l)) > IDSGML_MARGIN &&
146                             wlen < IDSGML_MARGIN)
147                         {
148                             sprintf(line, "\n%*s", col, "");
149                             lcol = col;
150                             wrbuf_write(b, line, strlen(line));
151                             first = 1;
152                         }
153                         if (!first)
154                         {
155                             wrbuf_putc(b, ' ');
156                             lcol++;
157                         }
158                         while (l && !d1_isspace(*p))
159                         {
160                             wrbuf_putc(b, *p);
161                             p++;
162                             l--;
163                             lcol++;
164                         }
165                         first = 0;
166                     }
167                     wrbuf_write(b, "\n", 1);
168                 }
169 #else
170                 wrbuf_write (b, p, l);
171 #endif
172                 break;
173             case DATA1I_num:
174                 wrbuf_write(b, c->u.data.data, c->u.data.len);
175 #if PRETTY_FORMAT
176                 wrbuf_puts(b, "\n");
177 #endif
178                 break;
179             case DATA1I_oid:
180                 wrbuf_write(b, c->u.data.data, c->u.data.len);
181 #if PRETTY_FORMAT
182                 wrbuf_puts(b, "\n");
183 #endif
184             }
185             if (c->which == DATA1N_comment)
186             {
187                 wrbuf_puts(b, "-->");
188 #if PRETTY_FORMAT
189                 wrbuf_puts(b, "\n");
190 #endif
191             }
192         }
193     }
194     return 0;
195 }
196
197 char *data1_nodetoidsgml (data1_handle dh, data1_node *n, int select, int *len)
198 {
199     WRBUF b = data1_get_wrbuf (dh);
200     
201     wrbuf_rewind(b);
202     
203     if (nodetoidsgml(n, select, b, 0))
204         return 0;
205     *len = wrbuf_len(b);
206     return wrbuf_buf(b);
207 }