papercraft 0.13 → 0.17
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 +20 -1
- data/README.md +78 -35
- data/lib/papercraft/component.rb +35 -26
- data/lib/papercraft/html.rb +1 -39
- data/lib/papercraft/json.rb +73 -0
- data/lib/papercraft/renderer.rb +25 -17
- data/lib/papercraft/version.rb +1 -1
- data/lib/papercraft.rb +94 -44
- metadata +19 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31c80224c2a9dc3a6d594d923e9a16ccd8127284bce501f1d7f1dc25386bf25c
|
|
4
|
+
data.tar.gz: 45dc43d353bc1f3c06e62d1b439751570ce7d46a915b0a72f1ce3ea182b0c225
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67529d1336456dded5d911548941c1accc695bd017b889b378ed008e177707b100e11e90b1adbe887d45530cfb94950808e21257955999d795b388dbeb13206e
|
|
7
|
+
data.tar.gz: 1caca448eb2a317b1616a529e82803f6571e26e8b0f36a19e771b2b4a9a96cabb8695ad5a01148acfa7481b016742e9c546c794fd2a9017ec54d299184d36c94
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## 0.17 2022-01-23
|
|
2
|
+
|
|
3
|
+
- Refactor markdown code, add `Papercraft.markdown` method (#8)
|
|
4
|
+
|
|
5
|
+
## 0.16 2022-01-23
|
|
6
|
+
|
|
7
|
+
- Implement JSON templating (#7)
|
|
8
|
+
- Add support for MIME types (#6)
|
|
9
|
+
- Change entrypoint from `Kernel#H`, `Kernel#X` to `Papercraft.html`, `.xml` (#5)
|
|
10
|
+
|
|
11
|
+
## 0.15 2022-01-20
|
|
12
|
+
|
|
13
|
+
- Fix tag method line reference
|
|
14
|
+
- Don't clobber ArgumentError exception
|
|
15
|
+
|
|
16
|
+
## 0.14 2022-01-19
|
|
17
|
+
|
|
18
|
+
- Add support for #emit_yield in applied component (#4)
|
|
19
|
+
|
|
1
20
|
## 0.13 2022-01-19
|
|
2
21
|
|
|
3
22
|
- Add support for partial parameter application (#3)
|
|
@@ -33,7 +52,7 @@
|
|
|
33
52
|
## 0.8 2021-12-22
|
|
34
53
|
|
|
35
54
|
- Cleanup and refactor code
|
|
36
|
-
- Add
|
|
55
|
+
- Add Papercraft.xml global method for XML templates
|
|
37
56
|
- Make `Component` a descendant of `Proc`
|
|
38
57
|
- Introduce new component API
|
|
39
58
|
- Rename Rubyoshka to Papercraft
|
data/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<h1 align="center">
|
|
2
|
+
<img src="papercraft.png">
|
|
3
|
+
<br>
|
|
2
4
|
Papercraft
|
|
3
5
|
</h1>
|
|
4
6
|
|
|
5
|
-
<h4 align="center">Composable
|
|
7
|
+
<h4 align="center">Composable templating for Ruby</h4>
|
|
6
8
|
|
|
7
9
|
<p align="center">
|
|
8
10
|
<a href="http://rubygems.org/gems/papercraft">
|
|
@@ -25,26 +27,28 @@
|
|
|
25
27
|
```ruby
|
|
26
28
|
require 'papercraft'
|
|
27
29
|
|
|
28
|
-
page =
|
|
30
|
+
page = Papercraft.html { |*args|
|
|
29
31
|
html {
|
|
30
32
|
head { }
|
|
31
33
|
body { emit_yield *args }
|
|
32
34
|
}
|
|
33
35
|
}
|
|
36
|
+
page.render { p 'foo' }
|
|
37
|
+
#=> "<html><head/><body><p>foo</p></body></html>"
|
|
34
38
|
|
|
35
|
-
hello =
|
|
39
|
+
hello = page.apply { |name| h1 "Hello, #{name}!" }
|
|
36
40
|
hello.render('world')
|
|
37
41
|
#=> "<html><head/><body><h1>Hello, world!</h1></body></html>"
|
|
38
42
|
```
|
|
39
43
|
|
|
40
|
-
Papercraft is
|
|
41
|
-
features:
|
|
44
|
+
Papercraft is a templating engine for Ruby that offers the following features:
|
|
42
45
|
|
|
43
|
-
- HTML and
|
|
46
|
+
- HTML, XML and JSON templating using plain Ruby syntax
|
|
44
47
|
- Minimal boilerplate
|
|
45
48
|
- Mix logic and tags freely
|
|
46
49
|
- Automatic HTML and XML escaping
|
|
47
50
|
- Composable components
|
|
51
|
+
- Standard or custom MIME types
|
|
48
52
|
- Explicit parameter passing to nested components
|
|
49
53
|
- Higher order components
|
|
50
54
|
- Built-in support for rendering [Markdown](#emitting-markdown)
|
|
@@ -71,7 +75,7 @@ To create a template use the global method `Kernel#H`:
|
|
|
71
75
|
```ruby
|
|
72
76
|
require 'papercraft'
|
|
73
77
|
|
|
74
|
-
html =
|
|
78
|
+
html = Papercraft.html {
|
|
75
79
|
div(id: 'greeter') { p 'Hello!' }
|
|
76
80
|
}
|
|
77
81
|
```
|
|
@@ -87,7 +91,7 @@ html.render #=> "<div id="greeter"><p>Hello!</p></div>"
|
|
|
87
91
|
Tags are added using unqualified method calls, and can be nested using blocks:
|
|
88
92
|
|
|
89
93
|
```ruby
|
|
90
|
-
|
|
94
|
+
Papercraft.html {
|
|
91
95
|
html {
|
|
92
96
|
head {
|
|
93
97
|
title 'page title'
|
|
@@ -104,19 +108,19 @@ H {
|
|
|
104
108
|
Tag methods accept a string argument, a block, or no argument at all:
|
|
105
109
|
|
|
106
110
|
```ruby
|
|
107
|
-
|
|
111
|
+
Papercraft.html { p 'hello' }.render #=> "<p>hello</p>"
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
Papercraft.html { p { span '1'; span '2' } }.render #=> "<p><span>1</span><span>2</span></p>"
|
|
110
114
|
|
|
111
|
-
|
|
115
|
+
Papercraft.html { hr() }.render #=> "<hr/>"
|
|
112
116
|
```
|
|
113
117
|
|
|
114
118
|
Tag methods also accept tag attributes, given as a hash:
|
|
115
119
|
|
|
116
120
|
```ruby
|
|
117
|
-
|
|
121
|
+
Papercraft.html { img src: '/my.gif' }.render #=> "<img src="/my.gif"/>
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
Papercraft.html { p "foobar", class: 'important' }.render #=> "<p class=\"important\">foobar</p>"
|
|
120
124
|
```
|
|
121
125
|
|
|
122
126
|
## Template parameters
|
|
@@ -126,14 +130,14 @@ parameters are specified as block parameters, and are passed to the template on
|
|
|
126
130
|
rendering:
|
|
127
131
|
|
|
128
132
|
```ruby
|
|
129
|
-
greeting =
|
|
133
|
+
greeting = Papercraft.html { |name| h1 "Hello, #{name}!" }
|
|
130
134
|
greeting.render('world') #=> "<h1>Hello, world!</h1>"
|
|
131
135
|
```
|
|
132
136
|
|
|
133
137
|
Templates can also accept named parameters:
|
|
134
138
|
|
|
135
139
|
```ruby
|
|
136
|
-
greeting =
|
|
140
|
+
greeting = Papercraft.html { |name:| h1 "Hello, #{name}!" }
|
|
137
141
|
greeting.render(name: 'world') #=> "<h1>Hello, world!</h1>"
|
|
138
142
|
```
|
|
139
143
|
|
|
@@ -143,7 +147,7 @@ Since Papercraft templates are just a bunch of Ruby, you can easily write your
|
|
|
143
147
|
view logic right in the template:
|
|
144
148
|
|
|
145
149
|
```ruby
|
|
146
|
-
|
|
150
|
+
Papercraft.html { |user = nil|
|
|
147
151
|
if user
|
|
148
152
|
span "Hello, #{user.name}!"
|
|
149
153
|
else
|
|
@@ -157,7 +161,7 @@ H { |user = nil|
|
|
|
157
161
|
Templates can also accept and render blocks by using `emit_yield`:
|
|
158
162
|
|
|
159
163
|
```ruby
|
|
160
|
-
page =
|
|
164
|
+
page = Papercraft.html {
|
|
161
165
|
html {
|
|
162
166
|
body { emit_yield }
|
|
163
167
|
}
|
|
@@ -174,14 +178,14 @@ it by passing it as a block to `H`:
|
|
|
174
178
|
|
|
175
179
|
```ruby
|
|
176
180
|
greeting = proc { |name| h1 "Hello, #{name}!" }
|
|
177
|
-
|
|
181
|
+
Papercraft.html(&greeting).render('world')
|
|
178
182
|
```
|
|
179
183
|
|
|
180
184
|
Components can also be expressed using lambda notation:
|
|
181
185
|
|
|
182
186
|
```ruby
|
|
183
187
|
greeting = ->(name) { h1 "Hello, #{name}!" }
|
|
184
|
-
|
|
188
|
+
Papercraft.html(&greeting).render('world')
|
|
185
189
|
```
|
|
186
190
|
|
|
187
191
|
## Component composition
|
|
@@ -208,7 +212,7 @@ ItemList = ->(items) {
|
|
|
208
212
|
}
|
|
209
213
|
}
|
|
210
214
|
|
|
211
|
-
page =
|
|
215
|
+
page = Papercraft.html { |title, items|
|
|
212
216
|
html5 {
|
|
213
217
|
head { Title(title) }
|
|
214
218
|
body { ItemList(items) }
|
|
@@ -227,7 +231,7 @@ non-constant components by invoking the `#emit` method:
|
|
|
227
231
|
```ruby
|
|
228
232
|
greeting = -> { span "Hello, world" }
|
|
229
233
|
|
|
230
|
-
|
|
234
|
+
Papercraft.html {
|
|
231
235
|
div {
|
|
232
236
|
emit greeting
|
|
233
237
|
}
|
|
@@ -245,12 +249,12 @@ or block to the original component:
|
|
|
245
249
|
|
|
246
250
|
```ruby
|
|
247
251
|
# parameter application
|
|
248
|
-
hello =
|
|
252
|
+
hello = Papercraft.html { |name| h1 "Hello, #{name}!" }
|
|
249
253
|
hello_world = hello.apply('world')
|
|
250
254
|
hello_world.render #=> "<h1>Hello, world!</h1>"
|
|
251
255
|
|
|
252
256
|
# block application
|
|
253
|
-
div_wrap =
|
|
257
|
+
div_wrap = Papercraft.html { div { emit_yield } }
|
|
254
258
|
wrapped_h1 = div_wrap.apply { h1 'hi' }
|
|
255
259
|
wrapped_h1.render #=> "<div><h1>hi</h1></div>"
|
|
256
260
|
|
|
@@ -269,8 +273,8 @@ markup, enhancing components or injecting component parameters.
|
|
|
269
273
|
Here is a HOC that takes a component as parameter:
|
|
270
274
|
|
|
271
275
|
```ruby
|
|
272
|
-
div_wrap =
|
|
273
|
-
greeter =
|
|
276
|
+
div_wrap = Papercraft.html { |inner| div { emit inner } }
|
|
277
|
+
greeter = Papercraft.html { h1 'hi' }
|
|
274
278
|
wrapped_greeter = div_wrap.apply(greeter)
|
|
275
279
|
wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
|
|
276
280
|
```
|
|
@@ -278,7 +282,7 @@ wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
|
|
|
278
282
|
The inner component can also be passed as a block, as shown above:
|
|
279
283
|
|
|
280
284
|
```ruby
|
|
281
|
-
div_wrap =
|
|
285
|
+
div_wrap = Papercraft.html { div { emit_yield } }
|
|
282
286
|
wrapped_greeter = div_wrap.apply { h1 'hi' }
|
|
283
287
|
wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
|
|
284
288
|
```
|
|
@@ -292,7 +296,7 @@ this by creating a `default` page template that takes a block, then use `#apply`
|
|
|
292
296
|
to create the other templates:
|
|
293
297
|
|
|
294
298
|
```ruby
|
|
295
|
-
default_layout =
|
|
299
|
+
default_layout = Papercraft.html { |**params|
|
|
296
300
|
html5 {
|
|
297
301
|
head {
|
|
298
302
|
title: params[:title]
|
|
@@ -321,7 +325,7 @@ article_layout.render(
|
|
|
321
325
|
Raw HTML can be emitted using `#emit`:
|
|
322
326
|
|
|
323
327
|
```ruby
|
|
324
|
-
wrapped =
|
|
328
|
+
wrapped = Papercraft.html { |html| div { emit html } }
|
|
325
329
|
wrapped.render("<h1>hi</h1>") #=> "<div><h1>hi</h1></div>"
|
|
326
330
|
```
|
|
327
331
|
|
|
@@ -331,7 +335,7 @@ To emit a string with proper HTML encoding, without wrapping it in an HTML
|
|
|
331
335
|
element, use `#text`:
|
|
332
336
|
|
|
333
337
|
```ruby
|
|
334
|
-
|
|
338
|
+
Papercraft.html { str 'hi&lo' }.render #=> "hi&lo"
|
|
335
339
|
```
|
|
336
340
|
|
|
337
341
|
## Emitting Markdown
|
|
@@ -341,7 +345,7 @@ Markdown is rendered using the
|
|
|
341
345
|
`#emit_markdown`:
|
|
342
346
|
|
|
343
347
|
```ruby
|
|
344
|
-
template =
|
|
348
|
+
template = Papercraft.html { |md| div { emit_markdown md } }
|
|
345
349
|
template.render("Here's some *Markdown*") #=> "<div><p>Here's some <em>Markdown</em><p>\n</div>"
|
|
346
350
|
```
|
|
347
351
|
|
|
@@ -350,10 +354,18 @@ options](https://kramdown.gettalong.org/options.html#available-options) can be
|
|
|
350
354
|
specified by adding them to the `#emit_markdown` call:
|
|
351
355
|
|
|
352
356
|
```ruby
|
|
353
|
-
template =
|
|
357
|
+
template = Papercraft.html { |md| div { emit_markdown md, auto_ids: false } }
|
|
354
358
|
template.render("# title") #=> "<div><h1>title</h1></div>"
|
|
355
359
|
```
|
|
356
360
|
|
|
361
|
+
The `#emit_markdown` method is available only to HTML templates. If you need to
|
|
362
|
+
render markdown in XML or JSON templates (usually for implementing RSS or JSON
|
|
363
|
+
feeds), you can use `Papercraft.markdown` directly:
|
|
364
|
+
|
|
365
|
+
```ruby
|
|
366
|
+
Papercraft.markdown('# title') #=> "<h1>title</h1>"
|
|
367
|
+
```
|
|
368
|
+
|
|
357
369
|
The default Kramdown options are:
|
|
358
370
|
|
|
359
371
|
```ruby
|
|
@@ -366,10 +378,10 @@ The default Kramdown options are:
|
|
|
366
378
|
```
|
|
367
379
|
|
|
368
380
|
The deafult options can be configured by accessing
|
|
369
|
-
`Papercraft
|
|
381
|
+
`Papercraft.default_kramdown_options`, e.g.:
|
|
370
382
|
|
|
371
383
|
```ruby
|
|
372
|
-
Papercraft
|
|
384
|
+
Papercraft.default_kramdown_options[:auto_ids] = false
|
|
373
385
|
```
|
|
374
386
|
|
|
375
387
|
## Deferred evaluation
|
|
@@ -393,7 +405,7 @@ class that can collect JS and CSS dependencies from the different components
|
|
|
393
405
|
integrated into the page, and adds them to the page's `<head>` element:
|
|
394
406
|
|
|
395
407
|
```ruby
|
|
396
|
-
default_layout =
|
|
408
|
+
default_layout = Papercraft.html { |**args|
|
|
397
409
|
@dependencies = DependencyMananger.new
|
|
398
410
|
head {
|
|
399
411
|
defer { emit @dependencies.head_markup }
|
|
@@ -479,7 +491,7 @@ The call to `Papercraft::extension` lets us access the different methods of
|
|
|
479
491
|
we'll be able to express the above markup as follows:
|
|
480
492
|
|
|
481
493
|
```ruby
|
|
482
|
-
|
|
494
|
+
Papercraft.html {
|
|
483
495
|
bootstrap.card(style: 'width: 18rem') {
|
|
484
496
|
bootstrap.card_title 'Card title'
|
|
485
497
|
bootstrap.card_subtitle 'Card subtitle'
|
|
@@ -490,6 +502,37 @@ H {
|
|
|
490
502
|
}
|
|
491
503
|
```
|
|
492
504
|
|
|
505
|
+
## JSON templating
|
|
506
|
+
|
|
507
|
+
You can create a JSON template using the same API used for HTML and XML
|
|
508
|
+
templating. The only difference is that for adding array items you'll need to
|
|
509
|
+
use the `#item` method:
|
|
510
|
+
|
|
511
|
+
```ruby
|
|
512
|
+
Papercraft.json {
|
|
513
|
+
item 1
|
|
514
|
+
item 2
|
|
515
|
+
item 3
|
|
516
|
+
}.render #=> "[1,2,3]"
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
Otherwise, you can create arbitrarily complex JSON structures by mixing hashes
|
|
520
|
+
and arrays:
|
|
521
|
+
|
|
522
|
+
```Ruby
|
|
523
|
+
Papercraft.json {
|
|
524
|
+
foo {
|
|
525
|
+
bar {
|
|
526
|
+
item nil
|
|
527
|
+
item true
|
|
528
|
+
item 123.456
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}.render #=> "{\"foo\":{\"bar\":[null,true,123.456]}}"
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Papercraft uses the [JSON gem](https://rubyapi.org/3.1/o/json) under the hood.
|
|
535
|
+
|
|
493
536
|
## API Reference
|
|
494
537
|
|
|
495
538
|
The API reference for this library can be found
|
data/lib/papercraft/component.rb
CHANGED
|
@@ -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
|
|
15
|
-
#
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
|
@@ -106,21 +119,16 @@ module Papercraft
|
|
|
106
119
|
template = self
|
|
107
120
|
Renderer.verify_proc_parameters(template, a, b)
|
|
108
121
|
renderer_class.new do
|
|
109
|
-
if block
|
|
110
|
-
|
|
111
|
-
else
|
|
112
|
-
instance_exec(*a, **b, &template)
|
|
113
|
-
end
|
|
122
|
+
push_emit_yield_block(block) if block
|
|
123
|
+
instance_exec(*a, **b, &template)
|
|
114
124
|
end.to_s
|
|
115
|
-
rescue ArgumentError => e
|
|
116
|
-
raise Papercraft::Error, e.message
|
|
117
125
|
end
|
|
118
126
|
|
|
119
127
|
# Creates a new component, applying the given parameters and or block to the
|
|
120
128
|
# current one. Application is one of the principal methods of composing
|
|
121
129
|
# components, particularly when passing inner components as blocks:
|
|
122
130
|
#
|
|
123
|
-
# article_wrapper =
|
|
131
|
+
# article_wrapper = Papercraft.html {
|
|
124
132
|
# article {
|
|
125
133
|
# emit_yield
|
|
126
134
|
# }
|
|
@@ -136,15 +144,10 @@ module Papercraft
|
|
|
136
144
|
# @return [Papercraft::Component] applied component
|
|
137
145
|
def apply(*a, **b, &block)
|
|
138
146
|
template = self
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
else
|
|
144
|
-
Component.new(&proc do |*x, **y|
|
|
145
|
-
instance_exec(*a, *x, **b, **y, &template)
|
|
146
|
-
end)
|
|
147
|
-
end
|
|
147
|
+
Component.new(mode: @mode, mime_type: @mime_type, &proc do |*x, **y|
|
|
148
|
+
push_emit_yield_block(block) if block
|
|
149
|
+
instance_exec(*a, *x, **b, **y, &template)
|
|
150
|
+
end)
|
|
148
151
|
end
|
|
149
152
|
|
|
150
153
|
# Returns the Renderer class used for rendering the templates, according to
|
|
@@ -157,10 +160,16 @@ module Papercraft
|
|
|
157
160
|
HTMLRenderer
|
|
158
161
|
when :xml
|
|
159
162
|
XMLRenderer
|
|
163
|
+
when :json
|
|
164
|
+
JSONRenderer
|
|
160
165
|
else
|
|
161
166
|
raise "Invalid mode #{@mode.inspect}"
|
|
162
167
|
end
|
|
163
168
|
end
|
|
169
|
+
|
|
170
|
+
def mime_type
|
|
171
|
+
@mime_type
|
|
172
|
+
end
|
|
164
173
|
|
|
165
174
|
# def compile
|
|
166
175
|
# Papercraft::Compiler.new.compile(self)
|
data/lib/papercraft/html.rb
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'kramdown'
|
|
4
|
-
require 'rouge'
|
|
5
|
-
require 'kramdown-parser-gfm'
|
|
6
|
-
|
|
7
3
|
module Papercraft
|
|
8
4
|
# HTML Markup extensions
|
|
9
5
|
module HTML
|
|
@@ -83,41 +79,7 @@ module Papercraft
|
|
|
83
79
|
# @param **opts [Hash] Kramdown options
|
|
84
80
|
# @return [void]
|
|
85
81
|
def emit_markdown(markdown, **opts)
|
|
86
|
-
emit
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
class << self
|
|
90
|
-
# Returns the default Kramdown options used for converting Markdown to
|
|
91
|
-
# HTML.
|
|
92
|
-
#
|
|
93
|
-
# @return [Hash] Default Kramdown options
|
|
94
|
-
def kramdown_options
|
|
95
|
-
@kramdown_options ||= {
|
|
96
|
-
entity_output: :numeric,
|
|
97
|
-
syntax_highlighter: :rouge,
|
|
98
|
-
input: 'GFM',
|
|
99
|
-
hard_wrap: false
|
|
100
|
-
}
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Sets the default Kramdown options used for converting Markdown to
|
|
104
|
-
# HTML.
|
|
105
|
-
#
|
|
106
|
-
# @param opts [Hash] New deafult Kramdown options
|
|
107
|
-
# @return [Hash] New default Kramdown options
|
|
108
|
-
def kramdown_options=(opts)
|
|
109
|
-
@kramdown_options = opts
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
private
|
|
114
|
-
|
|
115
|
-
# Returns the default Kramdown options, merged with the given overrides.
|
|
116
|
-
#
|
|
117
|
-
# @param opts [Hash] Kramdown option overrides
|
|
118
|
-
# @return [Hash] Merged Kramdown options
|
|
119
|
-
def kramdown_options(opts)
|
|
120
|
-
HTML.kramdown_options.merge(**opts)
|
|
82
|
+
emit Papercraft.markdown(markdown, **opts)
|
|
121
83
|
end
|
|
122
84
|
end
|
|
123
85
|
end
|
|
@@ -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
|
data/lib/papercraft/renderer.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'escape_utils'
|
|
4
|
+
|
|
3
5
|
require_relative './html'
|
|
6
|
+
require_relative './json'
|
|
4
7
|
require_relative './extension_proxy'
|
|
5
8
|
|
|
6
9
|
module Papercraft
|
|
@@ -55,7 +58,7 @@ module Papercraft
|
|
|
55
58
|
# end
|
|
56
59
|
#
|
|
57
60
|
# Papercraft.extension(components: ComponentLibrary)
|
|
58
|
-
#
|
|
61
|
+
# Papercraft.html { components.card('Foo', '**Bar**') }
|
|
59
62
|
#
|
|
60
63
|
# @param map [Hash] hash mapping methods to extension modules
|
|
61
64
|
# @return [void]
|
|
@@ -112,7 +115,7 @@ module Papercraft
|
|
|
112
115
|
|
|
113
116
|
# The tag method template below is optimized for performance. Do not touch!
|
|
114
117
|
|
|
115
|
-
S_TAG_METHOD_LINE = __LINE__ +
|
|
118
|
+
S_TAG_METHOD_LINE = __LINE__ + 2
|
|
116
119
|
S_TAG_METHOD = <<~EOF
|
|
117
120
|
S_TAG_%<TAG>s_PRE = %<tag_pre>s
|
|
118
121
|
S_TAG_%<TAG>s_CLOSE = %<tag_close>s
|
|
@@ -210,11 +213,11 @@ module Papercraft
|
|
|
210
213
|
# `#to_s` which is then added to the rendering buffer, without any escaping.
|
|
211
214
|
#
|
|
212
215
|
# greeter = proc { |name| h1 "Hello, #{name}!" }
|
|
213
|
-
#
|
|
216
|
+
# Papercraft.html { emit(greeter, 'world') }.render #=> "<h1>Hello, world!</h1>"
|
|
214
217
|
#
|
|
215
|
-
#
|
|
218
|
+
# Papercraft.html { emit 'hi&<bye>' }.render #=> "hi&<bye>"
|
|
216
219
|
#
|
|
217
|
-
#
|
|
220
|
+
# Papercraft.html { emit nil }.render #=> ""
|
|
218
221
|
#
|
|
219
222
|
# @param o [Proc, Papercraft::Component, String] emitted object
|
|
220
223
|
# @param *a [Array<any>] arguments to pass to a proc
|
|
@@ -234,7 +237,7 @@ module Papercraft
|
|
|
234
237
|
|
|
235
238
|
# Emits a block supplied using `Component#apply` or `Component#render`.
|
|
236
239
|
#
|
|
237
|
-
# div_wrap =
|
|
240
|
+
# div_wrap = Papercraft.html { |*args| div { emit_yield(*args) } }
|
|
238
241
|
# greeter = div_wrap.apply { |name| h1 "Hello, #{name}!" }
|
|
239
242
|
# greeter.render('world') #=> "<div><h1>Hello, world!</h1></div>"
|
|
240
243
|
#
|
|
@@ -242,9 +245,10 @@ module Papercraft
|
|
|
242
245
|
# @param **b [Hash] named arguments to pass to a proc
|
|
243
246
|
# @return [void]
|
|
244
247
|
def emit_yield(*a, **b)
|
|
245
|
-
|
|
248
|
+
block = @emit_yield_stack&.pop
|
|
249
|
+
raise Papercraft::Error, "No block given" unless block
|
|
246
250
|
|
|
247
|
-
instance_exec(*a, **b,
|
|
251
|
+
instance_exec(*a, **b, &block)
|
|
248
252
|
end
|
|
249
253
|
|
|
250
254
|
# Defers the given block to be evaluated later. Deferred evaluation allows
|
|
@@ -255,7 +259,7 @@ module Papercraft
|
|
|
255
259
|
# adding elements to the `<head>` section. Here's how a title can be
|
|
256
260
|
# controlled from a nested component:
|
|
257
261
|
#
|
|
258
|
-
# layout =
|
|
262
|
+
# layout = Papercraft.html {
|
|
259
263
|
# html {
|
|
260
264
|
# head {
|
|
261
265
|
# defer { title @title }
|
|
@@ -304,19 +308,19 @@ module Papercraft
|
|
|
304
308
|
private
|
|
305
309
|
|
|
306
310
|
# Escapes text. This method must be overriden in descendant classes.
|
|
311
|
+
#
|
|
312
|
+
# @param text [String] text to be escaped
|
|
307
313
|
def escape_text(text)
|
|
308
314
|
raise NotImplementedError
|
|
309
315
|
end
|
|
310
316
|
|
|
311
|
-
#
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
ensure
|
|
317
|
-
@inner_block = old_block
|
|
317
|
+
# Pushes the given block onto the emit_yield stack.
|
|
318
|
+
#
|
|
319
|
+
# @param block [Proc] block
|
|
320
|
+
def push_emit_yield_block(block)
|
|
321
|
+
(@emit_yield_stack ||= []) << block
|
|
318
322
|
end
|
|
319
|
-
|
|
323
|
+
|
|
320
324
|
# Emits tag attributes into the rendering buffer
|
|
321
325
|
# @param props [Hash] tag attributes
|
|
322
326
|
# @return [void]
|
|
@@ -379,4 +383,8 @@ module Papercraft
|
|
|
379
383
|
EscapeUtils.escape_xml(text.to_s)
|
|
380
384
|
end
|
|
381
385
|
end
|
|
386
|
+
|
|
387
|
+
class JSONRenderer < Renderer
|
|
388
|
+
include JSON
|
|
389
|
+
end
|
|
382
390
|
end
|
data/lib/papercraft/version.rb
CHANGED
data/lib/papercraft.rb
CHANGED
|
@@ -1,60 +1,110 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'kramdown'
|
|
4
|
+
require 'rouge'
|
|
5
|
+
require 'kramdown-parser-gfm'
|
|
4
6
|
|
|
5
7
|
require_relative 'papercraft/component'
|
|
6
8
|
require_relative 'papercraft/renderer'
|
|
7
9
|
require_relative 'papercraft/encoding'
|
|
8
10
|
# require_relative 'papercraft/compiler'
|
|
9
11
|
|
|
12
|
+
|
|
10
13
|
# Papercraft is a component-based HTML templating library
|
|
11
14
|
module Papercraft
|
|
12
15
|
# Exception class used to signal templating-related errors
|
|
13
16
|
class Error < RuntimeError; end
|
|
14
|
-
|
|
15
|
-
# Installs one or more extensions. Extensions enhance templating capabilities
|
|
16
|
-
# by adding namespaced methods to emplates. An extension is implemented as a
|
|
17
|
-
# Ruby module containing one or more methods. Each method in the extension
|
|
18
|
-
# module can be used to render a specific HTML element or a set of elements.
|
|
19
|
-
#
|
|
20
|
-
# This is a convenience method. For more information on using Papercraft
|
|
21
|
-
# extensions, see `Papercraft::Renderer::extension`
|
|
22
|
-
#
|
|
23
|
-
# @param map [Hash] hash mapping methods to extension modules
|
|
24
|
-
# @return [void]
|
|
25
|
-
def self.extension(map)
|
|
26
|
-
Renderer.extension(map)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Kernel extensions
|
|
31
|
-
module ::Kernel
|
|
32
17
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
18
|
+
class << self
|
|
19
|
+
|
|
20
|
+
# Installs one or more extensions. Extensions enhance templating capabilities
|
|
21
|
+
# by adding namespaced methods to emplates. An extension is implemented as a
|
|
22
|
+
# Ruby module containing one or more methods. Each method in the extension
|
|
23
|
+
# module can be used to render a specific HTML element or a set of elements.
|
|
24
|
+
#
|
|
25
|
+
# This is a convenience method. For more information on using Papercraft
|
|
26
|
+
# extensions, see `Papercraft::Renderer::extension`
|
|
27
|
+
#
|
|
28
|
+
# @param map [Hash] hash mapping methods to extension modules
|
|
29
|
+
# @return [void]
|
|
30
|
+
def extension(map)
|
|
31
|
+
Renderer.extension(map)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Creates a new papercraft component. `Papercraft.html` can take either a proc
|
|
35
|
+
# argument or a block. In both cases, the proc is converted to a
|
|
36
|
+
# `Papercraft::Component`.
|
|
37
|
+
#
|
|
38
|
+
# Papercraft.html(proc { h1 'hi' }).render #=> "<h1>hi</h1>"
|
|
39
|
+
# Papercraft.html { h1 'hi' }.render #=> "<h1>hi</h1>"
|
|
40
|
+
#
|
|
41
|
+
# @param template [Proc] template block
|
|
42
|
+
# @return [Papercraft::Component] Papercraft component
|
|
43
|
+
def html(o = nil, mime_type: nil, &template)
|
|
44
|
+
return o if o.is_a?(Papercraft::Component)
|
|
45
|
+
template ||= o
|
|
46
|
+
Papercraft::Component.new(mode: :html, mime_type: mime_type, &template)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Creates a new papercraft component in XML mode. `Papercraft.xml` can take
|
|
50
|
+
# either a proc argument or a block. In both cases, the proc is converted to a
|
|
51
|
+
# `Papercraft::Component`.
|
|
52
|
+
#
|
|
53
|
+
# Papercraft.xml(proc { item 'foo' }).render #=> "<item>foo</item>"
|
|
54
|
+
# Papercraft.xml { item 'foo' }.render #=> "<item>foo</item>"
|
|
55
|
+
#
|
|
56
|
+
# @param template [Proc] template block
|
|
57
|
+
# @return [Papercraft::Component] Papercraft component
|
|
58
|
+
def xml(o = nil, mime_type: nil, &template)
|
|
59
|
+
return o if o.is_a?(Papercraft::Component)
|
|
60
|
+
template ||= o
|
|
61
|
+
Papercraft::Component.new(mode: :xml, mime_type: mime_type, &template)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Creates a new papercraft component in JSON mode. `Papercraft.json` can take
|
|
65
|
+
# either a proc argument or a block. In both cases, the proc is converted to a
|
|
66
|
+
# `Papercraft::Component`.
|
|
67
|
+
#
|
|
68
|
+
# Papercraft.json(proc { item 42 }).render #=> "[42]"
|
|
69
|
+
# Papercraft.json { foo 'bar' }.render #=> "{\"foo\": \"bar\"}"
|
|
70
|
+
#
|
|
71
|
+
# @param template [Proc] template block
|
|
72
|
+
# @return [Papercraft::Component] Papercraft component
|
|
73
|
+
def json(o = nil, mime_type: nil, &template)
|
|
74
|
+
return o if o.is_a?(Papercraft::Component)
|
|
75
|
+
template ||= o
|
|
76
|
+
Papercraft::Component.new(mode: :json, mime_type: mime_type, &template)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Renders Markdown into HTML. The `opts` argument will be merged with the
|
|
80
|
+
# default Kramdown options in order to change the rendering behaviour.
|
|
81
|
+
#
|
|
82
|
+
# @param markdown [String] Markdown
|
|
83
|
+
# @param **opts [Hash] Kramdown option overrides
|
|
84
|
+
# @return [String] HTML
|
|
85
|
+
def markdown(markdown, **opts)
|
|
86
|
+
opts = default_kramdown_options.merge(opts)
|
|
87
|
+
Kramdown::Document.new(markdown, **opts).to_html
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Returns the default Kramdown options used for rendering Markdown.
|
|
91
|
+
#
|
|
92
|
+
# @return [Hash] Kramdown options
|
|
93
|
+
def default_kramdown_options
|
|
94
|
+
@default_kramdown_options ||= {
|
|
95
|
+
entity_output: :numeric,
|
|
96
|
+
syntax_highlighter: :rouge,
|
|
97
|
+
input: 'GFM',
|
|
98
|
+
hard_wrap: false
|
|
99
|
+
}
|
|
100
|
+
end
|
|
46
101
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# @return [Papercraft::Component] Papercraft component
|
|
55
|
-
def X(o = nil, &template)
|
|
56
|
-
return o if o.is_a?(Papercraft::Component)
|
|
57
|
-
template ||= o
|
|
58
|
-
Papercraft::Component.new(mode: :xml, &template)
|
|
102
|
+
# Sets the default Kramdown options used for rendering Markdown.
|
|
103
|
+
#
|
|
104
|
+
# @param opts [Hash] Kramdown options
|
|
105
|
+
# @return [void]
|
|
106
|
+
def default_kramdown_options=(opts)
|
|
107
|
+
@default_kramdown_options = opts
|
|
108
|
+
end
|
|
59
109
|
end
|
|
60
110
|
end
|
metadata
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: papercraft
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '0.
|
|
4
|
+
version: '0.17'
|
|
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-
|
|
11
|
+
date: 2022-01-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: escape_utils
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: 1.2.1
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- -
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 1.2.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
@@ -30,28 +30,28 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 2.3.
|
|
33
|
+
version: 2.3.1
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 2.3.
|
|
40
|
+
version: 2.3.1
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rouge
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 3.
|
|
47
|
+
version: 3.27.0
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 3.
|
|
54
|
+
version: 3.27.0
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: kramdown-parser-gfm
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -70,56 +70,56 @@ dependencies:
|
|
|
70
70
|
name: minitest
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- -
|
|
73
|
+
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: 5.
|
|
75
|
+
version: '5.15'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- -
|
|
80
|
+
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: 5.
|
|
82
|
+
version: '5.15'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: benchmark-ips
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- -
|
|
87
|
+
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: 2.7.2
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- -
|
|
94
|
+
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: 2.7.2
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: erubis
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
|
-
- -
|
|
101
|
+
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
103
|
version: 2.7.0
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
|
-
- -
|
|
108
|
+
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: 2.7.0
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: tilt
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
|
-
- -
|
|
115
|
+
- - "~>"
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
117
|
version: 2.0.9
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
|
-
- -
|
|
122
|
+
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: 2.0.9
|
|
125
125
|
description:
|
|
@@ -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
|