Retrieval module no longer uses ctype.h - functions.
[yaz-moved-to-github.git] / retrieval / d1_write.c
1 /*
2  * Copyright (c) 1995-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_write.c,v $
7  * Revision 1.7  1999-10-21 12:06:29  adam
8  * Retrieval module no longer uses ctype.h - functions.
9  *
10  * Revision 1.6  1999/07/06 12:16:00  adam
11  * Improved layout generated record in SGML/XML format.
12  *
13  * Revision 1.5  1998/06/05 08:57:43  adam
14  * Fixed problem with function wordlen.
15  *
16  * Revision 1.4  1998/05/18 13:07:08  adam
17  * Changed the way attribute sets are handled by the retriaval module.
18  * Extended Explain conversion / schema.
19  * Modified server and client to work with ASN.1 compiled protocol handlers.
20  *
21  * Revision 1.3  1997/09/17 12:10:39  adam
22  * YAZ version 1.4.
23  *
24  * Revision 1.2  1995/12/13 17:14:27  quinn
25  * *** empty log message ***
26  *
27  * Revision 1.1  1995/12/13  15:38:43  quinn
28  * Added SGML-output filter.
29  *
30  *
31  */
32
33 #include <string.h>
34
35 #include <data1.h>
36 #include <wrbuf.h>
37
38 #define IDSGML_MARGIN 75
39
40 static int wordlen(char *b, int max)
41 {
42     int l = 0;
43
44     while (l < max && !d1_isspace(*b))
45         l++, b++;
46     return l;
47 }
48
49 static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
50 {
51     data1_node *c;
52     char line[1024];
53
54     for (c = n->child; c; c = c->next)
55     {
56         char *tag;
57
58         if (c->which == DATA1N_tag)
59         {
60             if (select && c->u.tag.node_selected)
61                 continue;
62             if (c->u.tag.element && c->u.tag.element->tag)
63                 tag = c->u.tag.element->tag->names->name; /* first name */
64             else
65                 tag = c->u.tag.tag; /* local string 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                 sprintf(line, "%*s<%s>\n", col, "", tag);
74                 wrbuf_write(b, line, strlen(line));
75                 if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
76                     return -1;
77                 sprintf (line, "%*s</%s>\n", col, "", tag);
78                 wrbuf_write(b, line, strlen(line));
79             }
80         }
81         else if (c->which == DATA1N_data)
82         {
83             char *p = c->u.data.data;
84             int l = c->u.data.len;
85             int first = 1;
86             int lcol = col;
87
88             sprintf(line, "%*s", col, "");
89             wrbuf_write(b, line, strlen(line));
90             switch (c->u.data.what)
91             {
92             case DATA1I_text:
93                 while (l)
94                 {
95                     int wlen;
96                     
97                     while (l && d1_isspace(*p))
98                         p++, l--;
99                     if (!l)
100                         break;
101                     /* break if we'll cross margin and word is not too long */
102                     if (lcol + (wlen = wordlen(p, l)) > IDSGML_MARGIN && wlen <
103                         IDSGML_MARGIN)
104                     {
105                         sprintf(line, "\n%*s", col, "");
106                         lcol = col;
107                         wrbuf_write(b, line, strlen(line));
108                         first = 1;
109                     }
110                     if (!first)
111                     {
112                         wrbuf_putc(b, ' ');
113                         lcol++;
114                     }
115                     while (l && !d1_isspace(*p))
116                     {
117                         wrbuf_putc(b, *p);
118                         p++;
119                         l--;
120                         lcol++;
121                     }
122                     first = 0;
123                 }
124                 wrbuf_write(b, "\n", 1);
125                 break;
126             case DATA1I_num:
127                 wrbuf_write(b, c->u.data.data, c->u.data.len);
128                 break;
129             case DATA1I_oid:
130                 wrbuf_write(b, c->u.data.data, c->u.data.len);
131             }
132         }
133     }
134     return 0;
135 }
136
137 char *data1_nodetoidsgml (data1_handle dh, data1_node *n, int select, int *len)
138 {
139     WRBUF b = data1_get_wrbuf (dh);
140     char line[1024];
141     
142     wrbuf_rewind(b);
143     
144     sprintf(line, "<%s>\n", n->u.root.type);
145     wrbuf_write(b, line, strlen(line));
146     if (nodetoidsgml(n, select, b, 0))
147         return 0;
148     sprintf(line, "</%s>\n", n->u.root.type);
149     wrbuf_write(b, line, strlen(line));
150     *len = wrbuf_len(b);
151     return wrbuf_buf(b);
152 }