papercraft 0.8 → 0.9

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: 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"