p2 2.0.1 → 2.1

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: 9a0a95331ecb304e4fb0ae830d5c1f30a160a4ec9d26d86de8b22454fbef21e2
4
- data.tar.gz: 49ecb084b5881d3f8287c4af46edfbf9b83930438baddafb3502ddf44b2a8b24
3
+ metadata.gz: c34fa05073968d2f8aed0d766ec9b59275fdb061ce2a328ad18038ce0f986068
4
+ data.tar.gz: c0bab8233ffc293432b33a531e554ebc379ec7d796c2f4046e105b185e0c5f5e
5
5
  SHA512:
6
- metadata.gz: 3b4aae65ebce0e4e87adf6e19e7c7731aa481dfeb3d6efb66c2ae345c704f828d0d2143a147e49f49061e0ad30c1b48209d198ffa9aaeca1cd743167257e297b
7
- data.tar.gz: 6efe1aedca928c95a0102e1192c3406f8657c54536f18c0db741f86b8b365c9a178565171d7f5476f78ebb47b566a6d075c5dad674d6c4ae41fc995f603a0ce5
6
+ metadata.gz: bb711aac468494ad590779e45a97fa9593d9a7e0e172389ae14125ba1576a4dda90bf5f796c56592d8a1b939cf00d2a69cd91386f5ef583453b2045bee333f5d
7
+ data.tar.gz: 8a1ee9990feb82379a01bd1971b00c844d3b0f3f9f0cc6531596619f47abf0e56c629d04e34a54f12594e7a73718e88854ab6056b30ad8019ab9a63d133e2101
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 2.1 2025-08-08
2
+
3
+ - Optimize output code: directly invoke component templates instead of calling
4
+ `P2.render_emit_call`. P2 is now
5
+ - Optimize output code: use separate pushes to buffer instead of interpolated
6
+ strings.
7
+ - Streamline API: `emit proc` => `render`, `emit str` => `raw`, `emit_markdown`
8
+ => `markdown`
9
+ - Optimize output code: add `frozen_string_literal` to top of compiled code
10
+ - Add more benchmarks (#1)
11
+ - Optimize output code: use ERB::Escape.html_escape instead of CGI.escape_html
12
+ (#2)
13
+ - Fix source map calculation
14
+
1
15
  ## 2.0.1 2025-08-07
2
16
 
3
17
  - Fix source map calculation
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  P2
5
5
  </h1>
6
6
 
7
- <h4 align="center">Composable templating for Ruby</h4>
7
+ <h4 align="center">Functional HTML templating for Ruby</h4>
8
8
 
9
9
  <p align="center">
10
10
  <a href="http://rubygems.org/gems/p2">
@@ -86,7 +86,7 @@ P2 features:
86
86
  - [Higher-Order Templates](#higher-order-templates)
87
87
  - [Layout Template Composition](#layout-template-composition)
88
88
  - [Emitting Raw HTML](#emitting-raw-html)
89
- - [Emitting a String with HTML Encoding](#emitting-a-string-with-html-encoding)
89
+ - [Emitting a String with HTML Escaping](#emitting-a-string-with-html-escaping)
90
90
  - [Emitting Markdown](#emitting-markdown)
91
91
  - [Deferred Evaluation](#deferred-evaluation)
92
92
  - [API Reference](#api-reference)
@@ -298,14 +298,14 @@ page.render('Hello from composed templates', [
298
298
  ```
299
299
 
300
300
  In addition to using templates defined as constants, you can also use
301
- non-constant templates by invoking the `#emit` method:
301
+ non-constant templates by invoking the `#render` method:
302
302
 
303
303
  ```ruby
304
304
  greeting = -> { span "Hello, world" }
305
305
 
306
306
  -> {
307
307
  div {
308
- emit greeting
308
+ render greeting
309
309
  }
310
310
  }
311
311
  ```
@@ -345,7 +345,7 @@ templates or injecting template parameters.
345
345
  Here is a higher-order template that takes a template as parameter:
346
346
 
347
347
  ```ruby
348
- div_wrap = -> { |inner| div { emit inner } }
348
+ div_wrap = -> { |inner| div { render inner } }
349
349
  greeter = -> { h1 'hi' }
350
350
  wrapped_greeter = div_wrap.apply(greeter)
351
351
  wrapped_greeter.render #=> "<div><h1>hi</h1></div>"
@@ -382,7 +382,7 @@ default_layout = -> { |**params|
382
382
  article_layout = default_layout.apply { |title:, body:|
383
383
  article {
384
384
  h1 title
385
- emit_markdown body
385
+ markdown body
386
386
  }
387
387
  }
388
388
 
@@ -394,16 +394,16 @@ article_layout.render(
394
394
 
395
395
  ## Emitting Raw HTML
396
396
 
397
- Raw HTML can be emitted using `#emit`:
397
+ Raw HTML can be emitted using `#raw`:
398
398
 
399
399
  ```ruby
400
- wrapped = -> { |html| div { emit html } }
400
+ wrapped = -> { |html| div { raw html } }
401
401
  wrapped.render("<h1>hi</h1>") #=> "<div><h1>hi</h1></div>"
402
402
  ```
403
403
 
404
- ## Emitting a String with HTML Encoding
404
+ ## Emitting a String with HTML Escaping
405
405
 
406
- To emit a string with proper HTML encoding, without wrapping it in an HTML
406
+ To emit a string with proper HTML escaping, without wrapping it in an HTML
407
407
  element, use `#text`:
408
408
 
409
409
  ```ruby
@@ -414,19 +414,19 @@ element, use `#text`:
414
414
 
415
415
  Markdown is rendered using the
416
416
  [Kramdown](https://kramdown.gettalong.org/index.html) gem. To emit Markdown, use
417
- `#emit_markdown`:
417
+ `#markdown`:
418
418
 
419
419
  ```ruby
420
- template = -> { |md| div { emit_markdown md } }
420
+ template = -> { |md| div { markdown md } }
421
421
  template.render("Here's some *Markdown*") #=> "<div><p>Here's some <em>Markdown</em><p>\n</div>"
422
422
  ```
423
423
 
424
424
  [Kramdown
425
425
  options](https://kramdown.gettalong.org/options.html#available-options) can be
426
- specified by adding them to the `#emit_markdown` call:
426
+ specified by adding them to the `#markdown` call:
427
427
 
428
428
  ```ruby
429
- template = -> { |md| div { emit_markdown md, auto_ids: false } }
429
+ template = -> { |md| div { markdown md, auto_ids: false } }
430
430
  template.render("# title") #=> "<div><h1>title</h1></div>"
431
431
  ```
432
432
 
@@ -478,7 +478,7 @@ integrated into the page, and adds them to the page's `<head>` element:
478
478
  default_layout = -> { |**args|
479
479
  @dependencies = DependencyMananger.new
480
480
  head {
481
- defer { emit @dependencies.head_markup }
481
+ defer { render @dependencies.head_markup }
482
482
  }
483
483
  body { emit_yield **args }
484
484
  }
@@ -498,11 +498,11 @@ heading = proc { |text|
498
498
  }
499
499
 
500
500
  page = default_layout.apply {
501
- emit heading, "What's your favorite cheese?"
501
+ render heading, "What's your favorite cheese?"
502
502
 
503
- emit button, 'Beaufort', 'eat_beaufort()'
504
- emit button, 'Mont d''or', 'eat_montdor()'
505
- emit button, 'Époisses', 'eat_epoisses()'
503
+ render button, 'Beaufort', 'eat_beaufort()'
504
+ render button, 'Mont d''or', 'eat_montdor()'
505
+ render button, 'Époisses', 'eat_epoisses()'
506
506
  }
507
507
  ```
508
508
 
data/lib/p2/compiler.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'cgi'
4
4
  require 'sirop'
5
- require 'digest/md5'
5
+ require 'erb/escape'
6
6
 
7
7
  module P2
8
8
  class TagNode
@@ -48,7 +48,7 @@ module P2
48
48
  end
49
49
  end
50
50
 
51
- class EmitNode
51
+ class RenderNode
52
52
  attr_reader :call_node, :location, :block
53
53
 
54
54
  include Prism::DSL
@@ -107,7 +107,7 @@ module P2
107
107
  end
108
108
 
109
109
  def accept(visitor)
110
- visitor.visit_emit_node(self)
110
+ visitor.visit_render_node(self)
111
111
  end
112
112
  end
113
113
 
@@ -124,6 +124,19 @@ module P2
124
124
  end
125
125
  end
126
126
 
127
+ class RawNode
128
+ attr_reader :call_node, :location
129
+
130
+ def initialize(call_node, _compiler)
131
+ @call_node = call_node
132
+ @location = call_node.location
133
+ end
134
+
135
+ def accept(visitor)
136
+ visitor.visit_raw_node(self)
137
+ end
138
+ end
139
+
127
140
  class DeferNode
128
141
  attr_reader :call_node, :location, :block
129
142
 
@@ -172,13 +185,15 @@ module P2
172
185
  )
173
186
  when :raise
174
187
  super(node)
175
- when :emit, :e
176
- EmitNode.new(node, self)
188
+ when :render
189
+ RenderNode.new(node, self)
190
+ when :raw
191
+ RawNode.new(node, self)
177
192
  when :text
178
193
  TextNode.new(node, self)
179
194
  when :defer
180
195
  DeferNode.new(node, self)
181
- when :html5, :emit_markdown, :markdown
196
+ when :html5, :markdown
182
197
  CustomTagNode.new(node, self)
183
198
  else
184
199
  TagNode.new(node, self)
@@ -207,6 +222,10 @@ module P2
207
222
 
208
223
  def self.compile(proc, wrap: true)
209
224
  source_map, code = compile_to_code(proc, wrap:)
225
+ if ENV['DEBUG'] == '1'
226
+ puts '*' * 40
227
+ puts code
228
+ end
210
229
  eval(code, proc.binding, source_map[:compiled_fn])
211
230
  end
212
231
 
@@ -221,12 +240,12 @@ module P2
221
240
  end
222
241
 
223
242
  def with_source_map(orig_proc, orig_ast)
224
- ast_digest = Digest::MD5.hexdigest(orig_ast.inspect)
243
+ compiled_fn = "::(#{orig_proc.source_location.join(':')})"
225
244
  @source_map = {
226
245
  source_fn: orig_proc.source_location.first,
227
- compiled_fn: "::#{ast_digest}"
246
+ compiled_fn: compiled_fn
228
247
  }
229
- @source_map_line_ofs = 1
248
+ @source_map_line_ofs = 2
230
249
  self
231
250
  end
232
251
 
@@ -240,7 +259,7 @@ module P2
240
259
  source_code = @buffer
241
260
  @buffer = +''
242
261
  if wrap
243
- emit("(#{@source_map.inspect}).then { |src_map| ->(__buffer__")
262
+ emit("# frozen_string_literal: true\n(#{@source_map.inspect}).then { |src_map| ->(__buffer__")
244
263
 
245
264
  params = orig_ast.parameters
246
265
  params = params&.parameters
@@ -292,13 +311,13 @@ module P2
292
311
 
293
312
  if node.inner_text
294
313
  if is_static_node?(node.inner_text)
295
- emit_html(node.location, CGI.escape_html(format_literal(node.inner_text)))
314
+ emit_html(node.location, ERB::Escape.html_escape(format_literal(node.inner_text)))
296
315
  else
297
316
  convert_to_s = !is_string_type_node?(node.inner_text)
298
317
  if convert_to_s
299
- emit_html(node.location, "#\{CGI.escape_html((#{format_code(node.inner_text)}).to_s)}")
318
+ emit_html(node.location, interpolated("ERB::Escape.html_escape((#{format_code(node.inner_text)}).to_s)"))
300
319
  else
301
- emit_html(node.location, "#\{CGI.escape_html(#{format_code(node.inner_text)})}")
320
+ emit_html(node.location, interpolated("ERB::Escape.html_escape(#{format_code(node.inner_text)})"))
302
321
  end
303
322
  end
304
323
  end
@@ -320,34 +339,50 @@ module P2
320
339
  emit(');')
321
340
  end
322
341
 
323
- def visit_emit_node(node)
342
+ def visit_render_node(node)
343
+ args = node.call_node.arguments.arguments
344
+ first_arg = args.first
345
+
346
+ block_embed = node.block && "&(->(__buffer__) #{format_code(node.block)}.compiled!)"
347
+ block_embed = ", #{block_embed}" if block_embed && node.call_node.arguments
348
+
349
+ flush_html_parts!
350
+ adjust_whitespace(node.location)
351
+
352
+ if args.length == 1
353
+ emit("; #{format_code(first_arg)}.compiled_proc.(__buffer__#{block_embed})")
354
+ else
355
+ args_code = format_code_comma_separated_nodes(args[1..])
356
+ emit("; #{format_code(first_arg)}.compiled_proc.(__buffer__, #{args_code}#{block_embed})")
357
+ end
358
+ end
359
+
360
+ def visit_text_node(node)
361
+ return if !node.call_node.arguments
362
+
324
363
  args = node.call_node.arguments.arguments
325
364
  first_arg = args.first
326
365
  if args.length == 1
327
366
  if is_static_node?(first_arg)
328
- emit_html(node.location, format_literal(first_arg))
329
- elsif first_arg.is_a?(Prism::LambdaNode)
330
- visit(first_arg.body)
367
+ emit_html(node.location, ERB::Escape.html_escape(format_literal(first_arg)))
331
368
  else
332
- emit_html(node.location, "#\{P2.render_emit_call(#{format_code(first_arg)})}")
369
+ emit_html(node.location, interpolated("ERB::Escape.html_escape(#{format_code(first_arg)}.to_s)"))
333
370
  end
334
371
  else
335
- block_embed = node.block ? "&(->(__buffer__) #{format_code(node.block)}.compiled!)" : nil
336
- block_embed = ", #{block_embed}" if block_embed && node.call_node.arguments
337
- emit_html(node.location, "#\{P2.render_emit_call(#{format_code(node.call_node.arguments)}#{block_embed})}")
372
+ raise "Don't know how to compile #{node}"
338
373
  end
339
374
  end
340
375
 
341
- def visit_text_node(node)
376
+ def visit_raw_node(node)
342
377
  return if !node.call_node.arguments
343
378
 
344
379
  args = node.call_node.arguments.arguments
345
380
  first_arg = args.first
346
381
  if args.length == 1
347
382
  if is_static_node?(first_arg)
348
- emit_html(node.location, CGI.escape_html(format_literal(first_arg)))
383
+ emit_html(node.location, format_literal(first_arg))
349
384
  else
350
- emit_html(node.location, "#\{CGI.escape_html(#{format_code(first_arg)}.to_s)}")
385
+ emit_html(node.location, interpolated("(#{format_code(first_arg)}).to_s"))
351
386
  end
352
387
  else
353
388
  raise "Don't know how to compile #{node}"
@@ -382,11 +417,11 @@ module P2
382
417
  emit_html(node.location, '<!DOCTYPE html><html>')
383
418
  visit(node.block.body) if node.block
384
419
  emit_html(node.block.closing_loc, '</html>')
385
- when :emit_markdown, :markdown
420
+ when :markdown
386
421
  args = node.call_node.arguments
387
422
  return if !args
388
423
 
389
- emit_html(node.location, "#\{P2.markdown(#{format_code(args)})}")
424
+ emit_html(node.location, interpolated("P2.markdown(#{format_code(args)})"))
390
425
  end
391
426
  end
392
427
 
@@ -404,10 +439,20 @@ module P2
404
439
 
405
440
  private
406
441
 
407
- def format_code(node, klass = TemplateCompiler)
442
+ def interpolated(str)
443
+ "#\{#{str}}"
444
+ end
445
+
446
+ def format_code(node, klass = self.class)
408
447
  klass.new(minimize_whitespace: true).to_source(node)
409
448
  end
410
449
 
450
+ def format_code_comma_separated_nodes(list)
451
+ compiler = self.class.new(minimize_whitespace: true)
452
+ compiler.visit_comma_separated_nodes(list)
453
+ compiler.buffer
454
+ end
455
+
411
456
  VOID_TAGS = %w(area base br col embed hr img input link meta param source track wbr)
412
457
 
413
458
  def is_void_element?(tag)
@@ -488,7 +533,7 @@ module P2
488
533
  !is_static_node?(it.key) || !is_static_node?(it.value)
489
534
  end
490
535
 
491
- return "#\{P2.format_html_attrs(#{format_code(node)})}" if dynamic_attributes
536
+ return interpolated("P2.format_html_attrs(#{format_code(node)})") if dynamic_attributes
492
537
 
493
538
  parts = elements.map do
494
539
  key = it.key
@@ -522,11 +567,20 @@ module P2
522
567
  return if @pending_html_parts.empty?
523
568
 
524
569
  adjust_whitespace(@html_loc_start)
525
- if semicolon_prefix && @buffer =~ /[^\s]\s*$/m
526
- emit '; '
570
+
571
+ code = +''
572
+ part = +''
573
+
574
+ @pending_html_parts.each do
575
+ if (m = it.match(/^#\{(.+)\}$/m))
576
+ emit_buffer_push(code, part, quotes: true) if !part.empty?
577
+ emit_buffer_push(code, m[1])
578
+ else
579
+ part << it
580
+ end
527
581
  end
582
+ emit_buffer_push(code, part, quotes: true) if !part.empty?
528
583
 
529
- str = @pending_html_parts.join
530
584
  @pending_html_parts.clear
531
585
 
532
586
  @last_loc = @html_loc_end
@@ -536,7 +590,15 @@ module P2
536
590
  @html_loc_start = nil
537
591
  @html_loc_end = nil
538
592
 
539
- emit "__buffer__ << \"#{str}\""
593
+ emit code
594
+ end
595
+
596
+ def emit_buffer_push(buf, part, quotes: false)
597
+ return if part.empty?
598
+
599
+ q = quotes ? '"' : ''
600
+ buf << "; __buffer__ << #{q}#{part}#{q}"
601
+ part.clear
540
602
  end
541
603
 
542
604
  def emit_postlude
data/lib/p2/proc_ext.rb CHANGED
@@ -12,6 +12,8 @@ class ::Proc
12
12
  @is_compiled
13
13
  end
14
14
 
15
+ # marks the proc as compiled, i.e. can render directly and takes a string
16
+ # buffer as first argument
15
17
  def compiled!
16
18
  @is_compiled = true
17
19
  self
@@ -22,7 +24,7 @@ class ::Proc
22
24
  end
23
25
 
24
26
  def compile
25
- P2.compile(self).compiled!
27
+ P2::TemplateCompiler.compile(self).compiled!
26
28
  rescue Sirop::Error
27
29
  uncompiled_renderer
28
30
  end
data/lib/p2/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module P2
4
- VERSION = '2.0.1'
4
+ VERSION = '2.1'
5
5
  end
data/lib/p2.rb CHANGED
@@ -8,94 +8,84 @@ module P2
8
8
  # Exception class used to signal templating-related errors
9
9
  class Error < RuntimeError; end
10
10
 
11
- class << self
12
- def compile(proc)
13
- P2::TemplateCompiler.compile(proc)
14
- end
11
+ extend self
15
12
 
16
- def format_tag(tag)
17
- tag.to_s.gsub('_', '-')
18
- end
13
+ def format_tag(tag)
14
+ tag.to_s.gsub('_', '-')
15
+ end
19
16
 
20
- def format_html_attr_key(tag)
21
- tag.to_s.tr('_', '-')
22
- end
17
+ def format_html_attr_key(tag)
18
+ tag.to_s.tr('_', '-')
19
+ end
23
20
 
24
- def format_html_attrs(attrs)
25
- attrs.each_with_object(+'') do |(k, v), html|
26
- case v
27
- when nil, false
28
- when true
29
- html << ' ' if !html.empty?
30
- html << format_html_attr_key(k)
31
- else
32
- html << ' ' if !html.empty?
33
- v = v.join(' ') if v.is_a?(Array)
34
- html << "#{format_html_attr_key(k)}=\"#{v}\""
35
- end
21
+ def format_html_attrs(attrs)
22
+ attrs.each_with_object(+'') do |(k, v), html|
23
+ case v
24
+ when nil, false
25
+ when true
26
+ html << ' ' if !html.empty?
27
+ html << format_html_attr_key(k)
28
+ else
29
+ html << ' ' if !html.empty?
30
+ v = v.join(' ') if v.is_a?(Array)
31
+ html << "#{format_html_attr_key(k)}=\"#{v}\""
36
32
  end
37
33
  end
34
+ end
38
35
 
39
- def render_emit_call(o, *a, **b, &block)
40
- case o
41
- when nil
42
- # do nothing
43
- when ::Proc
44
- o.render(*a, **b, &block)
36
+ def translate_backtrace(e, source_map)
37
+ re = compute_source_map_re(source_map)
38
+ source_fn = source_map[:source_fn]
39
+ backtrace = e.backtrace.map {
40
+ if (m = it.match(re))
41
+ line = m[2].to_i
42
+ source_line = source_map[line] || "?(#{line})"
43
+ it.sub(m[1], "#{source_fn}:#{source_line}")
45
44
  else
46
- o.to_s
45
+ it
47
46
  end
48
- end
47
+ }
48
+ e.set_backtrace(backtrace)
49
+ end
49
50
 
50
- def translate_backtrace(e, source_map)
51
- re = /^(#{source_map[:compiled_fn]}\:(\d+))/
52
- source_fn = source_map[:source_fn]
53
- backtrace = e.backtrace.map {
54
- if (m = it.match(re))
55
- line = m[2].to_i
56
- source_line = source_map[line] || "?(#{line})"
57
- it.sub(m[1], "#{source_fn}:#{source_line}")
58
- else
59
- it
60
- end
61
- }
62
- e.set_backtrace(backtrace)
63
- end
51
+ def compute_source_map_re(source_map)
52
+ escaped = source_map[:compiled_fn].gsub(/[\(\)]/) { "\\#{it[0]}" }
53
+ /^(#{escaped}\:(\d+))/
54
+ end
64
55
 
65
- # Renders Markdown into HTML. The `opts` argument will be merged with the
66
- # default Kramdown options in order to change the rendering behaviour.
67
- #
68
- # @param markdown [String] Markdown
69
- # @param opts [Hash] Kramdown option overrides
70
- # @return [String] HTML
71
- def markdown(markdown, **opts)
72
- # require relevant deps on use
73
- require 'kramdown'
74
- require 'rouge'
75
- require 'kramdown-parser-gfm'
76
-
77
- opts = default_kramdown_options.merge(opts)
78
- Kramdown::Document.new(markdown, **opts).to_html
79
- end
56
+ # Renders Markdown into HTML. The `opts` argument will be merged with the
57
+ # default Kramdown options in order to change the rendering behaviour.
58
+ #
59
+ # @param markdown [String] Markdown
60
+ # @param opts [Hash] Kramdown option overrides
61
+ # @return [String] HTML
62
+ def markdown(markdown, **opts)
63
+ # require relevant deps on use
64
+ require 'kramdown'
65
+ require 'rouge'
66
+ require 'kramdown-parser-gfm'
67
+
68
+ opts = default_kramdown_options.merge(opts)
69
+ Kramdown::Document.new(markdown, **opts).to_html
70
+ end
80
71
 
81
- # Returns the default Kramdown options used for rendering Markdown.
82
- #
83
- # @return [Hash] Kramdown options
84
- def default_kramdown_options
85
- @default_kramdown_options ||= {
86
- entity_output: :numeric,
87
- syntax_highlighter: :rouge,
88
- input: 'GFM',
89
- hard_wrap: false
90
- }
91
- end
72
+ # Returns the default Kramdown options used for rendering Markdown.
73
+ #
74
+ # @return [Hash] Kramdown options
75
+ def default_kramdown_options
76
+ @default_kramdown_options ||= {
77
+ entity_output: :numeric,
78
+ syntax_highlighter: :rouge,
79
+ input: 'GFM',
80
+ hard_wrap: false
81
+ }
82
+ end
92
83
 
93
- # Sets the default Kramdown options used for rendering Markdown.
94
- #
95
- # @param opts [Hash] Kramdown options
96
- # @return [void]
97
- def default_kramdown_options=(opts)
98
- @default_kramdown_options = opts
99
- end
84
+ # Sets the default Kramdown options used for rendering Markdown.
85
+ #
86
+ # @param opts [Hash] Kramdown options
87
+ # @return [void]
88
+ def default_kramdown_options=(opts)
89
+ @default_kramdown_options = opts
100
90
  end
101
91
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: p2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: '2.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 0.8.2
18
+ version: 0.8.3
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 0.8.2
25
+ version: 0.8.3
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: kramdown
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -93,20 +93,6 @@ dependencies:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
95
  version: 2.7.2
96
- - !ruby/object:Gem::Dependency
97
- name: tilt
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: 2.2.0
103
- type: :development
104
- prerelease: false
105
- version_requirements: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: 2.2.0
110
96
  email: sharon@noteflakes.com
111
97
  executables: []
112
98
  extensions: []