ltdtemplate 0.1.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.
@@ -0,0 +1,135 @@
1
+ # LtdTemplate::Value::Namespace - Represents an LtdTemplate variable namespace
2
+ #
3
+ # @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
4
+ # @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
5
+ # @license MIT License
6
+
7
+ require 'ltdtemplate/value/array'
8
+
9
+ class LtdTemplate::Value::Namespace < LtdTemplate::Value::Array
10
+
11
+ attr_reader :method, :parameters, :parent, :root
12
+ attr_accessor :target
13
+
14
+ def initialize (template, method, parameters, parent = nil)
15
+ super template
16
+ @method, @parameters = method, parameters
17
+ @root = parent ? parent.root : self
18
+ @parent = parent
19
+ @target = nil
20
+ clear
21
+ end
22
+
23
+ #
24
+ # Clear values except for permanent namespace attributes.
25
+ #
26
+ def clear
27
+ super
28
+ @sarah.rnd['_'] = @parameters
29
+ @sarah.rnd['@'] = @root
30
+ @sarah.rnd['^'] = @parent if @parent
31
+ @sarah.rnd['$'] = self
32
+ self
33
+ end
34
+
35
+ #
36
+ # Search for the specified item in the current namespace or above.
37
+ #
38
+ def find_item (name)
39
+ namespace = self
40
+ while namespace
41
+ break if namespace.has_item? name
42
+ namespace = namespace.parent
43
+ end
44
+ namespace
45
+ end
46
+
47
+ #
48
+ # Template string-value for method
49
+ #
50
+ def method_string
51
+ @method_string ||= @template.factory :string, @method
52
+ end
53
+
54
+ def get_value (opts = {})
55
+ case opts[:method]
56
+ when 'array', '*' # anonymous array
57
+ opts[:parameters] ? opts[:parameters] :
58
+ @template.factory(:parameters)
59
+ when 'false' then @template.factory :boolean, false
60
+ when 'if' then do_if opts
61
+ when 'loop' then do_loop opts
62
+ when 'method' then method_string
63
+ when 'nil' then @template.factory :nil
64
+ when 'target' then @target || @template.factory(:nil)
65
+ when 'true' then @template.factory :boolean, true
66
+ when 'use' then do_use opts
67
+ when 'var' then do_add_names opts
68
+ else super
69
+ end
70
+ end
71
+
72
+ # Add new namespace names with nil or specific values
73
+ #
74
+ def do_add_names (opts)
75
+ params = opts[:parameters]
76
+ if params.positional.size
77
+ tnil = @template.factory :nil
78
+ params.positional.each { |item| set_item(item.to_native, tnil) }
79
+ end
80
+ if params.named.size
81
+ params.named.each { |item, val| set_item(item, val) }
82
+ end
83
+ @template.factory :nil
84
+ end
85
+
86
+ # Implement conditionals
87
+ def do_if (opts)
88
+ if params = opts[:parameters]
89
+ params.positional.each_slice(2) do |e1, e2|
90
+ e1 = e1.get_value :method => 'call'
91
+
92
+ #
93
+ # Return the "else" value, e1, in the absence of
94
+ # a condition/result value pair.
95
+ #
96
+ return e1 unless e2
97
+
98
+ # Return the e2 result if e1 evaluates to true
99
+ return e2.get_value(:method => 'call') if e1.to_boolean
100
+ end
101
+ end
102
+ @template.factory :nil
103
+ end
104
+
105
+ def do_loop (opts)
106
+ results = @template.factory(:array)
107
+ if params = opts[:parameters] and params.positional.size > 1
108
+ params = params.positional
109
+ while params[0].get_value(:method => 'call').to_boolean
110
+ @template.use :iterations
111
+ results.sarah.push params[1].get_value(:method => 'call')
112
+ break if params[2] and
113
+ !params[2].get_value(:method => 'call').to_boolean
114
+ end
115
+ end
116
+ results
117
+ end
118
+
119
+ def do_use (opts)
120
+ tpl = @template
121
+ if loader = tpl.options[:loader] and
122
+ params = opts[:parameters] and params.positional.size > 0
123
+ name = params.positional[0].get_value.to_text
124
+ if !tpl.used[name]
125
+ tpl.use :use
126
+ tpl.used[name] = true
127
+ result = loader.call(tpl, name)
128
+ tpl.parse_template(tpl.get_tokens result).get_value if
129
+ result.kind_of? String
130
+ end
131
+ end
132
+ tpl.factory :nil
133
+ end
134
+
135
+ end
@@ -0,0 +1,27 @@
1
+ # LtdTemplate::Value::Nil - Represents nil in an LtdTemplate
2
+ #
3
+ # @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
4
+ # @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
5
+ # @license MIT License
6
+
7
+ require 'ltdtemplate/code'
8
+
9
+ class LtdTemplate::Value::Nil < LtdTemplate::Code
10
+
11
+ # Use one shared instance per template.
12
+ def self.instance (template, *args)
13
+ template.factory_singletons[:nil] ||= self.new(template, *args)
14
+ end
15
+
16
+ def get_value (opts = {})
17
+ case opts[:method]
18
+ when 'type' then @template.factory :string, 'nil'
19
+ else do_method opts
20
+ end
21
+ end
22
+
23
+ def to_boolean; false; end
24
+ def to_native; ''; end
25
+ def to_text; ''; end
26
+
27
+ end
@@ -0,0 +1,93 @@
1
+ # LtdTemplate::Value::Number - Represents a number in an LtdTemplate
2
+ #
3
+ # @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
4
+ # @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
5
+ # @license MIT License
6
+
7
+ require 'ltdtemplate/code'
8
+
9
+ class LtdTemplate::Value::Number < LtdTemplate::Code
10
+
11
+ def initialize (template, value = 0)
12
+ super template
13
+ case value
14
+ when Numeric then @value = value
15
+ when String then @value = (value =~ /\./) ? value.to_f : value.to_i
16
+ end
17
+ end
18
+
19
+ def to_boolean; true; end
20
+ def to_native; @value; end
21
+ def to_text; @value.to_s; end
22
+
23
+ def get_value (opts = {})
24
+ case opts[:method]
25
+ when nil, 'call' then self
26
+ when 'abs' then (@value >= 0) ? self :
27
+ @template.factory(:number, -@value)
28
+ when 'ceil' then @template.factory :number, @value.ceil
29
+ when 'class' then @template.factory :string, 'Number'
30
+ when 'floor' then @template.factory :number, @value.floor
31
+ when 'flt', 'float' then @template.factory :number, @value.to_f
32
+ when 'int' then @template.factory :number, @value.to_i
33
+ when 'str', 'string' then @template.factory :number, @value.to_s
34
+ when 'type' then @template.factory :string, 'number'
35
+ when '+' then do_sequential(opts) { |a, b| a + b }
36
+ when '-' then do_subtract opts
37
+ when '*' then do_sequential(opts) { |a, b| a * b }
38
+ when '/' then do_sequential(opts) { |a, b| a / b }
39
+ when '%' then do_sequential(opts) { |a, b| a % b }
40
+ when '&' then do_sequential(opts) { |a, b| a & b }
41
+ when '|' then do_sequential(opts) { |a, b| a | b }
42
+ when '^' then do_sequential(opts) { |a, b| a ^ b }
43
+ when '<', '<=', '==', '!=', '>=', '>' then do_compare opts
44
+ else do_method opts, 'Number'
45
+ end
46
+ end
47
+
48
+ # Implement sequential operations (+, *, /, %, &, |, ^)
49
+ def do_sequential (opts = {}, &block)
50
+ if params = opts[:parameters]
51
+ @template.factory(:number,
52
+ params.positional.map { |tval| tval.to_native }.
53
+ select { |nval| nval.is_a? Numeric }.
54
+ inject(@value, &block))
55
+ else
56
+ @value
57
+ end
58
+ end
59
+
60
+ # Implement "-" method (subtraction/negation)
61
+ def do_subtract (opts)
62
+ sum = @value
63
+ params = params.positional if params = opts[:parameters]
64
+ if !params or params.size == 0
65
+ sum = -sum
66
+ else
67
+ params.each do |tval|
68
+ nval = tval.to_native
69
+ sum -= nval if nval.is_a? Numeric
70
+ end
71
+ end
72
+ @template.factory :number, sum
73
+ end
74
+
75
+ # Implement numeric comparison operators
76
+ def do_compare (opts)
77
+ diff = 0
78
+ if params = opts[:parameters] and params.positional.size > 0
79
+ diff = params.positional[0].to_native
80
+ diff = 0 unless diff.is_a? Numeric
81
+ end
82
+ diff = @value - diff
83
+ @template.factory :boolean, case opts[:method]
84
+ when '<' then diff < 0
85
+ when '<=' then diff <= 0
86
+ when '==' then diff == 0
87
+ when '!=' then diff != 0
88
+ when '>=' then diff >= 0
89
+ when '>' then diff > 0
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,121 @@
1
+ # LtdTemplate::Value::String - Represents a string in an LtdTemplate
2
+ #
3
+ # @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
4
+ # @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
5
+ # @license MIT License
6
+
7
+ require 'ltdtemplate/code'
8
+
9
+ class LtdTemplate::Value::String < LtdTemplate::Code
10
+
11
+ def initialize (template, value)
12
+ super template
13
+ template.use :string_total, value.length
14
+ @value = value
15
+ end
16
+
17
+ def to_boolean; true; end
18
+ def to_native; @value; end
19
+ def to_text; @value; end
20
+
21
+ def get_value (opts = {})
22
+ case opts[:method]
23
+ when nil, 'call', 'str', 'string' then self
24
+ when 'class' then @template.factory :string, 'String'
25
+ when 'flt', 'float' then @template.factory :number, @value.to_f
26
+ when 'int' then @template.factory :number, @value.to_i
27
+ when 'len', 'length' then @template.factory :number, @value.length
28
+ when 'rng', 'range', 'slc', 'slice' then do_range_slice opts
29
+ when 'type' then @template.factory :string, 'string'
30
+ when '+' then do_add opts
31
+ when '*' then do_multiply opts
32
+ when 'idx', 'index', 'ridx', 'rindex' then do_index opts
33
+ when '<', '<=', '==', '!=', '>=', '>' then do_compare opts
34
+ else do_method opts, 'String'
35
+ end
36
+ end
37
+
38
+ def do_add (opts)
39
+ combined = @value
40
+ if params = opts[:parameters]
41
+ params.positional.each do |tval|
42
+ part = tval.to_text
43
+ @template.using :string_length, (combined.length + part.length)
44
+ combined += part
45
+ end
46
+ end
47
+ @template.factory :string, combined
48
+ end
49
+
50
+ def do_multiply (opts)
51
+ str = ''
52
+ params = params.positional if params = opts[:parameters]
53
+ if params and params.size > 0
54
+ times = params[0].to_native
55
+ if times.is_a? Integer
56
+ str = @value
57
+ if times < 0
58
+ str = str.reverse
59
+ times = -times
60
+ end
61
+ @template.using :string_length, (str.length * times)
62
+ str = str * times
63
+ end
64
+ end
65
+ @template.factory :string, str
66
+ end
67
+
68
+ # Implement string comparison operators
69
+ def do_compare (opts)
70
+ if params = opts[:parameters] and params.positional.size > 0
71
+ diff = params.positional[0].to_text
72
+ else
73
+ diff = ''
74
+ end
75
+
76
+ diff = @value <=> diff
77
+ @template.factory :boolean, case opts[:method]
78
+ when '<' then diff < 0
79
+ when '<=' then diff <= 0
80
+ when '==' then diff == 0
81
+ when '!=' then diff != 0
82
+ when '>=' then diff >= 0
83
+ when '>' then diff > 0
84
+ end
85
+ end
86
+
87
+ # Index and rindex
88
+ # str.index(substring[, offset])
89
+ # str.rindex(substring[, offset]
90
+ def do_index (opts)
91
+ substr, offset = '', nil
92
+ params = params.positional if params = opts[:parameters]
93
+ substr = params[0].get_value.to_text if params and params.size > 0
94
+ offset = params[1].get_value.to_native if params and params.size > 1
95
+ case opts[:method][0]
96
+ when 'r'
97
+ offset = -1 unless offset.is_a? Integer
98
+ @template.factory :number, (@value.rindex(substr, offset) || -1)
99
+ else
100
+ offset = 0 unless offset.is_a? Integer
101
+ @template.factory :number, (@value.index(substr, offset) || -1)
102
+ end
103
+ end
104
+
105
+ # Range and slice:
106
+ # str.range([begin[, end]])
107
+ # str.slice([begin[, length]])
108
+ def do_range_slice (opts)
109
+ op1, op2 = 0, -1
110
+ params = params.positional if params = opts[:parameters]
111
+ op1 = params[0].get_value.to_native if params and params.size > 0
112
+ op2 = params[1].get_value.to_native if params and params.size > 1
113
+ if opts[:method][0] == 'r' or op2 < 0
114
+ str = @value[op1..op2]
115
+ else
116
+ str = @value[op1, op2]
117
+ end
118
+ @template.factory :string, (str || '')
119
+ end
120
+
121
+ end