libxsl-ruby 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/CHANGELOG +14 -0
  2. data/LICENSE +21 -0
  3. data/README +50 -0
  4. data/Rakefile +245 -0
  5. data/TODO +32 -0
  6. data/ext/xml/extconf.rb +97 -0
  7. data/ext/xml/libxml-ruby/libxml.h +92 -0
  8. data/ext/xml/libxml-ruby/ruby_xml_attr.h +31 -0
  9. data/ext/xml/libxml-ruby/ruby_xml_attribute.h +31 -0
  10. data/ext/xml/libxml-ruby/ruby_xml_document.h +37 -0
  11. data/ext/xml/libxml-ruby/ruby_xml_dtd.h +27 -0
  12. data/ext/xml/libxml-ruby/ruby_xml_input_cbg.h +31 -0
  13. data/ext/xml/libxml-ruby/ruby_xml_node.h +38 -0
  14. data/ext/xml/libxml-ruby/ruby_xml_node_set.h +36 -0
  15. data/ext/xml/libxml-ruby/ruby_xml_ns.h +31 -0
  16. data/ext/xml/libxml-ruby/ruby_xml_parser.h +41 -0
  17. data/ext/xml/libxml-ruby/ruby_xml_parser_context.h +32 -0
  18. data/ext/xml/libxml-ruby/ruby_xml_sax_parser.h +31 -0
  19. data/ext/xml/libxml-ruby/ruby_xml_schema.h +26 -0
  20. data/ext/xml/libxml-ruby/ruby_xml_tree.h +22 -0
  21. data/ext/xml/libxml-ruby/ruby_xml_xinclude.h +23 -0
  22. data/ext/xml/libxml-ruby/ruby_xml_xpath.h +34 -0
  23. data/ext/xml/libxml-ruby/ruby_xml_xpath_context.h +34 -0
  24. data/ext/xml/libxml-ruby/ruby_xml_xpointer.h +37 -0
  25. data/ext/xml/libxml-ruby/ruby_xml_xpointer_context.h +28 -0
  26. data/ext/xml/libxslt.c +247 -0
  27. data/ext/xml/libxslt.h +52 -0
  28. data/ext/xml/ruby_xslt_stylesheet.c +298 -0
  29. data/ext/xml/ruby_xslt_stylesheet.h +21 -0
  30. data/ext/xml/ruby_xslt_transform_context.c +63 -0
  31. data/ext/xml/ruby_xslt_transform_context.h +22 -0
  32. data/tests/commentary.dtd +34 -0
  33. data/tests/fuzface.rb +15 -0
  34. data/tests/fuzface.xml +154 -0
  35. data/tests/fuzface.xsl +4 -0
  36. data/tests/ramblings.xsl +46 -0
  37. data/tests/tc_libxslt.rb +65 -0
  38. data/tests/tc_xslt_stylesheet.rb +41 -0
  39. data/tests/tc_xslt_stylesheet2.rb +41 -0
  40. metadata +101 -0
@@ -0,0 +1,52 @@
1
+ /* $Id: libxslt.h,v 1.1 2006/03/24 10:54:55 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RUBY_LIBXSLT_H__
6
+ #define __RUBY_LIBXSLT_H__
7
+
8
+ #include <ruby.h>
9
+ #include <rubyio.h>
10
+ #include <libxml/parser.h>
11
+ #include <libxml/debugXML.h>
12
+ #include <libxslt/extra.h>
13
+ #include <libxslt/xslt.h>
14
+ #include <libxslt/xsltInternals.h>
15
+ #include <libxslt/transform.h>
16
+ #include <libxslt/xsltutils.h>
17
+ #include <libexslt/exslt.h>
18
+
19
+ #include "libxml-ruby/libxml.h"
20
+ #include "libxml-ruby/ruby_xml_document.h"
21
+ #include "ruby_xslt_stylesheet.h"
22
+ #include "ruby_xslt_transform_context.h"
23
+
24
+ #define RUBY_LIBXSLT_VERSION "0.3.6"
25
+ #define RUBY_LIBXSLT_VERNUM 036
26
+ #define RUBY_LIBXSLT_VER_MAJ 0
27
+ #define RUBY_LIBXSLT_VER_MIN 3
28
+ #define RUBY_LIBXSLT_VER_MIC 6
29
+
30
+ #define RUBY_LIBXSLT_SRC_TYPE_NULL 0
31
+ #define RUBY_LIBXSLT_SRC_TYPE_FILE 1
32
+
33
+ extern VALUE mXML;
34
+ extern VALUE cXMLDocument;
35
+
36
+ extern VALUE cXSLT;
37
+ extern VALUE eXMLXSLTStylesheetRequireParsedDoc;
38
+
39
+ typedef struct ruby_xslt {
40
+ int data_type;
41
+ void *data;
42
+ VALUE str;
43
+ VALUE xml_doc_obj;
44
+ VALUE ctxt;
45
+ xsltStylesheetPtr xsp;
46
+ } ruby_xslt;
47
+
48
+ #if ((RUBY_LIBXML_VER_MAJ != RUBY_LIBXSLT_VER_MAJ) || (RUBY_LIBXML_VER_MIN != RUBY_LIBXSLT_VER_MIN))
49
+ #error "Incompatible LibXML-Ruby headers - please install same major/micro version"
50
+ #endif
51
+
52
+ #endif
@@ -0,0 +1,298 @@
1
+ /* $Id: ruby_xslt_stylesheet.c,v 1.1 2006/03/24 10:54:55 roscopeco Exp $ */
2
+
3
+ /* See the LICENSE file for copyright and distribution information. */
4
+
5
+ #include "libxslt.h"
6
+ #include "ruby_xslt_stylesheet.h"
7
+
8
+ VALUE cXSLTStylesheet;
9
+
10
+ /* call-seq:
11
+ * sheet.apply => (true|false)
12
+ *
13
+ * Apply this stylesheet transformation to the source
14
+ * document.
15
+ */
16
+ VALUE
17
+ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
18
+ ruby_xslt_stylesheet *xss;
19
+ ruby_xml_document *rxd;
20
+ const char **params;
21
+ VALUE parameter, tmp;
22
+ int i, len;
23
+
24
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
25
+
26
+ if (NIL_P(xss->xml_doc_obj))
27
+ rb_raise(rb_eArgError, "Need a document object");
28
+
29
+ Data_Get_Struct(xss->xml_doc_obj, ruby_xml_document, rxd);
30
+
31
+ params = NULL;
32
+
33
+ switch(argc) {
34
+ case 0:
35
+ break;
36
+ case 1:
37
+ parameter = argv[0];
38
+ #if RUBY_VERSION_CODE >= 180
39
+ if (TYPE(parameter) == T_HASH) {
40
+ /* Convert parameter to an array */
41
+ parameter = rb_hash_to_a(parameter);
42
+ }
43
+ #endif
44
+
45
+ if (TYPE(parameter) == T_ARRAY) {
46
+ /* A hash is better than an array, but we can live with an array of arrays */
47
+ len = RARRAY(parameter)->len;
48
+ params = (void *)ALLOC_N(char *, (len * 2) + 2);
49
+ for (i=0; i < RARRAY(parameter)->len; i++) {
50
+ tmp = RARRAY(parameter)->ptr[i];
51
+
52
+ Check_Type(tmp, T_ARRAY);
53
+ Check_Type(RARRAY(tmp)->ptr[0], T_STRING);
54
+ Check_Type(RARRAY(tmp)->ptr[1], T_STRING);
55
+
56
+ params[2*i] = RSTRING(RARRAY(tmp)->ptr[0])->ptr;
57
+ params[2*i+1] = RSTRING(RARRAY(tmp)->ptr[1])->ptr;
58
+ }
59
+ params[2*i] = params[2*i+1] = 0;
60
+ } else {
61
+ /* I should test to see if the object responds to to_a and to_h before calling this, but oh well */
62
+ rb_raise(rb_eTypeError, "xslt_stylesheet_appy: expecting a hash or an array of arrays as a parameter");
63
+ }
64
+
65
+ break;
66
+ default:
67
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
68
+ }
69
+
70
+ xss->parsed = ruby_xml_document_new(cXMLDocument,
71
+ xsltApplyStylesheet(xss->xsp,
72
+ rxd->doc, params));
73
+
74
+ if (params) {
75
+ free(params);
76
+ }
77
+
78
+ if (xss->parsed == Qnil)
79
+ return(Qfalse);
80
+ else
81
+ return(Qtrue);
82
+ }
83
+
84
+
85
+ /* call-seq:
86
+ * sheet.debug(to = $stdout) => (true|false)
87
+ *
88
+ * Output a debug dump of this stylesheet to the specified output
89
+ * stream (an instance of IO, defaults to $stdout). Requires
90
+ * libxml/libxslt be compiled with debugging enabled. If this
91
+ * is not the case, a warning is triggered and the method returns
92
+ * false.
93
+ */
94
+ VALUE
95
+ ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) {
96
+ #ifdef LIBXML_DEBUG_ENABLED
97
+ OpenFile *fptr;
98
+ VALUE io;
99
+ FILE *out;
100
+ ruby_xml_document *parsed;
101
+ ruby_xslt_stylesheet *xss;
102
+
103
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
104
+ if (NIL_P(xss->parsed))
105
+ rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result");
106
+
107
+ switch (argc) {
108
+ case 0:
109
+ io = rb_stdout;
110
+ break;
111
+ case 1:
112
+ io = argv[0];
113
+ if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse)
114
+ rb_raise(rb_eTypeError, "need an IO object");
115
+ break;
116
+ default:
117
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
118
+ }
119
+
120
+ Data_Get_Struct(xss->parsed, ruby_xml_document, parsed);
121
+ if (parsed->doc == NULL)
122
+ return(Qnil);
123
+
124
+ GetOpenFile(io, fptr);
125
+ rb_io_check_writable(fptr);
126
+ out = GetWriteFile(fptr);
127
+ xmlDebugDumpDocument(out, parsed->doc);
128
+ return(Qtrue);
129
+ #else
130
+ rb_warn("libxml/libxslt was compiled without debugging support. Please recompile libxml/libxslt and their Ruby modules");
131
+ return(Qfalse);
132
+ #endif
133
+ }
134
+
135
+
136
+ void
137
+ ruby_xslt_stylesheet_free(ruby_xslt_stylesheet *xss) {
138
+ if (xss->xsp != NULL) {
139
+ xsltFreeStylesheet(xss->xsp);
140
+ xss->xsp = NULL;
141
+ }
142
+
143
+ free(xss);
144
+ }
145
+
146
+
147
+ void
148
+ ruby_xslt_stylesheet_mark(ruby_xslt_stylesheet *xss) {
149
+ if (!NIL_P(xss->parsed)) rb_gc_mark(xss->parsed);
150
+ if (!NIL_P(xss->xml_doc_obj)) rb_gc_mark(xss->xml_doc_obj);
151
+
152
+ switch (xss->data_type) {
153
+ case RUBY_LIBXSLT_SRC_TYPE_FILE:
154
+ if (xss->data != NULL)
155
+ rb_gc_mark((VALUE)xss->data);
156
+ break;
157
+ }
158
+ }
159
+
160
+
161
+ VALUE
162
+ ruby_xslt_stylesheet_new(VALUE class, xsltStylesheetPtr xsp) {
163
+ ruby_xslt_stylesheet *xss;
164
+
165
+ xss = ALLOC(ruby_xslt_stylesheet);
166
+ xss->xsp = xsp;
167
+ xss->xml_doc_obj = Qnil;
168
+ xss->parsed = Qnil;
169
+ xss->data_type = RUBY_LIBXSLT_SRC_TYPE_NULL;
170
+ xss->data = NULL;
171
+
172
+ return(Data_Wrap_Struct(cXSLTStylesheet, ruby_xslt_stylesheet_mark,
173
+ ruby_xslt_stylesheet_free, xss));
174
+ }
175
+
176
+ // TODO should this automatically apply the sheet if not already,
177
+ // given that we're unlikely to do much else with it?
178
+
179
+ /* call-seq:
180
+ * sheet.print(to = $stdout) => number_of_bytes
181
+ *
182
+ * Output the result of the transform to the specified output
183
+ * stream (an IO instance, defaults to $stdout). You *must* call
184
+ * +apply+ before this method or an exception will be raised.
185
+ */
186
+ VALUE
187
+ ruby_xslt_stylesheet_print(int argc, VALUE *argv, VALUE self) {
188
+ OpenFile *fptr;
189
+ VALUE io;
190
+ FILE *out;
191
+ ruby_xml_document *parsed;
192
+ ruby_xslt_stylesheet *xss;
193
+ int bytes;
194
+
195
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
196
+ if (NIL_P(xss->parsed))
197
+ rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result");
198
+
199
+ switch (argc) {
200
+ case 0:
201
+ io = rb_stdout;
202
+ break;
203
+ case 1:
204
+ io = argv[0];
205
+ if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse)
206
+ rb_raise(rb_eTypeError, "need an IO object");
207
+ break;
208
+ default:
209
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
210
+ }
211
+
212
+ Data_Get_Struct(xss->parsed, ruby_xml_document, parsed);
213
+ if (parsed->doc == NULL)
214
+ return(Qnil);
215
+
216
+ GetOpenFile(io, fptr);
217
+ rb_io_check_writable(fptr);
218
+ out = GetWriteFile(fptr);
219
+ bytes = xsltSaveResultToFile(out, parsed->doc, xss->xsp);
220
+
221
+ return(INT2NUM(bytes));
222
+ }
223
+
224
+ // TODO this, too. Either way, to_s probably should have prereqs
225
+ // like this, for one thing it makes IRB use tricky...
226
+
227
+ /* call-seq:
228
+ * sheet.to_s => "result"
229
+ *
230
+ * Obtain the result of the transform as a string. You *must* call
231
+ * +apply+ before this method or an exception will be raised.
232
+ */
233
+ VALUE
234
+ ruby_xslt_stylesheet_to_s(VALUE self) {
235
+ ruby_xml_document *parsed;
236
+ ruby_xslt_stylesheet *xss;
237
+ xmlChar *str;
238
+ int len;
239
+
240
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
241
+ if (NIL_P(xss->parsed))
242
+ rb_raise(eXMLXSLTStylesheetRequireParsedDoc, "must have a parsed XML result");
243
+ Data_Get_Struct(xss->parsed, ruby_xml_document, parsed);
244
+ if (parsed->doc == NULL)
245
+ return(Qnil);
246
+
247
+ xsltSaveResultToString(&str, &len, parsed->doc, xss->xsp);
248
+ if (str == NULL)
249
+ return(Qnil);
250
+ else
251
+ return(rb_str_new((const char*)str,len));
252
+ }
253
+
254
+
255
+
256
+ /* call-seq:
257
+ * sheet.save(io) => true
258
+ *
259
+ * Save the result of the transform to the supplied open
260
+ * file (an IO instance). You *must* call +apply+ before
261
+ * this method or an exception will be raised.
262
+ */
263
+ VALUE
264
+ ruby_xslt_stylesheet_save(VALUE self, VALUE io) {
265
+ ruby_xml_document *parsed;
266
+ ruby_xslt_stylesheet *xss;
267
+ OpenFile *fptr;
268
+
269
+ if (rb_obj_is_kind_of(io, rb_cIO) == Qfalse)
270
+ rb_raise(rb_eArgError, "Only accept IO objects for saving");
271
+
272
+ GetOpenFile(io, fptr);
273
+
274
+ Data_Get_Struct(self, ruby_xslt_stylesheet, xss);
275
+ Data_Get_Struct(xss->parsed, ruby_xml_document, parsed);
276
+
277
+ xsltSaveResultToFile(fptr->f, parsed->doc, xss->xsp);
278
+
279
+ return(Qtrue);
280
+ }
281
+
282
+ #ifdef RDOC_NEVER_DEFINED
283
+ mXML = rb_define_module("XML");
284
+ cXSLT = rb_define_class_under(mXML, "XSLT", rb_cObject);
285
+ #endif
286
+
287
+ void
288
+ ruby_init_xslt_stylesheet(void) {
289
+ cXSLTStylesheet = rb_define_class_under(cXSLT, "Stylesheet", rb_cObject);
290
+ eXMLXSLTStylesheetRequireParsedDoc =
291
+ rb_define_class_under(cXSLTStylesheet, "RequireParsedDoc", rb_eException);
292
+
293
+ rb_define_method(cXSLTStylesheet, "apply", ruby_xslt_stylesheet_apply, -1);
294
+ rb_define_method(cXSLTStylesheet, "debug", ruby_xslt_stylesheet_debug, -1);
295
+ rb_define_method(cXSLTStylesheet, "print", ruby_xslt_stylesheet_print, -1);
296
+ rb_define_method(cXSLTStylesheet, "to_s", ruby_xslt_stylesheet_to_s, 0);
297
+ rb_define_method(cXSLTStylesheet, "save", ruby_xslt_stylesheet_save, 1);
298
+ }
@@ -0,0 +1,21 @@
1
+ /* $Id: ruby_xslt_stylesheet.h,v 1.1 2006/03/24 10:54:55 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information. */
4
+
5
+ #ifndef __RUBY_LIBXSLT_STYLESHEET__
6
+ #define __RUBY_LIBXSLT_STYLESHEET__
7
+
8
+ extern VALUE cXSLTStylesheet;
9
+
10
+ typedef struct ruby_xslt_stylesheet {
11
+ int data_type;
12
+ void *data;
13
+ VALUE parsed; /* XML::Document # parsed xml document after xsl apply */
14
+ VALUE xml_doc_obj; /* XML::Document */
15
+ xsltStylesheetPtr xsp;
16
+ } ruby_xslt_stylesheet;
17
+
18
+ void ruby_init_xslt_stylesheet(void);
19
+ VALUE ruby_xslt_stylesheet_new(VALUE class, xsltStylesheetPtr xsp);
20
+
21
+ #endif /* __RUBY_LIBXSLT_STYLESHEET__ */
@@ -0,0 +1,63 @@
1
+ /* $Id: ruby_xslt_transform_context.c,v 1.1 2006/03/24 10:54:55 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "libxslt.h"
6
+ #include "ruby_xslt_transform_context.h"
7
+ #include "libxml-ruby/libxml.h"
8
+
9
+ VALUE cXSLTTransformContext;
10
+
11
+ void
12
+ ruby_xslt_transform_context_free(ruby_xslt_transform_context *rxtc) {
13
+ if (rxtc->ctxt != NULL) {
14
+ xsltFreeTransformContext(rxtc->ctxt);
15
+ rxtc->ctxt = NULL;
16
+ }
17
+ free(rxtc);
18
+ }
19
+
20
+ void
21
+ ruby_xslt_transform_context_mark(ruby_xslt_transform_context *rxtc) {
22
+ if (rxtc == NULL) return;
23
+ if (!NIL_P(rxtc->xslt)) rb_gc_mark(rxtc->xslt);
24
+ }
25
+
26
+
27
+ VALUE
28
+ ruby_xslt_transform_context_new(VALUE class, VALUE xslt,
29
+ xsltTransformContextPtr ctxt) {
30
+ ruby_xslt_transform_context *rxtc;
31
+ rxtc = ALLOC(ruby_xslt_transform_context);
32
+ ruby_xml_parser_count++;
33
+ rxtc->ctxt = ctxt;
34
+ rxtc->xslt = xslt;
35
+ //fprintf(stderr,"ruby_xslt_transform_context_new 2\n");
36
+ //if (class == Qfalse)
37
+ //fprintf(stderr,"ruby_xslt_transform_context_new: EEEEK!\n");
38
+ return(Data_Wrap_Struct(class, ruby_xslt_transform_context_mark,
39
+ ruby_xslt_transform_context_free, rxtc));
40
+ }
41
+
42
+
43
+ VALUE
44
+ ruby_xslt_transform_context_new2(VALUE class, VALUE xslt) {
45
+ return(ruby_xslt_transform_context_new(class, xslt, NULL));
46
+ }
47
+
48
+
49
+ VALUE
50
+ ruby_xslt_transform_context_new3(VALUE xslt) {
51
+ return(ruby_xslt_transform_context_new2(cXSLTTransformContext, xslt));
52
+ }
53
+
54
+ #ifdef RDOC_NEVER_DEFINED
55
+ mXML = rb_define_module("XML");
56
+ cXSLT = rb_define_class_under(mXML, "XSLT", rb_cObject);
57
+ #endif
58
+
59
+ void
60
+ ruby_init_xslt_transform_context(void) {
61
+ cXSLTTransformContext =
62
+ rb_define_class_under(cXSLT, "TransformContext", rb_cObject);
63
+ }
@@ -0,0 +1,22 @@
1
+ /* $Id: ruby_xslt_transform_context.h,v 1.1 2006/03/24 10:54:55 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RUBY_XSLT_TRANSFORM_CONTEXT__
6
+ #define __RUBY_XSLT_TRANSFORM_CONTEXT__
7
+
8
+ extern VALUE cXSLTTransformContext;
9
+
10
+ typedef struct ruby_xslt_transform_context {
11
+ xsltTransformContextPtr ctxt;
12
+ VALUE xslt;
13
+ } ruby_xslt_transform_context;
14
+
15
+ void ruby_init_xslt_transform_context(void);
16
+ void ruby_xslt_transform_context_free(ruby_xslt_transform_context *ctxt);
17
+ void ruby_xslt_transform_context_mark(ruby_xslt_transform_context *ctxt);
18
+ VALUE ruby_xslt_transform_context_new(VALUE class, VALUE xslt, xsltTransformContextPtr ctxt);
19
+ VALUE ruby_xslt_transform_context_new2(VALUE class, VALUE xslt);
20
+ VALUE ruby_xslt_transform_context_new3(VALUE xslt);
21
+
22
+ #endif