libxslt-ruby 1.0.1-x86-mingw32 → 1.0.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,17 +6,26 @@
6
6
  #define __RUBY_LIBXSLT_H__
7
7
 
8
8
  #include <ruby.h>
9
+ #if HAVE_RUBY_IO_H
10
+ #include <ruby/io.h>
11
+ #else
9
12
  #include <rubyio.h>
13
+ #endif
14
+
10
15
  #include <libxml/parser.h>
11
16
  #include <libxml/debugXML.h>
17
+ #include <ruby_libxml.h>
18
+
12
19
  #include <libxslt/extra.h>
13
20
  #include <libxslt/xslt.h>
14
21
  #include <libxslt/xsltInternals.h>
15
22
  #include <libxslt/transform.h>
16
23
  #include <libxslt/xsltutils.h>
24
+
17
25
  #include <libexslt/exslt.h>
18
26
 
19
27
  #include "ruby_xslt_stylesheet.h"
28
+ #include "ruby_exslt.h"
20
29
 
21
30
  #include "version.h"
22
31
 
@@ -27,5 +36,6 @@
27
36
  extern VALUE cLibXSLT;
28
37
  extern VALUE cXSLT;
29
38
  extern VALUE eXSLTError;
39
+ extern VALUE cXMLDocument;
30
40
 
31
41
  #endif
@@ -0,0 +1,148 @@
1
+ /* http://xmlsoft.org/XSLT/html/libxslt-extensions.html */
2
+
3
+ #include "libxslt.h"
4
+
5
+ /* Helper method to retrieve (and possibly initialize)
6
+ the module function registry hash for +namespace+ */
7
+ static VALUE
8
+ ruby_xslt_module_function_hash(VALUE namespace) {
9
+ VALUE ns_hash, func_hash;
10
+
11
+ if ((ns_hash = rb_ivar_get(cXSLT, rb_intern("@module_function_registry"))) == Qnil) {
12
+ ns_hash = rb_ivar_set(cXSLT, rb_intern("@module_function_registry"), rb_hash_new());
13
+ }
14
+
15
+ if ((func_hash = rb_hash_aref(ns_hash, namespace)) == Qnil) {
16
+ func_hash = rb_hash_aset(ns_hash, namespace, rb_hash_new());
17
+ }
18
+
19
+ return func_hash;
20
+ }
21
+
22
+ /* Helper method for xsltRegisterExtModuleFunction callback */
23
+ static void
24
+ ruby_xslt_module_function_callback(xmlXPathParserContextPtr ctxt, int nargs) {
25
+ VALUE callback, args[nargs];
26
+ const xmlChar *namespace, *name;
27
+ int i;
28
+
29
+ if (ctxt == NULL || ctxt->context == NULL) {
30
+ return;
31
+ }
32
+
33
+ namespace = ctxt->context->functionURI;
34
+ name = ctxt->context->function;
35
+
36
+ callback = rb_hash_aref(
37
+ ruby_xslt_module_function_hash(rb_str_new2((char *)namespace)),
38
+ rb_str_new2((char *)name)
39
+ );
40
+
41
+ if (callback == Qnil) {
42
+ rb_raise(rb_eArgError, "name `%s' not registered", name);
43
+ }
44
+
45
+ for (i = nargs - 1; i >= 0; i--) {
46
+ args[i] = rxml_xpath_to_value(ctxt->context, valuePop(ctxt));
47
+ }
48
+
49
+ valuePush(ctxt, rxml_xpath_from_value(
50
+ rb_funcall2(callback, rb_intern("call"), nargs, args)
51
+ ));
52
+ }
53
+
54
+ /* call-seq:
55
+ * XSLT.register_module_function(namespace, name) { ... } -> Proc or nil
56
+ *
57
+ * Registers +name+ as extension module function in +namespace+ with the
58
+ * block as callback. Returns the callback if successful, or +nil+ otherwise.
59
+ *
60
+ * The callback will be called with whatever XPath expression you pass
61
+ * into the function converted to a Ruby object. Its return value will
62
+ * be converted to an XPath expression again.
63
+ *
64
+ * Example:
65
+ *
66
+ * # register your extension function
67
+ * XSLT.register_module_function('http://ex.ns', 'ex-func') { |xp|
68
+ * xp.to_a.join('|').upcase
69
+ * }
70
+ *
71
+ * # then use it in your stylesheet
72
+ * <xsl:stylesheet ... xmlns:ex="http://ex.ns">
73
+ * ...
74
+ * <xsl:value-of select="ex:ex-func(.)" />
75
+ * <!-- the current node as upper case string -->
76
+ * </xsl:stylesheet>
77
+ */
78
+ static VALUE
79
+ ruby_xslt_register_module_function(VALUE class, VALUE namespace, VALUE name) {
80
+ VALUE callback;
81
+
82
+ if (!rb_block_given_p()) {
83
+ rb_raise(rb_eArgError, "no block given");
84
+ }
85
+
86
+ if (xsltRegisterExtModuleFunction(
87
+ BAD_CAST StringValuePtr(name),
88
+ BAD_CAST StringValuePtr(namespace),
89
+ ruby_xslt_module_function_callback
90
+ ) != 0) {
91
+ return Qnil;
92
+ }
93
+
94
+ callback = rb_block_proc();
95
+
96
+ rb_hash_aset(ruby_xslt_module_function_hash(namespace), name, callback);
97
+ return callback;
98
+ }
99
+
100
+ /* call-seq:
101
+ * XSLT.unregister_module_function(namespace, name) -> Proc or nil
102
+ *
103
+ * Unregisters +name+ as extension module function in +namespace+.
104
+ * Returns the previous callback if successful, or +nil+ otherwise.
105
+ */
106
+ static VALUE
107
+ ruby_xslt_unregister_module_function(VALUE class, VALUE namespace, VALUE name) {
108
+ VALUE func_hash, callback;
109
+
110
+ func_hash = ruby_xslt_module_function_hash(namespace);
111
+
112
+ if ((callback = rb_hash_aref(func_hash, name)) == Qnil) {
113
+ return Qnil;
114
+ }
115
+
116
+ if (xsltUnregisterExtModuleFunction(
117
+ BAD_CAST StringValuePtr(name),
118
+ BAD_CAST StringValuePtr(namespace)
119
+ ) != 0) {
120
+ return Qnil;
121
+ }
122
+
123
+ rb_hash_aset(func_hash, name, Qnil);
124
+ return callback;
125
+ }
126
+
127
+ /* call-seq:
128
+ * XSLT.registered_module_function?(namespace, name) -> true or false
129
+ *
130
+ * Returns +true+ if +name+ is currently registered as extension module
131
+ * function in +namespace+, or +false+ otherwise.
132
+ */
133
+ static VALUE
134
+ ruby_xslt_registered_module_function_p(VALUE class, VALUE namespace, VALUE name) {
135
+ return RTEST(rb_hash_aref(ruby_xslt_module_function_hash(namespace), name));
136
+ }
137
+
138
+ void
139
+ ruby_init_exslt() {
140
+ /* [HACK] Enclosing classes/modules for RDoc:
141
+ * cLibXSLT = rb_define_module("LibXSLT");
142
+ * cXSLT = rb_define_module_under(cLibXSLT, "XSLT");
143
+ */
144
+
145
+ rb_define_singleton_method(cXSLT, "register_module_function", ruby_xslt_register_module_function, 2);
146
+ rb_define_singleton_method(cXSLT, "unregister_module_function", ruby_xslt_unregister_module_function, 2);
147
+ rb_define_singleton_method(cXSLT, "registered_module_function?", ruby_xslt_registered_module_function_p, 2);
148
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef __RUBY_EXSLT__
2
+ #define __RUBY_EXSLT__
3
+
4
+ #include <libxslt/extensions.h>
5
+
6
+ void ruby_init_exslt(void);
7
+
8
+ #endif
@@ -3,25 +3,18 @@
3
3
  /* See the LICENSE file for copyright and distribution information. */
4
4
 
5
5
  #include "libxslt.h"
6
- #include "ruby_xslt_stylesheet.h"
7
6
 
8
7
  /*
9
8
  * Document-class: LibXSLT::XSLT::Stylesheet
10
- *
9
+ *
11
10
  * The XSLT::Stylesheet represents a XSL stylesheet that
12
11
  * can be used to transform an XML document. For usage information
13
12
  * refer to XSLT::Stylesheet#apply
14
13
  *
15
- */
14
+ */
16
15
 
17
16
  VALUE cXSLTStylesheet;
18
17
 
19
- static VALUE
20
- ruby_xslt_stylesheet_document_klass() {
21
- VALUE mXML = rb_const_get(rb_cObject, rb_intern("XML"));
22
- return rb_const_get(mXML, rb_intern("Document"));
23
- }
24
-
25
18
  void
26
19
  ruby_xslt_stylesheet_free(xsltStylesheetPtr xstylesheet) {
27
20
  xsltFreeStylesheet(xstylesheet);
@@ -33,11 +26,11 @@ ruby_xslt_stylesheet_alloc(VALUE klass) {
33
26
  NULL, ruby_xslt_stylesheet_free,
34
27
  NULL);
35
28
  }
36
-
29
+
37
30
 
38
31
  /* call-seq:
39
32
  * XSLT::Stylesheet.new(document) -> XSLT::Stylesheet
40
- *
33
+ *
41
34
  * Creates a new XSLT stylesheet based on the specified document.
42
35
  * For memory management reasons, a copy of the specified document
43
36
  * will be made, so its best to create a single copy of a stylesheet
@@ -53,24 +46,24 @@ ruby_xslt_stylesheet_initialize(VALUE self, VALUE document) {
53
46
  xmlDocPtr xcopy;
54
47
  xsltStylesheetPtr xstylesheet;
55
48
 
56
- if (!rb_obj_is_kind_of(document, ruby_xslt_stylesheet_document_klass()))
49
+ if (!rb_obj_is_kind_of(document, cXMLDocument))
57
50
  rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
58
-
59
- /* NOTE!! Since the stylesheet own the specified document, the easiest
60
- * thing to do from a memory standpoint is too copy it and not expose
61
- * the copy to Ruby. The other solution is expose a memory management
62
- * API on the document object for taking ownership of the document
63
- * and specifying when it has been freed. Then the document class
64
- * has to be updated to always check and see if the document is
65
- * still valid. That's all doable, but seems like a pain, so
66
- * just copy the document for now. */
51
+
52
+ /* NOTE!! Since the stylesheet own the specified document, the easiest
53
+ * thing to do from a memory standpoint is too copy it and not expose
54
+ * the copy to Ruby. The other solution is expose a memory management
55
+ * API on the document object for taking ownership of the document
56
+ * and specifying when it has been freed. Then the document class
57
+ * has to be updated to always check and see if the document is
58
+ * still valid. That's all doable, but seems like a pain, so
59
+ * just copy the document for now. */
67
60
  Data_Get_Struct(document, xmlDoc, xdoc);
68
61
  xcopy = xmlCopyDoc(xdoc, 1);
69
62
  xstylesheet = xsltParseStylesheetDoc(xcopy);
70
63
  xstylesheet->_private = (void *)self;
71
64
  DATA_PTR(self) = xstylesheet;
72
-
73
- /* Save a reference to the document as an attribute accessable to ruby*/
65
+
66
+ /* Save a reference to the document as an attribute accessable to ruby */
74
67
  return self;
75
68
  }
76
69
 
@@ -91,18 +84,17 @@ ruby_xslt_coerce_params(VALUE params) {
91
84
  memset(result[i], 0, strLen + 1);
92
85
  strncpy(result[i], RSTRING_PTR(str), strLen);
93
86
  }
94
-
87
+
95
88
  /* Null terminate the array - need to empty elements */
96
89
  result[i] = NULL;
97
90
  result[i+1] = NULL;
98
-
91
+
99
92
  return result;
100
- }
101
-
93
+ }
102
94
 
103
- /* call-seq:
95
+ /* call-seq:
104
96
  * stylesheet.apply(document, {params}) -> XML::Document
105
- *
97
+ *
106
98
  * Apply this stylesheet transformation to the provided document.
107
99
  * This method may be invoked multiple times.
108
100
  *
@@ -111,7 +103,7 @@ ruby_xslt_coerce_params(VALUE params) {
111
103
  * * params - An optional hash table that specifies the values for xsl:param values embedded in the stylesheet.
112
104
  *
113
105
  * Example:
114
- *
106
+ *
115
107
  * stylesheet_doc = XML::Document.file('stylesheet_file')
116
108
  * stylesheet = XSLT::Stylesheet.new(stylesheet_doc)
117
109
  *
@@ -127,15 +119,15 @@ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
127
119
  VALUE document;
128
120
  VALUE params;
129
121
  int i;
130
-
122
+
131
123
  char** pParams;
132
124
 
133
125
  if (argc > 2 || argc < 1)
134
126
  rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
135
-
127
+
136
128
  document = argv[0];
137
-
138
- if (!rb_obj_is_kind_of(document, ruby_xslt_stylesheet_document_klass()))
129
+
130
+ if (!rb_obj_is_kind_of(document, cXMLDocument))
139
131
  rb_raise(rb_eTypeError, "Must pass in an XML::Document instance.");
140
132
 
141
133
  /* Make sure params is a flat array */
@@ -143,29 +135,29 @@ ruby_xslt_stylesheet_apply(int argc, VALUE *argv, VALUE self) {
143
135
  params = rb_Array(params);
144
136
  rb_funcall(params, rb_intern("flatten!"), 0);
145
137
  pParams = ruby_xslt_coerce_params(params);
146
-
138
+
147
139
  Data_Get_Struct(document, xmlDoc, xdoc);
148
140
  Data_Get_Struct(self, xsltStylesheet, xstylesheet);
149
-
141
+
150
142
  result = xsltApplyStylesheet(xstylesheet, xdoc, (const char**)pParams);
151
-
143
+
152
144
  if (!result)
153
145
  rb_raise(eXSLTError, "Transformation failed");
154
-
146
+
155
147
  /* Free allocated array of *chars. Note we don't have to
156
148
  free the last array item since its set to NULL. */
157
149
  for (i=0; i<RARRAY_LEN(params); i++) {
158
150
  ruby_xfree(pParams[i]);
159
151
  }
160
152
  ruby_xfree(pParams);
161
-
153
+
162
154
  return rxml_document_wrap(result);
163
155
  }
164
156
 
165
157
 
166
- /* call-seq:
158
+ /* call-seq:
167
159
  * sheet.debug(to = $stdout) => (true|false)
168
- *
160
+ *
169
161
  * Output a debug dump of this stylesheet to the specified output
170
162
  * stream (an instance of IO, defaults to $stdout). Requires
171
163
  * libxml/libxslt be compiled with debugging enabled. If this
@@ -214,12 +206,12 @@ ruby_xslt_stylesheet_debug(int argc, VALUE *argv, VALUE self) {
214
206
  }
215
207
  */
216
208
 
217
- // TODO should this automatically apply the sheet if not already,
218
- // given that we're unlikely to do much else with it?
209
+ /* TODO should this automatically apply the sheet if not already,
210
+ given that we're unlikely to do much else with it? */
219
211
 
220
- /* call-seq:
212
+ /* call-seq:
221
213
  * sheet.print(to = $stdout) => number_of_bytes
222
- *
214
+ *
223
215
  * Output the result of the transform to the specified output
224
216
  * stream (an IO instance, defaults to $stdout). You *must* call
225
217
  * +apply+ before this method or an exception will be raised.
@@ -5,10 +5,6 @@
5
5
  #ifndef __RUBY_LIBXSLT_STYLESHEET__
6
6
  #define __RUBY_LIBXSLT_STYLESHEET__
7
7
 
8
- // Includes from libxml-ruby
9
- #include <libxml/ruby_libxml.h>
10
- #include <libxml/ruby_xml_document.h>
11
-
12
8
  extern VALUE cXSLTStylesheet;
13
9
 
14
10
  void ruby_init_xslt_stylesheet(void);
@@ -1,5 +1,5 @@
1
- #define RUBY_LIBXSLT_VERSION "1.0.1"
1
+ #define RUBY_LIBXSLT_VERSION "1.0.2"
2
2
  #define RUBY_LIBXSLT_VERNUM 1
3
3
  #define RUBY_LIBXSLT_VER_MAJ 0
4
- #define RUBY_LIBXSLT_VER_MIN 1
4
+ #define RUBY_LIBXSLT_VER_MIN 2
5
5
  #define RUBY_LIBXSLT_VER_MIC 0
Binary file
Binary file
@@ -1,11 +1,11 @@
1
1
  # encoding: UTF-8
2
2
  # :enddoc:
3
- # These classes provide provide backwards compatibility with
3
+ # These classes provide provide backwards compatibility with
4
4
  # versions of libxslt-ruby prior to version 0.7.0
5
5
 
6
6
  module LibXML
7
7
  module XML
8
- module XSLT
8
+ module XSLT
9
9
  MAX_DEPTH = LibXSLT::XSLT::MAX_DEPTH
10
10
  MAX_SORT = LibXSLT::XSLT::MAX_SORT
11
11
  ENGINE_VERSION = LibXSLT::XSLT::ENGINE_VERSION
data/lib/xslt.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # It is recommend that you only load this file for libs
6
6
  # that do not have their own namespace, eg. administrative
7
7
  # scripts, personal programs, etc. For other applications
8
- # require 'libxslt' instead and include LibXSLT into your
8
+ # require 'libxslt' instead and include LibXSLT into your
9
9
  # app/libs namespace.
10
10
 
11
11
  require 'libxslt'
data/libxslt-ruby.gemspec CHANGED
@@ -7,7 +7,7 @@ FILES = FileList[
7
7
  'CHANGES',
8
8
  'LICENSE',
9
9
  'Rakefile',
10
- 'README',
10
+ 'README.rdoc',
11
11
  'libxslt-ruby.gemspec',
12
12
  'setup.rb',
13
13
  'doc/**/*',
@@ -22,11 +22,11 @@ FILES = FileList[
22
22
  # Default GEM Specification
23
23
  Gem::Specification.new do |spec|
24
24
  spec.name = "libxslt-ruby"
25
-
25
+
26
26
  spec.homepage = "http://libxslt.rubyforge.org/"
27
27
  spec.summary = "Ruby libxslt bindings"
28
28
  spec.description = <<-EOF
29
- The Libxslt-Ruby project provides Ruby language bindings for the GNOME
29
+ The Libxslt-Ruby project provides Ruby language bindings for the GNOME
30
30
  XSLT C library. It is free software, released under the MIT License.
31
31
  EOF
32
32
 
@@ -34,16 +34,16 @@ Gem::Specification.new do |spec|
34
34
  spec.version = version
35
35
  spec.author = "Charlie Savage"
36
36
  spec.email = "libxml-devel@rubyforge.org"
37
- spec.add_dependency('libxml-ruby','>=2.0.2')
37
+ spec.add_dependency('libxml-ruby','>=2.1.1')
38
38
  spec.platform = Gem::Platform::RUBY
39
- spec.require_paths = ["lib", "ext/libxslt"]
40
-
39
+ spec.require_paths = ["lib", "ext/libxslt"]
40
+
41
41
  spec.bindir = "bin"
42
42
  spec.extensions = ["ext/libxslt/extconf.rb"]
43
43
  spec.files = FILES.to_a
44
44
  spec.test_files = Dir.glob("test/tc_*.rb")
45
-
46
- spec.required_ruby_version = '>= 1.8.4'
45
+
46
+ spec.required_ruby_version = '>= 1.8.6'
47
47
  spec.date = DateTime.now
48
48
  spec.rubyforge_project = 'libxslt-ruby'
49
- end
49
+ end