opulent 1.5.5 → 1.6.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.
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,123 +1,150 @@
1
- # @Opulent
2
- module Opulent
3
- # @Parser
4
- class Parser
5
- # Match one line or multiline, escaped or unescaped text
6
- #
7
- # @param parent [Array] Parent node element
8
- # @param indent [Fixnum] Size of the current indentation
9
- # @param multiline_or_print [Boolean] Allow only multiline text or print
10
- #
11
- def text(parent, indent = nil, multiline_or_print = true)
12
- # Try to see if we can match a multiline operator. If we can accept_stripped only
13
- # multiline, which is the case for filters, undo the operation.
14
- if accept :multiline
15
- multiline = true
16
- elsif multiline_or_print
17
- return nil unless lookahead :print_lookahead
18
- end
19
-
20
- # Get text node type
21
- type = if accept(:print) then :print else :text end
22
-
23
- # Check if the text or print node is escaped or unescaped
24
- escaped = accept(:unescaped_value) ? false : true
25
-
26
- # Get text value
27
- value = accept :line_feed
28
- value = value[1..-1] if value[0] == '\\'
29
-
30
- # Create the text node using input data
31
- text_node = [:plain, type, {value: value.strip, escaped: escaped}, nil, indent]
32
-
33
- # If we have a multiline node, get all the text which has higher
34
- # indentation than our indentation node.
35
- if multiline
36
- text_node[@options][:value] += accept(:newline) || ""
37
- text_node[@options][:value] += get_indented_lines(indent)
38
- text_node[@options][:value].strip!
39
- elsif value.empty?
40
- # If our value is empty and we're not going to add any more lines to
41
- # our buffer, skip the node
42
- return nil
43
- end
44
-
45
- # Increase indentation if this is an inline text node
46
- text_node[@indent] += Settings[:indent] unless multiline_or_print
47
-
48
- # Add text node to the parent element
49
- parent[@children] << text_node
50
- end
51
-
52
- # Match one line or multiline, escaped or unescaped text
53
- #
54
- def html_text(parent, indent)
55
- if (text_feed = accept :html_text)
56
- text_node = [:plain, :text, {value: text_feed.strip, escaped: false}, nil, indent]
57
-
58
- parent[@children] << text_node
59
- end
60
- end
61
-
62
- # Match a whitespace by preventing code trimming
63
- #
64
- def whitespace(required = false)
65
- accept :whitespace, required
66
- end
67
-
68
- # Gather all the lines which have higher indentation than the one given as
69
- # parameter and put them into the buffer
70
- #
71
- # @param indentation [Fixnum] parent node strating indentation
72
- #
73
- def get_indented_lines(indent)
74
- buffer = ''
75
-
76
- # Gather multiple blank lines between lines of text
77
- blank_lines = Proc.new do
78
- while lookahead_next_line :line_whitespace
79
- @line = @code[(@i += 1)]
80
- @offset = 0
81
-
82
- buffer += accept :line_whitespace
83
- end
84
- end
85
-
86
- # Get blank lines until we match something
87
- blank_lines[]
88
-
89
- # Get the next indentation after the parent line
90
- # and set it as primary indent
91
- next_indent = first_indent = (lookahead_next_line(:indent).to_s || "").size
92
-
93
- # While the indentation is smaller, add the line feed to our buffer
94
- while next_indent > indent
95
- # Advance current line and reset offset
96
- @line = @code[(@i += 1)]
97
- @offset = 0
98
-
99
- # Get leading whitespace trimmed with first_indent's size
100
- next_line_indent = accept(:indent)[first_indent..-1] || ""
101
- next_line_indent = next_line_indent.size
102
-
103
- # Add next line feed, prepend the indent and append the newline
104
- buffer += " " * next_line_indent if next_line_indent > 0
105
- buffer += accept_stripped(:line_feed) || ""
106
- buffer += accept(:newline) || ""
107
-
108
- # Get blank lines until we match something
109
- blank_lines[]
110
-
111
- # Check the indentation on the following line. When we reach EOF,
112
- # set the indentation to 0 and cause the loop to stop
113
- if (next_indent = lookahead_next_line :indent)
114
- next_indent = next_indent[0].size
115
- else
116
- next_indent = 0
117
- end
118
- end
119
-
120
- return buffer
121
- end
122
- end
123
- end
1
+ # @Opulent
2
+ module Opulent
3
+ # @Parser
4
+ class Parser
5
+ # Match one line or multiline, escaped or unescaped text
6
+ #
7
+ # @param parent [Array] Parent node element
8
+ # @param indent [Fixnum] Size of the current indentation
9
+ # @param multiline_or_print [Boolean] Allow only multiline text or print
10
+ #
11
+ def text(parent, indent = nil, multiline_or_print = true)
12
+ # Try to see if we can match a multiline operator. If we can accept_stripped only
13
+ # multiline, which is the case for filters, undo the operation.
14
+ if accept :multiline
15
+ multiline = true
16
+ elsif multiline_or_print
17
+ return nil unless lookahead :print_lookahead
18
+ end
19
+
20
+ # Get text node type
21
+ type = accept(:print) ? :print : :text
22
+
23
+ # Check if the text or print node is escaped or unescaped
24
+ escaped = accept(:unescaped_value) ? false : true
25
+
26
+ # Get leading whitespace
27
+ leading_whitespace = accept(:leading_whitespace)
28
+
29
+ # Get trailing whitespace
30
+ trailing_whitespace = accept(:trailing_whitespace)
31
+
32
+ # Get text value
33
+ value = accept :line_feed
34
+ value = value[1..-1] if value[0] == '\\'
35
+
36
+ # Create the text node using input data
37
+ text_node = [
38
+ :plain,
39
+ type,
40
+ {
41
+ value: value.strip,
42
+ escaped: escaped,
43
+ leading_whitespace: leading_whitespace,
44
+ trailing_whitespace: trailing_whitespace
45
+ },
46
+ nil,
47
+ indent
48
+ ]
49
+
50
+ # If we have a multiline node, get all the text which has higher
51
+ # indentation than our indentation node.
52
+ if multiline
53
+ text_node[@options][:value] += accept(:newline) || ''
54
+ text_node[@options][:value] += get_indented_lines(indent)
55
+ text_node[@options][:value].strip!
56
+ elsif value.empty?
57
+ # If our value is empty and we're not going to add any more lines to
58
+ # our buffer, skip the node
59
+ return nil
60
+ end
61
+
62
+ # Increase indentation if this is an inline text node
63
+ text_node[@indent] += @settings[:indent] unless multiline_or_print
64
+
65
+ # Add text node to the parent element
66
+ parent[@children] << text_node
67
+ end
68
+
69
+ # Match one line or multiline, escaped or unescaped text
70
+ #
71
+ def html_text(parent, indent)
72
+ return unless (text_feed = accept :html_text)
73
+
74
+ text_node = [
75
+ :plain,
76
+ :text,
77
+ {
78
+ value: text_feed.strip,
79
+ escaped: false
80
+ },
81
+ nil,
82
+ indent
83
+ ]
84
+
85
+ parent[@children] << text_node
86
+ end
87
+
88
+ # Match a whitespace by preventing code trimming
89
+ #
90
+ def whitespace(required = false)
91
+ accept :whitespace, required
92
+ end
93
+
94
+ # Gather all the lines which have higher indentation than the one given as
95
+ # parameter and put them into the buffer
96
+ #
97
+ # @param indentation [Fixnum] parent node strating indentation
98
+ #
99
+ def get_indented_lines(indent)
100
+ buffer = ''
101
+
102
+ # Gather multiple blank lines between lines of text
103
+ blank_lines = proc do
104
+ while lookahead_next_line :line_whitespace
105
+ @line = @code[(@i += 1)]
106
+ @offset = 0
107
+
108
+ buffer += accept :line_whitespace
109
+ end
110
+ end
111
+
112
+ # Get blank lines until we match something
113
+ blank_lines[]
114
+
115
+ # Get the next indentation after the parent line
116
+ # and set it as primary indent
117
+ first_indent = (lookahead_next_line(:indent).to_s || '').size
118
+ next_indent = first_indent
119
+
120
+ # While the indentation is smaller, add the line feed to our buffer
121
+ while next_indent > indent
122
+ # Advance current line and reset offset
123
+ @line = @code[(@i += 1)]
124
+ @offset = 0
125
+
126
+ # Get leading whitespace trimmed with first_indent's size
127
+ next_line_indent = accept(:indent)[first_indent..-1] || ''
128
+ next_line_indent = next_line_indent.size
129
+
130
+ # Add next line feed, prepend the indent and append the newline
131
+ buffer += ' ' * next_line_indent if next_line_indent > 0
132
+ buffer += accept_stripped(:line_feed) || ''
133
+ buffer += accept(:newline) || ''
134
+
135
+ # Get blank lines until we match something
136
+ blank_lines[]
137
+
138
+ # Check the indentation on the following line. When we reach EOF,
139
+ # set the indentation to 0 and cause the loop to stop
140
+ if (next_indent = lookahead_next_line :indent)
141
+ next_indent = next_indent[0].size
142
+ else
143
+ next_indent = 0
144
+ end
145
+ end
146
+
147
+ buffer
148
+ end
149
+ end
150
+ end
@@ -1,23 +1,23 @@
1
- # @Opulent
2
- module Opulent
3
- # @Parser
4
- class Parser
5
- # Match a yield with a explicit or implicit target
6
- #
7
- # yield target
8
- #
9
- # @param parent [Node] Parent node to which we append the definition
10
- #
11
- def block_yield(parent, indent)
12
- if accept :yield
13
- # Consume the newline from the end of the element
14
- error :yield unless accept(:line_feed).strip.empty?
15
-
16
- # Create a new node
17
- yield_node = [:yield, nil, {}, [], indent]
18
-
19
- parent[@children] << yield_node
20
- end
21
- end
22
- end
23
- end
1
+ # @Opulent
2
+ module Opulent
3
+ # @Parser
4
+ class Parser
5
+ # Match a yield with a explicit or implicit target
6
+ #
7
+ # yield target
8
+ #
9
+ # @param parent [Node] Parent node to which we append the definition
10
+ #
11
+ def block_yield(parent, indent)
12
+ return unless accept :yield
13
+
14
+ # Consume the newline from the end of the element
15
+ error :yield unless accept(:line_feed).strip.empty?
16
+
17
+ # Create a new node
18
+ yield_node = [:yield, nil, {}, [], indent]
19
+
20
+ parent[@children] << yield_node
21
+ end
22
+ end
23
+ end
@@ -1,7 +1,7 @@
1
1
  # @Opulent
2
2
  module Opulent
3
3
  # @Settings
4
- module Settings
4
+ class Settings
5
5
  # Set buffer variable name
6
6
  BUFFER = :@_opulent_buffer
7
7
 
@@ -9,76 +9,95 @@ module Opulent
9
9
  FILE_EXTENSION = '.op'
10
10
 
11
11
  # Default yield target which is used for child block replacements
12
- DefaultEachKey = :key
12
+ DEFAULT_EACH_KEY = :key
13
13
 
14
14
  # Default yield target which is used for child block replacements
15
- DefaultEachValue = :value
15
+ DEFAULT_EACH_VALUE = :value
16
16
 
17
17
  # List of self enclosing node elements
18
- SelfEnclosing = %i(img link input meta br hr area base col command embed keygen param source track wbr)
18
+ SELF_ENCLOSING = %i(
19
+ img link input meta br hr area base col command embed keygen param source
20
+ track wbr
21
+ )
19
22
 
20
23
  # List of inline node parents which can be either inline or have complex
21
24
  # structures inside of them, such as anchor tags
22
- MultiNode = %i(a)
25
+ MULTI_NODE = %i(a)
23
26
 
24
27
  # List of inline node names
25
- InlineNode = %i(text a span strong em br i b small label sub sup abbr var code kbd)
28
+ INLINE_NODE = %i(
29
+ text a span strong em br i b small label sub sup abbr var code kbd
30
+ )
26
31
 
27
32
  # Check whether text should or shouldn't be evaluated
28
- InterpolationCheck = /(?<!\\)\#\{.*\}/
33
+ INTERPOLATION_CHECK = /(?<!\\)\#\{.*\}/
29
34
 
30
35
  # Check if the attribute value is a bare string
31
- EvaluationCheck = /\A(("((?:[^"\\]|\\.)*?)")|('(?:[^'\\]|\\.)*?')|true|false|nil)\Z/
36
+ EVALUATION_CHECK = /\A(("((?:[^"\\]|\\.)*?)")|('(?:[^'\\]|\\.)*?')|true|false|nil)\Z/
37
+
38
+ # Check to see if we need to insert an end block for the current evaluation
39
+ # control do || .* end
40
+ END_INSERTION = /\A(if|begin|unless|else|elsif|when|rescue|ensure)\b|\bdo\s*(\|[^\|]*\|)?\s*$/
41
+ END_REMOVAL = /\A(else|elsif|when|rescue|ensure)/
42
+ END_EXPLICIT = /\A(end)/
32
43
 
33
44
  # Shorthand attribute associations
34
- Shorthand = {
35
- :'.' => :class,
36
- :'#' => :id,
37
- :'&' => :name
45
+ SHORTHAND = {
46
+ '.': :class,
47
+ '#': :id,
48
+ '&': :name
38
49
  }
39
50
 
40
- # @Singleton
41
- class << self
42
- # Opulent runtime options
43
- Defaults = {
44
- #pretty: true, # At the moment, code cannot be uglified
45
- #dependency_manager: true, # Soon to be implemented
46
- indent: 2,
47
- layouts: false,
48
- pretty: false, # Under work
49
- default_layout: :'views/layouts/application'
50
- }
51
-
52
- # Set defaults as initial options
53
- @@options = Defaults
54
-
55
- # Get an option at runtime
56
- #
57
- # @param name [Symbol] Identifier for the option
58
- #
59
- def [](name)
60
- @@options[name]
61
- end
51
+ # Opulent runtime settings
52
+ DEFAULTS = {
53
+ # dependency_manager: true, # Soon to be implemented
54
+ indent: 2,
55
+ layouts: false,
56
+ pretty: false,
57
+ default_layout: :'views/layouts/application'
58
+ }
62
59
 
63
- # Set a new option at runtime
64
- #
65
- # @param name [Symbol] Identifier for the option
66
- # @param value Option value to be set
67
- #
68
- def []=(name, value)
69
- @@options[name] = value
70
- end
60
+ # Set defaults as initial settings
61
+ #
62
+ def initialize
63
+ @settings = DEFAULTS
64
+ end
65
+
66
+ # Get an option at runtime
67
+ #
68
+ # @param name [Symbol] Identifier for the option
69
+ #
70
+ def [](name)
71
+ @settings[name]
72
+ end
73
+
74
+ # Set a new option at runtime
75
+ #
76
+ # @param name [Symbol] Identifier for the option
77
+ # @param value Option value to be set
78
+ #
79
+ def []=(name, value)
80
+ @settings[name] = value
81
+ end
82
+
83
+ # Remove an option at runtime
84
+ #
85
+ # @param name [Symbol] Identifier for the option
86
+ # @param value Option value to be set
87
+ #
88
+ def delete(name)
89
+ @settings.delete name
90
+ end
71
91
 
72
- # Update the engine options with the required option changes
73
- #
74
- # @param opts [Hash] Option extension hash
75
- #
76
- def update_settings(opts)
77
- @@options = Defaults
92
+ # Update the engine settings with the required option changes
93
+ #
94
+ # @param opts [Hash] Option extension hash
95
+ #
96
+ def update_settings(opts)
97
+ @settings = DEFAULTS
78
98
 
79
- opts.each do |key, value|
80
- @@options[key] = value
81
- end
99
+ opts.each do |key, value|
100
+ @settings[key] = value
82
101
  end
83
102
  end
84
103
  end