opulent 1.5.5 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +13 -0
  3. data/{LICENSE → LICENSE.md} +0 -0
  4. data/bin/opulent +0 -0
  5. data/lib/opulent.rb +10 -10
  6. data/lib/opulent/compiler.rb +15 -9
  7. data/lib/opulent/compiler/buffer.rb +123 -62
  8. data/lib/opulent/compiler/comment.rb +3 -4
  9. data/lib/opulent/compiler/control.rb +20 -26
  10. data/lib/opulent/compiler/define.rb +88 -36
  11. data/lib/opulent/compiler/doctype.rb +20 -22
  12. data/lib/opulent/compiler/eval.rb +23 -2
  13. data/lib/opulent/compiler/filter.rb +4 -5
  14. data/lib/opulent/compiler/node.rb +18 -12
  15. data/lib/opulent/compiler/root.rb +4 -5
  16. data/lib/opulent/compiler/text.rb +7 -2
  17. data/lib/opulent/compiler/yield.rb +2 -3
  18. data/lib/opulent/engine.rb +21 -20
  19. data/lib/opulent/exec.rb +21 -63
  20. data/lib/opulent/logger.rb +230 -3
  21. data/lib/opulent/parser.rb +14 -76
  22. data/lib/opulent/parser/comment.rb +45 -34
  23. data/lib/opulent/parser/control.rb +132 -111
  24. data/lib/opulent/parser/define.rb +15 -12
  25. data/lib/opulent/parser/doctype.rb +15 -15
  26. data/lib/opulent/parser/eval.rb +16 -6
  27. data/lib/opulent/parser/expression.rb +87 -84
  28. data/lib/opulent/parser/filter.rb +31 -25
  29. data/lib/opulent/parser/include.rb +38 -42
  30. data/lib/opulent/parser/node.rb +136 -118
  31. data/lib/opulent/parser/root.rb +24 -18
  32. data/lib/opulent/parser/text.rb +150 -123
  33. data/lib/opulent/parser/yield.rb +23 -23
  34. data/lib/opulent/settings.rb +70 -51
  35. data/lib/opulent/tokens.rb +17 -15
  36. data/lib/opulent/utils.rb +5 -4
  37. data/lib/opulent/version.rb +1 -1
  38. metadata +4 -43
  39. data/.libold/opulent.rb +0 -96
  40. data/.libold/opulent/context.rb +0 -80
  41. data/.libold/opulent/engine.rb +0 -88
  42. data/.libold/opulent/filter.rb +0 -101
  43. data/.libold/opulent/logger.rb +0 -67
  44. data/.libold/opulent/nodes.rb +0 -13
  45. data/.libold/opulent/nodes/block.rb +0 -29
  46. data/.libold/opulent/nodes/comment.rb +0 -35
  47. data/.libold/opulent/nodes/control.rb +0 -230
  48. data/.libold/opulent/nodes/define.rb +0 -42
  49. data/.libold/opulent/nodes/eval.rb +0 -41
  50. data/.libold/opulent/nodes/expression.rb +0 -28
  51. data/.libold/opulent/nodes/filter.rb +0 -70
  52. data/.libold/opulent/nodes/helper.rb +0 -69
  53. data/.libold/opulent/nodes/node.rb +0 -101
  54. data/.libold/opulent/nodes/root.rb +0 -62
  55. data/.libold/opulent/nodes/text.rb +0 -54
  56. data/.libold/opulent/nodes/theme.rb +0 -36
  57. data/.libold/opulent/parser.rb +0 -252
  58. data/.libold/opulent/parser/block.rb +0 -70
  59. data/.libold/opulent/parser/comment.rb +0 -32
  60. data/.libold/opulent/parser/control.rb +0 -83
  61. data/.libold/opulent/parser/define.rb +0 -39
  62. data/.libold/opulent/parser/eval.rb +0 -33
  63. data/.libold/opulent/parser/expression.rb +0 -350
  64. data/.libold/opulent/parser/filter.rb +0 -41
  65. data/.libold/opulent/parser/node.rb +0 -232
  66. data/.libold/opulent/parser/root.rb +0 -96
  67. data/.libold/opulent/parser/text.rb +0 -114
  68. data/.libold/opulent/parser/theme.rb +0 -36
  69. data/.libold/opulent/preprocessor.rb +0 -102
  70. data/.libold/opulent/runtime.rb +0 -144
  71. data/.libold/opulent/template.rb +0 -43
  72. data/.libold/opulent/tokens.rb +0 -276
  73. data/.libold/opulent/version.rb +0 -5
  74. data/.travis.yml +0 -4
  75. data/benchmark/benchmark.rb +0 -57
  76. data/benchmark/cases/node/node.haml +0 -7
  77. data/benchmark/cases/node/node.op +0 -7
  78. data/benchmark/cases/node/node.slim +0 -7
@@ -1,232 +0,0 @@
1
- # @Opulent
2
- module Opulent
3
- # @Parser
4
- module Parser
5
- # @node
6
- module Node
7
- # Check if we match an node node with its attributes and possibly
8
- # inline text
9
- #
10
- # node [ attributes ] Inline text
11
- #
12
- # @param parent [Node] Parent node to which we append the node
13
- #
14
- def node(parent, indent = nil)
15
- if (name = lookahead :identifier_lookahead)
16
- return nil if Tokens.keyword name
17
-
18
- # Get current line's indentation
19
- unless indent
20
- indent = accept_unstripped(:indent) || ""
21
- indent = indent.size
22
- end
23
-
24
- # Get a theme if set, or set append definitions to the default
25
- # element namespace
26
- if (theme_name = accept_unstripped(:theme_node))
27
- theme_name = theme_name.to_sym
28
- else
29
- theme_name = Engine::DEFAULT_THEME
30
- end
31
-
32
- # Accept either explicit node_name or implicit :div node_name
33
- # with shorthand attributes
34
- if (node_name = accept :identifier)
35
- shorthand = shorthand_attributes
36
- elsif (shorthand = shorthand_attributes)
37
- node_name = :div
38
- end
39
-
40
- # Get leading and trailing whitespace
41
- if accept_line_unstripped :leading_whitespace
42
- leading_whitespace = true
43
- if accept_line_unstripped :leading_trailing_whitespace
44
- trailing_whitespace = true
45
- end
46
- elsif accept_line_unstripped :trailing_whitespace
47
- trailing_whitespace = true
48
- end
49
-
50
- # Get wrapped node attributes
51
- atts = attributes(shorthand) || {}
52
-
53
- # Inherit attributes from definition
54
- extension = extend_attributes
55
-
56
- # Get unwrapped node attributes
57
- atts = attributes_assignments atts, false
58
-
59
- # Create a new node and set its extension
60
- _node = @create.node node_name.to_sym, atts, parent, indent, []
61
- _node.extension = extension
62
- _node.theme = theme_name
63
- _node.whitespace = [leading_whitespace, trailing_whitespace]
64
-
65
- if(accept_line :inline_child)
66
- if (child_node = node _node, indent + Engine[:indent])
67
- _node.push child_node
68
- else
69
- error :inline_child
70
- end
71
- end
72
-
73
- if(close = accept_line :self_enclosing)
74
- _node.self_enclosing = true
75
- unless close.strip.empty?
76
- undo close
77
- error :self_enclosing
78
- end
79
- end
80
-
81
- # Accept inline text or multiline text feed as first child
82
- if(text_node = text _node, " " * indent, false)
83
- text_node.indent += Engine[:indent]
84
- _node.push text_node unless text_node.nil?
85
- end
86
-
87
- return _node
88
- end
89
- end
90
-
91
- def shorthand_attributes(atts = {})
92
- find_shorthand = Proc.new do
93
- Engine[:shorthand].find do |key, value|
94
- if accept_unstripped :"shorthand@#{key}"
95
- key
96
- else
97
- false
98
- end
99
- end
100
- end
101
-
102
- while (attribute = find_shorthand[])
103
- key = attribute[0]
104
-
105
- # Get the attribute value and process it
106
- if (value = accept_unstripped(:identifier))
107
- value = @create.expression "\"#{value}\""
108
- elsif (value = (accept_unstripped(:exp_string) || paranthesis))
109
- value = @create.expression "#{value}"
110
- else
111
- error :shorthand
112
- end
113
-
114
- # IDs are unique, the rest of the attributes turn into arrays in
115
- # order to allow multiple values or identifiers
116
- if key == :id
117
- atts[key] = value
118
- else
119
- if atts[key].is_a? Array
120
- atts[key] << value
121
- elsif atts[key]
122
- atts[key] = [atts[key], value]
123
- else
124
- atts[key] = [value]
125
- end
126
- end
127
- end
128
-
129
- return atts
130
- end
131
-
132
- # Extend node attributes with hash from
133
- #
134
- # [hash]
135
- #
136
- def extend_attributes
137
- if (accept_unstripped :extend_attributes)
138
- bracket = accept_unstripped :brackets, :*
139
- extension = expression
140
- accept bracket.to_sym, :*
141
- return extension
142
- end
143
- end
144
-
145
- # Check if we match node attributes
146
- #
147
- # [ assignments ]
148
- #
149
- # @param as_parameters [Boolean] Accept or reject identifier nodes
150
- #
151
- def attributes(list)
152
- if (bracket = accept_unstripped :brackets)
153
- attributes_assignments list
154
- accept bracket.to_sym, :*
155
- end
156
-
157
- return list
158
- end
159
-
160
- # Check if we match an expression node or
161
- # a node node
162
- #
163
- # [ assignments ]
164
- #
165
- # @param parent [Hash] Parent to which we append nodes
166
- # @param as_parameters [Boolean] Accept or reject identifier nodes
167
- #
168
- def attributes_assignments(parent, wrapped = true)
169
- unless wrapped
170
- return parent if lookahead(:assignment_lookahead).nil?
171
- end
172
-
173
- if (argument = accept :identifier)
174
- argument = argument.to_sym
175
-
176
- if accept :assignment
177
- # Check if we have an attribute escape or not
178
- escaped = if accept_unstripped :assignment_unescaped
179
- false
180
- else
181
- true
182
- end
183
-
184
- # Get the argument value if we have an assignment
185
- if (value = expression(false, wrapped))
186
- value.escaped = escaped
187
-
188
- # Check if our argument already exists in the attributes list, and
189
- # if it does, check if it's an array. If it isn't, turn it into an
190
- # array literal, otherwise push the value into it. However, id
191
- # attributes do not get turned into arrays as they are supposed
192
- # to be unique
193
- if parent[argument] && argument != :id
194
- # Check if argument is already an array, otherwise create an
195
- # array in which we will add values
196
- if parent[argument].is_a? Array
197
- parent[argument] << value
198
- else
199
- new_parent = []
200
- new_parent.push parent[argument]
201
-
202
- parent[argument] = new_parent
203
- parent[argument] << value
204
- end
205
- else
206
- parent[argument] = value
207
- end
208
- else
209
- error :assignments_colon
210
- end
211
- else
212
- parent[argument] = @create.expression "true" unless parent[argument]
213
- end
214
-
215
- # If our attributes are wrapped, we allow method calls without
216
- # paranthesis, ruby style, therefore we need a terminator to signify
217
- # the expression end. If they are not wrapped (inline), we require
218
- # paranthesis and allow inline calls
219
- if wrapped && accept_line(:assignment_terminator)
220
- attributes_assignments parent, wrapped
221
- elsif lookahead(:assignment_lookahead)
222
- attributes_assignments parent, wrapped
223
- end
224
-
225
- return parent
226
- elsif !parent.empty?
227
- error :assignments_comma
228
- end
229
- end
230
- end
231
- end
232
- end
@@ -1,96 +0,0 @@
1
- # @Opulent
2
- module Opulent
3
- # @Parser
4
- module Parser
5
- # @Root
6
- module Root
7
- # Check if we match any root element. This is the starting point of the
8
- # parser and it checks for any elements which can be considered as root
9
- #
10
- # @param parent [Node] Parent element to append to
11
- # @param min_indent [Integer] Minimum indent to which the root responds
12
- #
13
- def root(parent)
14
- # Starting line of the root method
15
- starting_line = @current_line
16
-
17
- # Skip any whitespace at the beginning of the document
18
- accept_unstripped :newline
19
-
20
- if(element = define(parent))
21
- # Add definition elements to the root's knowledgebase and add elements
22
- # and evaluate elements to their parent elements
23
- if parent.is_a? Nodes::Root
24
- @root.themes[Engine::DEFAULT_THEME][element.name] = element
25
- elsif parent.is_a? Nodes::Theme
26
- @root.themes[parent.name][element.name] = element
27
- else
28
- error :definition
29
- end
30
- elsif(element = theme(parent))
31
- # Theme nodes cannot be nested, so we accept only a root parent and
32
- # we add the node in the themes hash and we allow reopening the theme
33
- # and adding more definitions to it, ruby style
34
- if parent.is_a? Nodes::Root
35
- @root.themes[element.name] ||= {}
36
- else
37
- error :theme
38
- end
39
- elsif (element = node(parent) ||
40
- text(parent) ||
41
- comment(parent) ||
42
- control(parent) ||
43
- evaluate(parent) ||
44
- filter_element(parent) ||
45
- html_text(parent))
46
- parent.push element
47
- elsif (element = block_yield(parent))
48
- # Handle yield node by searching for ther definition parent node
49
- yield_parent = element.parent
50
- begin
51
- until [Nodes::Define, Nodes::Root].include? yield_parent.class
52
- yield_parent = yield_parent.parent
53
- end
54
- rescue NoMethodError
55
- error :yield_parent
56
- end
57
-
58
- # Add the yield element to the parent and keep a pointer to the parent
59
- # for each yield element to avoid recursive searching as much as
60
- # possible
61
- parent.push element
62
- yield_parent.yields << parent
63
- elsif (element = block(parent))
64
- # Blocks will be set as separate entities for the parent element in
65
- # order to replace them fast in the definition yields
66
- parent.blocks[element.name] ||= []
67
- parent.blocks[element.name] << element
68
- end
69
-
70
- next_indent = lookahead(:indent_lookahead, false).length
71
- if element
72
- if next_indent > element.indent
73
- # If we have an indentation which is greater than the current one,
74
- # set the current element as a root element and add children to it
75
- root element
76
- elsif next_indent < element.indent
77
- # If we have an indentation which is smaller than the current one,
78
- # go through the current element's ancestors until we find one with
79
- # the same indentation as the next element
80
- next_parent = element.parent
81
- while next_parent.indent > next_indent
82
- next_parent = next_parent.parent
83
- end
84
- next_parent = next_parent.parent
85
-
86
- root next_parent
87
- else
88
- # If the indentation level stays the same, the parent element will
89
- # remain the current one
90
- root parent
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
@@ -1,114 +0,0 @@
1
- # @SugarCube
2
- module Opulent
3
- # @Parser
4
- module Parser
5
- # @Text
6
- module Text
7
- # Match one line or multiline, escaped or unescaped text
8
- #
9
- def text(parent, indent = nil, only_multiline = true)
10
- indent = indent || accept_unstripped(:indent) || ""
11
-
12
- # Try to see if we can match a multiline operator. If we can accept only
13
- # multiline, which is the case for filters, undo the operation.
14
- if accept_line :multiline
15
- multiline = true
16
- elsif only_multiline
17
- return undo indent unless lookahead :print_lookahead
18
- end
19
-
20
- indent = indent.size
21
-
22
- # Unescaped Print Eval
23
- if (text_feed = accept_unstripped :unescaped_print)
24
- text_node = @create.print(text_feed.strip, false, parent, indent)
25
- # Escaped Print Eval
26
- elsif (text_feed = accept_unstripped :escaped_print)
27
- text_node = @create.print(text_feed.strip, true, parent, indent)
28
- # Unescaped Text
29
- elsif (text_feed = accept_unstripped :unescaped_text)
30
- text_node = @create.text(text_feed.strip, false, parent, indent)
31
- # Escaped Text
32
- elsif (text_feed = accept_unstripped :escaped_text)
33
- text_node = @create.text(text_feed.strip, true, parent, indent)
34
- else
35
- # Undo by adding the found intentation back
36
- undo indent
37
- return nil
38
- end
39
-
40
-
41
- if text_node
42
- text_node
43
- if multiline
44
- text_node.value += accept_unstripped(:newline) || ""
45
- text_node.value += get_indented_lines(indent)
46
-
47
- text_node
48
- else
49
- accept_unstripped :newline
50
-
51
- text_node.value.strip!
52
- text_node.value = text_node.value[1..-1] if text_node.value[0] == '\\'
53
- text_node.value.size > 0 ? text_node : nil
54
- end
55
- else
56
- return nil
57
- end
58
- end
59
-
60
- # Match one line or multiline, escaped or unescaped text
61
- #
62
- def html_text(parent)
63
- indent = accept_unstripped(:indent) || ""
64
- indent_size = indent.size
65
-
66
- if (text_feed = accept_unstripped :html_text)
67
- text_node = @create.text(text_feed.strip, false, parent, indent_size)
68
- accept_unstripped :newline
69
- pp text_feed
70
- return text_node
71
- else
72
- return undo indent
73
- end
74
- end
75
-
76
- # Match a whitespace by preventing code trimming
77
- #
78
- def whitespace(required = false)
79
- accept_unstripped :whitespace, required
80
- end
81
-
82
- # Gather all the lines which have higher indentation than the one given as
83
- # parameter and put them into the buffer
84
- #
85
- # @param indentation [Fixnum] parent node strating indentation
86
- #
87
- def get_indented_lines(indent)
88
- buffer = ''
89
-
90
- # Get the next indentation after the parent line
91
- # and set it as primary indent
92
- first_indent = lookahead(:indent_lookahead, false).size
93
- next_indent = first_indent
94
-
95
- # While the indentation is smaller, add the line feed to our buffer
96
- while next_indent > indent
97
- # Get leading whitespace trimmed with first_indent's size
98
- next_line_indent = accept_unstripped(:indent)[first_indent..-1] || ""
99
- next_line_indent = next_line_indent.size
100
-
101
- # Add next line feed, prepend the indent and append the newline
102
- buffer += " " * next_line_indent if next_line_indent > 0
103
- buffer += accept_unstripped(:line_feed) || ""
104
- buffer += accept_unstripped(:newline) || ""
105
-
106
- # Get next indentation and repeat
107
- next_indent = lookahead(:indent_lookahead, false).size
108
- end
109
-
110
- buffer
111
- end
112
- end
113
- end
114
- end
@@ -1,36 +0,0 @@
1
- # @Opulent
2
- module Opulent
3
- # @Parser
4
- module Parser
5
- # @Define
6
- module Theme
7
- # Match a theme namespace node with its parameters and body
8
- #
9
- # theme node_name[ parameters ]
10
- # body nodes
11
- #
12
- # @param parent [Node] Parent node to which we append the definition
13
- #
14
- def theme(parent)
15
- if lookahead :theme_lookahead
16
- # Get current line's indentation
17
- indent = accept_unstripped(:indent) || ""
18
-
19
- if accept :theme
20
- # Get definition name
21
- theme_name = accept :theme_identifier, :*
22
-
23
- # Create a new node
24
- node = @create.theme theme_name.to_sym, parent, indent.size
25
-
26
- # Consume the newline from the end of the element
27
- error :theme unless accept_unstripped(:line_feed).strip.empty?
28
- accept_unstripped :newline
29
-
30
- return node
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end