papercraft 0.8 → 0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4404d5b6a84318eab12f0c7d13b4c3be4355c8ebb36b6a3fbd65c6f62af8f361
4
- data.tar.gz: 175a60878f6770ae52d956b6e7c72326af5a0db9faefecae2bd2c3e2fb406f97
3
+ metadata.gz: e1f7aa5872a78830c1a5662f055639ae2012b5b9d0f029640dce041f58d1ef4e
4
+ data.tar.gz: 0c5acc8b14254c63db2132caab42ce003a8ae4713ae6daea7225d0390a420219
5
5
  SHA512:
6
- metadata.gz: 307d3e37cb946b0adb54fa2d6b2939ec0016cc81205f3b4d4dfb6c01d57b65b1f609024b0499f6b5717c858b6dc5aea472f0b82585df44f761f4ac9fdb8c2eae
7
- data.tar.gz: 96162c1707785e3d54ce6cb55bd9a5801658b92d294e28b4168b78ee68e49027ec945eab13d47142382e458fdd33c6d26182a7a08bfc403038c170a8f119984f
6
+ metadata.gz: 02bf1f7bc1300f4fa7871a6942c6a2eae2dd2f8202c7f3cc354171806f82e8a68262c3ca5e2232b7b6dcf6788a33b134b5811641561fa5baba3b7c342643b082
7
+ data.tar.gz: 97a68a0f854f631a6a36b52a350faae4b1da1e337b27701209c6eec9dc16c62856555fdff3ab3d8f33e144e7fed8dc892b22433f38dd3f951a04010f710b63c4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.9 2021-12-23
2
+
3
+ - Add support for emitting Markdown
4
+ - Add support for passing proc as argument to `#H` and `#X`
5
+ - Deprecate `Encoding` module
6
+
7
+ ## 0.8.1 2021-12-22
8
+
9
+ - Fix gemspec
10
+
1
11
  ## 0.8 2021-12-22
2
12
 
3
13
  - Cleanup and refactor code
data/README.md CHANGED
@@ -2,26 +2,36 @@
2
2
 
3
3
  [INSTALL](#installing-papercraft) |
4
4
  [TUTORIAL](#getting-started) |
5
- [EXAMPLES](examples) |
6
- [REFERENCE](#api-reference)
5
+ [DOCS](https://www.rubydoc.info/gems/papercraft)
7
6
 
8
7
  ## What is Papercraft?
9
8
 
9
+ ```ruby
10
+ require 'papercraft'
11
+
12
+ page = H { |*args|
13
+ html {
14
+ head { }
15
+ body { emit_yield *args }
16
+ }
17
+ }
18
+
19
+ hello = H.apply { |name| h1 "Hello, #{name}!" }
20
+ hello.render('world')
21
+ #=> "<html><head/><body><h1>Hello, world!</h1></body></html>"
22
+ ```
23
+
10
24
  Papercraft is an HTML templating engine for Ruby that offers the following
11
25
  features:
12
26
 
13
- - HTML templating using plain Ruby syntax
27
+ - HTML and XML templating using plain Ruby syntax
14
28
  - Minimal boilerplate
15
29
  - Mix logic and tags freely
16
- - Use global and local contexts to pass values to reusable components
17
- - Automatic HTML escaping
30
+ - Automatic HTML and XML escaping
18
31
  - Composable components
32
+ - Explicit parameter passing to nested components
19
33
  - 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!
34
+ - Built-in support for rendering [Markdown](#emitting-markdown)
25
35
 
26
36
  With Papercraft you can structure your templates as nested HTML components, in a
27
37
  somewhat similar fashion to React.
@@ -48,7 +58,8 @@ To use Papercraft in your code just require it:
48
58
  require 'papercraft'
49
59
  ```
50
60
 
51
- To create a template use `Papercraft.new` or the global method `Kernel#H`:
61
+ To create a template use `Papercraft::Component.new` or the global method
62
+ `Kernel#H`:
52
63
 
53
64
  ```ruby
54
65
  # can also use Papercraft.new
@@ -114,8 +125,9 @@ H { p "foobar", class: 'important' }.render #=> "<p class=\"important\">foobar</
114
125
 
115
126
  ## Template parameters
116
127
 
117
- Template parameters are specified as block parameters, and are passed to the
118
- template on rendering:
128
+ In Papercraft, parameters are always passed explicitly. This means that template
129
+ parameters are specified as block parameters, and are passed to the template on
130
+ rendering:
119
131
 
120
132
  ```ruby
121
133
  greeting = H { |name| h1 "Hello, #{name}!" }
@@ -328,110 +340,43 @@ H { str 'hi&lo' }.render #=> "hi&amp;lo"
328
340
 
329
341
  ## Emitting Markdown
330
342
 
331
- To emit Markdown, use `#emit_markdown`:
343
+ Markdown is rendered using the
344
+ [Kramdown](https://kramdown.gettalong.org/index.html) gem. To emit Markdown, use
345
+ `#emit_markdown`:
332
346
 
333
347
  ```ruby
334
348
  template = H { |md| div { emit_markdown md } }
335
- template.render("Here's some *Markdown*") #=> "<div>Here's some <em>Markdown</em></div>"
349
+ template.render("Here's some *Markdown*") #=> "<div><p>Here's some <em>Markdown</em><p>\n</div>"
336
350
  ```
337
351
 
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!
352
+ [Kramdown
353
+ options](https://kramdown.gettalong.org/options.html#available-options) can be
354
+ specified by adding them to the `#emit_markdown` call:
342
355
 
343
- ### A higher-order list component
356
+ ```ruby
357
+ template = H { |md| div { emit_markdown md, auto_ids: false } }
358
+ template.render("# title") #=> "<div><h1>title</h1></div>"
359
+ ```
344
360
 
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:
361
+ The default Kramdown options are:
348
362
 
349
363
  ```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
- }
364
+ {
365
+ entity_output: :numeric,
366
+ syntax_highlighter: :rouge,
367
+ input: 'GFM',
368
+ hard_wrap: false
360
369
  }
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
370
  ```
372
371
 
373
- ## API Reference
374
-
375
- #### `Papercraft#initialize(**context, &block)` a.k.a. `Kernel#H`
376
-
377
- - `context`: local context hash
378
- - `block`: template block
372
+ The deafult options can be configured by accessing
373
+ `Papercraft::HTML.kramdown_options`:
379
374
 
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.
383
-
384
- #### `Papercraft#render(**context)`
385
-
386
- - `context`: global context hash
387
-
388
- Renders the template with an optional [global context](#global-context)
389
- hash.
390
-
391
- #### Methods accessible inside template blocks
392
-
393
- #### `#<tag/component>(*args, **props, &block)`
394
-
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
399
-
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).
402
-
403
- If a text argument is given for a tag, it will be escaped.
404
-
405
- #### `#cache(*vary, &block)`
406
-
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
410
-
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.
415
-
416
- #### `#context`
417
-
418
- Accesses the [global context](#global-context).
419
-
420
- #### `#emit(object)` a.k.a. `#e(object)`
421
-
422
- - `object`: `Proc`, `Papercraft` instance or `String`
423
-
424
- Adds the given object to the current template. If a `String` is given, it is
425
- rendered verbatim, i.e. without escaping.
426
-
427
- #### `html5(&block)`
428
-
429
- - `block`: inner HTML block
430
-
431
- Adds an HTML5 `doctype` tag, followed by an `html` tag with the given block.
432
-
433
- #### `#text(data)`
375
+ ```ruby
376
+ Papercraft::HTML.kramdown_options[:auto_ids] = false
377
+ ```
434
378
 
435
- - `data` - text to add
379
+ ## Documentation
436
380
 
437
- Adds text without wrapping it in a tag. The text will be escaped.
381
+ The complete documentation for this library can be found
382
+ [here](https://www.rubydoc.info/gems/papercraft).
@@ -3,18 +3,19 @@
3
3
  require_relative './html'
4
4
 
5
5
  module Papercraft
6
+
6
7
  # Component represents a distinct, reusable HTML template. A component can
7
8
  # include other components, and also be nested inside other components.
8
9
  #
9
10
  # Since in Papercraft HTML is expressed using blocks (or procs,) the Component
10
11
  # class is simply a special kind of Proc, which has some enhanced
11
12
  # capabilities, allowing it to be easily composed in a variety of ways.
12
-
13
+ #
13
14
  # Components are usually created using the global methods `H` or `X`, for HTML
14
15
  # or XML templates, respectively:
15
16
  #
16
- # greeter = H { |name| h1 "Hello, #{name}!" } greeter.render('world') #=>
17
- # "<h1>Hello, world!</h1>"
17
+ # greeter = H { |name| h1 "Hello, #{name}!" }
18
+ # greeter.render('world') #=> "<h1>Hello, world!</h1>"
18
19
  #
19
20
  # Components can also be created using the normal constructor:
20
21
  #
@@ -23,9 +24,71 @@ module Papercraft
23
24
  #
24
25
  # In the component block, HTML elements are created by simply calling
25
26
  # unqualified methods:
27
+ #
28
+ # page_layout = H {
29
+ # html5 {
30
+ # head {
31
+ # title 'foo'
32
+ # }
33
+ # body {
34
+ # h1 "Hello, world!"
35
+ # }
36
+ # }
37
+ # }
38
+ #
39
+ # Papercraft components can take explicit parameters in order to render
40
+ # dynamic content. This can be in the form of regular or named parameters. The
41
+ # `greeter` template shown above takes a single `name` parameter. Here's how a
42
+ # anchor component could be implemented with named parameters:
43
+ #
44
+ # anchor = H { |uri: , text: | a(text, href: uri) }
45
+ #
46
+ # The above component could later be rendered by passing the needed arguments:
47
+ #
48
+ # anchor.render(uri: 'https://example.com', text: 'Example')
49
+ #
50
+ # ## Component Composition
51
+ #
52
+ # A component can be included in another component using the `emit` method:
53
+ #
54
+ # links = H {
55
+ # emit anchor, uri: '/posts', text: 'Posts'
56
+ # emit anchor, uri: '/archive', text: 'Archive'
57
+ # emit anchor, uri: '/about', text: 'About'
58
+ # }
59
+ #
60
+ # Another way of composing components is to pass the components themselves as
61
+ # parameters:
62
+ #
63
+ # links = H { |anchors|
64
+ # anchors.each { |a| emit a }
65
+ # }
66
+ # links.render([
67
+ # anchor.apply(uri: '/posts', text: 'Posts'),
68
+ # anchor.apply(uri: '/archive', text: 'Archive'),
69
+ # anchor.apply(uri: '/about', text: 'About')
70
+ # ])
71
+ #
72
+ # The `#apply` method creates a new component, applying the given parameters
73
+ # such that the component can be rendered without parameters:
74
+ #
75
+ # links_with_anchors = links.apply([
76
+ # anchor.apply(uri: '/posts', text: 'Posts'),
77
+ # anchor.apply(uri: '/archive', text: 'Archive'),
78
+ # anchor.apply(uri: '/about', text: 'About')
79
+ # ])
80
+ # links_with_anchors.render
81
+ #
26
82
  class Component < Proc
27
- # Initializes a component with the given block
28
- # @param mode [Symbol] local context
83
+
84
+ # Determines the rendering mode: `:html` or `:xml`.
85
+ attr_accessor :mode
86
+
87
+ # Initializes a component with the given block. The rendering mode (HTML or
88
+ # XML) can be passed in the `mode:` parameter. If `mode:` is not specified,
89
+ # the component defaults to HTML.
90
+ #
91
+ # @param mode [:html, :xml] rendering mode
29
92
  # @param block [Proc] nested HTML block
30
93
  def initialize(mode: :html, &block)
31
94
  @mode = mode
@@ -34,7 +97,9 @@ module Papercraft
34
97
 
35
98
  H_EMPTY = {}.freeze
36
99
 
37
- # Renders the associated block and returns the string result
100
+ # Renders the template with the given parameters and or block, and returns
101
+ # the string result.
102
+ #
38
103
  # @param context [Hash] context
39
104
  # @return [String]
40
105
  def render(*a, **b, &block)
@@ -51,6 +116,24 @@ module Papercraft
51
116
  raise Papercraft::Error, e.message
52
117
  end
53
118
 
119
+ # Creates a new component, applying the given parameters and or block to the
120
+ # current one. Application is one of the principal methods of composing
121
+ # components, particularly when passing inner components as blocks:
122
+ #
123
+ # article_wrapper = H {
124
+ # article {
125
+ # emit_yield
126
+ # }
127
+ # }
128
+ # wrapped_article = article_wrapper.apply {
129
+ # h1 'Article title'
130
+ # }
131
+ # wrapped_article.render #=> "<article><h1>Article title</h1></article>"
132
+ #
133
+ # @param *a [<any>] normal parameters
134
+ # @param **b [Hash] named parameters
135
+ # @param &block [Proc] inner block
136
+ # @return [Papercraft::Component] applied component
54
137
  def apply(*a, **b, &block)
55
138
  template = self
56
139
  if block
@@ -64,6 +147,10 @@ module Papercraft
64
147
  end
65
148
  end
66
149
 
150
+ # Returns the Renderer class used for rendering the templates, according to
151
+ # the component's mode.
152
+ #
153
+ # @return [Papercraft::Renderer] Renderer used for rendering the component
67
154
  def renderer_class
68
155
  case @mode
69
156
  when :html
@@ -1,11 +1,14 @@
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
- # Markup extensions
7
+ module Papercraft
8
+ # HTML Markup extensions
7
9
  module HTML
8
10
  # Emits the p tag (overrides Object#p)
11
+ #
9
12
  # @param text [String] text content of tag
10
13
  # @param props [Hash] tag attributes
11
14
  # @para block [Proc] nested HTML block
@@ -16,7 +19,8 @@ module Papercraft
16
19
 
17
20
  S_HTML5_DOCTYPE = '<!DOCTYPE html>'
18
21
 
19
- # Emits an HTML5 doctype tag and an html tag with the given block
22
+ # Emits an HTML5 doctype tag and an html tag with the given block.
23
+ #
20
24
  # @param block [Proc] nested HTML block
21
25
  # @return [void]
22
26
  def html5(&block)
@@ -24,6 +28,11 @@ module Papercraft
24
28
  self.html(&block)
25
29
  end
26
30
 
31
+ # Emits a link element with a stylesheet.
32
+ #
33
+ # @param href [String] stylesheet URL
34
+ # @param custom_attributes [Hash] optional custom attributes for the link element
35
+ # @return [void]
27
36
  def link_stylesheet(href, custom_attributes = nil)
28
37
  attributes = {
29
38
  rel: 'stylesheet',
@@ -34,5 +43,28 @@ module Papercraft
34
43
  end
35
44
  link(**attributes)
36
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
37
69
  end
38
70
  end
@@ -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'
4
+ VERSION = '0.9'
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,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: papercraft
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.8'
4
+ version: '0.9'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-22 00:00:00.000000000 Z
11
+ date: 2021-12-23 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
@@ -101,6 +143,9 @@ licenses:
101
143
  - MIT
102
144
  metadata:
103
145
  source_code_uri: https://github.com/digital-fabric/papercraft
146
+ documentation_uri: https://www.rubydoc.info/gems/papercraft
147
+ homepage_uri: https://github.com/digital-fabric/papercraft
148
+ changelog_uri: https://github.com/digital-fabric/papercraft/blob/master/CHANGELOG.md
104
149
  post_install_message:
105
150
  rdoc_options:
106
151
  - "--title"