jam 0.2
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.
- data/HISTORY +21 -0
- data/MANIFEST +52 -0
- data/README +39 -0
- data/TODO +22 -0
- data/bin/jam +0 -0
- data/demo/array.rb +16 -0
- data/demo/attribute.rb +24 -0
- data/demo/demi/fixtures/ex1.html +10 -0
- data/demo/demi/fixtures/samples.yaml +19 -0
- data/demo/demi/integration/01_jam.rd +41 -0
- data/demo/demi/integration/02_xpath.rd +41 -0
- data/demo/demi/integration/samples.rd +28 -0
- data/demo/demi/unit/hpricot.rd +150 -0
- data/demo/demi/unit/libxml.rd +75 -0
- data/demo/demi/unit/nokogiri.rd +148 -0
- data/demo/demi/unit/rexml.rd +63 -0
- data/demo/hash.rb +20 -0
- data/demo/helloworld.rb +12 -0
- data/demo/object.rb +19 -0
- data/demo/table.rb +24 -0
- data/js/jquery.jam.js +230 -0
- data/lib/jam.rb +2 -0
- data/lib/jam/cherry.rb +1 -0
- data/lib/jam/css2xpath.rb +104 -0
- data/lib/jam/css_to_xpath.rb +132 -0
- data/lib/jam/engine.rb +169 -0
- data/lib/jam/hpricot.rb +137 -0
- data/lib/jam/libxml.rb +151 -0
- data/lib/jam/nokogiri.rb +167 -0
- data/lib/jam/rexml.rb +135 -0
- data/lib/jam/template.rb +224 -0
- data/meta/abstract +2 -0
- data/meta/author +1 -0
- data/meta/created +1 -0
- data/meta/homepage +1 -0
- data/meta/package +1 -0
- data/meta/project +1 -0
- data/meta/status +1 -0
- data/meta/summary +1 -0
- data/meta/timestamp +1 -0
- data/meta/title +1 -0
- data/meta/version +1 -0
- metadata +103 -0
data/lib/jam/libxml.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'libxml'
|
2
|
+
require 'jam/engine'
|
3
|
+
require 'jam/css_to_xpath'
|
4
|
+
|
5
|
+
module LibXML
|
6
|
+
|
7
|
+
class XML::Document
|
8
|
+
def jam(data, opts={})
|
9
|
+
engine = ::Jam::LibXML.new()
|
10
|
+
engine.interpolate(self, data)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class XML::Node
|
15
|
+
def jam(data, opts={})
|
16
|
+
engine = ::Jam::LibXML.new()
|
17
|
+
engine.interpolate(self, data)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class XML::XPath::Object
|
22
|
+
public :context
|
23
|
+
def jam(data, opts={})
|
24
|
+
engine = ::Jam::LibXML.new()
|
25
|
+
engine.interpolate(self, data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
module Jam
|
33
|
+
|
34
|
+
# LibXML Adaptor
|
35
|
+
#
|
36
|
+
class LibXML < Engine
|
37
|
+
|
38
|
+
#
|
39
|
+
def initialize(*options)
|
40
|
+
@options = options
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
def document(source)
|
45
|
+
::LibXML::XML::Document.string(source, *@options)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
def search(node, qry)
|
50
|
+
qry = Jam.css_to_xpath(qry)
|
51
|
+
case node
|
52
|
+
when ::LibXML::XML::XPath::Object, Array
|
53
|
+
a = []
|
54
|
+
node.each do |n|
|
55
|
+
z = n.find(qry).to_a
|
56
|
+
a.concat(z)
|
57
|
+
end
|
58
|
+
a
|
59
|
+
else
|
60
|
+
node.find(qry)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# deep copy
|
65
|
+
def copy(node)
|
66
|
+
node.copy(true)
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
def remove(node)
|
71
|
+
node.remove
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
def empty(ns)
|
76
|
+
case ns
|
77
|
+
when ::LibXML::XML::Node
|
78
|
+
ns.content = ''
|
79
|
+
when ::LibXML::XML::XPath::Object, Array
|
80
|
+
ns.each do |n|
|
81
|
+
n.content = ''
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
def append(ns, child)
|
88
|
+
if ::LibXML::XML::XPath::Object === child
|
89
|
+
child.each do |c|
|
90
|
+
case ns
|
91
|
+
when ::LibXML::XML::Node
|
92
|
+
ns << c
|
93
|
+
when ::LibXML::XML::XPath::Object, Array
|
94
|
+
ns.each do |n|
|
95
|
+
n << c
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
else
|
100
|
+
case ns
|
101
|
+
when ::LibXML::XML::Node
|
102
|
+
ns << child
|
103
|
+
when ::LibXML::XML::XPath::Object, Array
|
104
|
+
ns.each do |n|
|
105
|
+
n << child
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
def replace(ns, child)
|
113
|
+
empty(ns)
|
114
|
+
append(ns, child)
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
def remove(node)
|
119
|
+
node.remove
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
def attribute(ns, att, val)
|
124
|
+
case ns
|
125
|
+
when ::LibXML::XML::Node
|
126
|
+
ns.attr(att, val)
|
127
|
+
when ::LibXML::XML::XPath::Object, Array
|
128
|
+
ns.each do |n|
|
129
|
+
ns.attr(att, val)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Iterate over each node.
|
135
|
+
#
|
136
|
+
def each_node(nodes)
|
137
|
+
case nodes
|
138
|
+
when ::LibXML::XML::XPath::Object, Array
|
139
|
+
nodes = nodes
|
140
|
+
else
|
141
|
+
nodes = [nodes]
|
142
|
+
end
|
143
|
+
nodes.each do |node|
|
144
|
+
yield(node)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
data/lib/jam/nokogiri.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'jam/engine'
|
3
|
+
|
4
|
+
module Nokogiri
|
5
|
+
|
6
|
+
class XML::Document
|
7
|
+
def jam(data, opts={})
|
8
|
+
engine = ::Jam::Nokogiri.new()
|
9
|
+
engine.interpolate(self, data)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class XML::Node
|
14
|
+
def jam(data, opts={})
|
15
|
+
engine = ::Jam::Nokogiri.new()
|
16
|
+
engine.interpolate(self, data)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class XML::NodeSet
|
21
|
+
def jam(data, opts={})
|
22
|
+
engine = ::Jam::Nokogiri.new()
|
23
|
+
engine.interpolate(self, data)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
module Jam
|
31
|
+
|
32
|
+
# Nokogiri Adaptor
|
33
|
+
#
|
34
|
+
class Nokogiri < Engine
|
35
|
+
|
36
|
+
#
|
37
|
+
def initialize(*options)
|
38
|
+
@options = options
|
39
|
+
end
|
40
|
+
|
41
|
+
# Contruct XML document given source text.
|
42
|
+
#
|
43
|
+
def document(source)
|
44
|
+
::Nokogiri::XML(source, *@options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Use CSS or XPath to search node.
|
48
|
+
#
|
49
|
+
def search(node, qry)
|
50
|
+
node.search(qry)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Deep copy.
|
54
|
+
#
|
55
|
+
def copy(node)
|
56
|
+
node.dup
|
57
|
+
end
|
58
|
+
|
59
|
+
# Empty nodes.
|
60
|
+
#
|
61
|
+
def empty(node_or_nodeset)
|
62
|
+
case node_or_nodeset
|
63
|
+
when ::Nokogiri::XML::Node
|
64
|
+
node_or_nodeset.content = ''
|
65
|
+
when ::Nokogiri::XML::NodeSet
|
66
|
+
ns.each do |n|
|
67
|
+
node_or_nodeset.content = ''
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Append child to node(s).
|
73
|
+
#
|
74
|
+
def append(node_or_nodeset, child)
|
75
|
+
ns = node_or_nodeset
|
76
|
+
case child
|
77
|
+
when ::Nokogiri::XML::Node
|
78
|
+
each_node(node_or_nodeset) do |node|
|
79
|
+
node << child
|
80
|
+
end
|
81
|
+
when ::Nokogiri::XML::NodeSet
|
82
|
+
child.each do |n|
|
83
|
+
each_node(node_or_nodeset) do |node|
|
84
|
+
node << n.dup
|
85
|
+
end
|
86
|
+
end
|
87
|
+
else
|
88
|
+
append_text(node_or_nodeset, child)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# TODO
|
93
|
+
def append_text(node_or_nodeset, text)
|
94
|
+
end
|
95
|
+
|
96
|
+
# TODO: rename to replace_content
|
97
|
+
#def replace(ns, child)
|
98
|
+
# empty(ns)
|
99
|
+
# append(ns, child)
|
100
|
+
#end
|
101
|
+
|
102
|
+
# Replace node content with text.
|
103
|
+
#
|
104
|
+
def replace_content_with_text(node_or_nodeset, text)
|
105
|
+
each_node(node_or_nodeset) do |node|
|
106
|
+
node.content = text
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Remove node.
|
111
|
+
#
|
112
|
+
def remove(node)
|
113
|
+
node.remove
|
114
|
+
end
|
115
|
+
|
116
|
+
# Set an attribute.
|
117
|
+
#
|
118
|
+
def attribute(ns, att, val)
|
119
|
+
case ns
|
120
|
+
when ::Nokogiri::XML::Node
|
121
|
+
ns.attr(att, val)
|
122
|
+
when ::Nokogiri::XML::NodeSet
|
123
|
+
ns.each do |n|
|
124
|
+
ns.attr(att, val)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Remove jam nodes that ask for it, and all jam attributes.
|
130
|
+
#
|
131
|
+
def cleanup(node)
|
132
|
+
node = node.root if ::Nokogiri::XML::Document === node
|
133
|
+
# remove unwanted tags
|
134
|
+
node.xpath("//*[@jam='erase']").each do |n|
|
135
|
+
unwrap(n)
|
136
|
+
end
|
137
|
+
# remove jam attributes
|
138
|
+
|
139
|
+
#
|
140
|
+
node
|
141
|
+
end
|
142
|
+
|
143
|
+
# Iterate over each node.
|
144
|
+
#
|
145
|
+
def each_node(nodes)
|
146
|
+
unless ::Nokogiri::XML::NodeSet === nodes
|
147
|
+
nodes = [nodes]
|
148
|
+
end
|
149
|
+
nodes.each do |node|
|
150
|
+
yield(node)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Unwrap a node, such that the outer tag is
|
155
|
+
# removed, leaving only it's own children.
|
156
|
+
#
|
157
|
+
def unwrap(node)
|
158
|
+
node.children.each do |child|
|
159
|
+
node.parent << child
|
160
|
+
end
|
161
|
+
node.remove
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end #module Jam
|
167
|
+
|
data/lib/jam/rexml.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'jam/engine'
|
3
|
+
require 'jam/css2xpath'
|
4
|
+
|
5
|
+
module REXML
|
6
|
+
|
7
|
+
class Document
|
8
|
+
def jam(data, opts={})
|
9
|
+
engine = ::Jam::REXML.new()
|
10
|
+
engine.interpolate(self, data)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Element
|
15
|
+
def jam(data, opts={})
|
16
|
+
engine = ::Jam::REXML.new()
|
17
|
+
engine.interpolate(self, data)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class XPath
|
22
|
+
def self.jam(node, data)
|
23
|
+
engine = ::Jam::REXML.new()
|
24
|
+
engine.interpolate(node, data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
module Jam
|
32
|
+
|
33
|
+
# REXML Adaptor
|
34
|
+
#
|
35
|
+
class REXML < Engine
|
36
|
+
|
37
|
+
#
|
38
|
+
def initialize(*options)
|
39
|
+
@options = options
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
def document(source)
|
44
|
+
::REXML::Document.new(source, *@options)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
def search(node, qry)
|
49
|
+
qry = Jam.css_to_xpath(qry)
|
50
|
+
::REXML::XPath.match(node, qry)
|
51
|
+
end
|
52
|
+
|
53
|
+
# deep copy
|
54
|
+
def copy(node)
|
55
|
+
node.copy(true)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
def remove(node)
|
60
|
+
node.remove
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
def empty(ns)
|
65
|
+
case ns
|
66
|
+
when ::REXML::Element
|
67
|
+
ns.inner_html = ''
|
68
|
+
when Array
|
69
|
+
ns.each do |n|
|
70
|
+
n.inner_html = ''
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
def append(ns, child)
|
77
|
+
if Array === child
|
78
|
+
case ns
|
79
|
+
when ::REXML::Element
|
80
|
+
ns.add_element(child)
|
81
|
+
when Array
|
82
|
+
ns.each do |n|
|
83
|
+
nadd_element(child)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
else
|
87
|
+
case ns
|
88
|
+
when ::REXML::Element
|
89
|
+
ns.add_element(child)
|
90
|
+
when Array
|
91
|
+
ns.each do |n|
|
92
|
+
n.add_element(child)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
def replace(ns, child)
|
100
|
+
empty(ns)
|
101
|
+
append(ns, child)
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
def remove(node)
|
106
|
+
node.remove
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
def attribute(ns, att, val)
|
111
|
+
case ns
|
112
|
+
when ::REXML::Element
|
113
|
+
ns.attr(att, val)
|
114
|
+
when Array
|
115
|
+
ns.each do |n|
|
116
|
+
ns.attr(att, val)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Iterate over each node.
|
122
|
+
#
|
123
|
+
def each_node(nodes)
|
124
|
+
unless Array === nodes
|
125
|
+
nodes = [nodes]
|
126
|
+
end
|
127
|
+
nodes.each do |node|
|
128
|
+
yield(node)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end #module Jam
|
135
|
+
|