opulent 1.4.8 → 1.5.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/lib/opulent/compiler.rb +34 -29
- data/lib/opulent/compiler/buffer.rb +10 -10
- data/lib/opulent/compiler/define.rb +2 -2
- data/lib/opulent/compiler/root.rb +1 -1
- data/lib/opulent/context.rb +7 -7
- data/lib/opulent/engine.rb +28 -17
- data/lib/opulent/filters.rb +43 -31
- data/lib/opulent/logger.rb +36 -11
- data/lib/opulent/parser.rb +20 -20
- data/lib/opulent/parser/include.rb +1 -1
- data/lib/opulent/parser/node.rb +1 -1
- data/lib/opulent/settings.rb +2 -2
- data/lib/opulent/template.rb +1 -1
- data/lib/opulent/tokens.rb +5 -4
- 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: 400a61b79e430257b8e78d35a00168abf0b25b2a
|
4
|
+
data.tar.gz: f50f10dfe3f7673cf35eeb197bb06a62dfcaedb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14774d95d2d98deab955e1c62131e6ff6cee05c82aa79d4362aea9c2738f4e244628d05f886e08207e396d2875d43571db33ab030f68a9e6833f6d86857a6d12
|
7
|
+
data.tar.gz: 89f0081dd1d91648e877a6aa77efab4e3b70002f581ff739e83bc1bd5d8f51991346b5467d09affa0b2fa1fd83dbc8d7217b3d5204f4dd28cdb126c2d08323f9
|
data/lib/opulent/compiler.rb
CHANGED
@@ -14,10 +14,10 @@ require_relative 'compiler/yield.rb'
|
|
14
14
|
module Opulent
|
15
15
|
# @Compiler
|
16
16
|
class Compiler
|
17
|
-
|
17
|
+
BUFFER = :@_opulent_buffer
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
OPULENT_KEY = :_opulent_key
|
20
|
+
OPULENT_VALUE = :_opulent_value
|
21
21
|
|
22
22
|
# All node Objects (Array) must follow the next convention in order
|
23
23
|
# to make parsing faster
|
@@ -67,8 +67,8 @@ module Opulent
|
|
67
67
|
#
|
68
68
|
def compile(root_node, context = nil)
|
69
69
|
# Compiler generated code
|
70
|
-
@code =
|
71
|
-
@generator =
|
70
|
+
@code = ''
|
71
|
+
@generator = ''
|
72
72
|
|
73
73
|
# Set initial parent, from which we start generating code
|
74
74
|
@sibling_stack << root_node[@children].size
|
@@ -80,7 +80,7 @@ module Opulent
|
|
80
80
|
|
81
81
|
@template << [:postamble]
|
82
82
|
|
83
|
-
|
83
|
+
templatize
|
84
84
|
end
|
85
85
|
|
86
86
|
# Remove the last newline from the current code buffer
|
@@ -95,9 +95,9 @@ module Opulent
|
|
95
95
|
# @param indent [String] Indentation string to be appended
|
96
96
|
#
|
97
97
|
def indent_lines(text, indent)
|
98
|
-
text ||=
|
99
|
-
text.lines.inject(
|
100
|
-
|
98
|
+
text ||= ''
|
99
|
+
text.lines.inject('') do |_, line|
|
100
|
+
indent + line
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
@@ -109,28 +109,33 @@ module Opulent
|
|
109
109
|
#
|
110
110
|
def self.error(context, *data)
|
111
111
|
message = case context
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
112
|
+
when :enumerable
|
113
|
+
"The provided each structure iteration input \"#{data[0]}\"" \
|
114
|
+
' is not Enumerable.'
|
115
|
+
when :binding
|
116
|
+
data[0] = data[0].to_s.match(/\`(.*)\'/)
|
117
|
+
data[0] = data[0][1] if data[0]
|
118
|
+
"Found an undefined local variable or method \"#{data[0]}\"."
|
119
|
+
when :variable_name
|
120
|
+
data[0] = data[0].to_s.match(/\`(.*)\'/)[1]
|
121
|
+
"Found an undefined local variable or method \"#{data[0]}\"" \
|
122
|
+
' in locals.'
|
123
|
+
when :extension
|
124
|
+
"The extension sequence \"#{data[0]}\" is not a valid " \
|
125
|
+
'attributes extension. Please use a Hash to extend ' \
|
126
|
+
'attributes.'
|
127
|
+
when :filter_registered
|
128
|
+
"The \"#{data[0]}\" filter could not be recognized by " \
|
129
|
+
'Opulent.'
|
130
|
+
when :filter_load
|
131
|
+
"The gem required for the \"#{data[0]}\" filter is not " \
|
132
|
+
"installed. You can install it by running:\n\n#{data[1]}"
|
133
|
+
end
|
129
134
|
|
130
135
|
# Reconstruct lines to display where errors occur
|
131
|
-
fail "\n\nOpulent " + Logger.red(
|
132
|
-
|
133
|
-
"#{message}\n\n\n"
|
136
|
+
fail "\n\nOpulent " + Logger.red('[Runtime Error]') + "\n---\n" \
|
137
|
+
'A runtime error has been encountered when building the compiled ' \
|
138
|
+
" node tree.\n #{message}\n\n\n"
|
134
139
|
end
|
135
140
|
end
|
136
141
|
end
|
@@ -149,9 +149,9 @@ module Opulent
|
|
149
149
|
|
150
150
|
# @Hash
|
151
151
|
buffer_eval "elsif #{variable}.is_a? Hash"
|
152
|
-
buffer_eval "#{variable}.each do |#{
|
152
|
+
buffer_eval "#{variable}.each do |#{OPULENT_KEY}, #{OPULENT_VALUE}|"
|
153
153
|
dynamic ? buffer("\" #{key}-\"") : buffer_freeze(" #{key}-") # key-hashkey="
|
154
|
-
buffer "\"\#{#{
|
154
|
+
buffer "\"\#{#{OPULENT_KEY}}\""
|
155
155
|
buffer_freeze "=\""
|
156
156
|
escape ? buffer_escape("_opulent_value") : buffer("_opulent_value") # value
|
157
157
|
buffer_freeze '"'
|
@@ -191,7 +191,7 @@ module Opulent
|
|
191
191
|
# escape it. Otherwise, evaluate and initialize the type check.
|
192
192
|
if attribute[@value] =~ Tokens[:exp_string]
|
193
193
|
buffer_freeze " #{key}=\""
|
194
|
-
buffer_split_by_interpolation attribute[@value][1..-2]
|
194
|
+
buffer_split_by_interpolation attribute[@value][1..-2], attribute[@options][:escaped]
|
195
195
|
buffer_freeze "\""
|
196
196
|
else
|
197
197
|
# Evaluate and type check
|
@@ -213,8 +213,8 @@ module Opulent
|
|
213
213
|
|
214
214
|
# Process remaining extension keys if there are any
|
215
215
|
if extension
|
216
|
-
buffer_eval "#{extension}.each do |ext#{
|
217
|
-
buffer_data_attribute_type_check["\#{ext#{
|
216
|
+
buffer_eval "#{extension}.each do |ext#{OPULENT_KEY}, ext#{OPULENT_VALUE}|"
|
217
|
+
buffer_data_attribute_type_check["\#{ext#{OPULENT_KEY}}", "ext#{OPULENT_VALUE}", true, true]
|
218
218
|
buffer_eval "end"
|
219
219
|
end
|
220
220
|
end
|
@@ -226,17 +226,17 @@ module Opulent
|
|
226
226
|
@template.inject("") do |buffer, input|
|
227
227
|
buffer += case input[0]
|
228
228
|
when :preamble
|
229
|
-
"#{
|
229
|
+
"#{BUFFER} = []#{separator}"
|
230
230
|
when :buffer
|
231
|
-
"#{
|
231
|
+
"#{BUFFER} << (#{input[1]})#{separator}"
|
232
232
|
when :escape
|
233
|
-
"#{
|
233
|
+
"#{BUFFER} << (::Opulent::Utils::escape(#{input[1]}))#{separator}"
|
234
234
|
when :freeze
|
235
|
-
"#{
|
235
|
+
"#{BUFFER} << (#{input[1].inspect}.freeze)#{separator}"
|
236
236
|
when :eval
|
237
237
|
"#{input[1]}#{separator}"
|
238
238
|
when :postamble
|
239
|
-
"#{
|
239
|
+
"#{BUFFER}.join"
|
240
240
|
end
|
241
241
|
end
|
242
242
|
end
|
@@ -51,8 +51,8 @@ module Opulent
|
|
51
51
|
# the extension hash
|
52
52
|
if call_node[@options][:extension]
|
53
53
|
extension_attributes = buffer_set_variable :extension, call_node[@options][:extension][@value]
|
54
|
-
buffer_eval "#{call_attributes}.merge!(#{extension_attributes}) do |#{
|
55
|
-
buffer_eval "#{
|
54
|
+
buffer_eval "#{call_attributes}.merge!(#{extension_attributes}) do |#{OPULENT_KEY}, #{OPULENT_VALUE}1, #{OPULENT_VALUE}2|"
|
55
|
+
buffer_eval "#{OPULENT_KEY} == :class ? (#{OPULENT_VALUE}1 += #{OPULENT_VALUE}2) : (#{OPULENT_VALUE}2)"
|
56
56
|
buffer_eval "end"
|
57
57
|
end
|
58
58
|
|
@@ -9,7 +9,7 @@ module Opulent
|
|
9
9
|
# @param context [Context] Context holding environment variables
|
10
10
|
#
|
11
11
|
def root(current, indent, context)
|
12
|
-
if
|
12
|
+
if KEYWORDS.include? current[@type]
|
13
13
|
send :"#{current[@type]}_node", current, indent, context
|
14
14
|
else
|
15
15
|
send current[@type], current, indent, context
|
data/lib/opulent/context.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
module Opulent
|
3
3
|
# @Context
|
4
4
|
#
|
5
|
-
# The context class is used to differentiate local, instance and class
|
6
|
-
# and to define the current working environment. Each class, method
|
7
|
-
# has its own context
|
5
|
+
# The context class is used to differentiate local, instance and class
|
6
|
+
# variables and to define the current working environment. Each class, method
|
7
|
+
# and instance has its own context
|
8
8
|
#
|
9
9
|
class Context
|
10
10
|
attr_accessor :block, :binding, :name, :parent
|
@@ -20,10 +20,10 @@ module Opulent
|
|
20
20
|
@content = content
|
21
21
|
|
22
22
|
@block = block
|
23
|
-
|
24
|
-
@block.binding.clone
|
23
|
+
if @block
|
24
|
+
@binding = @block.binding.clone
|
25
25
|
else
|
26
|
-
Binding.new.get
|
26
|
+
@binding = Binding.new.get
|
27
27
|
end
|
28
28
|
|
29
29
|
extend_locals locals
|
@@ -80,7 +80,7 @@ module Opulent
|
|
80
80
|
# @Binding
|
81
81
|
class Binding
|
82
82
|
def get
|
83
|
-
|
83
|
+
binding
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
data/lib/opulent/engine.rb
CHANGED
@@ -6,8 +6,8 @@ module Opulent
|
|
6
6
|
|
7
7
|
# Module method wrapper for creating a new engine instance
|
8
8
|
#
|
9
|
-
def
|
10
|
-
|
9
|
+
def self.new(input, settings = {})
|
10
|
+
Engine.new input, settings
|
11
11
|
end
|
12
12
|
|
13
13
|
# @Engine
|
@@ -28,14 +28,9 @@ module Opulent
|
|
28
28
|
Settings.update_settings settings unless settings.empty?
|
29
29
|
|
30
30
|
# Read input parameter based on opening mode. If we have a file mode, we
|
31
|
-
# get its path and read the code. We need to reset the mode in case the
|
32
|
-
# render call is on code, not on a file.
|
33
|
-
@code =
|
34
|
-
when Symbol
|
35
|
-
@file = File.expand_path get_eval_file input; File.read @file
|
36
|
-
else
|
37
|
-
@file = File.expand_path __FILE__; input
|
38
|
-
end
|
31
|
+
# get its path and read the code. We need to reset the mode in case the
|
32
|
+
# next render call is on code, not on a file.
|
33
|
+
@code = read input
|
39
34
|
|
40
35
|
# Get the nodes tree
|
41
36
|
@nodes, @def = Parser.new(@file, @def).parse @code
|
@@ -44,6 +39,16 @@ module Opulent
|
|
44
39
|
@template = Compiler.new.compile @nodes
|
45
40
|
end
|
46
41
|
|
42
|
+
def read(input)
|
43
|
+
if input.is_a? Symbol
|
44
|
+
@file = File.expand_path get_eval_file input
|
45
|
+
File.read @file
|
46
|
+
else
|
47
|
+
@file = File.expand_path __FILE__
|
48
|
+
input
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
47
52
|
# Avoid code duplication when layouting is set. When we have a layout, look
|
48
53
|
# in layouts/application by default.
|
49
54
|
#
|
@@ -53,16 +58,20 @@ module Opulent
|
|
53
58
|
#
|
54
59
|
def render(scope = Object.new, locals = {}, &block)
|
55
60
|
# Get opulent buffer value
|
56
|
-
|
61
|
+
if scope.instance_variable_defined?(:@_opulent_buffer)
|
62
|
+
initial_buffer = scope.instance_variable_get(:@_opulent_buffer)
|
63
|
+
else
|
64
|
+
initial_buffer = []
|
65
|
+
end
|
57
66
|
|
58
67
|
# If a layout is set, get the specific layout, otherwise, set the default
|
59
68
|
# one. If a layout is set to false, the page will be render as it is.
|
60
69
|
if scope.is_a? binding.class
|
61
|
-
scope_object = eval
|
62
|
-
scope = scope_object.instance_eval{ binding } if block_given?
|
70
|
+
scope_object = eval 'self', scope
|
71
|
+
scope = scope_object.instance_eval { binding } if block_given?
|
63
72
|
else
|
64
73
|
scope_object = scope
|
65
|
-
scope = scope_object.instance_eval{ binding }
|
74
|
+
scope = scope_object.instance_eval { binding }
|
66
75
|
end
|
67
76
|
|
68
77
|
# Set input local variables in current scope
|
@@ -82,15 +91,17 @@ module Opulent
|
|
82
91
|
end
|
83
92
|
|
84
93
|
private
|
94
|
+
|
85
95
|
# Add .op extension to input file if it isn't already set.
|
86
96
|
#
|
87
97
|
# @param input [Symbol] Input file
|
88
98
|
#
|
89
99
|
def get_eval_file(input)
|
90
100
|
input = input.to_s
|
91
|
-
|
92
|
-
|
101
|
+
unless File.extname(input) == Settings::FILE_EXTENSION
|
102
|
+
input += Settings::FILE_EXTENSION
|
103
|
+
end
|
104
|
+
input
|
93
105
|
end
|
94
|
-
|
95
106
|
end
|
96
107
|
end
|
data/lib/opulent/filters.rb
CHANGED
@@ -19,8 +19,8 @@ module Opulent
|
|
19
19
|
|
20
20
|
# Check if the chosen filter name is registed within our knowledgebase
|
21
21
|
#
|
22
|
-
def
|
23
|
-
@filters.
|
22
|
+
def filter?(name)
|
23
|
+
@filters.key? name
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -39,15 +39,15 @@ module Opulent
|
|
39
39
|
# Error output in case the filter does not exist
|
40
40
|
#
|
41
41
|
def load_filter
|
42
|
-
unless gem_name.nil? || @loaded
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
return unless gem_name.nil? || @loaded
|
43
|
+
|
44
|
+
# Try to load the library associated to the chosen filter
|
45
|
+
begin
|
46
|
+
require gem_name
|
47
|
+
@loaded = true
|
48
|
+
rescue LoadError
|
49
|
+
# Error output with filter name and installation instructions
|
50
|
+
Compiler.error :filter_load, @name, install_error
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -61,23 +61,23 @@ module Opulent
|
|
61
61
|
# Process input code using this filter and return the output to the
|
62
62
|
# evaluation method from the Filter Node
|
63
63
|
#
|
64
|
-
def render(
|
65
|
-
|
64
|
+
def render(_code, _options = {})
|
65
|
+
fail NoMethodError
|
66
66
|
end
|
67
67
|
|
68
68
|
# RubyGems name for explicit library require
|
69
69
|
#
|
70
70
|
def gem_name
|
71
|
-
|
71
|
+
fail NoMethodError
|
72
72
|
# "gem_name"
|
73
73
|
end
|
74
74
|
|
75
75
|
# After defining how to render the code,
|
76
76
|
#
|
77
|
-
# Filters.register self, :filter, tag: :tag,
|
77
|
+
# Filters.register self, :filter, tag: :tag,
|
78
|
+
# attributes: { type: 'text/css' }
|
78
79
|
end
|
79
80
|
|
80
|
-
|
81
81
|
# Add the default registered rendering filters for Opulent
|
82
82
|
|
83
83
|
# @CoffeeScript
|
@@ -87,15 +87,18 @@ module Opulent
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def gem_name
|
90
|
-
|
90
|
+
'coffee-script'
|
91
91
|
end
|
92
92
|
|
93
|
-
Filters.register self,
|
93
|
+
Filters.register self,
|
94
|
+
:coffeescript,
|
95
|
+
tag: :script,
|
96
|
+
attributes: { type: 'javascript' }
|
94
97
|
end
|
95
98
|
|
96
99
|
# @JavaScript
|
97
100
|
class JavaScript < Filter
|
98
|
-
def render(code,
|
101
|
+
def render(code, _options = {})
|
99
102
|
code
|
100
103
|
end
|
101
104
|
|
@@ -103,7 +106,10 @@ module Opulent
|
|
103
106
|
nil
|
104
107
|
end
|
105
108
|
|
106
|
-
Filters.register self,
|
109
|
+
Filters.register self,
|
110
|
+
:javascript,
|
111
|
+
tag: :script,
|
112
|
+
attributes: { type: 'javascript' }
|
107
113
|
end
|
108
114
|
|
109
115
|
# @Scss
|
@@ -115,10 +121,13 @@ module Opulent
|
|
115
121
|
end
|
116
122
|
|
117
123
|
def gem_name
|
118
|
-
|
124
|
+
'sass'
|
119
125
|
end
|
120
126
|
|
121
|
-
Filters.register self,
|
127
|
+
Filters.register self,
|
128
|
+
:scss,
|
129
|
+
tag: :style,
|
130
|
+
attributes: { type: 'text/css' }
|
122
131
|
end
|
123
132
|
|
124
133
|
# @Sass
|
@@ -131,17 +140,20 @@ module Opulent
|
|
131
140
|
end
|
132
141
|
|
133
142
|
def gem_name
|
134
|
-
|
143
|
+
'sass'
|
135
144
|
end
|
136
145
|
|
137
|
-
Filters.register self,
|
146
|
+
Filters.register self,
|
147
|
+
:scss,
|
148
|
+
tag: :style,
|
149
|
+
attributes: { type: 'text/css' }
|
138
150
|
end
|
139
151
|
|
140
152
|
# @Css
|
141
153
|
class Css < Filter
|
142
154
|
def render(code, options = {})
|
143
155
|
if options[:cdata]
|
144
|
-
"<![CDATA[\n" + code +
|
156
|
+
"<![CDATA[\n" + code + ']]>'
|
145
157
|
else
|
146
158
|
code
|
147
159
|
end
|
@@ -156,8 +168,8 @@ module Opulent
|
|
156
168
|
|
157
169
|
# @CData
|
158
170
|
class CData < Filter
|
159
|
-
def render(code,
|
160
|
-
"<![CDATA[\n" + code +
|
171
|
+
def render(code, _options = {})
|
172
|
+
"<![CDATA[\n" + code + ']]>'
|
161
173
|
end
|
162
174
|
|
163
175
|
def gem_name
|
@@ -169,7 +181,7 @@ module Opulent
|
|
169
181
|
|
170
182
|
# @Escaped
|
171
183
|
class Escaped < Filter
|
172
|
-
def render(code,
|
184
|
+
def render(code, _options = {})
|
173
185
|
Compiler.escape code
|
174
186
|
end
|
175
187
|
|
@@ -187,7 +199,7 @@ module Opulent
|
|
187
199
|
end
|
188
200
|
|
189
201
|
def gem_name
|
190
|
-
|
202
|
+
'kramdown'
|
191
203
|
end
|
192
204
|
|
193
205
|
Filters.register self, :markdown, tag: nil, attributes: {}
|
@@ -200,7 +212,7 @@ module Opulent
|
|
200
212
|
end
|
201
213
|
|
202
214
|
def gem_name
|
203
|
-
|
215
|
+
'maruku'
|
204
216
|
end
|
205
217
|
|
206
218
|
Filters.register self, :maruku, tag: nil, attributes: {}
|
@@ -213,7 +225,7 @@ module Opulent
|
|
213
225
|
end
|
214
226
|
|
215
227
|
def gem_name
|
216
|
-
|
228
|
+
'RedCloth'
|
217
229
|
end
|
218
230
|
|
219
231
|
Filters.register self, :textile, tag: nil, attributes: {}
|
data/lib/opulent/logger.rb
CHANGED
@@ -16,15 +16,41 @@ module Opulent
|
|
16
16
|
|
17
17
|
# Colors available in the terminal
|
18
18
|
#
|
19
|
-
def black(text)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def
|
19
|
+
def black(text)
|
20
|
+
colorize(text, "\e[30m")
|
21
|
+
end
|
22
|
+
|
23
|
+
def red(text)
|
24
|
+
colorize(text, "\e[31m")
|
25
|
+
end
|
26
|
+
|
27
|
+
def green(text)
|
28
|
+
colorize(text, "\e[32m")
|
29
|
+
end
|
30
|
+
|
31
|
+
def yellow(text)
|
32
|
+
colorize(text, "\e[33m")
|
33
|
+
end
|
34
|
+
|
35
|
+
def blue(text)
|
36
|
+
colorize(text, "\e[34m")
|
37
|
+
end
|
38
|
+
|
39
|
+
def magenta(text)
|
40
|
+
colorize(text, "\e[35m")
|
41
|
+
end
|
42
|
+
|
43
|
+
def cyan(text)
|
44
|
+
colorize(text, "\e[36m")
|
45
|
+
end
|
46
|
+
|
47
|
+
def white(text)
|
48
|
+
colorize(text, "\e[37m")
|
49
|
+
end
|
50
|
+
|
51
|
+
def default(text)
|
52
|
+
colorize(text, "\e[38m")
|
53
|
+
end
|
28
54
|
|
29
55
|
# Require windows libraries for ANSI Console output
|
30
56
|
#
|
@@ -39,8 +65,7 @@ module Opulent
|
|
39
65
|
|
40
66
|
# Pretty print Nodes with their important details
|
41
67
|
#
|
42
|
-
def pretty_print(
|
43
|
-
|
68
|
+
def pretty_print(_model, _indent = 0)
|
44
69
|
end
|
45
70
|
end
|
46
71
|
end
|
data/lib/opulent/parser.rb
CHANGED
@@ -64,7 +64,7 @@ module Opulent
|
|
64
64
|
# nodes and definitions
|
65
65
|
root @root
|
66
66
|
|
67
|
-
|
67
|
+
[@root, @definitions]
|
68
68
|
end
|
69
69
|
|
70
70
|
# Check and accept or reject a given token as long as we have tokens
|
@@ -95,8 +95,8 @@ module Opulent
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
# Helper method which automatically sets the stripped options to true,
|
99
|
-
# do not have to explicitly specify it
|
98
|
+
# Helper method which automatically sets the stripped options to true,
|
99
|
+
# so that we do not have to explicitly specify it
|
100
100
|
#
|
101
101
|
# @param token [RegEx] Token to be accepted by the parser
|
102
102
|
# @param required [Boolean] Expect the given token syntax
|
@@ -122,7 +122,7 @@ module Opulent
|
|
122
122
|
# @param token [RegEx] Token to be checked by the parser
|
123
123
|
#
|
124
124
|
def lookahead_next_line(token)
|
125
|
-
return
|
125
|
+
return unless @code[@i + 1]
|
126
126
|
|
127
127
|
# Check if we match the token to the current line.
|
128
128
|
@code[@i + 1].match Tokens[token]
|
@@ -134,19 +134,17 @@ module Opulent
|
|
134
134
|
# @param match [String] Matched string to be undone
|
135
135
|
#
|
136
136
|
def undo(match)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
137
|
+
return if match.empty?
|
138
|
+
@offset -= match.size
|
139
|
+
nil
|
141
140
|
end
|
142
141
|
|
143
142
|
# Allow expressions to continue on a new line in certain conditions
|
144
143
|
#
|
145
144
|
def accept_newline
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
end
|
145
|
+
return unless @line[@offset..-1].strip.empty?
|
146
|
+
@line = @code[(@i += 1)]
|
147
|
+
@offset = 0
|
150
148
|
end
|
151
149
|
|
152
150
|
# Indent all lines of the input text using give indentation
|
@@ -155,9 +153,9 @@ module Opulent
|
|
155
153
|
# @param indent [String] Indentation string to be appended
|
156
154
|
#
|
157
155
|
def indent_lines(text, indent)
|
158
|
-
text ||=
|
159
|
-
text.lines.inject(
|
160
|
-
|
156
|
+
text ||= ''
|
157
|
+
text.lines.inject('') do |_, line|
|
158
|
+
indent + line
|
161
159
|
end
|
162
160
|
end
|
163
161
|
|
@@ -171,8 +169,11 @@ module Opulent
|
|
171
169
|
when :unknown_node_type
|
172
170
|
"An unknown node type has been encountered at:\n\n#{Logger.red @line}"
|
173
171
|
when :expected
|
174
|
-
|
175
|
-
|
172
|
+
if [:'(', :'{', :'[', :'<'].include? data[0]
|
173
|
+
data[0] = "#{Tokens.bracket data[0]}"
|
174
|
+
end
|
175
|
+
"Expected to find a :#{data[0]} token on line #{@i+1} of input at: " \
|
176
|
+
"\n\n#{@line[0..@offset-1]}#{Logger.red @line[@offset..-1].rstrip}"
|
176
177
|
when :root
|
177
178
|
"Unknown node type encountered on line #{@i+1} of input at:\n\n" +
|
178
179
|
"#{@line[0..@offset-1]}#{Logger.red @line[@offset..-1].rstrip}"
|
@@ -222,9 +223,8 @@ module Opulent
|
|
222
223
|
end
|
223
224
|
|
224
225
|
# Reconstruct lines to display where errors occur
|
225
|
-
fail "\n\nOpulent " + Logger.red(
|
226
|
-
"\n---\n"
|
227
|
-
"#{message}\n\n\n"
|
226
|
+
fail "\n\nOpulent " + Logger.red('[Parser Error]') +
|
227
|
+
"\n---\n#{message}\n\n\n"
|
228
228
|
end
|
229
229
|
end
|
230
230
|
end
|
@@ -30,7 +30,7 @@ module Opulent
|
|
30
30
|
include_path = File.expand_path name, File.dirname(@file[-1][0])
|
31
31
|
|
32
32
|
# Try to see if it has any existing extension, otherwise add .op
|
33
|
-
include_path += Settings::
|
33
|
+
include_path += Settings::FILE_EXTENSION if File.extname(name).empty?
|
34
34
|
|
35
35
|
# Throw an error if the file doesn't exist
|
36
36
|
error :include, name unless Dir[include_path].any?
|
data/lib/opulent/parser/node.rb
CHANGED
@@ -11,7 +11,7 @@ module Opulent
|
|
11
11
|
#
|
12
12
|
def node(parent, indent = nil)
|
13
13
|
if (name = lookahead(:node_lookahead) || lookahead(:shorthand_lookahead))
|
14
|
-
return nil if
|
14
|
+
return nil if KEYWORDS.include? name[0].to_sym
|
15
15
|
|
16
16
|
# Accept either explicit node_name or implicit :div node_name
|
17
17
|
# with shorthand attributes
|
data/lib/opulent/settings.rb
CHANGED
@@ -3,10 +3,10 @@ module Opulent
|
|
3
3
|
# @Settings
|
4
4
|
module Settings
|
5
5
|
# Set buffer variable name
|
6
|
-
|
6
|
+
BUFFER = :@_opulent_buffer
|
7
7
|
|
8
8
|
# Default Opulent file extension
|
9
|
-
|
9
|
+
FILE_EXTENSION = '.op'
|
10
10
|
|
11
11
|
# Default yield target which is used for child block replacements
|
12
12
|
DefaultEachKey = :key
|
data/lib/opulent/template.rb
CHANGED
@@ -30,7 +30,7 @@ module Opulent
|
|
30
30
|
# override render() may not support all features.
|
31
31
|
#
|
32
32
|
def evaluate(scope, locals, &block)
|
33
|
-
|
33
|
+
fail ArgumentError, 'Invalid scope: must not be frozen.' if scope.frozen?
|
34
34
|
super
|
35
35
|
end
|
36
36
|
|
data/lib/opulent/tokens.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
# @Opulent
|
1
2
|
module Opulent
|
2
|
-
# Opulent
|
3
|
-
|
3
|
+
# Opulent KEYWORDS
|
4
|
+
KEYWORDS = %i(def yield include if else elsif unless case when each while until doctype)
|
4
5
|
|
5
6
|
# @Tokens
|
6
7
|
class Tokens
|
@@ -24,7 +25,7 @@ module Opulent
|
|
24
25
|
trailing_whitespace: /\A(\-\>)/,
|
25
26
|
|
26
27
|
# Self enclosing node
|
27
|
-
self_enclosing:
|
28
|
+
self_enclosing: %r{\A\/(.*)},
|
28
29
|
|
29
30
|
# Definition
|
30
31
|
def: /\Adef +/,
|
@@ -49,7 +50,7 @@ module Opulent
|
|
49
50
|
inline_child: /\A *\> */,
|
50
51
|
|
51
52
|
# Comments
|
52
|
-
comment:
|
53
|
+
comment: %r{\A\/},
|
53
54
|
|
54
55
|
# Intepreted filters
|
55
56
|
filter: /\A\:[a-zA-Z]([\-\_]?[a-zA-Z0-9]+)*/,
|
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.5.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: 2015-
|
11
|
+
date: 2015-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|