general 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/general.rb +2 -0
- data/lib/gfile.rb +70 -0
- data/lib/gtemplate.rb +152 -0
- data/spec/gfile_spec.rb +60 -0
- data/spec/gtemplate_spec.rb +72 -0
- data/spec/spec_require.rb +2 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c1dd9eaba641900ea4e4570380a94b487c9ede48
|
4
|
+
data.tar.gz: 977d55f997291890f0c4c068ade7180fbef8e14e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4e1fea13b4dfb11723f4256d1870f96cf6bd72a592f1fb1491cb783123c9cf52c9615bd90983856d7ee751be13291ab1e3666bb225429d22781a172489a94283
|
7
|
+
data.tar.gz: 7bb540fb3b8a4a7f5b47f72429d2d74e46bb947823a42512978c0f31c79e7df7fb4480c507d3db2d36aa62431d08e03fe9cf3df52464a9cbcc535013fae56aa8
|
data/lib/general.rb
ADDED
data/lib/gfile.rb
ADDED
@@ -0,0 +1,70 @@
|
|
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 "gtemplate"
|
18
|
+
|
19
|
+
# General is a templating system in ruby
|
20
|
+
#
|
21
|
+
# Author: Anshul Kharbanda
|
22
|
+
# Created: 3 - 4 - 2016
|
23
|
+
module General
|
24
|
+
# Implements the general file IO
|
25
|
+
#
|
26
|
+
# Author: Anshul Kharbanda
|
27
|
+
# Created: 3 - 4 - 2016
|
28
|
+
class GFile
|
29
|
+
# The general file extention
|
30
|
+
EXTENTION = ".general"
|
31
|
+
|
32
|
+
# Can write to attributes "name" and "path"
|
33
|
+
#
|
34
|
+
# "name" is the name of the target file
|
35
|
+
#
|
36
|
+
# "path" is the path of the target file
|
37
|
+
attr_writer :name, :path
|
38
|
+
|
39
|
+
# Creates a new GFile with the given path
|
40
|
+
#
|
41
|
+
# Paraeter: path the path to the GFile
|
42
|
+
def initialize path
|
43
|
+
@name = File.basename path, EXTENTION
|
44
|
+
@path = File.dirname path
|
45
|
+
@general = General::GTemplate.new IO.read path
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the path of the target file
|
49
|
+
#
|
50
|
+
# Return: the path of the target file
|
51
|
+
def target
|
52
|
+
@path + "/" + @name
|
53
|
+
end
|
54
|
+
|
55
|
+
# Writes the general with the given
|
56
|
+
# data applied to the target file
|
57
|
+
#
|
58
|
+
# Parameter: data - the data to be applied (merges with defaults)
|
59
|
+
def write data={}
|
60
|
+
IO.write target, @general.apply(data)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the string representation of the GFile
|
64
|
+
#
|
65
|
+
# Return: the string representation of the GFile
|
66
|
+
def to_s
|
67
|
+
"#{@general} >>> #{target}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/gtemplate.rb
ADDED
@@ -0,0 +1,152 @@
|
|
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
|
+
# Implements the general templating system for strings
|
23
|
+
#
|
24
|
+
# Author: Anshul Kharbanda
|
25
|
+
# Created: 3 - 4 - 2016
|
26
|
+
class GTemplate
|
27
|
+
# Regular expression that matches placeholders
|
28
|
+
PLACEHOLDER = /@\((?<name>[a-zA-Z]\w*)\s*(\:\s*(?<default>.*?))?\s*(->\s*(?<operation>[a-zA-Z]\w*))?\)/
|
29
|
+
|
30
|
+
# Regular expression that matches array placeholders
|
31
|
+
ARRAY_PLACEHOLDER = /@\[(?<name>[a-zA-Z]\w*)\]\s*(?<text>.*?)\s*@\[(?<delimeter>.+)?\]/m
|
32
|
+
|
33
|
+
# Operations that can be called on placeholder values
|
34
|
+
OPERATIONS = {
|
35
|
+
# String operations
|
36
|
+
default: lambda { |string| return string },
|
37
|
+
capitalize: lambda { |string| return string.split(" ")
|
38
|
+
.collect(&:capitalize)
|
39
|
+
.join(" ") },
|
40
|
+
uppercase: lambda { |string| return string.uppercase },
|
41
|
+
lowercase: lambda { |string| return string.lowercase },
|
42
|
+
|
43
|
+
# Integer operations
|
44
|
+
dollars: lambda { |integer| return "$" + (integer * 0.01).to_s },
|
45
|
+
hourminsec: lambda { |integer| return (integer / 3600).to_s \
|
46
|
+
+ ":" + (integer % 3600 / 60).to_s \
|
47
|
+
+ ":" + (integer % 3600 % 60).to_s }
|
48
|
+
}
|
49
|
+
|
50
|
+
# Creates a GTemplate with the given template string
|
51
|
+
#
|
52
|
+
# Parameter: string - the string being converted to a template
|
53
|
+
def initialize string
|
54
|
+
@parts = []
|
55
|
+
@places = {}
|
56
|
+
@defaults = {}
|
57
|
+
@operation = {}
|
58
|
+
@array = Hash.new(false)
|
59
|
+
|
60
|
+
parse_string string
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns a string representation of the string
|
64
|
+
#
|
65
|
+
# Return: a string representation of the string
|
66
|
+
def to_s; @parts.join; end
|
67
|
+
|
68
|
+
# Returns the template with the given data applied
|
69
|
+
#
|
70
|
+
# Parameter: data - the data to be applied (merges with defaults)
|
71
|
+
#
|
72
|
+
# Return: the template with the given data applied
|
73
|
+
def apply data={}
|
74
|
+
applied_data = @defaults.merge data.to_hash
|
75
|
+
applied_parts = @parts.clone
|
76
|
+
applied_data.each do |key, value|
|
77
|
+
if @array[key]
|
78
|
+
@places[key].each do |place|
|
79
|
+
applied_parts[place[:index]] = value.collect {|subvalue| place[:template].apply subvalue}.join(place[:delimeter])
|
80
|
+
end
|
81
|
+
else
|
82
|
+
@places[key].each do |place|
|
83
|
+
applied_parts[place[:index]] = place[:operation].call(value)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
return applied_parts.join
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Returns true if given string has a placeholder
|
93
|
+
#
|
94
|
+
# Parameter: string - the string to check for a placeholder
|
95
|
+
#
|
96
|
+
# Return: true if given string has a placeholder
|
97
|
+
def has_placeholder string
|
98
|
+
return PLACEHOLDER =~ string || ARRAY_PLACEHOLDER =~ string
|
99
|
+
end
|
100
|
+
|
101
|
+
# Parses the string into General template data
|
102
|
+
#
|
103
|
+
# Parameter: string - the string to parse
|
104
|
+
def parse_string string
|
105
|
+
# While match remains in string
|
106
|
+
while has_placeholder string
|
107
|
+
if ARRAY_PLACEHOLDER =~ string
|
108
|
+
# Split match and add parts
|
109
|
+
match = ARRAY_PLACEHOLDER.match string
|
110
|
+
name = match[:name].to_sym
|
111
|
+
@parts << string[0...match.begin(0)] << name
|
112
|
+
string = string[match.end(0)..-1]
|
113
|
+
|
114
|
+
# Get delimeter (if any) and parse array template
|
115
|
+
delimeter = match[:delimeter].nil? ? " " : match[:delimeter]
|
116
|
+
template = GTemplate.new(match[:text])
|
117
|
+
|
118
|
+
# Push place and array information
|
119
|
+
push_place name, {index: @parts.length - 1, template: template, delimeter: delimeter}
|
120
|
+
@array[name] = true
|
121
|
+
elsif PLACEHOLDER =~ string
|
122
|
+
# Split match and add parts
|
123
|
+
match = PLACEHOLDER.match string
|
124
|
+
name = match[:name].to_sym
|
125
|
+
@parts << string[0...match.begin(0)] << name
|
126
|
+
string = string[match.end(0)..-1]
|
127
|
+
|
128
|
+
operation = match[:operation].nil? ? OPERATIONS[:default] : OPERATIONS[match[:operation].to_sym]
|
129
|
+
|
130
|
+
# Push place and default information
|
131
|
+
push_place name, {index: @parts.length - 1, operation: operation}
|
132
|
+
@defaults[name] = match[:default] unless @defaults.has_key? name
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Add end of string
|
137
|
+
@parts << string
|
138
|
+
end
|
139
|
+
|
140
|
+
# Adds the given place for the placeholder of the given name
|
141
|
+
#
|
142
|
+
# Parameter: name - the name of the placeholder add a place to
|
143
|
+
# Parameter: place - the place information to add
|
144
|
+
def push_place name, place
|
145
|
+
if @places.has_key? name
|
146
|
+
@places[name] << place
|
147
|
+
else
|
148
|
+
@places[name] = [place]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/spec/gfile_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require "spec_require"
|
2
|
+
|
3
|
+
describe Generic::GFile do
|
4
|
+
before :all do
|
5
|
+
@filepath = "tmp"
|
6
|
+
@filename = "sample.txt"
|
7
|
+
@new_filename = "supersample.txt"
|
8
|
+
@new_filepath = "tmp/supertmp"
|
9
|
+
@data = {name: "joe", food: "Joe's Schmoes"}
|
10
|
+
@default_text = "There once was a chef name Gordon Ramsay, and he loved eating carrots."
|
11
|
+
@applied_text = "There once was a chef name Joe, and he loved eating Joe's Schmoes."
|
12
|
+
end
|
13
|
+
|
14
|
+
before :each do
|
15
|
+
@file = Generic::GFile.new (@filepath + "/" + @filename + Generic::GFile::EXTENTION)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#new" do
|
19
|
+
it "Creates a new GFile with the given filename" do
|
20
|
+
expect(@file).to be_an_instance_of Generic::GFile
|
21
|
+
expect(@file.target).to eql (@filepath + "/" + @filename)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#target" do
|
26
|
+
it "Returns the name of the target" do
|
27
|
+
expect(@file.target).to eql (@filepath + "/" + @filename)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#name=" do
|
32
|
+
it "Changes the name of the target" do
|
33
|
+
@file.name = @new_filename
|
34
|
+
expect(@file.target).to eql (@filepath + "/" + @new_filename)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#path=" do
|
39
|
+
it "Changes the path of the target" do
|
40
|
+
@file.path = @new_filepath
|
41
|
+
expect(@file.target).to eql (@new_filepath + "/" + @filename)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#write" do
|
46
|
+
context "With no data" do
|
47
|
+
it "Writes the default data to the target file" do
|
48
|
+
@file.write
|
49
|
+
expect(IO.read(@file.target)).to eql @default_text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "With given data" do
|
54
|
+
it "Writes the given data to the target file" do
|
55
|
+
@file.write(@data)
|
56
|
+
expect(IO.read(@file.target)).to eql @applied_text
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "spec_require"
|
2
|
+
|
3
|
+
describe Generic::GTemplate do
|
4
|
+
before :all do
|
5
|
+
@template1 = Generic::GTemplate.new "There once was a man named @(name: Gordon Ramsay). @(name) loved @(food: Cat Food)!"
|
6
|
+
@default_text = "There once was a man named Gordon Ramsay. Gordon Ramsay loved Cat Food!"
|
7
|
+
@all_applied_text = "There once was a man named Joe. Joe loved Joe's Shmoes!"
|
8
|
+
@name_applied_text = "There once was a man named Dog. Dog loved Cat Food!"
|
9
|
+
@food_applied_text = "There once was a man named Gordon Ramsay. Gordon Ramsay loved Denny's Fennies!"
|
10
|
+
@data1 = {name: "Joe", food: "Joe's Shmoes"}
|
11
|
+
@name = "Dog"
|
12
|
+
@food = "Denny's Fennies"
|
13
|
+
|
14
|
+
@template2 = Generic::GTemplate.new "@[greetings] Hello, @(name)! How is the @(pet)? @[\n]"
|
15
|
+
@data2 = {greetings: [
|
16
|
+
{name: "Joe", pet: "cat"},
|
17
|
+
{name: "Ben", pet: "dog"},
|
18
|
+
{name: "Ken", pet: "plant"}
|
19
|
+
]}
|
20
|
+
@applied_text2 = "Hello, Joe! How is the cat?\nHello, Ben! How is the dog?\nHello, Ken! How is the plant?"
|
21
|
+
|
22
|
+
@template3 = Generic::GTemplate.new "There once was a dog named @(name: dog -> capitalize). @(name -> capitalize) earned @(amount -> dollars) last week."
|
23
|
+
@data3 = {name: "cat", amount: 19999}
|
24
|
+
@applied_text3 = "There once was a dog named Cat. Cat earned $199.99 last week."
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#new" do
|
28
|
+
it "Creates a new GTemplate with the given template string" do
|
29
|
+
expect(@template1).to be_an_instance_of Generic::GTemplate
|
30
|
+
expect(@template2).to be_an_instance_of Generic::GTemplate
|
31
|
+
expect(@template3).to be_an_instance_of Generic::GTemplate
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#apply" do
|
36
|
+
context "With no data" do
|
37
|
+
it "Returns the template with the default data applied" do
|
38
|
+
expect(@template1.apply).to eql @default_text
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "With only name given" do
|
43
|
+
it "Returns the template with the given name and default food applied" do
|
44
|
+
expect(@template1.apply(name: @name)).to eql @name_applied_text
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "With only food given" do
|
49
|
+
it "Returns the template with the default name and given food applied" do
|
50
|
+
expect(@template1.apply(food: @food)).to eql @food_applied_text
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "With all data" do
|
55
|
+
it "Returns the template with the given data applied" do
|
56
|
+
expect(@template1.apply(@data1)).to eql @all_applied_text
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "With array template" do
|
61
|
+
it "Returns the template with the given array data applied and formatted according to the template" do
|
62
|
+
expect(@template2.apply(@data2)).to eql @applied_text2
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "With placeholder operation" do
|
67
|
+
it "Returns the template with the given array data applied and formatted according to the format operations" do
|
68
|
+
expect(@template3.apply(@data3)).to eql @applied_text3
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: general
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anshul Kharbanda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-25 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: "General is a simple templating system in ruby that allows you to create
|
14
|
+
templates from both \t\t\t\t\t\tpure strings and files (with the extension .general),
|
15
|
+
as well as create new strings and files \t\t\t\t\t\twith these created objects.
|
16
|
+
For more information, read the README for documentation."
|
17
|
+
email: akanshul97@gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/general.rb
|
23
|
+
- lib/gfile.rb
|
24
|
+
- lib/gtemplate.rb
|
25
|
+
- spec/gfile_spec.rb
|
26
|
+
- spec/gtemplate_spec.rb
|
27
|
+
- spec/spec_require.rb
|
28
|
+
homepage:
|
29
|
+
licenses:
|
30
|
+
- GPL-3.0
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.4.8
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: A templating system for ruby.
|
52
|
+
test_files: []
|