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