general 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # General
2
+
3
+ ## Overview
4
+
5
+ General is a simple templating system in ruby that allows you to create templates from both pure strings and files (with the extension .general), as well as create new strings and files with these created objects.
6
+
7
+ ## General Templates
8
+
9
+ ### Basic Templates
10
+
11
+ A general template consists of regular text along with placeholders, which are defined as follows: `@(-name-)`. You can also specify default text as well like so: `@(-name-: -default text-)`.
12
+
13
+ Here's an exmple of a general template text: `"Hello, I am @(name: Gordon Ramsay) and I like @(food: cat food)!"`
14
+
15
+ To import all classes in the library, type `require 'general'`. You can then create a general template from a string within your ruby code using the GTemplate object:
16
+
17
+ ```ruby
18
+ template = General::GTemplate.new "Hello, I am @(name: Gordon Ramsay) and I like @(food: cat food)!"
19
+ ```
20
+
21
+ To generate a string from the template, use the "apply" method and add your data as named arguments.
22
+
23
+ ```ruby
24
+ string = template.apply name: "Joe", food: "Joe's Schmoes"
25
+
26
+ # string now equals "Hello, I am Joe and I like Joe's Schmoes"
27
+ ```
28
+
29
+ If you don't specify a value for a particular placeholder, it will take on it's default value.
30
+
31
+ ```ruby
32
+ string = template.apply food: "Joe's Schmoes"
33
+
34
+ # string now equals "Hello, I am Gordon Ramsay and I like Joe's Schmoes"
35
+ ```
36
+
37
+ If you have an array of data, you can use `apply_all` to apply the template to each individual element separately.
38
+
39
+ ```ruby
40
+ array = template.apply_all [{name: "Joe", food: "Joe Schmoes"}, {name: "Jane", food: "Jane's Danes"}, {name: "Denny", food: "Denny's Fennies"}]
41
+
42
+ #array now has these elements:
43
+ # - Hello, I am Joe and I like Joe's Schmoes
44
+ # - Hello, I am Jane and I like Jane's Danes
45
+ # - Hello, I am Denny and I like Denny's Fennies
46
+ ```
47
+
48
+ ### Placeholder Operations
49
+
50
+ You can also specify operations to be performed on values passed to placeholders, akin to AngularJS's filters. For example: `@(name -> capitalize)` will capitalize whatever name is inputted before applying it to the text.
51
+
52
+ The current placeholder operations are:
53
+
54
+ | Operation | Description |
55
+ |:-----------|:--------------------------------------------------------|
56
+ | capitalize | Capitalizes the first letter of each word in a string |
57
+ | uppercase | Makes every letter in a string uppercase |
58
+ | lowercase | Makes every letter in a string lowercase |
59
+ | dollars | Formats an integer money amount (in cents) to dollars |
60
+ | time | Formats an integer time (in seconds) to HH:MM:SS format |
61
+
62
+ ### Array Templates
63
+
64
+ You can also make array templates within templates, which will format each value in an array of data according to a general template
65
+
66
+ A general array template is as follows: `@[-name-] -general template for each value- @[]`. You can also specify the delimeter, which will be appended to the end of each element. The delimeter should be added in the end tag, like so: `@[-name-] -general template for each value- @[-delimeter-]`. If no delimeter is given, the default is a space. The start and end tags are invariant with atleast 1 whitespace or newline. So you can also define the template like such:
67
+
68
+ ```
69
+ @[-name-]
70
+ -general template for each value-
71
+ @[-delimeter-]
72
+ ```
73
+
74
+ An example of an array template:
75
+
76
+ ```ruby
77
+ template = General::GTemplate.new \
78
+ "List of Film Crew:
79
+ @[crew]
80
+ @(name): @(role)
81
+ @[\n]"
82
+ ```
83
+
84
+ You can now specify an array of values for "crew" in template, and it will format the data accordingly:
85
+
86
+ ```ruby
87
+ string = template.apply crew: [
88
+ {name: "Chris Nolan", role: "Director"},
89
+ {name: "Wally Pfister", role: "Director of Photography"},
90
+ {name: "Christian Bale", role: "Bruce Wayne/Batman"},
91
+ {name: "Michael Caine", role: "Alfred Pennyworth"}
92
+ ]
93
+
94
+ # string now equals:
95
+ # "List of Film Crew:
96
+ # Chris Nolan: Director
97
+ # Wally Pfister: Director of Photography
98
+ # Christian Bale: Bruce Wayne/Batman
99
+ # Michael Caine: Alfred Pennyworth"
100
+ ```
101
+
102
+ ## General IO
103
+
104
+ You can also write to files using io GIO, a general template capable of writing to files. You can create a GIO like a GTemplate:
105
+
106
+ ```ruby
107
+ gio = General::GIO.new "Hello, I am @(name: Gordon Ramsay) and I like @(food: cat food)!"
108
+ ```
109
+
110
+ You can also load a GIO from a file. For example, here's how you create a template file from the file "example.txt.general"
111
+
112
+ ```ruby
113
+ gio = General::GFile.load "example.txt.general"
114
+ ```
115
+
116
+ To write to a file, simply call the write method, pass in the file and the data to apply (like in GTemplate#apply):
117
+
118
+ ```ruby
119
+ gio.write file, name: "Joe", food: "Joe's Schmoes"
120
+ ```
121
+
122
+ Where `file` is the file you are writing to. You can also pass the name of the file to write to as well:
123
+
124
+ ```ruby
125
+ gio.write "example.txt", name: "Joe", food: "Joe's Schmoes"
126
+ ```
127
+
128
+ To get the original source filename of the GIO, just call `source`
129
+
130
+ ```ruby
131
+ gio.source # == "example.txt.general"
132
+ ```
133
+
134
+ -------------------------------------------------------------------------------------------------------------------------------------
135
+ Anshul Kharbanda
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ =begin
2
+
3
+ Program: Roject
4
+
5
+ Roject is a programming project manager written in Ruby.
6
+ With Roject, you can create and edit projects based on templates
7
+ using simple commands without a heavy IDE.
8
+
9
+ Author: Anshul Kharbanda
10
+ Created: 7 - 8 - 2016
11
+
12
+ =end
13
+
14
+ # Required libraries
15
+ require "rspec/core/rake_task"
16
+ require "rubygems/tasks"
17
+ require "fileutils"
18
+
19
+ # Directories
20
+ SPECDIR = "spec"
21
+
22
+ # Default Task
23
+ task :default => :spec
24
+
25
+ # RSpec Tasks
26
+ RSpec::Core::RakeTask.new do |task|
27
+ task.pattern = "#{SPECDIR}/*_spec.rb"
28
+ task.rspec_opts = "--format documentation --color"
29
+ end
30
+
31
+ # Gem Tasks
32
+ Gem::Tasks.new
33
+
34
+ # Git Tasks
35
+ namespace :git do
36
+ desc "Push changes to remote"
37
+ task :push, [:message] => :commit do
38
+ sh "git push origin master"
39
+ end
40
+
41
+ desc "Commit changes"
42
+ task :commit, [:message] do |task, args|
43
+ sh "git add --all"
44
+ sh "git commit -m #{args[:message].inspect}"
45
+ end
46
+
47
+ desc "Soft git reset"
48
+ task :reset do sh "git reset" end
49
+
50
+ desc "Hard git reset"
51
+ task :reset_hard do sh "git reset --hard HEAD" end
52
+ end
@@ -0,0 +1,11 @@
1
+ @@include sample
2
+
3
+ @if(drives: true)
4
+
5
+ @(name) drove to the store to get some @(food).
6
+
7
+ @else
8
+
9
+ @(name) walked thirty blocks uphil to the store to get some @(food)
10
+
11
+ @end
data/exp/out.txt ADDED
@@ -0,0 +1 @@
1
+ There once was a chef name Joe, and he loved eating Joe's Schmoes. He went to Kentucky.
@@ -0,0 +1 @@
1
+ There once was a chef name @(name: gordon ramsay -> capitalize all), and he loved eating @(food: carrots). He went to @(place -> capitalize).
data/lib/gdothash.rb ADDED
@@ -0,0 +1,106 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # General is a templating system in ruby
18
+ #
19
+ # Author: Anshul Kharbanda
20
+ # Created: 3 - 4 - 2016
21
+ module General
22
+ # Wrapper for hash objects which implements dot notation
23
+ #
24
+ # Author: Anshul Kharbanda
25
+ # Created: 9 - 27 - 2016
26
+ class GDotHash
27
+ # Initializes the given GDotHash with the given hash
28
+ #
29
+ # Parameter: hash - the hash being manipulated
30
+ def initialize(hash={}); @hash = hash; end
31
+
32
+ # Returns the string representation of the hash
33
+ #
34
+ # Return: the string representation of the hash
35
+ def to_s; @hash.to_s; end
36
+
37
+ # Returns true if the GDotHash contains the given key
38
+ #
39
+ # Parameter: key - the key to check
40
+ #
41
+ # Return: true if the GDotHash contains the given key
42
+ def has_key? key
43
+ # Split keys
44
+ subkeys = key.to_s.split(".").collect(&:to_sym)
45
+
46
+ # Check each subkey
47
+ sub = @hash
48
+ subkeys.each do |subkey|
49
+ # Return false if subhash doesn't contain key
50
+ # Else continue
51
+ if sub.is_a?(Hash) && sub.has_key?(subkey)
52
+ sub = sub[subkey]
53
+ else
54
+ return false
55
+ end
56
+ end
57
+
58
+ # Return true if passed
59
+ return true
60
+ end
61
+
62
+ # Gets the value at the given key
63
+ #
64
+ # Parameter: key - the key to return
65
+ #
66
+ # Return: the value at the given key
67
+ def [] key
68
+ # Split keys
69
+ subkeys = key.to_s.split(".").collect(&:to_sym)
70
+
71
+ # Travel down to value
72
+ get = @hash
73
+ subkeys.each do |subkey|
74
+ if get.is_a?(Hash) && get.has_key?(subkey)
75
+ get = get[subkey]
76
+ else
77
+ raise ArgumentError, "key is not defined in hash: #{key}"
78
+ end
79
+ end
80
+
81
+ # Return value
82
+ return get
83
+ end
84
+
85
+ # Sets the given key to the given value
86
+ #
87
+ # Parameter: key - the key to set
88
+ # Parameter: value - the value to set
89
+ def []= key, value
90
+ # Split subkeys
91
+ subkeys = key.to_s.split(".").collect(&:to_sym)
92
+
93
+ # Generate structure of new data
94
+ new_data = Hash.new
95
+ sub = new_data
96
+ subkeys[0...-1].each do |subkey|
97
+ sub[subkey] = Hash.new
98
+ sub = sub[subkey]
99
+ end
100
+ sub[subkeys[-1]] = value
101
+
102
+ # Merge hash with new data
103
+ @hash.merge! new_data
104
+ end
105
+ end
106
+ end
data/lib/general.rb CHANGED
@@ -14,6 +14,6 @@
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
- require_relative "gtemplate"
18
- require_relative "gtimeformat"
19
- require_relative "gio"
17
+ require_relative "template/gtemplate"
18
+ require_relative "template/gtimeformat"
19
+ require_relative "template/gio"
data/lib/goperations.rb CHANGED
@@ -14,6 +14,8 @@
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
+ require_relative "templates/gtimeformat"
18
+
17
19
  # General is a templating system in ruby
18
20
  #
19
21
  # Author: Anshul Kharbanda
@@ -24,6 +26,15 @@ module General
24
26
  # Author: Anshul Kharbanda
25
27
  # Created: 6 - 3 - 2016
26
28
  module GOperations
29
+ # The money types used by the money operation
30
+ MONEY_TYPES = {
31
+ "USD" => "$",
32
+ "EUR" => "€"
33
+ }
34
+
35
+ # The default time format
36
+ DEFAULT_TIME = "@I:@MM:@SS @A"
37
+
27
38
  #-----------------------------------STRING OPERATIONS------------------------------------
28
39
 
29
40
  # Capitalizes every word in the string
@@ -31,8 +42,13 @@ module General
31
42
  # Parameter: string - the string being capitalized
32
43
  #
33
44
  # Return: the capitalized string
34
- def self.capitalize string
35
- return string.split(' ').collect(&:capitalize).join(' ')
45
+ def self.capitalize string, what="first"
46
+ assert_type string, String
47
+ case what
48
+ when "all" then string.split(' ').collect(&:capitalize).join(' ')
49
+ when "first" then string.capitalize
50
+ else raise TypeError.new "Undefined second argument for operation capitalize: #{what}"
51
+ end
36
52
  end
37
53
 
38
54
  # Converts every letter in the string to uppercase
@@ -40,8 +56,9 @@ module General
40
56
  # Parameter: string - the string being uppercased
41
57
  #
42
58
  # Return: the uppercased string
43
- def self.uppercase string
44
- return string.upcase
59
+ def self.uppercase(string)
60
+ assert_type string, String
61
+ string.upcase
45
62
  end
46
63
 
47
64
  # Converts every letter in the string to lowercase
@@ -49,47 +66,51 @@ module General
49
66
  # Parameter: string - the string being lowercased
50
67
  #
51
68
  # Return: the lowercased string
52
- def self.lowercase string
53
- return string.downcase
69
+ def self.lowercase(string)
70
+ assert_type string, String
71
+ string.downcase
54
72
  end
55
73
 
56
74
  #-----------------------------------INTEGER OPERATIONS------------------------------------
57
75
 
58
- # Returns the integer monetary value (in cents) formatted to USD
76
+ # Returns the integer monetary value formatted to the given money type
59
77
  #
60
- # Parameter: integer - the integer being formatted (representing the amount in cents)
78
+ # Parameter: integer - the monetary amount being formatted
79
+ # Parameter: type - the type of money (defaults to USD)
61
80
  #
62
- # Return: the formatted USD amount
63
- def self.dollars integer
64
- if integer < 0
65
- return "-$" + (integer * -0.01).to_s
81
+ # Return: the formatted money amount
82
+ def self.money integer, type="USD"
83
+ assert_type integer, Integer
84
+ if MONEY_TYPES[type]
85
+ (integer < 0 ? "-" : "") + MONEY_TYPES[type] + (integer * 0.01).abs.to_s
66
86
  else
67
- return '$' + (integer * 0.01).to_s
87
+ raise TypeError.new("Money type: #{type} is not supported!")
68
88
  end
69
89
  end
70
90
 
71
- # Returns the integer time value (in seconds) formatted to I:MM:SS A
91
+ # Returns the integer time value (in seconds) formatted with the given formatter
72
92
  #
73
93
  # Parameter: integer - the integer being formatted (representing the time in seconds)
94
+ # Parameter: format - the format being used (defaults to DEFAULT_TIME)
74
95
  #
75
- # Return: the formatted I:MM:SS A
76
- def self.time integer
77
- return format_time "I:MM:SS A", integer
96
+ # Return: the time formatted with the given formatter
97
+ def self.time integer, format=DEFAULT_TIME
98
+ assert_type integer, Integer
99
+ General::GTimeFormat.new(format).apply(integer)
78
100
  end
79
101
 
80
102
  private
81
103
 
82
- def self.format_time formatter, value
83
- return formatter
84
- .sub(/II/, (value / 3600 % 12 + 1).to_s.rjust(2, '0'))
85
- .sub(/HH/, (value / 3600).to_s.rjust(2, '0'))
86
- .sub(/MM/, (value % 3600 / 60).to_s.rjust(2, '0'))
87
- .sub(/SS/, (value % 3600 % 60).to_s.rjust(2, '0'))
88
- .sub(/I/, (value / 3600 % 12 + 1).to_s)
89
- .sub(/H/, (value / 3600).to_s)
90
- .sub(/M/, (value % 3600 / 60).to_s)
91
- .sub(/S/, (value % 3600 % 60).to_s)
92
- .sub(/A/, value / 3600 > 12 ? 'PM' : 'AM')
104
+ # Raises TypeError if the given value is not one of the given types
105
+ #
106
+ # Parameter: value - the value to check
107
+ # Parameter: types - the types to check for
108
+ #
109
+ # Raises: TypeError - if the given value is not one of the given types
110
+ def self.assert_type value, *types
111
+ unless types.any? {|type| value.is_a? type}
112
+ raise TypeError.new "Unexpected value type #{value.class.name}. Expected #{types.collect(&:name).join(",")}"
113
+ end
93
114
  end
94
115
  end
95
116
  end
@@ -0,0 +1,43 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # General is a templating system in ruby
18
+ #
19
+ # Author: Anshul Kharbanda
20
+ # Created: 3 - 4 - 2016
21
+ module General
22
+ # A unit of the GTemplate. Returns a string based on an argument hash
23
+ # When GTemplate is applied
24
+ #
25
+ # Author: Anshul Kharbanda
26
+ # Created: 7 - 29 - 2016
27
+ class GPartial
28
+ protected
29
+
30
+ # Regular expression that matches placeholder names
31
+ NAME = /(?<name>[a-zA-Z]\w*(\.[a-zA-Z]\w*)*)/
32
+
33
+ public
34
+
35
+ # Get name
36
+ attr :name
37
+
38
+ # Initializes the GPartial with the given object
39
+ #
40
+ # Parameter: obj - the object containing information for the partial
41
+ def initialize(obj); @name = obj[:name].to_sym; end
42
+ end
43
+ end
@@ -0,0 +1,156 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "gpartial"
18
+ require_relative "../goperations"
19
+
20
+ # General is a templating system in ruby
21
+ #
22
+ # Author: Anshul Kharbanda
23
+ # Created: 3 - 4 - 2016
24
+ module General
25
+ # Represents a placeholder partial in a GTemplate
26
+ #
27
+ # Author: Anshul Kharbanda
28
+ # Created: 7 - 1 - 2016
29
+ class GPlaceholder < GPartial
30
+ private
31
+
32
+ # Regular expression that matches a single placeholder
33
+ ARGUMENT = /(?<text>\w+)|((?<qtat>'|")(?<text>.*)\k<qtat>)/
34
+
35
+ # Regular expression that matches placeholder arguments
36
+ ARGUMENTS = /(?<arguments>(#{ARGUMENT}\s*)*)/
37
+
38
+ # Regular expression that matches placeholder operations
39
+ OPERATION = /(->\s*(?<operation>\w+))/
40
+
41
+ # Regular expression that matches placeholder defaults
42
+ DEFAULT = /(\:\s*(?<default>[^(\-\>)]+))/
43
+
44
+ public
45
+
46
+ # Regular expression that matches placeholders
47
+ REGEX = /@\(\s*#{NAME}\s*#{DEFAULT}?\s*(#{OPERATION}\s*#{ARGUMENTS}?)?\s*\)/
48
+
49
+ # Initializes the GPlaceholder with the given match
50
+ #
51
+ # Parameter: match - the match data from the string being parsed
52
+ # Parameter: defaults - the hash of default data from the GTemplate
53
+ def initialize match, defaults
54
+ super match
55
+ @operation = match[:operation]
56
+ if match[:arguments]
57
+ @arguments = match[:arguments].gsub(ARGUMENT).collect { |arg|
58
+ ARGUMENT.match(arg)[:text]
59
+ }
60
+ else
61
+ @arguments = []
62
+ end
63
+ @defaults = defaults
64
+ @defaults[@name] = match[:default] unless @defaults.has_key? @name
65
+ end
66
+
67
+ # Returns the value of the placeholder in the given data
68
+ # with the given operation performed on it
69
+ #
70
+ # Parameter: data - the data being applied
71
+ #
72
+ # Return: the value of the placeholder in the given data
73
+ # with the given operation performed on it
74
+ def apply data
75
+ # Get value from either data or defaults
76
+ if data.has_key? @name
77
+ value = data[@name]
78
+ else
79
+ value = @defaults[@name]
80
+ end
81
+
82
+ # Return value (operation performed if one is defined)
83
+ return (@operation ? General::GOperations.send(@operation, value, *@arguments) : value).to_s
84
+ end
85
+
86
+ # Returns the string as a regex
87
+ #
88
+ # Parameter: first - true if the placeholder is the first of its kind in the GTemplate
89
+ #
90
+ # Returns: the string as a regex
91
+ def regex(first=true); first ? "(?<#{@name.to_s}>.*)" : "\\k<#{@name.to_s}>"; end
92
+
93
+ # Returns the string representation of the placeholder
94
+ #
95
+ # Parameter: first - true if the placeholder is the first of its kind in the GTemplate
96
+ #
97
+ # Return: the string representation of the placeholder
98
+ def string first=true
99
+ str = "@(#{@name}"
100
+ if first
101
+ if @defaults[@name]
102
+ str += ": #{@defaults[@name]}"
103
+ end
104
+ if @operation
105
+ str += " -> #{@operation}"
106
+ unless @arguments.empty?
107
+ str += @arguments.collect {|s| " \"#{s}\""}.join
108
+ end
109
+ end
110
+ end
111
+ return str + ")"
112
+ end
113
+ end
114
+
115
+ # Represents an array placeholder partial in a GTemplate
116
+ #
117
+ # Author: Anshul Kharbanda
118
+ # Created: 7 - 1 - 2016
119
+ class GArrayPlaceholder < GPartial
120
+ # Regular expression that matches array placeholders
121
+ REGEX = /\A@\[#{NAME}\]( +|\n+)?(?<text>.*?)( +|\n+)?@\[(?<delimeter>.+)?\]/m
122
+
123
+ # Default delimeter
124
+ DEFAULT_DELIMETER = " "
125
+
126
+ # Initializes the GPlaceholder with the given match
127
+ #
128
+ # Parameter: match - the match data from the string being parsed
129
+ def initialize match
130
+ super
131
+ @delimeter = match[:delimeter] || DEFAULT_DELIMETER
132
+ @template = General::GTemplate.new match[:text]
133
+ end
134
+
135
+ # Returns the value of the array placeholder in the given data
136
+ # formatted by the given GTemplate and joined by the given delimeter
137
+ #
138
+ # Parameter: data - the data being applied
139
+ #
140
+ # Return: the value of the array placeholder in the given data
141
+ # formatted by the given GTemplate and joined by the given delimeter
142
+ def apply(data); @template.apply_all(data[@name]).join(@delimeter); end
143
+
144
+ # Throws TypeError
145
+ #
146
+ # Parameter: first - true if the placeholder is the first of it's kind
147
+ def regex(first=true); raise TypeError.new("Array Templates cannot be matched."); end
148
+
149
+ # Returns the string representation of the array placeholder
150
+ #
151
+ # Parameter: first - true if the placeholder is the first of it's kind
152
+ #
153
+ # Return: the string representation of the array placeholder
154
+ def string(first=true); "@[#{@name}] #{@template.to_s} @[#{@delimeter.inspect[1...-1]}]"; end
155
+ end
156
+ end