papercraft 0.20 → 0.21
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/papercraft/extension_proxy.rb +3 -1
- data/lib/papercraft/html.rb +22 -1
- data/lib/papercraft/json.rb +89 -36
- data/lib/papercraft/renderer.rb +3 -85
- data/lib/papercraft/tags.rb +112 -3
- data/lib/papercraft/template.rb +3 -0
- data/lib/papercraft/version.rb +1 -1
- data/lib/papercraft/xml.rb +13 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a23bf614d84747a18eecf84545604c9c2f58710dc3fa0e0c651a863a53c919b0
|
4
|
+
data.tar.gz: 6b1ca8f4a90801beff11807dd357ce801b7526b5d114d5cca5f41f41aec69958
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dcd7eada8280cb0fcd68528eaea0d2500ff99ac149c8495dd5a3955a93c3f181301a4decc9eeb4d7efdd8cfe2c4f6047c9f838e5084b413c1118a76d6abc4252
|
7
|
+
data.tar.gz: 840ce0fc2a83de9b5a83bb10a5f4ed98986f7201737d6e31a4e89877aeb6bb22b2f2449c6efa08302473c073e26c830cfbe9e267456b450a56222b57a429fd15
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,7 @@ module Papercraft
|
|
10
10
|
class ExtensionProxy
|
11
11
|
|
12
12
|
# Initializes a new ExtensionProxy.
|
13
|
+
#
|
13
14
|
# @param renderer [Papercraft::Renderer] renderer to proxy to
|
14
15
|
# @param mod [Module] extension module
|
15
16
|
# @return [void]
|
@@ -18,7 +19,8 @@ module Papercraft
|
|
18
19
|
extend(mod)
|
19
20
|
end
|
20
21
|
|
21
|
-
# Proxies missing methods to the renderer
|
22
|
+
# Proxies missing methods to the renderer.
|
23
|
+
#
|
22
24
|
# @param sym [Symbol] method name
|
23
25
|
# @param *args [Array] arguments
|
24
26
|
# @param &block [Proc] block
|
data/lib/papercraft/html.rb
CHANGED
@@ -88,9 +88,30 @@ module Papercraft
|
|
88
88
|
|
89
89
|
private
|
90
90
|
|
91
|
-
# Escapes the given text using
|
91
|
+
# Escapes the given text using HTML entities.
|
92
|
+
#
|
93
|
+
# @param text [String] text
|
94
|
+
# @return [String] escaped text
|
92
95
|
def escape_text(text)
|
93
96
|
EscapeUtils.escape_html(text.to_s)
|
94
97
|
end
|
98
|
+
|
99
|
+
# Converts a tag to its string representation. Underscores will be converted
|
100
|
+
# to dashes.
|
101
|
+
#
|
102
|
+
# @param tag [Symbol, String] tag
|
103
|
+
# @return [String] tag string
|
104
|
+
def tag_repr(tag)
|
105
|
+
tag.to_s.tr('_', '-')
|
106
|
+
end
|
107
|
+
|
108
|
+
# Converts an attribute to its string representation. Underscores will be
|
109
|
+
# converted to dashes.
|
110
|
+
#
|
111
|
+
# @param att [Symbol, String] attribute
|
112
|
+
# @return [String] attribute string
|
113
|
+
def att_repr(att)
|
114
|
+
att.to_s.tr('_', '-')
|
115
|
+
end
|
95
116
|
end
|
96
117
|
end
|
data/lib/papercraft/json.rb
CHANGED
@@ -5,69 +5,122 @@ require 'json'
|
|
5
5
|
module Papercraft
|
6
6
|
# JSON renderer extensions
|
7
7
|
module JSON
|
8
|
-
|
9
|
-
|
8
|
+
# Initializes a JSON renderer, setting up an object stack.
|
9
|
+
def initialize(&template)
|
10
|
+
@object_stack = [nil]
|
11
|
+
super
|
10
12
|
end
|
11
13
|
|
14
|
+
# Adds an array item to the current object target. If a block is given, the
|
15
|
+
# block is evaulated against a new object target, then added to the current
|
16
|
+
# array.
|
17
|
+
#
|
18
|
+
# @param value [Object] item
|
19
|
+
# @param &block [Proc] template block
|
20
|
+
# @return [void]
|
21
|
+
def item(value = nil, &block)
|
22
|
+
verify_array_target
|
23
|
+
if block
|
24
|
+
value = enter_object(&block)
|
25
|
+
end
|
26
|
+
push_array_item(value)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adds a key-value item to the current object target. If a block is given,
|
30
|
+
# the block is evaulated against a new object target, then used as the
|
31
|
+
# value.
|
32
|
+
#
|
33
|
+
# @param key [Object] key
|
34
|
+
# @param value [Object] value
|
35
|
+
# @param &block [Proc] template block
|
36
|
+
# @return [void]
|
37
|
+
def kv(key, value = nil, &block)
|
38
|
+
verify_hash_target
|
39
|
+
if block
|
40
|
+
value = enter_object(&block)
|
41
|
+
end
|
42
|
+
push_kv_item(key, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Intercepts method calls by adding key-value pairs to the current object
|
46
|
+
# target.
|
47
|
+
#
|
48
|
+
# @param key [Object] key
|
49
|
+
# @param value [Object] value
|
50
|
+
# @param &block [Proc] template block
|
51
|
+
# @return [void]
|
52
|
+
def method_missing(sym, value = nil, &block)
|
53
|
+
kv(sym, value, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Converts the root object target to JSON.
|
57
|
+
#
|
58
|
+
# @return [String] JSON template result
|
59
|
+
def to_s
|
60
|
+
@object_stack[0].to_json
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# Adds a new entry to the object stack and evaluates the given block.
|
66
|
+
#
|
67
|
+
# @param &block [Proc] template block
|
68
|
+
# @return [void]
|
12
69
|
def with_object(&block)
|
13
|
-
object_stack << nil
|
70
|
+
@object_stack << nil
|
14
71
|
instance_eval(&block)
|
15
72
|
end
|
16
73
|
|
74
|
+
# Verifies that the current object target is not a hash.
|
75
|
+
#
|
76
|
+
# @return [bool]
|
17
77
|
def verify_array_target
|
18
|
-
case object_stack[-1]
|
78
|
+
case @object_stack[-1]
|
19
79
|
when nil
|
20
|
-
object_stack[-1] = []
|
80
|
+
@object_stack[-1] = []
|
21
81
|
when Hash
|
22
82
|
raise "Mixing array and hash values"
|
23
83
|
end
|
24
84
|
end
|
25
85
|
|
86
|
+
# Verifies that the current object target is not an array.
|
87
|
+
#
|
88
|
+
# @return [bool]
|
26
89
|
def verify_hash_target
|
27
|
-
case object_stack[-1]
|
90
|
+
case @object_stack[-1]
|
28
91
|
when nil
|
29
|
-
object_stack[-1] = {}
|
92
|
+
@object_stack[-1] = {}
|
30
93
|
when Array
|
31
94
|
raise "Mixing array and hash values"
|
32
95
|
end
|
33
96
|
end
|
34
97
|
|
98
|
+
# Pushes an array item to the current object target.
|
99
|
+
#
|
100
|
+
# @param value [Object] item
|
101
|
+
# @return [void]
|
35
102
|
def push_array_item(value)
|
36
|
-
object_stack[-1] << value
|
103
|
+
@object_stack[-1] << value
|
37
104
|
end
|
38
105
|
|
106
|
+
# Pushes a key value into the current object target.
|
107
|
+
#
|
108
|
+
# @param key [Object] key
|
109
|
+
# @param value [Object] value
|
110
|
+
# @return [void]
|
39
111
|
def push_kv_item(key, value)
|
40
|
-
object_stack[-1][key] = value
|
112
|
+
@object_stack[-1][key] = value
|
41
113
|
end
|
42
114
|
|
115
|
+
# Adds a new object to the object stack, evaluates the given template block,
|
116
|
+
# then pops the object off the stack.
|
117
|
+
#
|
118
|
+
# @param &block [Proc] template block
|
119
|
+
# @return [void]
|
43
120
|
def enter_object(&block)
|
44
|
-
object_stack << nil
|
121
|
+
@object_stack << nil
|
45
122
|
instance_eval(&block)
|
46
|
-
object_stack.pop
|
47
|
-
end
|
48
|
-
|
49
|
-
def item(value = nil, &block)
|
50
|
-
verify_array_target
|
51
|
-
if block
|
52
|
-
value = enter_object(&block)
|
53
|
-
end
|
54
|
-
push_array_item(value)
|
55
|
-
end
|
56
|
-
|
57
|
-
def kv(key, value, &block)
|
58
|
-
verify_hash_target
|
59
|
-
if block
|
60
|
-
value = enter_object(&block)
|
61
|
-
end
|
62
|
-
push_kv_item(key, value)
|
63
|
-
end
|
64
|
-
|
65
|
-
def method_missing(sym, value = nil, &block)
|
66
|
-
kv(sym, value, &block)
|
67
|
-
end
|
68
|
-
|
69
|
-
def to_s
|
70
|
-
object_stack[0].to_json
|
71
|
-
end
|
123
|
+
@object_stack.pop
|
124
|
+
end
|
72
125
|
end
|
73
126
|
end
|
data/lib/papercraft/renderer.rb
CHANGED
@@ -80,38 +80,14 @@ module Papercraft
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
INITIAL_BUFFER_CAPACITY = 8192
|
84
|
-
|
85
83
|
# Initializes the renderer and evaulates the given template in the
|
86
84
|
# renderer's scope.
|
87
85
|
#
|
88
86
|
# @param &template [Proc] template block
|
89
87
|
def initialize(&template)
|
90
|
-
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
91
88
|
instance_eval(&template)
|
92
89
|
end
|
93
90
|
|
94
|
-
# Returns the rendered template.
|
95
|
-
#
|
96
|
-
# @return [String]
|
97
|
-
def to_s
|
98
|
-
if @parts
|
99
|
-
last = @buffer
|
100
|
-
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
101
|
-
parts = @parts
|
102
|
-
@parts = nil
|
103
|
-
parts.each do |p|
|
104
|
-
if Proc === p
|
105
|
-
render_deferred_proc(&p)
|
106
|
-
else
|
107
|
-
@buffer << p
|
108
|
-
end
|
109
|
-
end
|
110
|
-
@buffer << last unless last.empty?
|
111
|
-
end
|
112
|
-
@buffer
|
113
|
-
end
|
114
|
-
|
115
91
|
# Emits the given object into the rendering buffer. If the given object is a
|
116
92
|
# proc or a component, `emit` will passes any additional arguments and named
|
117
93
|
# arguments to the object when rendering it. If the given object is nil,
|
@@ -136,8 +112,9 @@ module Papercraft
|
|
136
112
|
push_emit_yield_block(block) if block
|
137
113
|
instance_exec(*a, **b, &o)
|
138
114
|
when nil
|
115
|
+
# do nothing
|
139
116
|
else
|
140
|
-
|
117
|
+
emit_object(o)
|
141
118
|
end
|
142
119
|
end
|
143
120
|
alias_method :e, :emit
|
@@ -157,75 +134,15 @@ module Papercraft
|
|
157
134
|
|
158
135
|
instance_exec(*a, **b, &block)
|
159
136
|
end
|
160
|
-
|
161
|
-
# Defers the given block to be evaluated later. Deferred evaluation allows
|
162
|
-
# Papercraft templates to inject state into sibling components, regardless
|
163
|
-
# of the component's order in the container component. For example, a nested
|
164
|
-
# component may set an instance variable used by another component. This is
|
165
|
-
# an elegant solution to the problem of setting the XML page's title, or
|
166
|
-
# adding elements to the `<head>` section. Here's how a title can be
|
167
|
-
# controlled from a nested component:
|
168
|
-
#
|
169
|
-
# layout = Papercraft.html {
|
170
|
-
# html {
|
171
|
-
# head {
|
172
|
-
# defer { title @title }
|
173
|
-
# }
|
174
|
-
# body {
|
175
|
-
# emit_yield
|
176
|
-
# }
|
177
|
-
# }
|
178
|
-
# }
|
179
|
-
#
|
180
|
-
# html.render {
|
181
|
-
# @title = 'My super page'
|
182
|
-
# h1 'content'
|
183
|
-
# }
|
184
|
-
#
|
185
|
-
# @param &block [Proc] Deferred block to be emitted
|
186
|
-
# @return [void]
|
187
|
-
def defer(&block)
|
188
|
-
if !@parts
|
189
|
-
@parts = [@buffer, block]
|
190
|
-
else
|
191
|
-
@parts << @buffer unless @buffer.empty?
|
192
|
-
@parts << block
|
193
|
-
end
|
194
|
-
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
195
|
-
end
|
196
137
|
|
197
138
|
private
|
198
139
|
|
199
|
-
# Escapes text. This method must be overriden in descendant classes.
|
200
|
-
#
|
201
|
-
# @param text [String] text to be escaped
|
202
|
-
def escape_text(text)
|
203
|
-
raise NotImplementedError
|
204
|
-
end
|
205
|
-
|
206
140
|
# Pushes the given block onto the emit_yield stack.
|
207
141
|
#
|
208
142
|
# @param block [Proc] block
|
209
143
|
def push_emit_yield_block(block)
|
210
144
|
(@emit_yield_stack ||= []) << block
|
211
145
|
end
|
212
|
-
|
213
|
-
# Renders a deferred proc by evaluating it, then adding the rendered result
|
214
|
-
# to the buffer.
|
215
|
-
#
|
216
|
-
# @param &block [Proc] deferred proc
|
217
|
-
# @return [void]
|
218
|
-
def render_deferred_proc(&block)
|
219
|
-
old_buffer = @buffer
|
220
|
-
|
221
|
-
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
222
|
-
@parts = nil
|
223
|
-
|
224
|
-
instance_eval(&block)
|
225
|
-
|
226
|
-
old_buffer << to_s
|
227
|
-
@buffer = old_buffer
|
228
|
-
end
|
229
146
|
end
|
230
147
|
|
231
148
|
# Implements an HTML renderer
|
@@ -238,6 +155,7 @@ module Papercraft
|
|
238
155
|
include XML
|
239
156
|
end
|
240
157
|
|
158
|
+
# Implements a JSON renderer
|
241
159
|
class JSONRenderer < Renderer
|
242
160
|
include JSON
|
243
161
|
end
|
data/lib/papercraft/tags.rb
CHANGED
@@ -44,6 +44,72 @@ module Papercraft
|
|
44
44
|
end
|
45
45
|
EOF
|
46
46
|
|
47
|
+
INITIAL_BUFFER_CAPACITY = 8192
|
48
|
+
|
49
|
+
# Initializes a tag renderer.
|
50
|
+
def initialize(&template)
|
51
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
52
|
+
super
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the rendered template.
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
def to_s
|
59
|
+
if @parts
|
60
|
+
last = @buffer
|
61
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
62
|
+
parts = @parts
|
63
|
+
@parts = nil
|
64
|
+
parts.each do |p|
|
65
|
+
if Proc === p
|
66
|
+
render_deferred_proc(&p)
|
67
|
+
else
|
68
|
+
@buffer << p
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@buffer << last unless last.empty?
|
72
|
+
end
|
73
|
+
@buffer
|
74
|
+
end
|
75
|
+
|
76
|
+
# Defers the given block to be evaluated later. Deferred evaluation allows
|
77
|
+
# Papercraft templates to inject state into sibling components, regardless
|
78
|
+
# of the component's order in the container component. For example, a nested
|
79
|
+
# component may set an instance variable used by another component. This is
|
80
|
+
# an elegant solution to the problem of setting the XML page's title, or
|
81
|
+
# adding elements to the `<head>` section. Here's how a title can be
|
82
|
+
# controlled from a nested component:
|
83
|
+
#
|
84
|
+
# layout = Papercraft.html {
|
85
|
+
# html {
|
86
|
+
# head {
|
87
|
+
# defer { title @title }
|
88
|
+
# }
|
89
|
+
# body {
|
90
|
+
# emit_yield
|
91
|
+
# }
|
92
|
+
# }
|
93
|
+
# }
|
94
|
+
#
|
95
|
+
# html.render {
|
96
|
+
# @title = 'My super page'
|
97
|
+
# h1 'content'
|
98
|
+
# }
|
99
|
+
#
|
100
|
+
# @param &block [Proc] Deferred block to be emitted
|
101
|
+
# @return [void]
|
102
|
+
def defer(&block)
|
103
|
+
if !@parts
|
104
|
+
@parts = [@buffer, block]
|
105
|
+
else
|
106
|
+
@parts << @buffer unless @buffer.empty?
|
107
|
+
@parts << block
|
108
|
+
end
|
109
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
47
113
|
# Emits an XML tag with the given content, properties and optional block.
|
48
114
|
# This method is an alternative to emitting XML tags using dynamically
|
49
115
|
# created methods. This is particularly useful when using extensions that
|
@@ -118,15 +184,58 @@ module Papercraft
|
|
118
184
|
|
119
185
|
private
|
120
186
|
|
187
|
+
# Emits an arbitrary object by converting it to string, then adding it to
|
188
|
+
# the internal buffer. This method is called internally by `Renderer#emit`.
|
189
|
+
#
|
190
|
+
# @param obj [Object] emitted object
|
191
|
+
# @return [void]
|
192
|
+
def emit_object(obj)
|
193
|
+
@buffer << obj.to_s
|
194
|
+
end
|
195
|
+
|
196
|
+
# Renders a deferred proc by evaluating it, then adding the rendered result
|
197
|
+
# to the buffer.
|
198
|
+
#
|
199
|
+
# @param &block [Proc] deferred proc
|
200
|
+
# @return [void]
|
201
|
+
def render_deferred_proc(&block)
|
202
|
+
old_buffer = @buffer
|
203
|
+
|
204
|
+
@buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
|
205
|
+
@parts = nil
|
206
|
+
|
207
|
+
instance_eval(&block)
|
208
|
+
|
209
|
+
old_buffer << to_s
|
210
|
+
@buffer = old_buffer
|
211
|
+
end
|
212
|
+
|
213
|
+
# Escapes text. This method must be overriden in Renderers which include
|
214
|
+
# this module.
|
215
|
+
#
|
216
|
+
# @param text [String] text to be escaped
|
217
|
+
def escape_text(text)
|
218
|
+
raise NotImplementedError
|
219
|
+
end
|
220
|
+
|
221
|
+
# Converts a tag to its string representation. This method must be overriden
|
222
|
+
# in Renderers which include this module.
|
223
|
+
#
|
224
|
+
# @param tag [Symbol, String] tag
|
121
225
|
def tag_repr(tag)
|
122
|
-
|
226
|
+
raise NotImplementedError
|
123
227
|
end
|
124
228
|
|
229
|
+
# Converts an attribute to its string representation. This method must be
|
230
|
+
# overriden in Renderers which include this module.
|
231
|
+
#
|
232
|
+
# @param att [Symbol, String] attribute
|
125
233
|
def att_repr(att)
|
126
|
-
|
234
|
+
raise NotImplementedError
|
127
235
|
end
|
128
236
|
|
129
|
-
# Emits tag attributes into the rendering buffer
|
237
|
+
# Emits tag attributes into the rendering buffer.
|
238
|
+
#
|
130
239
|
# @param props [Hash] tag attributes
|
131
240
|
# @return [void]
|
132
241
|
def emit_props(props)
|
data/lib/papercraft/template.rb
CHANGED
data/lib/papercraft/version.rb
CHANGED
data/lib/papercraft/xml.rb
CHANGED
@@ -10,15 +10,28 @@ module Papercraft
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
+
# Converts a tag to its string representation. Underscores will be converted
|
14
|
+
# to dashes, double underscores will be converted to colon.
|
15
|
+
#
|
16
|
+
# @param tag [Symbol, String] tag
|
17
|
+
# @return [String] tag string
|
13
18
|
def tag_repr(tag)
|
14
19
|
tag.to_s.gsub('__', ':').tr('_', '-')
|
15
20
|
end
|
16
21
|
|
22
|
+
# Converts an attribute to its string representation. Underscores will be
|
23
|
+
# converted to dashes, double underscores will be converted to colon.
|
24
|
+
#
|
25
|
+
# @param att [Symbol, String] attribute
|
26
|
+
# @return [String] attribute string
|
17
27
|
def att_repr(att)
|
18
28
|
att.to_s.gsub('__', ':').tr('_', '-')
|
19
29
|
end
|
20
30
|
|
21
31
|
# Escapes the given text using XML entities.
|
32
|
+
#
|
33
|
+
# @param text [String] text
|
34
|
+
# @return [String] escaped text
|
22
35
|
def escape_text(text)
|
23
36
|
EscapeUtils.escape_xml(text.to_s)
|
24
37
|
end
|