papercraft 0.8.3 → 0.11

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: 125df0455a1b4c3373b36b3f52b6d965249a7ddf470439ec48df3f7216ea3991
4
- data.tar.gz: be9cea2084785a3dc135b852b66f0d91375cafd6050834d06f26f8a6b497f95f
3
+ metadata.gz: 3452d115d85742018d1497b369ea27970f0c144e3dcb1772f4d81e33315dce51
4
+ data.tar.gz: e7217a9d9bcfd7af0dc92482650bc03392b0406cf4f3d6141c253a2918638545
5
5
  SHA512:
6
- metadata.gz: f45e9101d8bb14bfdde19958988343d6e4d87e270462a0db13630860aff5d6adc560df90aefd78317642f6987d3853cc68ad8adb7d0b74e381b43930424d7a79
7
- data.tar.gz: c7a153329948a8fa5dbe90602a293b22e060f0118cc3cdfd629f9af9644f57bea4add8ec13e40a5194178bdebc5dd43a26c0507f03e8dd78e3a3a5662968e390
6
+ metadata.gz: 8f76b9e73aa48f91af932af3308d3dd43239c3d5ca39e305cb1535417b5997483aa884f0e34ed128800b07a3135ebc1d18ea81d0df64e6170726a66c86969288
7
+ data.tar.gz: dbe744ca25996c3d263ff609ca26f42076784fdbceabd2dd1604dd1016e2d840830230f4205a673b9e5ba14eb8e480627612971b71ca6631e0a6e473d59ccb73
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 0.11 2022-01-04
2
+
3
+ - Add deferred evaluation
4
+
5
+ ## 0.10.1 2021-12-25
6
+
7
+ - Fix tag rendering with empty text in Ruby 3.0
8
+
9
+ ## 0.10 2021-12-25
10
+
11
+ - Add support for extensions
12
+
13
+ ## 0.9 2021-12-23
14
+
15
+ - Add support for emitting Markdown
16
+ - Add support for passing proc as argument to `#H` and `#X`
17
+ - Deprecate `Encoding` module
18
+
1
19
  ## 0.8.1 2021-12-22
2
20
 
3
21
  - Fix gemspec
data/README.md CHANGED
@@ -1,30 +1,56 @@
1
- # Papercraft - Composable HTML templating for Ruby
1
+ <h1 align="center">
2
+ Papercraft
3
+ </h1>
4
+
5
+ <h4 align="center">Composable HTML templating for Ruby</h4>
6
+
7
+ <p align="center">
8
+ <a href="http://rubygems.org/gems/papercraft">
9
+ <img src="https://badge.fury.io/rb/papercraft.svg" alt="Ruby gem">
10
+ </a>
11
+ <a href="https://github.com/digital-fabric/papercraft/actions?query=workflow%3ATests">
12
+ <img src="https://github.com/digital-fabric/papercraft/workflows/Tests/badge.svg" alt="Tests">
13
+ </a>
14
+ <a href="https://github.com/digital-fabric/papercraft/blob/master/LICENSE">
15
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
16
+ </a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://www.rubydoc.info/gems/papercraft">API reference</a>
21
+ </p>
2
22
 
3
- [INSTALL](#installing-papercraft) |
4
- [TUTORIAL](#getting-started) |
5
- [EXAMPLES](examples) |
6
- [REFERENCE](#api-reference)
23
+ # Papercraft - Composable HTML templating for Ruby
7
24
 
8
25
  ## What is Papercraft?
9
26
 
27
+ ```ruby
28
+ require 'papercraft'
29
+
30
+ page = H { |*args|
31
+ html {
32
+ head { }
33
+ body { emit_yield *args }
34
+ }
35
+ }
36
+
37
+ hello = H.apply { |name| h1 "Hello, #{name}!" }
38
+ hello.render('world')
39
+ #=> "<html><head/><body><h1>Hello, world!</h1></body></html>"
40
+ ```
41
+
10
42
  Papercraft is an HTML templating engine for Ruby that offers the following
11
43
  features:
12
44
 
13
- - HTML templating using plain Ruby syntax
45
+ - HTML and XML templating using plain Ruby syntax
14
46
  - Minimal boilerplate
15
47
  - Mix logic and tags freely
16
- - Use global and local contexts to pass values to reusable components
17
- - Automatic HTML escaping
48
+ - Automatic HTML and XML escaping
18
49
  - Composable components
50
+ - Explicit parameter passing to nested components
19
51
  - Higher order components
20
- - Built-in support for rendering Markdown
21
-
22
- > **Note** Papercraft is a new library and as such may be missing features and
23
- > contain bugs. Also, its API may change unexpectedly. Your issue reports and
24
- > code contributions are most welcome!
25
-
26
- With Papercraft you can structure your templates as nested HTML components, in a
27
- somewhat similar fashion to React.
52
+ - Built-in support for rendering [Markdown](#emitting-markdown)
53
+ - Support for namespaced extensions
28
54
 
29
55
  ## Installing Papercraft
30
56
 
@@ -42,42 +68,25 @@ $ gem install papercraft
42
68
 
43
69
  ## Getting started
44
70
 
45
- To use Papercraft in your code just require it:
71
+ To create a template use the global method `Kernel#H`:
46
72
 
47
73
  ```ruby
48
74
  require 'papercraft'
49
- ```
50
-
51
- To create a template use `Papercraft.new` or the global method `Kernel#H`:
52
75
 
53
- ```ruby
54
- # can also use Papercraft.new
55
76
  html = H {
56
- div { p 'hello' }
77
+ div(id: 'greeter') { p 'Hello!' }
57
78
  }
58
79
  ```
59
80
 
60
- ## Rendering a template
61
-
62
- To render a Papercraft template use the `#render` method:
81
+ Rendering a template is done using `#render`:
63
82
 
64
83
  ```ruby
65
- H { span 'best span' }.render #=> "<span>best span</span>"
66
- ```
67
-
68
- The render method accepts an arbitrary context variable:
69
-
70
- ```ruby
71
- html = H {
72
- h1 context[:title]
73
- }
74
-
75
- html.render(title: 'My title') #=> "<h1>My title</h1>"
84
+ html.render #=> "<div id="greeter"><p>Hello!</p></div>"
76
85
  ```
77
86
 
78
87
  ## All about tags
79
88
 
80
- Tags are added using unqualified method calls, and are nested using blocks:
89
+ Tags are added using unqualified method calls, and can be nested using blocks:
81
90
 
82
91
  ```ruby
83
92
  H {
@@ -114,8 +123,9 @@ H { p "foobar", class: 'important' }.render #=> "<p class=\"important\">foobar</
114
123
 
115
124
  ## Template parameters
116
125
 
117
- Template parameters are specified as block parameters, and are passed to the
118
- template on rendering:
126
+ In Papercraft, parameters are always passed explicitly. This means that template
127
+ parameters are specified as block parameters, and are passed to the template on
128
+ rendering:
119
129
 
120
130
  ```ruby
121
131
  greeting = H { |name| h1 "Hello, #{name}!" }
@@ -328,110 +338,161 @@ H { str 'hi&lo' }.render #=> "hi&amp;lo"
328
338
 
329
339
  ## Emitting Markdown
330
340
 
331
- To emit Markdown, use `#emit_markdown`:
341
+ Markdown is rendered using the
342
+ [Kramdown](https://kramdown.gettalong.org/index.html) gem. To emit Markdown, use
343
+ `#emit_markdown`:
332
344
 
333
345
  ```ruby
334
346
  template = H { |md| div { emit_markdown md } }
335
- template.render("Here's some *Markdown*") #=> "<div>Here's some <em>Markdown</em></div>"
347
+ template.render("Here's some *Markdown*") #=> "<div><p>Here's some <em>Markdown</em><p>\n</div>"
336
348
  ```
337
349
 
338
- ## Some interesting use cases
339
-
340
- Papercraft opens up all kinds of new possibilities when it comes to putting
341
- together pieces of HTML. Feel free to explore the API!
350
+ [Kramdown
351
+ options](https://kramdown.gettalong.org/options.html#available-options) can be
352
+ specified by adding them to the `#emit_markdown` call:
342
353
 
343
- ### A higher-order list component
354
+ ```ruby
355
+ template = H { |md| div { emit_markdown md, auto_ids: false } }
356
+ template.render("# title") #=> "<div><h1>title</h1></div>"
357
+ ```
344
358
 
345
- Here's another demonstration of a higher-order component, a list component that
346
- takes an item component as an argument. The `List` component can be reused for
347
- rendering any kind of unordered list, and with any kind of item component:
359
+ The default Kramdown options are:
348
360
 
349
361
  ```ruby
350
- List = ->(items, item_component) {
351
- H {
352
- ul {
353
- items.each { |item|
354
- with(item: item) {
355
- li { emit item_component }
356
- }
357
- }
358
- }
359
- }
362
+ {
363
+ entity_output: :numeric,
364
+ syntax_highlighter: :rouge,
365
+ input: 'GFM',
366
+ hard_wrap: false
360
367
  }
361
-
362
- TodoItem = H {
363
- span item.text, class: item.completed ? 'completed' : 'pending'
364
- }
365
-
366
- def todo_list(items)
367
- H {
368
- div { List(items, TodoItem) }
369
- }
370
- end
371
368
  ```
372
369
 
373
- ## API Reference
374
-
375
- #### `Papercraft#initialize(**context, &block)` a.k.a. `Kernel#H`
370
+ The deafult options can be configured by accessing
371
+ `Papercraft::HTML.kramdown_options`:
376
372
 
377
- - `context`: local context hash
378
- - `block`: template block
373
+ ```ruby
374
+ Papercraft::HTML.kramdown_options[:auto_ids] = false
375
+ ```
379
376
 
380
- Initializes a new Papercraft instance. This method takes a block of template
381
- code, and an optional [local context](#local-context) in the form of a hash.
382
- The `Kernel#H` method serves as a shortcut for creating Papercraft instances.
377
+ ## Deferred evaluation
383
378
 
384
- #### `Papercraft#render(**context)`
379
+ Deferred evaluation allows deferring the rendering of parts of a template until
380
+ the last moment, thus allowing an inner component to manipulate the state of the
381
+ outer component. To in order to defer a part of a template, use `#defer`, and
382
+ include any markup in the provided block. This technique, in in conjunction with
383
+ holding state in instance variables, is an alternative to passing parameters,
384
+ which can be limiting in some situations.
385
385
 
386
- - `context`: global context hash
386
+ A few use cases for deferred evaulation come to mind:
387
387
 
388
- Renders the template with an optional [global context](#global-context)
389
- hash.
388
+ - Setting the page title.
389
+ - Adding a flash message to a page.
390
+ - Using components that dynamically add static dependencies (JS and CSS) to the
391
+ page.
390
392
 
391
- #### Methods accessible inside template blocks
393
+ The last use case is particularly interesting. Imagine a `DependencyMananger`
394
+ class that can collect JS and CSS dependencies from the different components
395
+ integrated into the page, and adds them to the page's `<head>` element:
392
396
 
393
- #### `#<tag/component>(*args, **props, &block)`
397
+ ```ruby
398
+ default_layout = H { |**args|
399
+ @dependencies = DependencyMananger.new
400
+ head {
401
+ defer { emit @dependencies.head_markup }
402
+ }
403
+ body { emit_yield **args }
404
+ }
394
405
 
395
- - `args`: tag arguments. For an HTML tag Papercraft expects a single `String`
396
- argument containing the inner text of the tag.
397
- - `props`: hash of tag attributes
398
- - `block`: inner HTML block
406
+ button = proc { |text, onclick|
407
+ @dependencies.js '/static/js/button.js'
408
+ @dependencies.css '/static/css/button.css'
399
409
 
400
- Adds a tag or component to the current template. If the method name starts with
401
- an upper-case letter, it is considered a [component](#templates-as-components).
410
+ button text, onclick: onclick
411
+ }
402
412
 
403
- If a text argument is given for a tag, it will be escaped.
413
+ heading = proc { |text|
414
+ @dependencies.js '/static/js/heading.js'
415
+ @dependencies.css '/static/css/heading.css'
404
416
 
405
- #### `#cache(*vary, &block)`
417
+ h1 text
418
+ }
406
419
 
407
- - `vary`: variables used in cached block. The given values will be used to
408
- create a separate cache entry.
409
- - `block`: inner HTML block
420
+ page = default_layout.apply {
421
+ emit heading, "What's your favorite cheese?"
410
422
 
411
- Caches the markup in the given block, storing it in the Papercraft cache store.
412
- If a cache entry for the given block is found, it will be used instead of
413
- invoking the block. If one or more variables given, those will be used to create
414
- a separate cache entry.
423
+ emit button, 'Beaufort', 'eat_beaufort()'
424
+ emit button, 'Mont d''or', 'eat_montdor()'
425
+ emit button, 'Époisses', 'eat_epoisses()'
426
+ }
427
+ ```
415
428
 
416
- #### `#context`
429
+ ## Papercraft extensions
430
+
431
+ Papercraft extensions are modules that contain one or more methods that can be
432
+ used to render complex HTML components. Extension modules can be used by
433
+ installing them as a namespaced extension using `Papercraft.extension`.
434
+ Extensions are particularly useful when you work with CSS frameworks such as
435
+ [Bootstrap](https://getbootstrap.com/), [Tailwind](https://tailwindui.com/) or
436
+ [Primer](https://primer.style/).
437
+
438
+ For example, to create a Bootstrap card component, the following HTML markup is
439
+ needed (example taken from the [Bootstrap
440
+ docs](https://getbootstrap.com/docs/5.1/components/card/#titles-text-and-links)):
441
+
442
+ ```html
443
+ <div class="card" style="width: 18rem;">
444
+ <div class="card-body">
445
+ <h5 class="card-title">Card title</h5>
446
+ <h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
447
+ <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
448
+ <a href="#" class="card-link">Card link</a>
449
+ <a href="#" class="card-link">Another link</a>
450
+ </div>
451
+ </div>
452
+ ```
417
453
 
418
- Accesses the [global context](#global-context).
454
+ With Papercraft, we could create a `Bootstrap` extension with a `#card` method
455
+ and other associated methods:
419
456
 
420
- #### `#emit(object)` a.k.a. `#e(object)`
457
+ ```ruby
458
+ module BootstrapComponents
459
+ ...
421
460
 
422
- - `object`: `Proc`, `Papercraft` instance or `String`
461
+ def card(**props)
462
+ div(class: 'card', **props) {
463
+ div(class: 'card-body') {
464
+ emit_yield
465
+ }
466
+ }
467
+ end
423
468
 
424
- Adds the given object to the current template. If a `String` is given, it is
425
- rendered verbatim, i.e. without escaping.
469
+ def card_title(title)
470
+ h5 title, class: 'card-title'
471
+ end
426
472
 
427
- #### `html5(&block)`
473
+ ...
474
+ end
428
475
 
429
- - `block`: inner HTML block
476
+ Papercraft.extension(bootstrap: BootstrapComponents)
477
+ ```
430
478
 
431
- Adds an HTML5 `doctype` tag, followed by an `html` tag with the given block.
479
+ The call to `Papercraft.extension` lets us access the different methods of
480
+ `BootstrapComponents` by calling `#bootstrap` inside a template. With this,
481
+ we'll be able to express the above markup as follows:
432
482
 
433
- #### `#text(data)`
483
+ ```ruby
484
+ H {
485
+ bootstrap.card(style: 'width: 18rem') {
486
+ bootstrap.card_title 'Card title'
487
+ bootstrap.card_subtitle 'Card subtitle'
488
+ bootstrap.card_text 'Some quick example text to build on the card title and make up the bulk of the card''s content.'
489
+ bootstrap.card_link '#', 'Card link'
490
+ bootstrap.card_link '#', 'Another link'
491
+ }
492
+ }
493
+ ```
434
494
 
435
- - `data` - text to add
495
+ ## API Reference
436
496
 
437
- Adds text without wrapping it in a tag. The text will be escaped.
497
+ The API reference for this library can be found
498
+ [here](https://www.rubydoc.info/gems/papercraft).
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Papercraft
4
+
5
+ # An ExtensionProxy proxies method calls to a renderer. Extension proxies are
6
+ # used to provide an namespaced interface to Papercraft extensions. When an
7
+ # extension is installed using `Papercraft.extension`, a corresponding method
8
+ # is defined on the `Papercraft::Renderer` class that creates an extension
9
+ # proxy that gives access to the different extension methods.
10
+ class ExtensionProxy
11
+
12
+ # Initializes a new ExtensionProxy.
13
+ # @param renderer [Papercraft::Renderer] renderer to proxy to
14
+ # @param mod [Module] extension module
15
+ # @return [void]
16
+ def initialize(renderer, mod)
17
+ @renderer = renderer
18
+ extend(mod)
19
+ end
20
+
21
+ # Proxies missing methods to the renderer
22
+ # @param sym [Symbol] method name
23
+ # @param *args [Array] arguments
24
+ # @param &block [Proc] block
25
+ # @return void
26
+ def method_missing(sym, *args, &block)
27
+ @renderer.send(sym, *args, &block)
28
+ end
29
+ end
30
+ end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './html'
3
+ require 'kramdown'
4
+ require 'rouge'
5
+ require 'kramdown-parser-gfm'
4
6
 
5
- module Papercraft
6
-
7
+ module Papercraft
7
8
  # HTML Markup extensions
8
9
  module HTML
9
10
  # Emits the p tag (overrides Object#p)
@@ -42,5 +43,28 @@ module Papercraft
42
43
  end
43
44
  link(**attributes)
44
45
  end
46
+
47
+ def emit_markdown(markdown, **opts)
48
+ emit Kramdown::Document.new(markdown, **kramdown_options(opts)).to_html
49
+ end
50
+
51
+ def kramdown_options(opts)
52
+ HTML.kramdown_options.merge(**opts)
53
+ end
54
+
55
+ class << self
56
+ def kramdown_options
57
+ @kramdown_options ||= {
58
+ entity_output: :numeric,
59
+ syntax_highlighter: :rouge,
60
+ input: 'GFM',
61
+ hard_wrap: false
62
+ }
63
+ end
64
+
65
+ def kramdown_options=(opts)
66
+ @kramdown_options = opts
67
+ end
68
+ end
45
69
  end
46
70
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative './html'
4
+ require_relative './extension_proxy'
4
5
 
5
6
  module Papercraft
6
7
 
@@ -31,15 +32,39 @@ module Papercraft
31
32
  if param_count > args.size
32
33
  raise Papercraft::Error, "Missing template parameters"
33
34
  end
34
- end
35
+ end
36
+
37
+ # Installs the given extensions, mapping a method name to the extension
38
+ # module.
39
+ # @param map [Hash] hash mapping methods to extension modules
40
+ # @return [void]
41
+ def extension(map)
42
+ map.each do |sym, mod|
43
+ define_extension_method(sym, mod)
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Defines a method returning an extension proxy for the given module
50
+ # @param sym [Symbol] method name
51
+ # @param mod [Module] extension module
52
+ # @return [void]
53
+ def define_extension_method(sym, mod)
54
+ define_method(sym) do
55
+ (@extension_proxies ||= {})[mod] ||= ExtensionProxy.new(self, mod)
56
+ end
57
+ end
35
58
  end
36
59
 
60
+ INITIAL_BUFFER_CAPACITY = 8192
61
+
37
62
  # Initializes the renderer and evaulates the given template in the
38
63
  # renderer's scope.
39
64
  #
40
65
  # @param &template [Proc] template block
41
66
  def initialize(&template)
42
- @buffer = +''
67
+ @buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
43
68
  instance_eval(&template)
44
69
  end
45
70
 
@@ -47,6 +72,20 @@ module Papercraft
47
72
  #
48
73
  # @return [String]
49
74
  def to_s
75
+ if @parts
76
+ last = @buffer
77
+ @buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
78
+ parts = @parts
79
+ @parts = nil
80
+ parts.each do |p|
81
+ if Proc === p
82
+ render_deferred_proc(&p)
83
+ else
84
+ @buffer << p
85
+ end
86
+ end
87
+ @buffer << last unless last.empty?
88
+ end
50
89
  @buffer
51
90
  end
52
91
 
@@ -56,6 +95,11 @@ module Papercraft
56
95
  S_TAG_%<TAG>s_CLOSE = '</%<tag>s>'.tr('_', '-')
57
96
 
58
97
  def %<tag>s(text = nil, **props, &block)
98
+ if text.is_a?(Hash) && props.empty?
99
+ props = text
100
+ text = nil
101
+ end
102
+
59
103
  @buffer << S_TAG_%<TAG>s_PRE
60
104
  emit_props(props) unless props.empty?
61
105
 
@@ -83,9 +127,6 @@ module Papercraft
83
127
  # @param &block [Proc] block passed to method
84
128
  # @return [void]
85
129
  def method_missing(sym, *args, **opts, &block)
86
- value = @local && @local[sym]
87
- return value if value
88
-
89
130
  tag = sym.to_s
90
131
  code = S_TAG_METHOD % { tag: tag, TAG: tag.upcase }
91
132
  self.class.class_eval(code, __FILE__, S_TAG_METHOD_LINE)
@@ -135,6 +176,42 @@ module Papercraft
135
176
 
136
177
  instance_exec(*a, **b, &@inner_block)
137
178
  end
179
+
180
+ # Defers the given block to be evaluated later. Deferred evaluation allows
181
+ # Papercraft components to inject state into sibling components, regardless
182
+ # of the component's order in the container component. For example, a nested
183
+ # component may set an instance variable used by another component. This is
184
+ # an elegant solution to the problem of setting the HTML page's title, or
185
+ # adding elements to the `<head>` section. Here's how a title can be
186
+ # controlled from a nested component:
187
+ #
188
+ # layout = H {
189
+ # html {
190
+ # head {
191
+ # defer { title @title }
192
+ # }
193
+ # body {
194
+ # emit_yield
195
+ # }
196
+ # }
197
+ # }
198
+ #
199
+ # html.render {
200
+ # @title = 'My super page'
201
+ # h1 'content'
202
+ # }
203
+ #
204
+ # @param &block [Proc] Deferred block to be emitted
205
+ # @return [void]
206
+ def defer(&block)
207
+ if !@parts
208
+ @parts = [@buffer, block]
209
+ else
210
+ @parts << @buffer unless @buffer.empty?
211
+ @parts << block
212
+ end
213
+ @buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
214
+ end
138
215
 
139
216
  S_LT = '<'
140
217
  S_GT = '>'
@@ -192,6 +269,23 @@ module Papercraft
192
269
  end
193
270
  }
194
271
  end
272
+
273
+ # Renders a deferred proc by evaluating it, then adding the rendered result
274
+ # to the buffer.
275
+ #
276
+ # @param &block [Proc] deferred proc
277
+ # @return [void]
278
+ def render_deferred_proc(&block)
279
+ old_buffer = @buffer
280
+
281
+ @buffer = String.new(capacity: INITIAL_BUFFER_CAPACITY)
282
+ @parts = nil
283
+
284
+ instance_eval(&block)
285
+
286
+ old_buffer << to_s
287
+ @buffer = old_buffer
288
+ end
195
289
  end
196
290
 
197
291
  # Implements an HTML renderer
@@ -200,6 +294,7 @@ module Papercraft
200
294
 
201
295
  private
202
296
 
297
+ # Escapes the given text using HTML entities.
203
298
  def escape_text(text)
204
299
  EscapeUtils.escape_html(text.to_s)
205
300
  end
@@ -209,6 +304,7 @@ module Papercraft
209
304
  class XMLRenderer < Renderer
210
305
  private
211
306
 
307
+ # Escapes the given text using XML entities.
212
308
  def escape_text(text)
213
309
  EscapeUtils.escape_xml(text.to_s)
214
310
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Papercraft
4
- VERSION = '0.8.3'
4
+ VERSION = '0.11'
5
5
  end
data/lib/papercraft.rb CHANGED
@@ -11,6 +11,14 @@ require_relative 'papercraft/encoding'
11
11
  module Papercraft
12
12
  # Exception class used to signal templating-related errors
13
13
  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
+ def self.extension(map)
20
+ Renderer.extension(map)
21
+ end
14
22
  end
15
23
 
16
24
  # Kernel extensions
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.8.3
4
+ version: '0.11'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-23 00:00:00.000000000 Z
11
+ date: 2022-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: escape_utils
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: kramdown
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.3.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.3.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rouge
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.26.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.26.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: kramdown-parser-gfm
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.0
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: minitest
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +122,7 @@ dependencies:
80
122
  - - '='
81
123
  - !ruby/object:Gem::Version
82
124
  version: 2.0.9
83
- description:
125
+ description:
84
126
  email: sharon@noteflakes.com
85
127
  executables: []
86
128
  extensions: []
@@ -93,6 +135,7 @@ files:
93
135
  - lib/papercraft/compiler.rb
94
136
  - lib/papercraft/component.rb
95
137
  - lib/papercraft/encoding.rb
138
+ - lib/papercraft/extension_proxy.rb
96
139
  - lib/papercraft/html.rb
97
140
  - lib/papercraft/renderer.rb
98
141
  - lib/papercraft/version.rb
@@ -104,7 +147,7 @@ metadata:
104
147
  documentation_uri: https://www.rubydoc.info/gems/papercraft
105
148
  homepage_uri: https://github.com/digital-fabric/papercraft
106
149
  changelog_uri: https://github.com/digital-fabric/papercraft/blob/master/CHANGELOG.md
107
- post_install_message:
150
+ post_install_message:
108
151
  rdoc_options:
109
152
  - "--title"
110
153
  - Papercraft
@@ -123,8 +166,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
166
  - !ruby/object:Gem::Version
124
167
  version: '0'
125
168
  requirements: []
126
- rubygems_version: 3.1.6
127
- signing_key:
169
+ rubygems_version: 3.3.3
170
+ signing_key:
128
171
  specification_version: 4
129
172
  summary: 'Papercraft: component-based HTML templating for Ruby'
130
173
  test_files: []