opulent 1.7.11 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/benchmarks/data-attribute/view.haml +1 -1
- data/benchmarks/methods/view.op +4 -4
- data/benchmarks/run-benchmarks.rb +11 -6
- data/lib/opulent/compiler.rb +8 -7
- data/lib/opulent/compiler/buffer.rb +14 -0
- data/lib/opulent/compiler/eval.rb +3 -5
- data/lib/opulent/compiler/node.rb +53 -3
- data/lib/opulent/compiler/text.rb +24 -0
- data/lib/opulent/filters.rb +1 -1
- data/lib/opulent/settings.rb +1 -3
- data/lib/opulent/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76bdc4c7325218912ef5e71007f9d64f7342b0e9
|
4
|
+
data.tar.gz: 79d52447ddcbaa17c138998e278a270febf2cff5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad0e14bd3dddc7e32ebcabcccf0696aed4cdfd79e790cdd65f866c967d3559b2da7ace8c21ce0b25a5dfe28f5dc32c3247b0d13b83d583c7a65049685971279f
|
7
|
+
data.tar.gz: d0ecfc90dfb792a0410fc50d7b44d6bfec78eb135b19edf6e0abdbbbc10548e0edf3d93bede9bd48225e80c4273d63cbe4a614997bc4d0b714244471fff92085
|
data/benchmarks/methods/view.op
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
2
|
-
div id="test-#{i}"
|
3
|
-
div(id="test".upcase)
|
4
|
-
div(id="TEST".downcase)
|
1
|
+
- 10.times do |i|
|
2
|
+
div id="test-#{i}"
|
3
|
+
div(id="test".upcase)
|
4
|
+
div(id="TEST".downcase)
|
@@ -43,6 +43,7 @@ class Benchmarks
|
|
43
43
|
haml_ugly.def_method(context, :run_haml_ugly)
|
44
44
|
context.instance_eval %{
|
45
45
|
def run_opulent_ugly; #{Opulent.new(@opulent_code).src}; end
|
46
|
+
def run_opulent_pretty; #{Opulent.new(@opulent_code, pretty: true).src}; end
|
46
47
|
def run_erb; #{ERB.new(@erb_code).src}; end
|
47
48
|
def run_erubis; #{Erubis::Eruby.new(@erb_code).src}; end
|
48
49
|
def run_fast_erubis; #{Erubis::FastEruby.new(@erb_code).src}; end
|
@@ -50,10 +51,11 @@ class Benchmarks
|
|
50
51
|
def run_slim_ugly; #{Slim::Engine.new.call @slim_code}; end
|
51
52
|
}
|
52
53
|
|
53
|
-
bench(:compiled, 'opulent') { context.run_opulent_ugly }
|
54
54
|
bench(:compiled, 'erb') { context.run_erb }
|
55
55
|
bench(:compiled, 'erubis') { context.run_erubis }
|
56
56
|
bench(:compiled, 'fast erubis') { context.run_fast_erubis }
|
57
|
+
bench(:compiled, 'opulent pretty') { context.run_opulent_pretty }
|
58
|
+
bench(:compiled, 'opulent ugly') { context.run_opulent_ugly }
|
57
59
|
bench(:compiled, 'slim pretty') { context.run_slim_pretty }
|
58
60
|
bench(:compiled, 'slim ugly') { context.run_slim_ugly }
|
59
61
|
bench(:compiled, 'haml pretty') { context.run_haml_pretty }
|
@@ -61,7 +63,8 @@ class Benchmarks
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def init_tilt_benches
|
64
|
-
|
66
|
+
tilt_opulent_ugly = Opulent::Template.new() { @opulent_code }
|
67
|
+
tilt_opulent_pretty = Opulent::Template.new(pretty: true) { @opulent_code }
|
65
68
|
tilt_erb = Tilt::ERBTemplate.new { @erb_code }
|
66
69
|
tilt_erubis = Tilt::ErubisTemplate.new { @erb_code }
|
67
70
|
tilt_haml_pretty = Tilt::HamlTemplate.new(format: :html5) { @haml_code }
|
@@ -71,9 +74,10 @@ class Benchmarks
|
|
71
74
|
|
72
75
|
context = Context.new
|
73
76
|
|
74
|
-
bench(:tilt, 'opulent') { tilt_opulent.render(context) }
|
75
77
|
bench(:tilt, 'erb') { tilt_erb.render(context) }
|
76
78
|
bench(:tilt, 'erubis') { tilt_erubis.render(context) }
|
79
|
+
bench(:tilt, 'opulent pretty') { tilt_opulent_pretty.render(context) }
|
80
|
+
bench(:tilt, 'opulent ugly') { tilt_opulent_ugly.render(context) }
|
77
81
|
bench(:tilt, 'slim pretty') { tilt_slim_pretty.render(context) }
|
78
82
|
bench(:tilt, 'slim ugly') { tilt_slim_ugly.render(context) }
|
79
83
|
bench(:tilt, 'haml pretty') { tilt_haml_pretty.render(context) }
|
@@ -84,10 +88,11 @@ class Benchmarks
|
|
84
88
|
context = Context.new
|
85
89
|
context_binding = context.instance_eval { binding }
|
86
90
|
|
87
|
-
bench(:parsing, 'opulent') { Opulent.new(@opulent_code).render(context) }
|
88
91
|
bench(:parsing, 'erb') { ERB.new(@erb_code).result(context_binding) }
|
89
92
|
bench(:parsing, 'erubis') { Erubis::Eruby.new(@erb_code).result(context_binding) }
|
90
93
|
bench(:parsing, 'fast erubis') { Erubis::FastEruby.new(@erb_code).result(context_binding) }
|
94
|
+
bench(:parsing, 'opulent pretty') { Opulent.new(@opulent_code, pretty: true).render(context) }
|
95
|
+
bench(:parsing, 'opulent ugly') { Opulent.new(@opulent_code).render(context) }
|
91
96
|
bench(:parsing, 'slim pretty') { Slim::Template.new(pretty: true) { @slim_code }.render(context) }
|
92
97
|
bench(:parsing, 'slim ugly') { Slim::Template.new { @slim_code }.render(context) }
|
93
98
|
bench(:parsing, 'haml pretty') { Haml::Engine.new(@haml_code, format: :html5).render(context) }
|
@@ -139,8 +144,8 @@ Compiled Tilt benchmark: Template is compiled with Tilt, which gives a more
|
|
139
144
|
compilation.)
|
140
145
|
|
141
146
|
Parsing benchmark: Template is parsed every time.
|
142
|
-
This is not the recommended way to use the template engine
|
143
|
-
|
147
|
+
This is not the recommended way to use the template engine because
|
148
|
+
performance is greatly increased when reusing the compiled source code.
|
144
149
|
"
|
145
150
|
end
|
146
151
|
|
data/lib/opulent/compiler.rb
CHANGED
@@ -42,7 +42,7 @@ module Opulent
|
|
42
42
|
@inline_node = Settings::INLINE_NODE
|
43
43
|
|
44
44
|
# Initialize amble object
|
45
|
-
@template = [
|
45
|
+
@template = []
|
46
46
|
|
47
47
|
# Incrmental counters
|
48
48
|
@current_variable_count = 0
|
@@ -54,13 +54,15 @@ module Opulent
|
|
54
54
|
# from the current branch level
|
55
55
|
@node_stack = []
|
56
56
|
|
57
|
-
# The sibling stack keeps track of the sibling count from the current
|
58
|
-
# branch level being generated
|
59
|
-
@sibling_stack = []
|
60
|
-
|
61
57
|
# Whenever we enter a definition compilation, add the provided blocks to
|
62
58
|
# the current block stack. When exiting a definition, remove blocks.
|
63
59
|
@block_stack = []
|
60
|
+
|
61
|
+
# Remember last compiled node, required for pretty printing purposes
|
62
|
+
@sibling_stack = [[[:root, nil]]]
|
63
|
+
|
64
|
+
# Set parent node, required for pretty printing
|
65
|
+
@parent_stack = []
|
64
66
|
end
|
65
67
|
|
66
68
|
# Compile input nodes, replace them with their definitions and
|
@@ -73,8 +75,7 @@ module Opulent
|
|
73
75
|
@generator = ''
|
74
76
|
@definitions = definitions
|
75
77
|
|
76
|
-
|
77
|
-
@sibling_stack << root_node[@children].size
|
78
|
+
@template << [:preamble]
|
78
79
|
|
79
80
|
# Write all node definitions as method defs
|
80
81
|
@definitions.each do |_, node|
|
@@ -59,6 +59,20 @@ module Opulent
|
|
59
59
|
@template[-1][1] = @template[-1][1][0..-1 - n] if @template[-1][0] == type
|
60
60
|
end
|
61
61
|
|
62
|
+
# Remove last n characters from the most recent template item
|
63
|
+
#
|
64
|
+
# @param type [Symbol] Remove only if last buffer part is of this type
|
65
|
+
# @param n [Fixnum] Number of characters to be removed
|
66
|
+
#
|
67
|
+
def buffer_remove_trailing_whitespace(type = :freeze)
|
68
|
+
if @template[-1][0] == type
|
69
|
+
n = @template[-1][1][/\s$/]
|
70
|
+
return if n.nil?
|
71
|
+
|
72
|
+
@template[-1][1] = @template[-1][1][0..-1 - n.size]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
62
76
|
# Turn call node attributes into a hash string
|
63
77
|
#
|
64
78
|
# @param attributes [Array] Array of node attributes
|
@@ -23,11 +23,9 @@ module Opulent
|
|
23
23
|
buffer_eval node[@value]
|
24
24
|
|
25
25
|
# If the node has children, evaluate each one of them
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
26
|
+
node[@children].each do |child|
|
27
|
+
root child, indent + @settings[:indent]
|
28
|
+
end if node[@children]
|
31
29
|
|
32
30
|
# Check if the node is actually a block expression
|
33
31
|
buffer_eval 'end' if node[@value] =~ Settings::END_INSERTION
|
@@ -9,10 +9,25 @@ module Opulent
|
|
9
9
|
# @param indent [Fixnum] Size of the indentation to be added
|
10
10
|
#
|
11
11
|
def node(node, indent)
|
12
|
-
|
12
|
+
# Pretty print
|
13
|
+
if @settings[:pretty]
|
14
|
+
indentation = ' ' * indent
|
15
|
+
inline = Settings::INLINE_NODE.include? node[@value]
|
16
|
+
|
17
|
+
if inline
|
18
|
+
if @sibling_stack[-1][-1][0] == :plain
|
19
|
+
buffer_remove_trailing_whitespace
|
20
|
+
end
|
21
|
+
else
|
22
|
+
buffer_freeze indentation
|
23
|
+
end
|
24
|
+
|
25
|
+
@sibling_stack[-1] << [node[@type], node[@value]]
|
26
|
+
@sibling_stack << [[node[@type], node[@value]]]
|
27
|
+
end
|
13
28
|
|
14
29
|
# Add the tag opening, with leading whitespace to the code buffer
|
15
|
-
buffer_freeze ' ' if node[@options][:leading_whitespace]
|
30
|
+
buffer_freeze ' ' if node[@options][:leading_whitespace]
|
16
31
|
buffer_freeze "<#{node[@value]}"
|
17
32
|
|
18
33
|
# Evaluate node extension in the current context
|
@@ -28,7 +43,6 @@ module Opulent
|
|
28
43
|
|
29
44
|
# Evaluate and generate node attributes, then process each one to
|
30
45
|
# by generating the required attribute code
|
31
|
-
# attributes = {}
|
32
46
|
buffer_attributes node[@options][:attributes],
|
33
47
|
extension
|
34
48
|
|
@@ -38,18 +52,54 @@ module Opulent
|
|
38
52
|
if node[@options][:self_enclosing]
|
39
53
|
# If the tag is self enclosing, it cannot have any child elements.
|
40
54
|
buffer_freeze '>'
|
55
|
+
|
56
|
+
# Pretty print
|
57
|
+
buffer_freeze "\n" if @settings[:pretty]
|
58
|
+
|
59
|
+
# If we mistakenly add children to self enclosing nodes,
|
60
|
+
# process each child element as if it was correctly indented
|
61
|
+
# node[@children].each do |child|
|
62
|
+
# root child, indent + @settings[:indent]
|
63
|
+
# end
|
41
64
|
else
|
42
65
|
# Set tag ending code
|
43
66
|
buffer_freeze '>'
|
44
67
|
|
68
|
+
# Pretty print
|
69
|
+
if @settings[:pretty]
|
70
|
+
buffer_freeze "\n" if node[@children].size > 0 and !inline
|
71
|
+
end
|
72
|
+
|
45
73
|
# Process each child element recursively, increasing indentation
|
46
74
|
node[@children].each do |child|
|
47
75
|
root child, indent + @settings[:indent]
|
48
76
|
end
|
49
77
|
|
78
|
+
# Pretty print
|
79
|
+
if @settings[:pretty]
|
80
|
+
if node[@children].size > 1 &&
|
81
|
+
(@sibling_stack[-1][-1][0] == :plain ||
|
82
|
+
Settings::INLINE_NODE.include?(@sibling_stack[-1][-1][1]))
|
83
|
+
buffer_freeze "\n"
|
84
|
+
end
|
85
|
+
|
86
|
+
if node[@children].size > 0 and !inline
|
87
|
+
buffer_freeze indentation
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
50
91
|
# Set tag closing code
|
51
92
|
buffer_freeze "</#{node[@value]}>"
|
52
93
|
buffer_freeze ' ' if node[@options][:trailing_whitespace]
|
94
|
+
|
95
|
+
# Pretty print
|
96
|
+
if @settings[:pretty]
|
97
|
+
buffer_freeze "\n" unless inline
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
if @settings[:pretty]
|
102
|
+
@sibling_stack.pop
|
53
103
|
end
|
54
104
|
end
|
55
105
|
end
|
@@ -8,8 +8,27 @@ module Opulent
|
|
8
8
|
# @param indent [Fixnum] Size of the indentation to be added
|
9
9
|
#
|
10
10
|
def plain(node, indent)
|
11
|
+
# Text value
|
11
12
|
value = node[@options][:value]
|
12
13
|
|
14
|
+
# Pretty print
|
15
|
+
if @settings[:pretty]
|
16
|
+
indentation = ' ' * indent
|
17
|
+
inline = @sibling_stack[-1][-1][0] == :node &&
|
18
|
+
Settings::INLINE_NODE.include?(@sibling_stack[-1][-1][1])
|
19
|
+
|
20
|
+
# Add current node to the siblings stack
|
21
|
+
@sibling_stack[-1] << [node[@type], node[@value]]
|
22
|
+
|
23
|
+
# If we have a text on multiple lines and the text isn't supposed to be
|
24
|
+
# inline, indent all the lines of the text
|
25
|
+
if !inline || value.split("\n").size > 1
|
26
|
+
value.gsub!(/^(?!$)/, indentation)
|
27
|
+
else
|
28
|
+
value.strip!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
13
32
|
# Leading whitespace
|
14
33
|
buffer_freeze ' ' if node[@options][:leading_whitespace]
|
15
34
|
|
@@ -23,6 +42,11 @@ module Opulent
|
|
23
42
|
|
24
43
|
# Trailing whitespace
|
25
44
|
buffer_freeze ' ' if node[@options][:trailing_whitespace]
|
45
|
+
|
46
|
+
# Pretty print
|
47
|
+
if @settings[:pretty]
|
48
|
+
buffer_freeze "\n" unless inline
|
49
|
+
end
|
26
50
|
end
|
27
51
|
end
|
28
52
|
end
|
data/lib/opulent/filters.rb
CHANGED
data/lib/opulent/settings.rb
CHANGED
@@ -60,7 +60,7 @@ module Opulent
|
|
60
60
|
# Set defaults as initial settings
|
61
61
|
#
|
62
62
|
def initialize
|
63
|
-
@settings = DEFAULTS
|
63
|
+
@settings = DEFAULTS.clone
|
64
64
|
end
|
65
65
|
|
66
66
|
# Get an option at runtime
|
@@ -94,8 +94,6 @@ module Opulent
|
|
94
94
|
# @param opts [Hash] Option extension hash
|
95
95
|
#
|
96
96
|
def update_settings(opts)
|
97
|
-
@settings = DEFAULTS
|
98
|
-
|
99
97
|
opts.each do |key, value|
|
100
98
|
@settings[key] = value
|
101
99
|
end
|
data/lib/opulent/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opulent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Grozav
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|