XML reader for data1 (EXPAT)
[yaz-moved-to-github.git] / retrieval / d1_sutrs.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_sutrs.c,v 1.7 2002-05-03 13:48:27 adam Exp $
7  *
8  */
9
10 #include <yaz/data1.h>
11
12 #define NTOBUF_INDENT   2
13 #define NTOBUF_MARGIN 75
14
15 static int wordlen(char *b, int i)
16 {
17     int l = 0;
18
19     while (i && !d1_isspace(*b))
20         l++, b++, i--;
21     return l;
22 }
23
24 static int nodetobuf(data1_node *n, int select, WRBUF b, int indent, int col)
25 {
26     data1_node *c;
27     char line[1024];
28
29     for (c = n->child; c; c = c->next)
30     {
31         char *tag;
32
33         if (c->which == DATA1N_tag)
34         {
35             if (select && !c->u.tag.node_selected)
36                 continue;
37             if (c->u.tag.element && c->u.tag.element->tag)
38                 tag = c->u.tag.element->tag->names->name; /* first name */
39             else
40                 tag = c->u.tag.tag; /* local string tag */
41             if (data1_matchstr(tag, "wellknown")) /* skip wellknown */
42             {
43                 if (col)
44                     wrbuf_putc(b, '\n');
45                 sprintf(line, "%*s%s:", indent * NTOBUF_INDENT, "", tag);
46                 wrbuf_write(b, line, strlen(line));
47                 col = strlen(line);
48             }
49             if (nodetobuf(c, select, b, indent+1, col) < 0)
50                 return 0;
51         }
52         else if (c->which == DATA1N_data)
53         {
54             char *p = c->u.data.data;
55             int l = c->u.data.len;
56             int first = 0;
57
58             if (c->u.data.what == DATA1I_text && c->u.data.formatted_text)
59             {
60                 wrbuf_putc(b, '\n');
61                 wrbuf_write(b, c->u.data.data, c->u.data.len);
62                 sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
63                 wrbuf_write(b, line, strlen(line));
64                 col = indent * NTOBUF_INDENT;
65             }
66             else if (c->u.data.what == DATA1I_text)
67             {
68                 while (l)
69                 {
70                     int wlen;
71
72                     while (l && d1_isspace(*p))
73                         p++, l--;
74                     if (!l)
75                         break;
76                     /* break if we'll cross margin and word is not too long */
77                     if (col + (wlen = wordlen(p, l)) > NTOBUF_MARGIN && wlen <
78                         NTOBUF_MARGIN - indent * NTOBUF_INDENT)
79                     {
80                         sprintf(line, "\n%*s", indent * NTOBUF_INDENT, "");
81                         wrbuf_write(b, line, strlen(line));
82                         col = indent * NTOBUF_INDENT;
83                         first = 1;
84                     }
85                     if (!first)
86                     {
87                         wrbuf_putc(b, ' ');
88                         col++;
89                     }
90                     while (l && !d1_isspace(*p))
91                     {
92                         if (col > NTOBUF_MARGIN)
93                         {
94                             wrbuf_putc(b, '=');
95                             wrbuf_putc(b, '\n');
96                             sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
97                             wrbuf_write(b, line, strlen(line));
98                             col = indent * NTOBUF_INDENT;
99                         }
100                         wrbuf_putc(b, *p);
101                         p++;
102                         l--;
103                         col++;
104                     }
105                     first = 0;
106                 }
107             }
108             else if (c->u.data.what == DATA1I_num)
109             {
110                 wrbuf_putc(b, ' ');
111                 wrbuf_write(b, c->u.data.data, c->u.data.len);
112             }
113         }
114     }
115     return 0;
116 }
117
118 /*
119  * Return area containing SUTRS-formatted data. Ownership of this data
120  * remains in this module, and the buffer is reused on next call. This may
121  * need changing.
122  */
123
124 char *data1_nodetobuf (data1_handle dh, data1_node *n, int select, int *len)
125 {
126     WRBUF b = data1_get_wrbuf (dh);
127
128     wrbuf_rewind(b);
129     if (nodetobuf(n, select, b, 0, 0))
130         return 0;
131     wrbuf_putc(b, '\n');
132     *len = wrbuf_len(b);
133     return wrbuf_buf(b);
134 }