Added SGML-output filter.
[yaz-moved-to-github.git] / retrieval / d1_write.c
1 /*
2  * Copyright (c) 1995, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_write.c,v $
7  * Revision 1.1  1995-12-13 15:38:43  quinn
8  * Added SGML-output filter.
9  *
10  *
11  */
12
13 #include <string.h>
14 #include <ctype.h>
15
16 #include <data1.h>
17 #include <wrbuf.h>
18
19 #define IDSGML_MARGIN 75
20
21 static int wordlen(char *b)
22 {
23     int l = 0;
24
25     while (*b && !isspace(*b))
26         l++, b++;
27     return l;
28 }
29
30 static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
31 {
32     data1_node *c;
33     char line[1024];
34
35     for (c = n->child; c; c = c->next)
36     {
37         char *tag;
38
39         if (c->which == DATA1N_tag)
40         {
41             if (select && c->u.tag.node_selected)
42                 continue;
43             if (c->u.tag.element && c->u.tag.element->tag)
44                 tag = c->u.tag.element->tag->names->name; /* first name */
45             else
46                 tag = c->u.tag.tag; /* local string tag */
47             if (data1_matchstr(tag, "wellknown")) /* skip wellknown */
48             {
49                 sprintf(line, "<%s>\n", tag);
50                 wrbuf_write(b, line, strlen(line));
51                 col = 0;
52             }
53             if (nodetoidsgml(c, select, b, col) < 0)
54                 return -1;
55             wrbuf_write(b, "</>\n", 5);
56             col = 0;
57         }
58         else if (c->which == DATA1N_data)
59         {
60             char *p = c->u.data.data;
61             int l = c->u.data.len;
62             int first = 1;
63
64             if (c->u.data.what == DATA1I_text)
65             {
66                 while (l)
67                 {
68                     int wlen;
69
70                     while (l && isspace(*p))
71                         p++, l--;
72                     if (!l)
73                         break;
74                     /* break if we'll cross margin and word is not too long */
75                     if (col + (wlen = wordlen(p)) > IDSGML_MARGIN && wlen <
76                         IDSGML_MARGIN)
77                     {
78                         sprintf(line, "\n");
79                         col = 0;
80                         wrbuf_write(b, line, strlen(line));
81                         first = 1;
82                     }
83                     if (!first)
84                     {
85                         wrbuf_putc(b, ' ');
86                         col++;
87                     }
88                     while (l && !isspace(*p))
89                     {
90 #if 0
91                         if (col > NTOBUF_MARGIN)
92                         {
93                             wrbuf_putc(b, '=');
94                             wrbuf_putc(b, '\n');
95                             sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
96                             wrbuf_write(b, line, strlen(line));
97                             col = indent * NTOBUF_INDENT;
98                         }
99 #endif
100                         wrbuf_putc(b, *p);
101                         p++;
102                         l--;
103                         col++;
104                     }
105                     first = 0;
106                 }
107                 wrbuf_write(b, "\n", 1);
108                 col = 0;
109             }
110             else if (c->u.data.what == DATA1I_num)
111             {
112                 wrbuf_putc(b, ' ');
113                 wrbuf_write(b, c->u.data.data, c->u.data.len);
114             }
115         }
116     }
117     return 0;
118 }
119
120 char *data1_nodetoidsgml(data1_node *n, int select, int *len)
121 {
122     static WRBUF b = 0;
123     char line[1024];
124
125     if (!b)
126         b = wrbuf_alloc();
127     else
128         wrbuf_rewind(b);
129     
130     sprintf(line, "<%s>\n", n->u.root.type);
131     wrbuf_write(b, line, strlen(line));
132     if (nodetoidsgml(n, select, b, 0))
133         return 0;
134     sprintf(line, "</%s>\n", n->u.root.type);
135     wrbuf_write(b, line, strlen(line));
136     *len = wrbuf_len(b);
137     return wrbuf_buf(b);
138 }