opulent 1.0.2 → 1.0.3
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 +13 -2
- data/lib/opulent/compiler/require.rb +24 -0
- data/lib/opulent/context.rb +3 -3
- data/lib/opulent/engine.rb +38 -10
- data/lib/opulent/parser.rb +10 -7
- data/lib/opulent/parser/require.rb +29 -0
- data/lib/opulent/parser/root.rb +2 -1
- data/lib/opulent/tokens.rb +4 -1
- data/lib/opulent/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a41bc661663219aac5c2cbdbc6def8eedbe6abeb
|
4
|
+
data.tar.gz: 68d65112e22329817b60acdf1aa6aad48ad68653
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd1a7efd68cd841e5085ffc2b14f5158f8e8a4a4b0ca07ace88f400857797fc0cd7ba695822b33ad1638c884cf93c8816a70f2dd15021356c88e2d83db2f9446
|
7
|
+
data.tar.gz: 07249aab1bf67424862905d9f643b4dd1f80a95c4d59423bb61b9c09ee925d87ca91da6f5f54f80cf0edfc7c054254cbc35b1ede2fc888f2c321e003de1546d5
|
data/lib/opulent/compiler.rb
CHANGED
@@ -5,6 +5,7 @@ require_relative 'compiler/define.rb'
|
|
5
5
|
require_relative 'compiler/eval.rb'
|
6
6
|
require_relative 'compiler/filter.rb'
|
7
7
|
require_relative 'compiler/node.rb'
|
8
|
+
require_relative 'compiler/require.rb'
|
8
9
|
require_relative 'compiler/root.rb'
|
9
10
|
require_relative 'compiler/text.rb'
|
10
11
|
|
@@ -19,7 +20,9 @@ module Opulent
|
|
19
20
|
#
|
20
21
|
# [:node_type, :value, :attributes, :children, :indent]
|
21
22
|
#
|
22
|
-
|
23
|
+
# @param path [String] Current file path needed for require nodes
|
24
|
+
#
|
25
|
+
def initialize(settings = {})
|
23
26
|
# Setup convention accessors
|
24
27
|
@type = 0
|
25
28
|
@value = 1
|
@@ -27,6 +30,12 @@ module Opulent
|
|
27
30
|
@children = 3
|
28
31
|
@indent = 4
|
29
32
|
|
33
|
+
# Set current compiled file
|
34
|
+
@path = File.dirname settings.delete :path
|
35
|
+
|
36
|
+
# Extract definitions for require directives
|
37
|
+
@definitions = settings.delete :definitions
|
38
|
+
|
30
39
|
# Create the HTML Entities encoder/decoder
|
31
40
|
@entities = HTMLEntities.new
|
32
41
|
|
@@ -52,7 +61,7 @@ module Opulent
|
|
52
61
|
|
53
62
|
# Compile input nodes, replace them with their definitions and
|
54
63
|
#
|
55
|
-
# @param
|
64
|
+
# @param root_node [Array] Root node containing all document nodes
|
56
65
|
# @param context [Context] Context holding environment variables
|
57
66
|
#
|
58
67
|
def compile(root_node, context)
|
@@ -121,6 +130,8 @@ module Opulent
|
|
121
130
|
"The \"#{data[0]}\" filter could not be recognized by Opulent."
|
122
131
|
when :filter_load
|
123
132
|
"The gem required for the \"#{data[0]}\" filter is not installed. You can install it by running:\n\n#{data[1]}"
|
133
|
+
when :require
|
134
|
+
"The required file #{data[0]} does not exist or an incorrect path has been specified."
|
124
135
|
end
|
125
136
|
|
126
137
|
# Reconstruct lines to display where errors occur
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# @Opulent
|
2
|
+
module Opulent
|
3
|
+
# @Compiler
|
4
|
+
class Compiler
|
5
|
+
# Compile a new Opulent file using the current page context data
|
6
|
+
#
|
7
|
+
# @param node [Array] Node code generation data
|
8
|
+
# @param indent [Fixnum] Size of the indentation to be added
|
9
|
+
# @param context [Context] Processing environment data
|
10
|
+
#
|
11
|
+
def require_node(node, indent, context)
|
12
|
+
require_file = File.expand_path context.evaluate(node[@value]), @path
|
13
|
+
error :require, node[@value] unless File.file? require_file
|
14
|
+
|
15
|
+
data = {
|
16
|
+
definitions: @definitions,
|
17
|
+
overwrite: true
|
18
|
+
}
|
19
|
+
rendered = Engine.new(data).render_file require_file, &context.block
|
20
|
+
|
21
|
+
@code += indent_lines rendered, " " * indent
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/opulent/context.rb
CHANGED
@@ -7,7 +7,7 @@ module Opulent
|
|
7
7
|
# has its own context
|
8
8
|
#
|
9
9
|
class Context
|
10
|
-
attr_accessor :binding, :name, :parent
|
10
|
+
attr_accessor :block, :binding, :name, :parent
|
11
11
|
|
12
12
|
# Create a context from the environment binding, extended with the locals
|
13
13
|
# given as arguments
|
@@ -15,10 +15,10 @@ module Opulent
|
|
15
15
|
# @param locals [Hash] Binding extension
|
16
16
|
# @param bind [Binding] Call environment binding
|
17
17
|
#
|
18
|
-
def initialize(locals = {}, &block)
|
18
|
+
def initialize(locals = {}, override = false, &block)
|
19
19
|
@block = block || Proc.new
|
20
20
|
@binding = if @block
|
21
|
-
@block.binding.clone
|
21
|
+
override ? @block.binding : @block.binding.clone
|
22
22
|
else
|
23
23
|
Binding.new
|
24
24
|
end
|
data/lib/opulent/engine.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module Opulent
|
3
3
|
# Module method wrapper for creating a new engine instance
|
4
4
|
#
|
5
|
-
def Opulent.new(settings =
|
5
|
+
def Opulent.new(settings = {})
|
6
6
|
return Engine.new settings
|
7
7
|
end
|
8
8
|
|
@@ -10,9 +10,17 @@ module Opulent
|
|
10
10
|
class Engine
|
11
11
|
attr_reader :nodes, :preamble, :buffer
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
# Update render settings
|
14
|
+
#
|
15
|
+
# @param settings [Hash] Opulent settings override
|
16
|
+
# @param definitions [Hash] Definitions from previously parsed files
|
17
|
+
# @param overwrite [Boolean] Write changes directly to the parent binding
|
18
|
+
#
|
19
|
+
def initialize(settings = {})
|
20
|
+
@definitions = settings.delete(:definitions) || {}
|
21
|
+
@overwrite = settings.delete :overwrite
|
22
|
+
|
23
|
+
Settings.update_settings settings unless settings.empty?
|
16
24
|
end
|
17
25
|
|
18
26
|
# Analyze the input code and check for matching tokens. In case no match was
|
@@ -23,8 +31,9 @@ module Opulent
|
|
23
31
|
# @param block [Proc] Processing environment data
|
24
32
|
#
|
25
33
|
def render_file(file, locals = {}, &block)
|
26
|
-
|
27
|
-
|
34
|
+
@mode = :file
|
35
|
+
|
36
|
+
render file, locals, &block
|
28
37
|
end
|
29
38
|
|
30
39
|
# Analyze the input code and check for matching tokens. In case no match was
|
@@ -34,19 +43,22 @@ module Opulent
|
|
34
43
|
# @param locals [Hash] Render call local variables
|
35
44
|
# @param block [Proc] Processing environment data
|
36
45
|
#
|
37
|
-
def render(
|
46
|
+
def render(input, locals = {}, &block)
|
47
|
+
# Get input code
|
48
|
+
@code = read input
|
49
|
+
|
38
50
|
# Get the nodes tree
|
39
|
-
@nodes = Parser.new.parse code
|
51
|
+
@nodes, @definitions = Parser.new(@definitions).parse @code
|
40
52
|
|
41
53
|
# @TODO
|
42
54
|
# Implement precompiled template handling
|
43
55
|
@preamble = @nodes.inspect.inspect
|
44
56
|
|
45
57
|
# Create a new context based on our rendering environment
|
46
|
-
@context = Context.new locals, &block
|
58
|
+
@context = Context.new locals, @overwrite, &block
|
47
59
|
|
48
60
|
# Compile our syntax tree using input context
|
49
|
-
@output = Compiler.new.compile @nodes, @context
|
61
|
+
@output = Compiler.new({path: @file, definitions: @definitions}).compile @nodes, @context
|
50
62
|
|
51
63
|
# puts "Nodes\n---\n"
|
52
64
|
# pp @nodes
|
@@ -56,5 +68,21 @@ module Opulent
|
|
56
68
|
|
57
69
|
return @output
|
58
70
|
end
|
71
|
+
|
72
|
+
# Read input parameter based on opening mode. If we have a file mode, we
|
73
|
+
# get its path and read the code. We need to reset the mode in case the next
|
74
|
+
# render call is on code, not on a file.
|
75
|
+
#
|
76
|
+
# @param input [String] Input file or code
|
77
|
+
#
|
78
|
+
def read(input)
|
79
|
+
if @mode == :file
|
80
|
+
@file = File.expand_path input; @mode = nil
|
81
|
+
return File.read @file
|
82
|
+
else
|
83
|
+
@file = File.expand_path __FILE__
|
84
|
+
return input
|
85
|
+
end
|
86
|
+
end
|
59
87
|
end
|
60
88
|
end
|
data/lib/opulent/parser.rb
CHANGED
@@ -6,6 +6,7 @@ require_relative 'parser/eval.rb'
|
|
6
6
|
require_relative 'parser/expression.rb'
|
7
7
|
require_relative 'parser/filter.rb'
|
8
8
|
require_relative 'parser/node.rb'
|
9
|
+
require_relative 'parser/require.rb'
|
9
10
|
require_relative 'parser/root.rb'
|
10
11
|
require_relative 'parser/text.rb'
|
11
12
|
|
@@ -13,19 +14,23 @@ require_relative 'parser/text.rb'
|
|
13
14
|
module Opulent
|
14
15
|
# @Parser
|
15
16
|
class Parser
|
16
|
-
attr_reader :type, :value, :options, :children, :indent
|
17
|
+
attr_reader :type, :value, :options, :children, :indent, :definitions
|
17
18
|
|
18
19
|
# All node Objects (Array) must follow the next convention in order
|
19
20
|
# to make parsing faster
|
20
21
|
#
|
21
22
|
# [:node_type, :value, :attributes, :children, :indent]
|
22
23
|
#
|
23
|
-
def initialize
|
24
|
+
def initialize(definitions = {})
|
25
|
+
# Convention accessors
|
24
26
|
@type = 0
|
25
27
|
@value = 1
|
26
28
|
@options = 2
|
27
29
|
@children = 3
|
28
30
|
@indent = 4
|
31
|
+
|
32
|
+
# Node definitions encountered up to the current point
|
33
|
+
@definitions = definitions
|
29
34
|
end
|
30
35
|
|
31
36
|
# Initialize the parsing process by splitting the code into lines and
|
@@ -39,17 +44,15 @@ module Opulent
|
|
39
44
|
# Split the code into lines and parse them one by one
|
40
45
|
@code = code.lines
|
41
46
|
|
42
|
-
# Node definitions encountered up to the current point
|
43
|
-
@definitions = {}
|
44
|
-
|
45
47
|
# Current line index
|
46
48
|
@i = -1
|
47
49
|
|
48
50
|
# Initialize root node
|
49
51
|
@root = [:root, nil, {}, [], -1]
|
50
52
|
|
51
|
-
# Get all nodes starting from the root element
|
52
|
-
|
53
|
+
# Get all nodes starting from the root element and return output
|
54
|
+
# nodes and definitions
|
55
|
+
[root(@root), @definitions]
|
53
56
|
end
|
54
57
|
|
55
58
|
# Check and accept or reject a given token as long as we have tokens
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# @Opulent
|
2
|
+
module Opulent
|
3
|
+
# @Parser
|
4
|
+
class Parser
|
5
|
+
# Check if we match a new node definition to use within our page.
|
6
|
+
#
|
7
|
+
# Definitions will not be recursive because, by the time we parse
|
8
|
+
# the definition children, the definition itself is not in the
|
9
|
+
# knowledgebase yet.
|
10
|
+
#
|
11
|
+
# However, we may use previously defined nodes inside new definitions,
|
12
|
+
# due to the fact that they are known at parse time.
|
13
|
+
#
|
14
|
+
# @param nodes [Array] Parent node to which we append to
|
15
|
+
#
|
16
|
+
def require_file(parent, indent)
|
17
|
+
if(match = accept :require)
|
18
|
+
# Process data
|
19
|
+
name = accept(:exp_string, :*)
|
20
|
+
|
21
|
+
# Create node
|
22
|
+
require_node = [:require, name, {}, [], indent]
|
23
|
+
|
24
|
+
# Add to parent
|
25
|
+
parent[@children] << require_node
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/opulent/parser/root.rb
CHANGED
@@ -36,7 +36,8 @@ module Opulent
|
|
36
36
|
evaluate(parent, indent) ||
|
37
37
|
filter(parent, indent) ||
|
38
38
|
block_yield(parent, indent) ||
|
39
|
-
block(parent, indent)
|
39
|
+
block(parent, indent) ||
|
40
|
+
require_file(parent, indent)
|
40
41
|
|
41
42
|
# Throw an error if we couldn't find a valid node
|
42
43
|
error :unknown_node_type unless current_node
|
data/lib/opulent/tokens.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Opulent
|
2
2
|
# Opulent Keywords
|
3
|
-
Keywords = %i(def block yield if else elsif unless case when each while until)
|
3
|
+
Keywords = %i(def block yield require if else elsif unless case when each while until)
|
4
4
|
|
5
5
|
# @Tokens
|
6
6
|
class Tokens
|
@@ -29,6 +29,9 @@ module Opulent
|
|
29
29
|
# Definition
|
30
30
|
def: /\Adef +/,
|
31
31
|
|
32
|
+
# Require file
|
33
|
+
require: /\Arequire +/,
|
34
|
+
|
32
35
|
# Node Attributes
|
33
36
|
attributes_bracket: /\A\(\[\{/,
|
34
37
|
extend_attributes: /\A(\+)/,
|
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.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Grozav
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- lib/opulent/compiler/eval.rb
|
148
148
|
- lib/opulent/compiler/filter.rb
|
149
149
|
- lib/opulent/compiler/node.rb
|
150
|
+
- lib/opulent/compiler/require.rb
|
150
151
|
- lib/opulent/compiler/root.rb
|
151
152
|
- lib/opulent/compiler/text.rb
|
152
153
|
- lib/opulent/context.rb
|
@@ -162,6 +163,7 @@ files:
|
|
162
163
|
- lib/opulent/parser/expression.rb
|
163
164
|
- lib/opulent/parser/filter.rb
|
164
165
|
- lib/opulent/parser/node.rb
|
166
|
+
- lib/opulent/parser/require.rb
|
165
167
|
- lib/opulent/parser/root.rb
|
166
168
|
- lib/opulent/parser/text.rb
|
167
169
|
- lib/opulent/settings.rb
|