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.
- data/HISTORY.txt +15 -0
- data/TEMPLATE_MANUAL.html +838 -0
- data/lib/ltdtemplate/code/call.rb +46 -0
- data/lib/ltdtemplate/code/code_block.rb +30 -0
- data/lib/ltdtemplate/code/parameters.rb +40 -0
- data/lib/ltdtemplate/code/subscript.rb +81 -0
- data/lib/ltdtemplate/code/variable.rb +77 -0
- data/lib/ltdtemplate/code.rb +102 -0
- data/lib/ltdtemplate/value/array.rb +168 -0
- data/lib/ltdtemplate/value/boolean.rb +79 -0
- data/lib/ltdtemplate/value/code_block.rb +40 -0
- data/lib/ltdtemplate/value/namespace.rb +135 -0
- data/lib/ltdtemplate/value/nil.rb +27 -0
- data/lib/ltdtemplate/value/number.rb +93 -0
- data/lib/ltdtemplate/value/string.rb +121 -0
- data/lib/ltdtemplate.rb +451 -0
- data/ltdtemplate.gemspec +16 -0
- data/test/00class.rb +20 -0
- data/test/01instance.rb +30 -0
- data/test/02tpl_literal.rb +61 -0
- data/test/03tpl_singletons.rb +48 -0
- data/test/04number.rb +36 -0
- data/test/05string.rb +30 -0
- data/test/06array.rb +34 -0
- metadata +94 -0
@@ -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
|