papercraft 0.15 → 0.16

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: 2200153b1b339d33c7e9e81c45c23bd4c117c274a52b1d1bfc97f83995727697
4
- data.tar.gz: 3dae3cf3b6ea2530df8c498cdafb876e06d45d527b6e2bbbcb6302e6ef0842e9
3
+ metadata.gz: 996d95088c85415ca883c27b6b1c98e65af5c046e3121ea08f092ac7bcdcc588
4
+ data.tar.gz: 8fe294225c04dcfc82289fd2b9047760260b814712e83e9bf5ea7d361dad6950
5
5
  SHA512:
6
- metadata.gz: 5f9727de69aac6d48de53ca174280c68dce7825b9a4aa6f8c955b6122f30d9f4541a7d47e7ed7caa319feda5659b14b73a3ad343db2733b4bb9518e9ade94f8c
7
- data.tar.gz: 765e786959a6fdda6c25cddda11f5f987837d6853245e5bc8533dbe7b904792b09fc39e726371c81981275ef0abdb8d1d95de63a76889af34b037f34d01c6c3a
6
+ metadata.gz: 54fdbe164a4a2541153e57b90cdb35ba71b6887fbe2d199505da3389730f1bd937fe0254f8c019b39d81957058c5f51ad71bc900f324e3178b979f368642ee57
7
+ data.tar.gz: fa05ea9ae79a57a3eace2e708b01fe5f44412591875776cf1a2fe95cc6d9d1586357756e702e8a17e5458b3fa4c3e3224290bc234b71fdcd426db0dedff31dc0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.16 2022-01-23
2
+
3
+ - Implement JSON templating (#7)
4
+ - Add support for MIME types (#6)
5
+ - Change entrypoint from `Kernel#H`, `Kernel#X` to `Papercraft.html`, `.xml` (#5)
6
+
1
7
  ## 0.15 2022-01-20
2
8
 
3
9
  - Fix tag method line reference
@@ -42,7 +48,7 @@
42
48
  ## 0.8 2021-12-22
43
49
 
44
50
  - Cleanup and refactor code
45
- - Add X global method for XML templates
51
+ - Add Papercraft.xml global method for XML templates
46
52
  - Make `Component` a descendant of `Proc`
47
53
  - Introduce new component API
48
54
  - Rename Rubyoshka to Papercraft
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  Papercraft
5
5
  </h1>
6
6
 
7
- <h4 align="center">Composable HTML templating for Ruby</h4>
7
+ <h4 align="center">Composable templating for Ruby</h4>
8
8
 
9
9
  <p align="center">
10
10
  <a href="http://rubygems.org/gems/papercraft">
@@ -27,26 +27,28 @@
27
27
  ```ruby
28
28
  require 'papercraft'
29
29
 
30
- page = H { |*args|
30
+ page = Papercraft.html { |*args|
31
31
  html {
32
32
  head { }
33
33
  body { emit_yield *args }
34
34
  }
35
35
  }
36
+ page.render { p 'foo' }
37
+ #=> "<html><head/><body><p>foo</p></body></html>"
36
38
 
37
- hello = H.apply { |name| h1 "Hello, #{name}!" }
39
+ hello = page.apply { |name| h1 "Hello, #{name}!" }
38
40
  hello.render('world')
39
41
  #=> "<html><head/><body><h1>Hello, world!</h1></body></html>"
40
42
  ```
41
43
 
42
- Papercraft is an HTML templating engine for Ruby that offers the following
43
- features:
44
+ Papercraft is a templating engine for Ruby that offers the following features:
44
45
 
45
- - HTML and XML templating using plain Ruby syntax
46
+ - HTML, XML and JSON templating using plain Ruby syntax
46
47
  - Minimal boilerplate
47
48
  - Mix logic and tags freely
48
49
  - Automatic HTML and XML escaping
49
50
  - Composable components
51
+ - Standard or custom MIME types
50
52
  - Explicit parameter passing to nested components
51
53
  - Higher order components
52
54
  - Built-in support for rendering [Markdown](#emitting-markdown)
@@ -73,7 +75,7 @@ To create a template use the global method `Kernel#H`:
73
75
  ```ruby
74
76
  require 'papercraft'
75
77
 
76
- html = H {
78
+ html = Papercraft.html {
77
79
  div(id: 'greeter') { p 'Hello!' }
78
80
  }
79
81
  ```
@@ -89,7 +91,7 @@ html.render #=> "<div id="greeter"><p>Hello!</p></div>"
89
91
  Tags are added using unqualified method calls, and can be nested using blocks:
90
92
 
91
93
  ```ruby
92
- H {
94
+ Papercraft.html {
93
95
  html {
94
96
  head {
95
97
  title 'page title'
@@ -106,19 +108,19 @@ H {
106
108
  Tag methods accept a string argument, a block, or no argument at all:
107
109
 
108
110
  ```ruby
109
- H { p 'hello' }.render #=> "<p>hello</p>"
111
+ Papercraft.html { p 'hello' }.render #=> "<p>hello</p>"
110
112
 
111
- H { p { span '1'; span '2' } }.render #=> "<p><span>1</span><span>2</span></p>"
113
+ Papercraft.html { p { span '1'; span '2' } }.render #=> "<p><span>1</span><span>2</span></p>"
112
114
 
113
- H { hr() }.render #=> "<hr/>"
115
+ Papercraft.html { hr() }.render #=> "<hr/>"
114
116
  ```
115
117
 
116
118
  Tag methods also accept tag attributes, given as a hash:
117
119
 
118
120
  ```ruby
119
- H { img src: '/my.gif' }.render #=> "<img src="/my.gif"/>
121
+ Papercraft.html { img src: '/my.gif' }.render #=> "<img src="/my.gif"/>
120
122
 
121
- H { p "foobar", class: 'important' }.render #=> "<p class=\"important\">foobar</p>"
123
+ Papercraft.html { p "foobar", class: 'important' }.render #=> "<p class=\"important\">foobar</p>"
122
124
  ```
123
125
 
124
126
  ## Template parameters
@@ -128,14 +130,14 @@ parameters are specified as block parameters, and are passed to the template on
128
130
  rendering:
129
131
 
130
132
  ```ruby
131
- greeting = H { |name| h1 "Hello, #{name}!" }
133
+ greeting = Papercraft.html { |name| h1 "Hello, #{name}!" }
132
134
  greeting.render('world') #=> "<h1>Hello, world!</h1>"
133
135
  ```
134
136
 
135
137
  Templates can also accept named parameters:
136
138
 
137
139
  ```ruby
138
- greeting = H { |name:| h1 "Hello, #{name}!" }
140
+ greeting = Papercraft.html { |name:| h1 "Hello, #{name}!" }
139
141
  greeting.render(name: 'world') #=> "<h1>Hello, world!</h1>"
140
142
  ```
141
143
 
@@ -145,7 +147,7 @@ Since Papercraft templates are just a bunch of Ruby, you can easily write your
145
147
  view logic right in the template:
146
148
 
147
149
  ```ruby
148
- H { |user = nil|
150
+ Papercraft.html { |user = nil|
149
151
  if user
150
152
  span "Hello, #{user.name}!"
151
153
  else
@@ -159,7 +161,7 @@ H { |user = nil|
159
161
  Templates can also accept and render blocks by using `emit_yield`:
160
162
 
161
163
  ```ruby
162
- page = H {
164
+ page = Papercraft.html {
163
165
  html {
164
166
  body { emit_yield }
165
167
  }
@@ -176,14 +178,14 @@ it by passing it as a block to `H`:
176
178
 
177
179
  ```ruby
178
180
  greeting = proc { |name| h1 "Hello, #{name}!" }
179
- H(&greeting).render('world')
181
+ Papercraft.html(&greeting).render('world')
180
182
  ```
181
183
 
182
184
  Components can also be expressed using lambda notation:
183
185
 
184
186
  ```ruby
185
187
  greeting = ->(name) { h1 "Hello, #{name}!" }
186
- H(&greeting).render('world')
188
+ Papercraft.html(&greeting).render('world')
187
189
  ```
188
190
 
189
191
  ## Component composition
@@ -210,7 +212,7 @@ ItemList = ->(items) {
210
212
  }
211
213
  }
212
214
 
213
- page = H { |title, items|
215
+ page = Papercraft.html { |title, items|
214
216
  html5 {
215
217
  head { Title(title) }
216
218
  body { ItemList(items) }
@@ -229,7 +231,7 @@ non-constant components by invoking the `#emit` method:
229
231
  ```ruby
230
232
  greeting = -> { span "Hello, world" }
231
233
 
232
- H {
234
+ Papercraft.html {
233
235
  div {
234
236
  emit greeting
235
237
  }
@@ -247,12 +249,12 @@ or block to the original component:
247
249
 
248
250
  ```ruby
249
251
  # parameter application
250
- hello = H { |name| h1 "Hello, #{name}!" }
252
+ hello = Papercraft.html { |name| h1 "Hello, #{name}!" }
251
253
  hello_world = hello.apply('world')
252
254
  hello_world.render #=> "<h1>Hello, world!</h1>"
253
255
 
254
256
  # block application
255
- div_wrap = H { div { emit_yield } }
257
+ div_wrap = Papercraft.html { div { emit_yield } }
256
258
  wrapped_h1 = div_wrap.apply { h1 'hi' }
257
259
  wrapped_h1.render #=> "<div><h1>hi</h1></div>"
258
260
 
@@ -271,8 +273,8 @@ markup, enhancing components or injecting component parameters.
271
273
  Here is a HOC that takes a component as parameter:
272
274
 
273
275
  ```ruby
274
- div_wrap = H { |inner| div { emit inner } }
275
- greeter = H { h1 'hi' }
276
+ div_wrap = Papercraft.html { |inner| div { emit inner } }
277
+ greeter = Papercraft.html { h1 'hi' }
276
278
  wrapped_greeter = div_wrap.apply(greeter)
277
279
  wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
278
280
  ```
@@ -280,7 +282,7 @@ wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
280
282
  The inner component can also be passed as a block, as shown above:
281
283
 
282
284
  ```ruby
283
- div_wrap = H { div { emit_yield } }
285
+ div_wrap = Papercraft.html { div { emit_yield } }
284
286
  wrapped_greeter = div_wrap.apply { h1 'hi' }
285
287
  wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
286
288
  ```
@@ -294,7 +296,7 @@ this by creating a `default` page template that takes a block, then use `#apply`
294
296
  to create the other templates:
295
297
 
296
298
  ```ruby
297
- default_layout = H { |**params|
299
+ default_layout = Papercraft.html { |**params|
298
300
  html5 {
299
301
  head {
300
302
  title: params[:title]
@@ -323,7 +325,7 @@ article_layout.render(
323
325
  Raw HTML can be emitted using `#emit`:
324
326
 
325
327
  ```ruby
326
- wrapped = H { |html| div { emit html } }
328
+ wrapped = Papercraft.html { |html| div { emit html } }
327
329
  wrapped.render("<h1>hi</h1>") #=> "<div><h1>hi</h1></div>"
328
330
  ```
329
331
 
@@ -333,7 +335,7 @@ To emit a string with proper HTML encoding, without wrapping it in an HTML
333
335
  element, use `#text`:
334
336
 
335
337
  ```ruby
336
- H { str 'hi&lo' }.render #=> "hi&amp;lo"
338
+ Papercraft.html { str 'hi&lo' }.render #=> "hi&amp;lo"
337
339
  ```
338
340
 
339
341
  ## Emitting Markdown
@@ -343,7 +345,7 @@ Markdown is rendered using the
343
345
  `#emit_markdown`:
344
346
 
345
347
  ```ruby
346
- template = H { |md| div { emit_markdown md } }
348
+ template = Papercraft.html { |md| div { emit_markdown md } }
347
349
  template.render("Here's some *Markdown*") #=> "<div><p>Here's some <em>Markdown</em><p>\n</div>"
348
350
  ```
349
351
 
@@ -352,7 +354,7 @@ options](https://kramdown.gettalong.org/options.html#available-options) can be
352
354
  specified by adding them to the `#emit_markdown` call:
353
355
 
354
356
  ```ruby
355
- template = H { |md| div { emit_markdown md, auto_ids: false } }
357
+ template = Papercraft.html { |md| div { emit_markdown md, auto_ids: false } }
356
358
  template.render("# title") #=> "<div><h1>title</h1></div>"
357
359
  ```
358
360
 
@@ -395,7 +397,7 @@ class that can collect JS and CSS dependencies from the different components
395
397
  integrated into the page, and adds them to the page's `<head>` element:
396
398
 
397
399
  ```ruby
398
- default_layout = H { |**args|
400
+ default_layout = Papercraft.html { |**args|
399
401
  @dependencies = DependencyMananger.new
400
402
  head {
401
403
  defer { emit @dependencies.head_markup }
@@ -481,7 +483,7 @@ The call to `Papercraft::extension` lets us access the different methods of
481
483
  we'll be able to express the above markup as follows:
482
484
 
483
485
  ```ruby
484
- H {
486
+ Papercraft.html {
485
487
  bootstrap.card(style: 'width: 18rem') {
486
488
  bootstrap.card_title 'Card title'
487
489
  bootstrap.card_subtitle 'Card subtitle'
@@ -492,6 +494,37 @@ H {
492
494
  }
493
495
  ```
494
496
 
497
+ ## JSON templating
498
+
499
+ You can create a JSON template using the same API used for HTML and XML
500
+ templating. The only difference is that for adding array items you'll need to
501
+ use the `#item` method:
502
+
503
+ ```ruby
504
+ Papercraft.json {
505
+ item 1
506
+ item 2
507
+ item 3
508
+ }.render #=> "[1,2,3]"
509
+ ```
510
+
511
+ Otherwise, you can create arbitrarily complex JSON structures by mixing hashes
512
+ and arrays:
513
+
514
+ ```Ruby
515
+ Papercraft.json {
516
+ foo {
517
+ bar {
518
+ item nil
519
+ item true
520
+ item 123.456
521
+ }
522
+ }
523
+ }.render #=> "{\"foo\":{\"bar\":[null,true,123.456]}}"
524
+ ```
525
+
526
+ Papercraft uses the [JSON gem](https://rubyapi.org/3.1/o/json) under the hood.
527
+
495
528
  ## API Reference
496
529
 
497
530
  The API reference for this library can be found
@@ -11,21 +11,26 @@ module Papercraft
11
11
  # class is simply a special kind of Proc, which has some enhanced
12
12
  # capabilities, allowing it to be easily composed in a variety of ways.
13
13
  #
14
- # Components are usually created using the global methods `H` or `X`, for HTML
15
- # or XML templates, respectively:
14
+ # Components are usually created using the class methods `html`, `xml` or
15
+ # `json`, for HTML, XML or JSON templates, respectively:
16
16
  #
17
- # greeter = H { |name| h1 "Hello, #{name}!" }
17
+ # greeter = Papercraft.html { |name| h1 "Hello, #{name}!" }
18
18
  # greeter.render('world') #=> "<h1>Hello, world!</h1>"
19
19
  #
20
20
  # Components can also be created using the normal constructor:
21
21
  #
22
- # greeter = Papercraft::Component.new { |name| h1 "Hello, #{name}!" }
22
+ # greeter = Papercraft::Component.new(mode: :html) { |name| h1 "Hello, #{name}!" }
23
23
  # greeter.render('world') #=> "<h1>Hello, world!</h1>"
24
24
  #
25
+ # The different methods for creating components can also take a custom MIME
26
+ # type, by passing a `mime_type` named argument:
27
+ #
28
+ # json = Papercraft.json(mime_type: 'application/feed+json') { ... }
29
+ #
25
30
  # In the component block, HTML elements are created by simply calling
26
31
  # unqualified methods:
27
32
  #
28
- # page_layout = H {
33
+ # page_layout = Papercraft.html {
29
34
  # html5 {
30
35
  # head {
31
36
  # title 'foo'
@@ -41,7 +46,7 @@ module Papercraft
41
46
  # `greeter` template shown above takes a single `name` parameter. Here's how a
42
47
  # anchor component could be implemented with named parameters:
43
48
  #
44
- # anchor = H { |uri: , text: | a(text, href: uri) }
49
+ # anchor = Papercraft.html { |uri: , text: | a(text, href: uri) }
45
50
  #
46
51
  # The above component could later be rendered by passing the needed arguments:
47
52
  #
@@ -51,7 +56,7 @@ module Papercraft
51
56
  #
52
57
  # A component can be included in another component using the `emit` method:
53
58
  #
54
- # links = H {
59
+ # links = Papercraft.html {
55
60
  # emit anchor, uri: '/posts', text: 'Posts'
56
61
  # emit anchor, uri: '/archive', text: 'Archive'
57
62
  # emit anchor, uri: '/about', text: 'About'
@@ -60,7 +65,7 @@ module Papercraft
60
65
  # Another way of composing components is to pass the components themselves as
61
66
  # parameters:
62
67
  #
63
- # links = H { |anchors|
68
+ # links = Papercraft.html { |anchors|
64
69
  # anchors.each { |a| emit a }
65
70
  # }
66
71
  # links.render([
@@ -84,14 +89,22 @@ module Papercraft
84
89
  # Determines the rendering mode: `:html` or `:xml`.
85
90
  attr_accessor :mode
86
91
 
92
+ STOCK_MIME_TYPE = {
93
+ html: 'text/html',
94
+ xml: 'application/xml',
95
+ json: 'application/json'
96
+ }.freeze
97
+
87
98
  # Initializes a component with the given block. The rendering mode (HTML or
88
99
  # XML) can be passed in the `mode:` parameter. If `mode:` is not specified,
89
100
  # the component defaults to HTML.
90
101
  #
91
102
  # @param mode [:html, :xml] rendering mode
103
+ # @param mime_type [String, nil] the component's mime type (nil for default)
92
104
  # @param block [Proc] nested HTML block
93
- def initialize(mode: :html, &block)
105
+ def initialize(mode: :html, mime_type: nil, &block)
94
106
  @mode = mode
107
+ @mime_type = mime_type || STOCK_MIME_TYPE[mode]
95
108
  super(&block)
96
109
  end
97
110
 
@@ -115,7 +128,7 @@ module Papercraft
115
128
  # current one. Application is one of the principal methods of composing
116
129
  # components, particularly when passing inner components as blocks:
117
130
  #
118
- # article_wrapper = H {
131
+ # article_wrapper = Papercraft.html {
119
132
  # article {
120
133
  # emit_yield
121
134
  # }
@@ -131,7 +144,7 @@ module Papercraft
131
144
  # @return [Papercraft::Component] applied component
132
145
  def apply(*a, **b, &block)
133
146
  template = self
134
- Component.new(&proc do |*x, **y|
147
+ Component.new(mode: @mode, mime_type: @mime_type, &proc do |*x, **y|
135
148
  push_emit_yield_block(block) if block
136
149
  instance_exec(*a, *x, **b, **y, &template)
137
150
  end)
@@ -147,10 +160,16 @@ module Papercraft
147
160
  HTMLRenderer
148
161
  when :xml
149
162
  XMLRenderer
163
+ when :json
164
+ JSONRenderer
150
165
  else
151
166
  raise "Invalid mode #{@mode.inspect}"
152
167
  end
153
168
  end
169
+
170
+ def mime_type
171
+ @mime_type
172
+ end
154
173
 
155
174
  # def compile
156
175
  # Papercraft::Compiler.new.compile(self)
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Papercraft
6
+ # JSON renderer extensions
7
+ module JSON
8
+ def object_stack
9
+ @object_stack ||= [nil]
10
+ end
11
+
12
+ def with_object(&block)
13
+ object_stack << nil
14
+ instance_eval(&block)
15
+ end
16
+
17
+ def verify_array_target
18
+ case object_stack[-1]
19
+ when nil
20
+ object_stack[-1] = []
21
+ when Hash
22
+ raise "Mixing array and hash values"
23
+ end
24
+ end
25
+
26
+ def verify_hash_target
27
+ case object_stack[-1]
28
+ when nil
29
+ object_stack[-1] = {}
30
+ when Array
31
+ raise "Mixing array and hash values"
32
+ end
33
+ end
34
+
35
+ def push_array_item(value)
36
+ object_stack[-1] << value
37
+ end
38
+
39
+ def push_kv_item(key, value)
40
+ object_stack[-1][key] = value
41
+ end
42
+
43
+ def enter_object(&block)
44
+ object_stack << nil
45
+ 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
72
+ end
73
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative './html'
4
+ require_relative './json'
4
5
  require_relative './extension_proxy'
5
6
 
6
7
  module Papercraft
@@ -55,7 +56,7 @@ module Papercraft
55
56
  # end
56
57
  #
57
58
  # Papercraft.extension(components: ComponentLibrary)
58
- # H { components.card('Foo', '**Bar**') }
59
+ # Papercraft.html { components.card('Foo', '**Bar**') }
59
60
  #
60
61
  # @param map [Hash] hash mapping methods to extension modules
61
62
  # @return [void]
@@ -210,11 +211,11 @@ module Papercraft
210
211
  # `#to_s` which is then added to the rendering buffer, without any escaping.
211
212
  #
212
213
  # greeter = proc { |name| h1 "Hello, #{name}!" }
213
- # H { emit(greeter, 'world') }.render #=> "<h1>Hello, world!</h1>"
214
+ # Papercraft.html { emit(greeter, 'world') }.render #=> "<h1>Hello, world!</h1>"
214
215
  #
215
- # H { emit 'hi&<bye>' }.render #=> "hi&<bye>"
216
+ # Papercraft.html { emit 'hi&<bye>' }.render #=> "hi&<bye>"
216
217
  #
217
- # H { emit nil }.render #=> ""
218
+ # Papercraft.html { emit nil }.render #=> ""
218
219
  #
219
220
  # @param o [Proc, Papercraft::Component, String] emitted object
220
221
  # @param *a [Array<any>] arguments to pass to a proc
@@ -234,7 +235,7 @@ module Papercraft
234
235
 
235
236
  # Emits a block supplied using `Component#apply` or `Component#render`.
236
237
  #
237
- # div_wrap = H { |*args| div { emit_yield(*args) } }
238
+ # div_wrap = Papercraft.html { |*args| div { emit_yield(*args) } }
238
239
  # greeter = div_wrap.apply { |name| h1 "Hello, #{name}!" }
239
240
  # greeter.render('world') #=> "<div><h1>Hello, world!</h1></div>"
240
241
  #
@@ -256,7 +257,7 @@ module Papercraft
256
257
  # adding elements to the `<head>` section. Here's how a title can be
257
258
  # controlled from a nested component:
258
259
  #
259
- # layout = H {
260
+ # layout = Papercraft.html {
260
261
  # html {
261
262
  # head {
262
263
  # defer { title @title }
@@ -380,4 +381,8 @@ module Papercraft
380
381
  EscapeUtils.escape_xml(text.to_s)
381
382
  end
382
383
  end
384
+
385
+ class JSONRenderer < Renderer
386
+ include JSON
387
+ end
383
388
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Papercraft
4
- VERSION = '0.15'
4
+ VERSION = '0.16'
5
5
  end
data/lib/papercraft.rb CHANGED
@@ -25,36 +25,49 @@ module Papercraft
25
25
  def self.extension(map)
26
26
  Renderer.extension(map)
27
27
  end
28
- end
29
28
 
30
- # Kernel extensions
31
- module ::Kernel
32
-
33
- # Creates a new papercraft component. `#H` can take either a proc argument or
34
- # a block. In both cases, the proc is converted to a `Papercraft::Component`.
29
+ # Creates a new papercraft component. `Papercraft.html` can take either a proc
30
+ # argument or a block. In both cases, the proc is converted to a
31
+ # `Papercraft::Component`.
32
+ #
33
+ # Papercraft.html(proc { h1 'hi' }).render #=> "<h1>hi</h1>"
34
+ # Papercraft.html { h1 'hi' }.render #=> "<h1>hi</h1>"
35
+ #
36
+ # @param template [Proc] template block
37
+ # @return [Papercraft::Component] Papercraft component
38
+ def self.html(o = nil, mime_type: nil, &template)
39
+ return o if o.is_a?(Papercraft::Component)
40
+ template ||= o
41
+ Papercraft::Component.new(mode: :html, mime_type: mime_type, &template)
42
+ end
43
+
44
+ # Creates a new papercraft component in XML mode. `Papercraft.xml` can take
45
+ # either a proc argument or a block. In both cases, the proc is converted to a
46
+ # `Papercraft::Component`.
35
47
  #
36
- # H(proc { h1 'hi' }).render #=> "<h1>hi</h1>"
37
- # H { h1 'hi' }.render #=> "<h1>hi</h1>"
48
+ # Papercraft.xml(proc { item 'foo' }).render #=> "<item>foo</item>"
49
+ # Papercraft.xml { item 'foo' }.render #=> "<item>foo</item>"
38
50
  #
39
51
  # @param template [Proc] template block
40
52
  # @return [Papercraft::Component] Papercraft component
41
- def H(o = nil, &template)
53
+ def self.xml(o = nil, mime_type: nil, &template)
42
54
  return o if o.is_a?(Papercraft::Component)
43
55
  template ||= o
44
- Papercraft::Component.new(mode: :html, &template)
56
+ Papercraft::Component.new(mode: :xml, mime_type: mime_type, &template)
45
57
  end
46
58
 
47
- # Creates a new papercraft component in XML mode. `#X` can take either a proc argument or
48
- # a block. In both cases, the proc is converted to a `Papercraft::Component`.
59
+ # Creates a new papercraft component in JSON mode. `Papercraft.json` can take
60
+ # either a proc argument or a block. In both cases, the proc is converted to a
61
+ # `Papercraft::Component`.
49
62
  #
50
- # X(proc { item 'foo' }).render #=> "<item>foo</item>"
51
- # X { item 'foo' }.render #=> "<item>foo</item>"
63
+ # Papercraft.json(proc { item 42 }).render #=> "[42]"
64
+ # Papercraft.json { foo 'bar' }.render #=> "{\"foo\": \"bar\"}"
52
65
  #
53
66
  # @param template [Proc] template block
54
67
  # @return [Papercraft::Component] Papercraft component
55
- def X(o = nil, &template)
68
+ def self.json(o = nil, mime_type: nil, &template)
56
69
  return o if o.is_a?(Papercraft::Component)
57
70
  template ||= o
58
- Papercraft::Component.new(mode: :xml, &template)
71
+ Papercraft::Component.new(mode: :json, mime_type: mime_type, &template)
59
72
  end
60
73
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: papercraft
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.15'
4
+ version: '0.16'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -137,6 +137,7 @@ files:
137
137
  - lib/papercraft/encoding.rb
138
138
  - lib/papercraft/extension_proxy.rb
139
139
  - lib/papercraft/html.rb
140
+ - lib/papercraft/json.rb
140
141
  - lib/papercraft/renderer.rb
141
142
  - lib/papercraft/version.rb
142
143
  homepage: http://github.com/digital-fabric/papercraft