p2 2.0.1 → 2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +56 -66
- data/lib/p2/compiler/nodes.rb +139 -0
- data/lib/p2/compiler/tag_translator.rb +44 -0
- data/lib/p2/compiler.rb +226 -237
- data/lib/p2/proc_ext.rb +32 -42
- data/lib/p2/version.rb +1 -1
- data/lib/p2.rb +85 -79
- metadata +5 -17
data/lib/p2/proc_ext.rb
CHANGED
@@ -4,83 +4,73 @@ require_relative './compiler'
|
|
4
4
|
|
5
5
|
# Extensions to the Proc class
|
6
6
|
class ::Proc
|
7
|
+
# Returns the compiled form code for the proc
|
8
|
+
#
|
9
|
+
# @return [String] compiled proc code
|
7
10
|
def compiled_code
|
8
|
-
P2::
|
11
|
+
P2::Compiler.compile_to_code(self).last
|
9
12
|
end
|
10
13
|
|
14
|
+
# Returns true if proc is marked as compiled
|
15
|
+
#
|
16
|
+
# @return [bool] is the proc marked as compiled
|
11
17
|
def compiled?
|
12
18
|
@is_compiled
|
13
19
|
end
|
14
20
|
|
21
|
+
# marks the proc as compiled, i.e. can render directly and takes a string
|
22
|
+
# buffer as first argument
|
23
|
+
#
|
24
|
+
# @return [self]
|
15
25
|
def compiled!
|
16
26
|
@is_compiled = true
|
17
27
|
self
|
18
28
|
end
|
19
29
|
|
30
|
+
# Returns the compiled proc for the given proc. If marked as compiled, returns
|
31
|
+
# self.
|
32
|
+
#
|
33
|
+
# @return [Proc] compiled proc or self
|
20
34
|
def compiled_proc
|
21
35
|
@compiled_proc ||= @is_compiled ? self : compile
|
22
36
|
end
|
23
|
-
|
37
|
+
|
38
|
+
# Compiles the proc into the compiled form
|
39
|
+
#
|
40
|
+
# @return [Proc] compiled proc
|
24
41
|
def compile
|
25
|
-
P2.compile(self).compiled!
|
42
|
+
P2::Compiler.compile(self).compiled!
|
26
43
|
rescue Sirop::Error
|
27
|
-
|
44
|
+
raise P2::Error, "Dynamically defined procs cannot be compiled"
|
28
45
|
end
|
29
46
|
|
47
|
+
# Renders the proc to HTML with the given arguments
|
48
|
+
#
|
49
|
+
# @return [String] HTML string
|
30
50
|
def render(*a, **b, &c)
|
31
51
|
compiled_proc.(+'', *a, **b, &c)
|
32
52
|
end
|
33
53
|
|
54
|
+
# Renders the proc into the given buffer
|
55
|
+
#
|
56
|
+
# @return [String] HTML string
|
34
57
|
def render_to_buffer(buf, *a, **b, &c)
|
35
58
|
compiled_proc.(buf, *a, **b, &c)
|
36
59
|
end
|
37
60
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
__buffer__
|
42
|
-
}.compiled!
|
43
|
-
end
|
44
|
-
|
61
|
+
# Returns a proc that applies the given arguments to the original proc
|
62
|
+
#
|
63
|
+
# @return [Proc] applied proc
|
45
64
|
def apply(*a, **b, &c)
|
46
65
|
compiled = compiled_proc
|
47
66
|
c_compiled = c&.compiled_proc
|
48
|
-
|
67
|
+
|
49
68
|
->(__buffer__, *x, **y, &z) {
|
50
69
|
c_proc = c_compiled && ->(__buffer__, *d, **e) {
|
51
70
|
c_compiled.(__buffer__, *a, *d, **b, **e, &z)
|
52
71
|
}.compiled!
|
53
|
-
|
72
|
+
|
54
73
|
compiled.(__buffer__, *a, *x, **b, **y, &c_proc)
|
55
74
|
}.compiled!
|
56
75
|
end
|
57
76
|
end
|
58
|
-
|
59
|
-
module P2
|
60
|
-
class UncompiledProcWrapper
|
61
|
-
def initialize(proc)
|
62
|
-
@proc = proc
|
63
|
-
end
|
64
|
-
|
65
|
-
def call(buffer, *a, **b)
|
66
|
-
@buffer = buffer
|
67
|
-
instance_exec(*a, **b, &@proc)
|
68
|
-
end
|
69
|
-
|
70
|
-
def method_missing(sym, *a, **b, &c)
|
71
|
-
tag(sym, *a, **b, &c)
|
72
|
-
end
|
73
|
-
|
74
|
-
def p(*a, **b, &c)
|
75
|
-
tag(:p, *a, **b, &c)
|
76
|
-
end
|
77
|
-
|
78
|
-
def tag(sym, *a, **b, &block)
|
79
|
-
@buffer << "<#{sym}>"
|
80
|
-
if block
|
81
|
-
instance_eval(&block)
|
82
|
-
end
|
83
|
-
@buffer << "</#{sym}>"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/p2/version.rb
CHANGED
data/lib/p2.rb
CHANGED
@@ -3,99 +3,105 @@
|
|
3
3
|
require_relative 'p2/compiler'
|
4
4
|
require_relative 'p2/proc_ext'
|
5
5
|
|
6
|
-
# P2 is a
|
6
|
+
# P2 is a functional templating library. In P2, templates are expressed as plain
|
7
|
+
# Ruby procs.
|
7
8
|
module P2
|
8
9
|
# Exception class used to signal templating-related errors
|
9
10
|
class Error < RuntimeError; end
|
10
11
|
|
11
|
-
|
12
|
-
def compile(proc)
|
13
|
-
P2::TemplateCompiler.compile(proc)
|
14
|
-
end
|
12
|
+
extend self
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
# Formats the given string, converting underscores to dashes.
|
15
|
+
#
|
16
|
+
# @param tag [String, Symbol] input string
|
17
|
+
# @return [String] output string
|
18
|
+
def underscores_to_dashes(tag)
|
19
|
+
tag.to_s.gsub('_', '-')
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
22
|
+
# Formats the given hash as tag attributes.
|
23
|
+
#
|
24
|
+
# @param attrs [Hash] input hash
|
25
|
+
# @return [String] formatted attributes
|
26
|
+
def format_tag_attrs(attrs)
|
27
|
+
attrs.each_with_object(+'') do |(k, v), html|
|
28
|
+
case v
|
29
|
+
when nil, false
|
30
|
+
when true
|
31
|
+
html << ' ' if !html.empty?
|
32
|
+
html << underscores_to_dashes(k)
|
33
|
+
else
|
34
|
+
html << ' ' if !html.empty?
|
35
|
+
v = v.join(' ') if v.is_a?(Array)
|
36
|
+
html << "#{underscores_to_dashes(k)}=\"#{v}\""
|
36
37
|
end
|
37
38
|
end
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
# Translates an exceptions backtrace using a source map.
|
42
|
+
#
|
43
|
+
# @param exception [Exception] raised exception
|
44
|
+
# @param source_map [Hash] source map
|
45
|
+
#
|
46
|
+
# @return [Exception] raised exception
|
47
|
+
def translate_backtrace(exception, source_map)
|
48
|
+
re = compute_source_map_re(source_map)
|
49
|
+
source_fn = source_map[:source_fn]
|
50
|
+
backtrace = exception.backtrace.map {
|
51
|
+
if (m = it.match(re))
|
52
|
+
line = m[2].to_i
|
53
|
+
source_line = source_map[line] || "?(#{line})"
|
54
|
+
it.sub(m[1], "#{source_fn}:#{source_line}")
|
45
55
|
else
|
46
|
-
|
56
|
+
it
|
47
57
|
end
|
48
|
-
|
58
|
+
}
|
59
|
+
exception.set_backtrace(backtrace)
|
60
|
+
exception
|
61
|
+
end
|
49
62
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
else
|
59
|
-
it
|
60
|
-
end
|
61
|
-
}
|
62
|
-
e.set_backtrace(backtrace)
|
63
|
-
end
|
63
|
+
# Computes a Regexp for matching hits in a backtrace.
|
64
|
+
#
|
65
|
+
# @param source_map [Hash] source map
|
66
|
+
# @return [Regexp] computed regexp
|
67
|
+
def compute_source_map_re(source_map)
|
68
|
+
escaped = source_map[:compiled_fn].gsub(/[\(\)]/) { "\\#{it[0]}" }
|
69
|
+
/^(#{escaped}\:(\d+))/
|
70
|
+
end
|
64
71
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
opts = default_kramdown_options.merge(opts)
|
78
|
-
Kramdown::Document.new(markdown, **opts).to_html
|
79
|
-
end
|
72
|
+
# Renders Markdown into HTML. The `opts` argument will be merged with the
|
73
|
+
# default Kramdown options in order to change the rendering behaviour.
|
74
|
+
#
|
75
|
+
# @param markdown [String] Markdown
|
76
|
+
# @param opts [Hash] Kramdown option overrides
|
77
|
+
# @return [String] HTML
|
78
|
+
def markdown(markdown, **opts)
|
79
|
+
# require relevant deps on use
|
80
|
+
require 'kramdown'
|
81
|
+
require 'rouge'
|
82
|
+
require 'kramdown-parser-gfm'
|
80
83
|
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
84
|
+
opts = default_kramdown_options.merge(opts)
|
85
|
+
Kramdown::Document.new(markdown, **opts).to_html
|
86
|
+
end
|
92
87
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
88
|
+
# Returns the default Kramdown options used for rendering Markdown.
|
89
|
+
#
|
90
|
+
# @return [Hash] Kramdown options
|
91
|
+
def default_kramdown_options
|
92
|
+
@default_kramdown_options ||= {
|
93
|
+
entity_output: :numeric,
|
94
|
+
syntax_highlighter: :rouge,
|
95
|
+
input: 'GFM',
|
96
|
+
hard_wrap: false
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
# Sets the default Kramdown options used for rendering Markdown.
|
101
|
+
#
|
102
|
+
# @param opts [Hash] Kramdown options
|
103
|
+
# @return [Hash] Kramdown options
|
104
|
+
def default_kramdown_options=(opts)
|
105
|
+
@default_kramdown_options = opts
|
100
106
|
end
|
101
107
|
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.
|
4
|
+
version: '2.2'
|
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.
|
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.
|
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: []
|
@@ -118,6 +104,8 @@ files:
|
|
118
104
|
- README.md
|
119
105
|
- lib/p2.rb
|
120
106
|
- lib/p2/compiler.rb
|
107
|
+
- lib/p2/compiler/nodes.rb
|
108
|
+
- lib/p2/compiler/tag_translator.rb
|
121
109
|
- lib/p2/proc_ext.rb
|
122
110
|
- lib/p2/version.rb
|
123
111
|
- p2.png
|