libxslt-ruby 1.0.1 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +37 -7
- data/LICENSE +7 -7
- data/{README → README.rdoc} +19 -19
- data/Rakefile +25 -9
- data/ext/libxslt/extconf.h +0 -1
- data/ext/libxslt/extconf.rb +20 -22
- data/ext/libxslt/libxslt.c +7 -8
- data/ext/libxslt/libxslt.h +10 -0
- data/ext/libxslt/ruby_exslt.c +148 -0
- data/ext/libxslt/ruby_exslt.h +8 -0
- data/ext/libxslt/ruby_xslt_stylesheet.c +37 -45
- data/ext/libxslt/ruby_xslt_stylesheet.h +0 -4
- data/ext/libxslt/version.h +2 -2
- data/lib/libxslt/deprecated.rb +2 -2
- data/lib/xslt.rb +1 -1
- data/libxslt-ruby.gemspec +9 -9
- data/setup.rb +1585 -1585
- data/test/test_deprecated.rb +16 -14
- data/test/test_exslt.rb +70 -0
- data/test/test_helper.rb +16 -12
- data/test/test_stylesheet.rb +22 -22
- data/test/test_suite.rb +2 -1
- metadata +34 -40
- data/test/text.xml +0 -134
data/CHANGES
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
== 1.0.3 / 2011-07-31
|
2
|
+
|
3
|
+
* Added support for extension function registration. This was adapted from
|
4
|
+
Gregoire Lejeune's ruby-xslt library at https://github.com/glejeune/ruby-xslt (Jens Willie).
|
5
|
+
|
6
|
+
* Update to work with libxml-ruby 2.1.0 and higher (Jens Willie).
|
7
|
+
|
8
|
+
* Use ENV for rake compiler task configuration (Jens Willie)
|
9
|
+
|
10
|
+
* Build fixes (Charlie Savage).
|
11
|
+
|
12
|
+
* Switch to using def files to control library exports (Charlie Savage).
|
13
|
+
|
14
|
+
|
15
|
+
== 1.0.1 / 2011-04-18 Charlie Savage
|
16
|
+
|
17
|
+
* Modernize gem - add gemspec file, use rake-compiler
|
18
|
+
|
19
|
+
* Fix Ruby 1.9.2 compile errors
|
20
|
+
|
21
|
+
* Build fixes
|
22
|
+
|
23
|
+
* Update tests scripts to make testing during development easier
|
24
|
+
|
25
|
+
|
26
|
+
== 0.9.8 / 2011-01-18 Charlie Savage
|
27
|
+
|
28
|
+
* Update build environment
|
29
|
+
|
30
|
+
|
1
31
|
== 0.9.1 / 2008-11-24 Charlie Savage
|
2
32
|
|
3
33
|
* Support libxml-ruby bindings 0.9.3 and above which has a changed
|
@@ -13,11 +43,11 @@
|
|
13
43
|
|
14
44
|
== 0.8.2 / 2008-07-21 Charlie Savage
|
15
45
|
|
16
|
-
* To use LibXSLT you can either require 'xslt' or require 'libxslt'.
|
17
|
-
The differences is that require 'xslt' mixes the LibXML and
|
18
|
-
LIBXSLT modules into the global namespace, thereby allowing
|
46
|
+
* To use LibXSLT you can either require 'xslt' or require 'libxslt'.
|
47
|
+
The differences is that require 'xslt' mixes the LibXML and
|
48
|
+
LIBXSLT modules into the global namespace, thereby allowing
|
19
49
|
you to write code such as:
|
20
|
-
stylesheet = XSLT::Stylesheet.new(XML::Document.new). Note that
|
50
|
+
stylesheet = XSLT::Stylesheet.new(XML::Document.new). Note that
|
21
51
|
this is different from 0.8.0 release and may require updating your code.
|
22
52
|
|
23
53
|
* Support for libxml-ruby 0.8.2
|
@@ -41,7 +71,7 @@
|
|
41
71
|
|
42
72
|
* Simpler api
|
43
73
|
|
44
|
-
* Compatibility layer for pre-0.7.0 versions
|
74
|
+
* Compatibility layer for pre-0.7.0 versions
|
45
75
|
|
46
76
|
* Major rewrite, resulting in significantly less code
|
47
77
|
|
@@ -54,7 +84,7 @@
|
|
54
84
|
|
55
85
|
* Windows support (both lots of memory fixes and binaries)
|
56
86
|
|
57
|
-
* New libxslt.rb ruby wrapper, so programs can simply say require 'xslt'
|
87
|
+
* New libxslt.rb ruby wrapper, so programs can simply say require 'xslt'
|
58
88
|
|
59
89
|
|
60
90
|
== 0.5.0 / 2006-02-27 Ross Bamford <rosco at roscopeco.co.uk>
|
@@ -76,6 +106,6 @@
|
|
76
106
|
|
77
107
|
== 0.3.0 / 2004-02-01 Martin Povolny <martin@solnet.cz>
|
78
108
|
|
79
|
-
* libxslt.c: added call to ruby_init_xslt_transform_context() to make it
|
109
|
+
* libxslt.c: added call to ruby_init_xslt_transform_context() to make it
|
80
110
|
work on ruby1.8
|
81
111
|
|
data/LICENSE
CHANGED
@@ -3,19 +3,19 @@
|
|
3
3
|
Copyright (c) 2002-2006 Sean Chittenden <sean@chittenden.org> and contributors
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
-
this software and associated documentation files (the "Software"), to deal in
|
7
|
-
the Software without restriction, including without limitation the rights to
|
8
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
9
9
|
of the Software, and to permit persons to whom the Software is furnished to do
|
10
10
|
so, subject to the following conditions:
|
11
11
|
|
12
12
|
The above copyright notice and this permission notice shall be included in all
|
13
13
|
copies or substantial portions of the Software.
|
14
14
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
SOFTWARE.
|
data/{README → README.rdoc}
RENAMED
@@ -8,7 +8,7 @@ toolkit. It is free software, released under the MIT License.
|
|
8
8
|
|
9
9
|
== Requirements
|
10
10
|
|
11
|
-
libxslt-ruby requires Ruby 1.8.4 or higher. It is dependent on
|
11
|
+
libxslt-ruby requires Ruby 1.8.4 or higher. It is dependent on
|
12
12
|
the following libraries to function properly:
|
13
13
|
|
14
14
|
* libm (math routines: very standard)
|
@@ -24,7 +24,7 @@ includes an already built extension.
|
|
24
24
|
|
25
25
|
!!!NOTE!!! The libxml-ruby and libxslt-ruby bindings must absolutely, positively,
|
26
26
|
without a doubt share the same libxml2 library. This is because libxslt modifies
|
27
|
-
XML documents created by libxml2. If there are two copies of libxml2 on your
|
27
|
+
XML documents created by libxml2. If there are two copies of libxml2 on your
|
28
28
|
system, then when XML documents allocated in copy #1 are manipulated by copy #2,
|
29
29
|
a segmentation fault will occur. So make sure that your system has only one copy of libxml2
|
30
30
|
installed.
|
@@ -36,13 +36,13 @@ The easiest way to install libxslt-ruby is via Ruby Gems. To install:
|
|
36
36
|
|
37
37
|
<tt>gem install libxslt-ruby</tt>
|
38
38
|
|
39
|
-
If you are running Windows, make sure to install the Win32 RubyGem which
|
39
|
+
If you are running Windows, make sure to install the Win32 RubyGem which
|
40
40
|
includes an already built binary file. The binary is built against
|
41
41
|
libxml2 version 2.6.32, iconv version 1.11 and libxslt version 1.1.24.
|
42
42
|
Binaries for libxml2 and iconv are provided in the libxml-ruby bindings,
|
43
|
-
while a binary for libxslt is provided in the libxslt-ruby bindings.
|
43
|
+
while a binary for libxslt is provided in the libxslt-ruby bindings.
|
44
44
|
|
45
|
-
The Windows binaries are biult with MingW. The gem also includes
|
45
|
+
The Windows binaries are biult with MingW. The gem also includes
|
46
46
|
a Microsoft VC++ 2005 solution. If you wish to run a debug version
|
47
47
|
of libxml-ruby on Windows, then it is highly recommended
|
48
48
|
you use VC++.
|
@@ -51,12 +51,12 @@ you use VC++.
|
|
51
51
|
== USAGE
|
52
52
|
|
53
53
|
For in-depth information about using libxslt-ruby please refer
|
54
|
-
to its online Rdoc documentation.
|
54
|
+
to its online Rdoc documentation.
|
55
55
|
|
56
56
|
All libxslt classes are in the LibXSLT::XSLT module. The simplest
|
57
|
-
way to use libxslt is to require 'xslt'. This will mixin the
|
58
|
-
LibXML and LibXSLT modules into the global namespace, allowing you to
|
59
|
-
write code like this:
|
57
|
+
way to use libxslt is to require 'xslt'. This will mixin the
|
58
|
+
LibXML and LibXSLT modules into the global namespace, allowing you to
|
59
|
+
write code like this:
|
60
60
|
|
61
61
|
require 'xslt'
|
62
62
|
document = XML::Document.new
|
@@ -78,10 +78,10 @@ Given an XML file like:
|
|
78
78
|
|
79
79
|
<?xml version="1.0" encoding="UTF-8"?>
|
80
80
|
<?xml-stylesheet href="fuzface.xsl" type="text/xsl"?>
|
81
|
-
|
81
|
+
|
82
82
|
<commentary>
|
83
83
|
<meta>
|
84
|
-
<author>
|
84
|
+
<author>
|
85
85
|
<first_name>Sean</first_name>
|
86
86
|
<last_name>Chittenden</last_name>
|
87
87
|
<email>sean@chittenden.org</email>
|
@@ -91,7 +91,7 @@ Given an XML file like:
|
|
91
91
|
<id>$Id$</id> <title>Fuzface...</title>
|
92
92
|
<subtitle>The Internet's a big place and here's some proof...</subtitle>
|
93
93
|
</meta>
|
94
|
-
|
94
|
+
|
95
95
|
<body>
|
96
96
|
<para>
|
97
97
|
I think it's a tragedy that I'm going to start off my new
|
@@ -111,21 +111,21 @@ And an XSLT file like this:
|
|
111
111
|
<xsl:element name="head">
|
112
112
|
<xsl:element name="title">Ramblings - <xsl:value-of select="commentary/meta/title" /> - <xsl:value-of select="commentary/meta/subtitle" /></xsl:element>
|
113
113
|
</xsl:element>
|
114
|
-
|
114
|
+
|
115
115
|
<xsl:element name="body">
|
116
116
|
<xsl:element name="h1"><xsl:value-of select="commentary/meta/title" /></xsl:element>
|
117
117
|
<xsl:element name="h3"><xsl:value-of select="commentary/meta/subtitle" /></xsl:element>
|
118
118
|
By: <xsl:value-of select="commentary/meta/author/first_name" /> <xsl:value-of select="commentary/meta/author/last_name" /><xsl:element name="br" />
|
119
119
|
Date: <xsl:value-of select="commentary/meta/date" /><xsl:element name="br" />
|
120
|
-
|
120
|
+
|
121
121
|
<xsl:for-each select="./commentary/body">
|
122
122
|
<xsl:apply-templates />
|
123
123
|
</xsl:for-each>
|
124
|
-
|
124
|
+
|
125
125
|
</xsl:element>
|
126
126
|
</xsl:element>
|
127
127
|
</xsl:template>
|
128
|
-
|
128
|
+
|
129
129
|
<xsl:template match="para">
|
130
130
|
<xsl:element name="p">
|
131
131
|
<xsl:value-of select="." />
|
@@ -136,7 +136,7 @@ And an XSLT file like this:
|
|
136
136
|
We can easily transform the XML with the following ruby code:
|
137
137
|
|
138
138
|
require 'xslt'
|
139
|
-
|
139
|
+
|
140
140
|
# Create a new XSL Transform
|
141
141
|
stylesheet_doc = XML::Document.file('files/fuzface.xsl')
|
142
142
|
stylesheet = LibXSLT::Stylesheet.new(stylesheet_doc)
|
@@ -144,7 +144,7 @@ We can easily transform the XML with the following ruby code:
|
|
144
144
|
# Transform a xml document
|
145
145
|
xml_doc = XML::Document.file('files/fuzface.xml')
|
146
146
|
result = stylesheet.apply(xml_doc)
|
147
|
-
|
147
|
+
|
148
148
|
You can then print, save or manipulate the returned document.
|
149
149
|
|
150
150
|
== License
|
@@ -161,4 +161,4 @@ You can find the latest documentation at:
|
|
161
161
|
== MORE INFORMATION
|
162
162
|
|
163
163
|
For more information please refer to the documentation. If you have any
|
164
|
-
questions, please send email to libxml-devel@rubyforge.org.
|
164
|
+
questions, please send email to libxml-devel@rubyforge.org.
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require "rubygems"
|
4
4
|
require "rake/extensiontask"
|
5
5
|
require "rake/testtask"
|
6
|
-
require '
|
6
|
+
require 'rdoc/task'
|
7
7
|
require "grancher/task"
|
8
8
|
require "yaml"
|
9
9
|
|
@@ -13,19 +13,33 @@ SO_NAME = "libxslt_ruby"
|
|
13
13
|
# Read the spec file
|
14
14
|
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
15
15
|
|
16
|
-
# Setup compile tasks
|
16
|
+
# Setup compile tasks. Configuration can be passed via EVN.
|
17
|
+
# Example:
|
18
|
+
# rake compile with_xml2_include=C:/MinGW/local/include/libxml2
|
19
|
+
# with_xslt_include=C:/MinGW/local/include/libxslt
|
20
|
+
# with_exslt_include=C:/MinGW/local/include/libexslt
|
17
21
|
Rake::ExtensionTask.new do |ext|
|
18
22
|
ext.gem_spec = spec
|
19
23
|
ext.name = SO_NAME
|
20
24
|
ext.ext_dir = "ext/libxslt"
|
21
25
|
ext.lib_dir = "lib/#{RUBY_VERSION.sub(/\.\d$/, '')}"
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
|
27
|
+
ENV.each do |key, val|
|
28
|
+
next unless key =~ /\Awith_(\w+)\z/i
|
29
|
+
puts key
|
30
|
+
puts val
|
31
|
+
opt = $1.downcase.tr('_', '-')
|
32
|
+
|
33
|
+
if File.directory?(path = File.expand_path(val))
|
34
|
+
ext.config_options << "--with-#{opt}=#{path}"
|
35
|
+
else
|
36
|
+
warn "No such directory: #{opt}: #{path}"
|
37
|
+
end
|
38
|
+
end
|
25
39
|
end
|
26
40
|
|
27
41
|
# Setup generic gem
|
28
|
-
|
42
|
+
Gem::PackageTask.new(spec) do |pkg|
|
29
43
|
pkg.package_dir = 'pkg'
|
30
44
|
pkg.need_tar = false
|
31
45
|
end
|
@@ -39,12 +53,13 @@ if RUBY_PLATFORM.match(/win32|mingw32/)
|
|
39
53
|
win_spec = spec.clone
|
40
54
|
win_spec.platform = Gem::Platform::CURRENT
|
41
55
|
win_spec.files += binaries.to_a
|
56
|
+
win_spec.instance_variable_set(:@cache_file, nil)
|
42
57
|
|
43
58
|
# Unset extensions
|
44
59
|
win_spec.extensions = nil
|
45
60
|
|
46
61
|
# Rake task to build the windows package
|
47
|
-
|
62
|
+
Gem::PackageTask.new(win_spec) do |pkg|
|
48
63
|
pkg.package_dir = 'pkg'
|
49
64
|
pkg.need_tar = false
|
50
65
|
end
|
@@ -52,11 +67,11 @@ end
|
|
52
67
|
|
53
68
|
# RDoc Task
|
54
69
|
desc "Generate rdoc documentation"
|
55
|
-
|
70
|
+
RDoc::Task.new("rdoc") do |rdoc|
|
56
71
|
rdoc.rdoc_dir = 'doc'
|
57
72
|
rdoc.title = "libxml-xslt"
|
58
73
|
# Show source inline with line numbers
|
59
|
-
rdoc.options << "--
|
74
|
+
rdoc.options << "--line-numbers"
|
60
75
|
# Make the readme file the start page for the generated html
|
61
76
|
rdoc.options << '--main' << 'README'
|
62
77
|
rdoc.rdoc_files.include('doc/*.rdoc',
|
@@ -70,5 +85,6 @@ end
|
|
70
85
|
# Test Task
|
71
86
|
Rake::TestTask.new do |t|
|
72
87
|
t.libs << "test"
|
88
|
+
t.test_files = FileList['test/test*.rb'].exclude('test/test_suite.rb')
|
73
89
|
t.verbose = true
|
74
90
|
end
|
data/ext/libxslt/extconf.h
CHANGED
data/ext/libxslt/extconf.rb
CHANGED
@@ -21,7 +21,9 @@ dir_config('zlib')
|
|
21
21
|
dir_config('xml2')
|
22
22
|
dir_config('xslt')
|
23
23
|
dir_config('exslt')
|
24
|
-
|
24
|
+
|
25
|
+
# Ruby 1.9 has ruby/io.h instead of rubyio.h
|
26
|
+
have_header('ruby/io.h')
|
25
27
|
|
26
28
|
# First get zlib
|
27
29
|
unless have_library('z', 'inflate') or
|
@@ -109,38 +111,34 @@ unless (have_library('exslt','exsltRegisterAll') or
|
|
109
111
|
end
|
110
112
|
|
111
113
|
# Figure out where libxml-ruby is installed
|
112
|
-
|
113
|
-
if gem_specs.empty?
|
114
|
+
unless gem_spec = Gem::Specification.find_by_name('libxml-ruby')
|
114
115
|
crash(<<-EOL)
|
115
116
|
libxml-ruby bindings must be installed
|
116
117
|
EOL
|
117
118
|
end
|
118
119
|
|
119
|
-
|
120
|
-
libxml_ruby_path = gem_specs.first.full_gem_path
|
121
|
-
|
122
|
-
$INCFLAGS += " -I#{libxml_ruby_path}/ext"
|
123
|
-
|
124
|
-
unless have_header('libxml/ruby_libxml.h')
|
120
|
+
unless find_header("ruby_libxml.h", "#{gem_spec.full_gem_path}/ext/libxml")
|
125
121
|
crash(<<-EOL)
|
126
122
|
Need headers for libxml-ruby.
|
127
123
|
EOL
|
128
124
|
end
|
129
125
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
126
|
+
|
127
|
+
RUBY_VERSION =~ /(\d+.\d+)/
|
128
|
+
minor_version = $1
|
129
|
+
paths = ["#{gem_spec.full_gem_path}/lib", "#{gem_spec.full_gem_path}/lib/#{minor_version}"]
|
130
|
+
|
131
|
+
# Hack to make sure ruby library is *after* xml_ruby library
|
132
|
+
$LIBS += " #{$LIBRUBYARG_STATIC}"
|
133
|
+
unless find_library("xml_ruby", "Init_libxml_ruby", *paths) or
|
134
|
+
find_library(":libxml_ruby.so", "Init_libxml_ruby", *paths)
|
135
|
+
crash(<<-EOL)
|
136
|
+
Need libxml-ruby
|
137
|
+
Please install libxml-ruby or specify the path to the gem via:
|
138
|
+
--with-libxml-ruby=/path/to/libxml-ruby gem
|
139
|
+
EOL
|
143
140
|
end
|
141
|
+
$LIBS.gsub!($LIBRUBYARG_STATIC,'')
|
144
142
|
|
145
143
|
create_header()
|
146
144
|
create_makefile("libxslt_ruby")
|
data/ext/libxslt/libxslt.c
CHANGED
@@ -11,7 +11,7 @@ VALUE eXSLTError;
|
|
11
11
|
|
12
12
|
/*
|
13
13
|
* Document-class: LibXSLT::XSLT
|
14
|
-
*
|
14
|
+
*
|
15
15
|
* The libxslt gem provides Ruby language bindings for GNOME's Libxslt
|
16
16
|
* toolkit. It is free software, released under the MIT License.
|
17
17
|
*
|
@@ -22,26 +22,24 @@ VALUE eXSLTError;
|
|
22
22
|
*
|
23
23
|
* xml_doc = XML::Document.file('xml_file')
|
24
24
|
* result = stylesheet.apply(xml_doc)
|
25
|
-
*
|
26
25
|
*
|
27
|
-
*/
|
26
|
+
*/
|
28
27
|
|
29
28
|
#ifdef RDOC_NEVER_DEFINED
|
30
29
|
cLibXSLT = rb_define_module("XSLT");
|
31
30
|
#endif
|
32
31
|
|
33
32
|
|
34
|
-
#if defined(_WIN32)
|
35
|
-
__declspec(dllexport)
|
36
|
-
#endif
|
37
|
-
|
38
33
|
void
|
39
34
|
Init_libxslt_ruby(void) {
|
40
35
|
LIBXML_TEST_VERSION;
|
41
|
-
|
36
|
+
|
42
37
|
cLibXSLT = rb_define_module("LibXSLT");
|
43
38
|
cXSLT = rb_define_module_under(cLibXSLT, "XSLT");
|
44
39
|
|
40
|
+
cXMLDocument = rb_const_get(rb_const_get(rb_const_get(rb_cObject,
|
41
|
+
rb_intern("LibXML")), rb_intern("XML")), rb_intern("Document"));
|
42
|
+
|
45
43
|
rb_define_const(cXSLT, "MAX_DEPTH", INT2NUM(xsltMaxDepth));
|
46
44
|
rb_define_const(cXSLT, "MAX_SORT", INT2NUM(XSLT_MAX_SORT));
|
47
45
|
rb_define_const(cXSLT, "ENGINE_VERSION", rb_str_new2(xsltEngineVersion));
|
@@ -60,6 +58,7 @@ Init_libxslt_ruby(void) {
|
|
60
58
|
eXSLTError = rb_define_class_under(cLibXSLT, "XSLTError", rb_eRuntimeError);
|
61
59
|
|
62
60
|
ruby_init_xslt_stylesheet();
|
61
|
+
ruby_init_exslt();
|
63
62
|
|
64
63
|
/* Now load exslt. */
|
65
64
|
exsltRegisterAll();
|
data/ext/libxslt/libxslt.h
CHANGED
@@ -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
|
+
}
|