opulent 1.7.11 → 1.8.0
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/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
|