papercraft 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 309174da790e301142b03cc8aad3e966c6b1482d514da8d3910c2e84f6981af6
4
- data.tar.gz: 64fb5b791fce05c0347ba21ccf70160323f70ad708ece9c14222b8544efdf8e0
3
+ metadata.gz: 125df0455a1b4c3373b36b3f52b6d965249a7ddf470439ec48df3f7216ea3991
4
+ data.tar.gz: be9cea2084785a3dc135b852b66f0d91375cafd6050834d06f26f8a6b497f95f
5
5
  SHA512:
6
- metadata.gz: d1f56c25e4854cb6b0ffce1d149d831d51d4141159a44fd6a962c27d9e0878b33e9438d9ad621c0c30a42dfa853b96a26b20c6ebe42243844be2b42d4e2901ef
7
- data.tar.gz: 46952658d3e237f784cfd9b608c82b001fdd188b788c931f0a1a3669d5800d8ed3ef89623f88ff9a617237fbfbbd3a0f9f5b30bfc693b2e6f0b5659f66afa41b
6
+ metadata.gz: f45e9101d8bb14bfdde19958988343d6e4d87e270462a0db13630860aff5d6adc560df90aefd78317642f6987d3853cc68ad8adb7d0b74e381b43930424d7a79
7
+ data.tar.gz: c7a153329948a8fa5dbe90602a293b22e060f0118cc3cdfd629f9af9644f57bea4add8ec13e40a5194178bdebc5dd43a26c0507f03e8dd78e3a3a5662968e390
@@ -14,8 +14,8 @@ module Papercraft
14
14
  # Components are usually created using the global methods `H` or `X`, for HTML
15
15
  # or XML templates, respectively:
16
16
  #
17
- # greeter = H { |name| h1 "Hello, #{name}!" } greeter.render('world') #=>
18
- # "<h1>Hello, world!</h1>"
17
+ # greeter = H { |name| h1 "Hello, #{name}!" }
18
+ # greeter.render('world') #=> "<h1>Hello, world!</h1>"
19
19
  #
20
20
  # Components can also be created using the normal constructor:
21
21
  #
@@ -25,7 +25,10 @@ module Papercraft
25
25
  # In the component block, HTML elements are created by simply calling
26
26
  # unqualified methods:
27
27
  #
28
- # page_layout = H { html5 { head { title 'foo'
28
+ # page_layout = H {
29
+ # html5 {
30
+ # head {
31
+ # title 'foo'
29
32
  # }
30
33
  # body {
31
34
  # h1 "Hello, world!"
@@ -75,7 +78,11 @@ module Papercraft
75
78
  # anchor.apply(uri: '/about', text: 'About')
76
79
  # ])
77
80
  # links_with_anchors.render
81
+ #
78
82
  class Component < Proc
83
+
84
+ # Determines the rendering mode: `:html` or `:xml`.
85
+ attr_accessor :mode
79
86
 
80
87
  # Initializes a component with the given block. The rendering mode (HTML or
81
88
  # XML) can be passed in the `mode:` parameter. If `mode:` is not specified,
@@ -113,15 +120,15 @@ module Papercraft
113
120
  # current one. Application is one of the principal methods of composing
114
121
  # components, particularly when passing inner components as blocks:
115
122
  #
116
- # article_wrapper = H {
117
- # article {
118
- # emit_yield
123
+ # article_wrapper = H {
124
+ # article {
125
+ # emit_yield
126
+ # }
127
+ # }
128
+ # wrapped_article = article_wrapper.apply {
129
+ # h1 'Article title'
119
130
  # }
120
- # }
121
- # wrapped_article = article_wrapper.apply {
122
- # h1 'Article title'
123
- # }
124
- # wrapped_article.render #=> "<article><h1>Article title</h1></article>"
131
+ # wrapped_article.render #=> "<article><h1>Article title</h1></article>"
125
132
  #
126
133
  # @param *a [<any>] normal parameters
127
134
  # @param **b [Hash] named parameters
@@ -3,9 +3,11 @@
3
3
  require_relative './html'
4
4
 
5
5
  module Papercraft
6
- # Markup extensions
6
+
7
+ # HTML Markup extensions
7
8
  module HTML
8
9
  # Emits the p tag (overrides Object#p)
10
+ #
9
11
  # @param text [String] text content of tag
10
12
  # @param props [Hash] tag attributes
11
13
  # @para block [Proc] nested HTML block
@@ -16,7 +18,8 @@ module Papercraft
16
18
 
17
19
  S_HTML5_DOCTYPE = '<!DOCTYPE html>'
18
20
 
19
- # Emits an HTML5 doctype tag and an html tag with the given block
21
+ # Emits an HTML5 doctype tag and an html tag with the given block.
22
+ #
20
23
  # @param block [Proc] nested HTML block
21
24
  # @return [void]
22
25
  def html5(&block)
@@ -24,6 +27,11 @@ module Papercraft
24
27
  self.html(&block)
25
28
  end
26
29
 
30
+ # Emits a link element with a stylesheet.
31
+ #
32
+ # @param href [String] stylesheet URL
33
+ # @param custom_attributes [Hash] optional custom attributes for the link element
34
+ # @return [void]
27
35
  def link_stylesheet(href, custom_attributes = nil)
28
36
  attributes = {
29
37
  rel: 'stylesheet',
@@ -3,9 +3,19 @@
3
3
  require_relative './html'
4
4
 
5
5
  module Papercraft
6
+
6
7
  # A Renderer renders a Papercraft component into a string
7
8
  class Renderer
9
+
8
10
  class << self
11
+
12
+ # Verifies that the given template proc can be called with the given
13
+ # arguments and named arguments. If the proc demands named argument keys
14
+ # that do not exist in `named_args`, `Papercraft::Error` is raised.
15
+ #
16
+ # @param template [Proc] proc to verify
17
+ # @param args [Array<any>] arguments passed to proc
18
+ # @param named_args [Hash] named arguments passed to proc
9
19
  def verify_proc_parameters(template, args, named_args)
10
20
  param_count = 0
11
21
  template.parameters.each do |(type, name)|
@@ -24,31 +34,22 @@ module Papercraft
24
34
  end
25
35
  end
26
36
 
27
- attr_reader :context
28
-
29
- # Initializes attributes and renders the given block
30
- # @param context [Hash] rendering context
31
- # @param block [Proc] template block
32
- # @return [void]
37
+ # Initializes the renderer and evaulates the given template in the
38
+ # renderer's scope.
39
+ #
40
+ # @param &template [Proc] template block
33
41
  def initialize(&template)
34
42
  @buffer = +''
35
43
  instance_eval(&template)
36
44
  end
37
45
 
38
- # Returns the result of the rendering
46
+ # Returns the rendered template.
47
+ #
39
48
  # @return [String]
40
49
  def to_s
41
50
  @buffer
42
51
  end
43
52
 
44
- def escape_text(text)
45
- raise NotImplementedError
46
- end
47
-
48
- def escape_uri(uri)
49
- EscapeUtils.escape_uri(v)
50
- end
51
-
52
53
  S_TAG_METHOD_LINE = __LINE__ + 1
53
54
  S_TAG_METHOD = <<~EOF
54
55
  S_TAG_%<TAG>s_PRE = '<%<tag>s'.tr('_', '-')
@@ -74,10 +75,12 @@ module Papercraft
74
75
  end
75
76
  EOF
76
77
 
77
- # Catches undefined tag method call and handles them by defining the method
78
+ # Catches undefined tag method call and handles it by defining the method.
79
+ #
78
80
  # @param sym [Symbol] HTML tag or component identifier
79
- # @param args [Array] method call arguments
80
- # @param block [Proc] block passed to method call
81
+ # @param args [Array] method arguments
82
+ # @param opts [Hash] named method arguments
83
+ # @param &block [Proc] block passed to method
81
84
  # @return [void]
82
85
  def method_missing(sym, *args, **opts, &block)
83
86
  value = @local && @local[sym]
@@ -89,18 +92,28 @@ module Papercraft
89
92
  send(sym, *args, **opts, &block)
90
93
  end
91
94
 
92
- # Emits the given object into the rendering buffer
95
+ # Emits the given object into the rendering buffer. If the given object is a
96
+ # proc or a component, `emit` will passes any additional arguments and named
97
+ # arguments to the object when rendering it. If the given object is nil,
98
+ # nothing is emitted. Otherwise, the object is converted into a string using
99
+ # `#to_s` which is then added to the rendering buffer, without any escaping.
100
+ #
101
+ # greeter = proc { |name| h1 "Hello, #{name}!" }
102
+ # H { emit(greeter, 'world') }.render #=> "<h1>Hello, world!</h1>"
103
+ #
104
+ # H { emit 'hi&<bye>' }.render #=> "hi&<bye>"
105
+ #
106
+ # H { emit nil }.render #=> ""
107
+ #
93
108
  # @param o [Proc, Papercraft::Component, String] emitted object
109
+ # @param *a [Array<any>] arguments to pass to a proc
110
+ # @param **b [Hash] named arguments to pass to a proc
94
111
  # @return [void]
95
112
  def emit(o, *a, **b)
96
113
  case o
97
114
  when ::Proc
98
115
  Renderer.verify_proc_parameters(o, a, b)
99
116
  instance_exec(*a, **b, &o)
100
- # when Papercraft::Component
101
- # o = o.template
102
- # Renderer.verify_proc_parameters(o, a, b)
103
- # instance_exec(*a, **b, &o)
104
117
  when nil
105
118
  else
106
119
  @buffer << o.to_s
@@ -108,14 +121,15 @@ module Papercraft
108
121
  end
109
122
  alias_method :e, :emit
110
123
 
111
- def with_block(block, &run_block)
112
- old_block = @inner_block
113
- @inner_block = block
114
- instance_eval(&run_block)
115
- ensure
116
- @inner_block = old_block
117
- end
118
-
124
+ # Emits a block supplied using `Component#apply` or `Component#render`.
125
+ #
126
+ # div_wrap = H { |*args| div { emit_yield(*args) } }
127
+ # greeter = div_wrap.apply { |name| h1 "Hello, #{name}!" }
128
+ # greeter.render('world') #=> "<div><h1>Hello, world!</h1></div>"
129
+ #
130
+ # @param *a [Array<any>] arguments to pass to a proc
131
+ # @param **b [Hash] named arguments to pass to a proc
132
+ # @return [void]
119
133
  def emit_yield(*a, **b)
120
134
  raise Papercraft::Error, "No block given" unless @inner_block
121
135
 
@@ -131,6 +145,31 @@ module Papercraft
131
145
  S_EQUAL_QUOTE = '="'
132
146
  S_QUOTE = '"'
133
147
 
148
+ # Emits text into the rendering buffer, escaping any special characters to
149
+ # the respective HTML entities.
150
+ #
151
+ # @param data [String] text
152
+ # @return [void]
153
+ def text(data)
154
+ @buffer << escape_text(data)
155
+ end
156
+
157
+ private
158
+
159
+ # Escapes text. This method must be overriden in descendant classes.
160
+ def escape_text(text)
161
+ raise NotImplementedError
162
+ end
163
+
164
+ # Sets up a block to be called with `#emit_yield`
165
+ def with_block(block, &run_block)
166
+ old_block = @inner_block
167
+ @inner_block = block
168
+ instance_eval(&run_block)
169
+ ensure
170
+ @inner_block = old_block
171
+ end
172
+
134
173
  # Emits tag attributes into the rendering buffer
135
174
  # @param props [Hash] tag attributes
136
175
  # @return [void]
@@ -153,23 +192,23 @@ module Papercraft
153
192
  end
154
193
  }
155
194
  end
156
-
157
- # Emits text into the rendering buffer
158
- # @param data [String] text
159
- def text(data)
160
- @buffer << escape_text(data)
161
- end
162
195
  end
163
196
 
197
+ # Implements an HTML renderer
164
198
  class HTMLRenderer < Renderer
165
199
  include HTML
166
200
 
201
+ private
202
+
167
203
  def escape_text(text)
168
204
  EscapeUtils.escape_html(text.to_s)
169
205
  end
170
206
  end
171
207
 
208
+ # Implements an XML renderer
172
209
  class XMLRenderer < Renderer
210
+ private
211
+
173
212
  def escape_text(text)
174
213
  EscapeUtils.escape_xml(text.to_s)
175
214
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Papercraft
4
- VERSION = '0.8.2'
4
+ VERSION = '0.8.3'
5
5
  end
data/lib/papercraft.rb CHANGED
@@ -15,20 +15,32 @@ end
15
15
 
16
16
  # Kernel extensions
17
17
  module ::Kernel
18
- # Convenience method for creating a new Papercraft
19
- # @param ctx [Hash] local context
18
+
19
+ # Creates a new papercraft component. `#H` can take either a proc argument or
20
+ # a block. In both cases, the proc is converted to a `Papercraft::Component`.
21
+ #
22
+ # H(proc { h1 'hi' }).render #=> "<h1>hi</h1>"
23
+ # H { h1 'hi' }.render #=> "<h1>hi</h1>"
24
+ #
20
25
  # @param template [Proc] template block
21
- # @return [Papercraft] Papercraft template
22
- def H(&template)
23
- Papercraft::Component.new(&template)
26
+ # @return [Papercraft::Component] Papercraft component
27
+ def H(o = nil, &template)
28
+ return o if o.is_a?(Papercraft::Component)
29
+ template ||= o
30
+ Papercraft::Component.new(mode: :html, &template)
24
31
  end
25
32
 
26
- def X(&template)
33
+ # Creates a new papercraft component in XML mode. `#X` can take either a proc argument or
34
+ # a block. In both cases, the proc is converted to a `Papercraft::Component`.
35
+ #
36
+ # X(proc { item 'foo' }).render #=> "<item>foo</item>"
37
+ # X { item 'foo' }.render #=> "<item>foo</item>"
38
+ #
39
+ # @param template [Proc] template block
40
+ # @return [Papercraft::Component] Papercraft component
41
+ def X(o = nil, &template)
42
+ return o if o.is_a?(Papercraft::Component)
43
+ template ||= o
27
44
  Papercraft::Component.new(mode: :xml, &template)
28
45
  end
29
46
  end
30
-
31
- # Object extensions
32
- class Object
33
- include Papercraft::Encoding
34
- end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: papercraft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner