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