resulang 2.0.0 → 3.0.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.
- checksums.yaml +4 -4
- data/.ruby-gemset +1 -1
- data/README.md +28 -59
- data/examples/my_resume/resume.yaml +29 -0
- data/examples/my_resume/templates/_other.html.erb +6 -0
- data/examples/my_resume/templates/resume.html.erb +1 -1
- data/lib/resulang.rb +0 -2
- data/lib/resulang/app.rb +2 -2
- data/lib/resulang/exec.rb +21 -13
- data/lib/resulang/resume.rb +8 -13
- data/lib/resulang/section.rb +33 -6
- data/lib/resulang/version.rb +1 -1
- data/resulang.gemspec +5 -4
- metadata +19 -7
- data/examples/my_resume/resume.html +0 -27
- data/examples/my_resume/resume.rb +0 -67
- data/lib/resulang/dsl.rb +0 -32
- data/lib/resulang/fields.rb +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 793e6930ec9d8dabd66b436ed63916b1e18ee3b0fcfaa1adce684a8bdb019119
|
4
|
+
data.tar.gz: 6c28b6a08207b1a37e4ba1d071cf0e05f616b7621c6712545b1ab8d95912a1b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b43376f525f24a8f9d48cc15442b6f4c241a2202b4f712a1de8ad8e20e899c091de0bea20047b89871ae68e18996613e93189db2bb206b0950eaeb3bb6880dc2
|
7
|
+
data.tar.gz: 484df2a62449d87f4fa93056af0ea61c5d889bb4b73b09d68d29d650e3c36a8cd8057771d6c6a539b6c466e206afbbd8499acb1756c29f3202b67cb39cfb2100
|
data/.ruby-gemset
CHANGED
@@ -1 +1 @@
|
|
1
|
-
resulang
|
1
|
+
resulang
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Resulang
|
2
2
|
|
3
|
-
Resulang is a simple
|
3
|
+
Resulang is a simple tool for creating html resumes. It can also be used to
|
4
4
|
create other kinds of documents with structured data. It works by separating
|
5
5
|
the data from the html template, which means the data could theoretically be
|
6
6
|
used to generate other kinds of output in the future, not just html.
|
@@ -15,47 +15,41 @@ used to generate other kinds of output in the future, not just html.
|
|
15
15
|
|
16
16
|
Once resulang is installed, create a new resulang app with:
|
17
17
|
```sh
|
18
|
-
resulang new my_resume
|
18
|
+
bundle exec resulang new my_resume --section one two three
|
19
19
|
```
|
20
20
|
|
21
21
|
This will generate the basic structure of a resulang app as well as a few key files:
|
22
22
|
|
23
|
-
* `my_resume/data/resume.
|
23
|
+
* `my_resume/data/resume.yaml`
|
24
24
|
|
25
25
|
This is where you define your resume.
|
26
26
|
|
27
27
|
* `my_resume/templates/resume.html.erb`
|
28
28
|
|
29
29
|
This is where you write your resume html which has access to the data in
|
30
|
-
my_resume/data/resume.
|
30
|
+
my_resume/data/resume.yaml
|
31
31
|
|
32
32
|
|
33
33
|
A resume is broken into named sections. For example:
|
34
|
-
```
|
35
|
-
personal
|
36
|
-
name
|
37
|
-
phone
|
38
|
-
email
|
39
|
-
github
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
description <<-DESCRIPTION
|
34
|
+
```yaml
|
35
|
+
personal:
|
36
|
+
name: Peter Brindisi
|
37
|
+
phone: 555-555-5555
|
38
|
+
email: superduperprivate@example.com
|
39
|
+
github: https://github.com/npj
|
40
|
+
|
41
|
+
background:
|
42
|
+
description: >-
|
44
43
|
I am a guy that does things. Things are awesome and they are also cool.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
point 'Reading about Haskell'
|
55
|
-
point 'Evangelizing monads'
|
56
|
-
point 'Making beer'
|
57
|
-
end
|
58
|
-
end
|
44
|
+
|
45
|
+
skills:
|
46
|
+
things: ['foo', 'bar', 'baz', 'qux']
|
47
|
+
|
48
|
+
hobbies:
|
49
|
+
points:
|
50
|
+
- Reading about Haskell
|
51
|
+
- Evangelizing monads
|
52
|
+
- Making beer
|
59
53
|
```
|
60
54
|
|
61
55
|
A template for the above data might look like this:
|
@@ -63,8 +57,8 @@ A template for the above data might look like this:
|
|
63
57
|
```html
|
64
58
|
<html>
|
65
59
|
<head>
|
66
|
-
<title><%= sections
|
67
|
-
<link rel="stylesheet" href="
|
60
|
+
<title><%= sections.personal.name %></title>
|
61
|
+
<link rel="stylesheet" href="css/style.css" />
|
68
62
|
</head>
|
69
63
|
<body>
|
70
64
|
<div class="section">
|
@@ -99,52 +93,27 @@ and "hobbies" sections might look like:
|
|
99
93
|
```html
|
100
94
|
<!-- my_resume/templates/_hobbies.html.erb -->
|
101
95
|
<ul>
|
102
|
-
<%
|
96
|
+
<% points.each do |point| %>
|
103
97
|
<li><%= point %></li>
|
104
98
|
<% end %>
|
105
99
|
</ul>
|
106
100
|
```
|
107
101
|
|
108
|
-
The data in `resume.rb` needs to be defined, which is what the
|
109
|
-
`my_resume/data/sections` directory is for. Each section is a class that
|
110
|
-
inherits from `Resulang::Section`. A section class declares the fields a
|
111
|
-
section can have as well as their types. The `Personal` and `Hobbies` sections
|
112
|
-
would look like this:
|
113
|
-
|
114
|
-
```ruby
|
115
|
-
# my_resume/data/sections/personal.rb
|
116
|
-
class Personal < Resulang::Section
|
117
|
-
string :name, :phone
|
118
|
-
email :email
|
119
|
-
link :github
|
120
|
-
end
|
121
|
-
```
|
122
|
-
|
123
|
-
```ruby
|
124
|
-
# my_resume/data/sections/hobbies.rb
|
125
|
-
class Hobbies < Resulang::Section
|
126
|
-
pointlist :info
|
127
|
-
end
|
128
|
-
```
|
129
|
-
|
130
102
|
To easily view changes to the resume as you make them, you can run a local
|
131
103
|
server with:
|
132
104
|
```sh
|
133
|
-
resulang server
|
105
|
+
bundle exec resulang server
|
134
106
|
```
|
135
107
|
|
136
|
-
However, if you make any changes to the classes in `my_resume/data/sections`
|
137
|
-
you must restart the server.
|
138
|
-
|
139
108
|
You can put assets like images and stylesheets in directories off `my_resume`,
|
140
109
|
like `css` and `images` or `assets/css` and `assets/images`. These can be
|
141
110
|
referenced in `resume.html.erb`.
|
142
111
|
|
143
112
|
To generate a static html page, run:
|
144
113
|
```sh
|
145
|
-
resulang make
|
114
|
+
bundle exec resulang make
|
146
115
|
```
|
147
116
|
|
148
117
|
This will output `./resume.html`
|
149
118
|
|
150
|
-
Please see the `
|
119
|
+
Please see the `examples` directory of this project for a working example.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
personal:
|
2
|
+
name: Peter Brindisi
|
3
|
+
phone: 555-555-5555
|
4
|
+
email: superduperprivate@example.com
|
5
|
+
github: https://github.com/npj
|
6
|
+
|
7
|
+
background:
|
8
|
+
description: >-
|
9
|
+
I am a guy that does things. Things are awesome and they are also cool.
|
10
|
+
|
11
|
+
skills:
|
12
|
+
things: ['foo', 'bar', 'baz', 'qux']
|
13
|
+
|
14
|
+
hobbies:
|
15
|
+
points:
|
16
|
+
- Reading about Haskell
|
17
|
+
- Evangelizing monads
|
18
|
+
- Making beer
|
19
|
+
|
20
|
+
other:
|
21
|
+
things:
|
22
|
+
- name: foo
|
23
|
+
description: foo desc
|
24
|
+
|
25
|
+
- name: bar
|
26
|
+
description: bar desc
|
27
|
+
|
28
|
+
- name: baz
|
29
|
+
description: baz desc
|
data/lib/resulang.rb
CHANGED
data/lib/resulang/app.rb
CHANGED
@@ -52,11 +52,11 @@ module Resulang
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def load_resume
|
55
|
-
@resume = Resulang::
|
55
|
+
@resume = Resulang::Resume.new(path: resume_path)
|
56
56
|
end
|
57
57
|
|
58
58
|
def resume_path
|
59
|
-
File.join(path, 'resume.
|
59
|
+
File.join(path, 'resume.yaml')
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
data/lib/resulang/exec.rb
CHANGED
@@ -17,28 +17,36 @@ module Resulang
|
|
17
17
|
contents.join("\n")
|
18
18
|
end
|
19
19
|
|
20
|
-
create_file('resume.
|
21
|
-
|
22
|
-
list.push("
|
23
|
-
end
|
24
|
-
|
25
|
-
sections = options[:sections].inject([]) do |list, s|
|
26
|
-
list.push("#{s} do\n\n end")
|
27
|
-
end
|
28
|
-
|
29
|
-
structure = "structure do\n " + declarations.join(" \n\n ") + "\nend"
|
30
|
-
data = "data do\n " + sections.join(" \n\n ") + "\nend"
|
20
|
+
create_file('resume.yaml') do
|
21
|
+
options[:sections].inject([]) do |list, s|
|
22
|
+
list.push("#{s}:")
|
23
|
+
end.join("\n\n")
|
24
|
+
end
|
31
25
|
|
32
|
-
|
26
|
+
empty_directory 'css'
|
27
|
+
inside('css') do
|
28
|
+
create_file('style.css')
|
33
29
|
end
|
34
30
|
|
35
31
|
empty_directory 'templates'
|
36
32
|
inside('templates') do
|
37
|
-
create_file('resume.html.erb')
|
33
|
+
create_file('resume.html.erb') do
|
34
|
+
<<-HTML
|
35
|
+
<html>
|
36
|
+
<head>
|
37
|
+
<link rel="stylesheet" href="css/style.css" />
|
38
|
+
</head>
|
39
|
+
<body>
|
40
|
+
#{options[:sections].map { |section| %Q{<div class="section"><%= render_section(:#{section}) %></div>} }.join("\n ")}
|
41
|
+
</body>
|
42
|
+
</html>
|
43
|
+
HTML
|
44
|
+
end
|
38
45
|
options[:sections].each do |s|
|
39
46
|
create_file("_#{s}.html.erb")
|
40
47
|
end
|
41
48
|
end
|
49
|
+
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
data/lib/resulang/resume.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
|
+
require 'psych'
|
2
|
+
|
1
3
|
module Resulang
|
2
4
|
class Resume
|
3
|
-
@@declared_sections = { }
|
4
|
-
|
5
5
|
attr_reader :sections
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@sections =
|
9
|
-
|
7
|
+
def initialize(path:)
|
8
|
+
@sections = OpenStruct.new
|
9
|
+
load_yaml(path)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
define_method(name) do |&instance_block|
|
16
|
-
unless @@declared_sections[name]
|
17
|
-
raise "Section \"#{name}\" not found"
|
18
|
-
end
|
19
|
-
@sections[name] = @@declared_sections[name].new(name: name, &instance_block)
|
12
|
+
private def load_yaml(path)
|
13
|
+
Psych.load_file(path).each do |section_name, section_data|
|
14
|
+
@sections[section_name] = Section.new(name: section_name, data: section_data)
|
20
15
|
end
|
21
16
|
end
|
22
17
|
end
|
data/lib/resulang/section.rb
CHANGED
@@ -1,17 +1,44 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module Resulang
|
2
|
-
class Section
|
3
|
-
attr_reader :
|
4
|
+
class Section < OpenStruct
|
5
|
+
attr_reader :_section_name
|
4
6
|
|
5
|
-
include Fields
|
6
7
|
include Rendering
|
7
8
|
|
8
|
-
def initialize(name:,
|
9
|
-
|
10
|
-
|
9
|
+
def initialize(name:, data:)
|
10
|
+
super(_section_name: name)
|
11
|
+
interpret_object(self, data)
|
11
12
|
end
|
12
13
|
|
13
14
|
def get_binding
|
14
15
|
binding
|
15
16
|
end
|
17
|
+
|
18
|
+
private def interpret(value)
|
19
|
+
if (range = interpret_range(value))
|
20
|
+
range
|
21
|
+
elsif value.respond_to?(:keys)
|
22
|
+
interpret_object(OpenStruct.new, value)
|
23
|
+
elsif value.respond_to?(:map)
|
24
|
+
value.map { |v| interpret(v) }
|
25
|
+
else
|
26
|
+
value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private def interpret_object(struct, value)
|
31
|
+
struct.tap do |s|
|
32
|
+
value.each do |key, value|
|
33
|
+
s[key] = interpret(value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private def interpret_range(value)
|
39
|
+
if value.respond_to?(:keys) && value.keys == ['range']
|
40
|
+
(value['range'].first..value['range'].last)
|
41
|
+
end
|
42
|
+
end
|
16
43
|
end
|
17
44
|
end
|
data/lib/resulang/version.rb
CHANGED
data/resulang.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Resulang::VERSION
|
9
9
|
spec.authors = ["Peter Brindisi"]
|
10
10
|
spec.email = ["peter.brindisi+resulang@gmail.com"]
|
11
|
-
spec.summary = %q{Resulang is a simple
|
11
|
+
spec.summary = %q{Resulang is a simple tool to help create html resumes.}
|
12
12
|
spec.homepage = "https://github.com/npj/resulang"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
@@ -22,7 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "rack", "~> 2.1.4"
|
23
23
|
spec.add_dependency "mime-types", "~> 3.0"
|
24
24
|
|
25
|
-
spec.add_development_dependency "bundler",
|
26
|
-
spec.add_development_dependency "rake",
|
27
|
-
spec.add_development_dependency "rspec",
|
25
|
+
spec.add_development_dependency "bundler", "~> 2.1.4"
|
26
|
+
spec.add_development_dependency "rake", "~> 12.3.3"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.4.0"
|
28
|
+
spec.add_development_dependency "pry", "~> 0.13.0"
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resulang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Brindisi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 3.4.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.13.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.13.0
|
111
125
|
description:
|
112
126
|
email:
|
113
127
|
- peter.brindisi+resulang@gmail.com
|
@@ -125,19 +139,17 @@ files:
|
|
125
139
|
- Rakefile
|
126
140
|
- bin/resulang
|
127
141
|
- examples/my_resume/assets/css/style.css
|
128
|
-
- examples/my_resume/resume.
|
129
|
-
- examples/my_resume/resume.rb
|
142
|
+
- examples/my_resume/resume.yaml
|
130
143
|
- examples/my_resume/server.ru
|
131
144
|
- examples/my_resume/templates/_background.html.erb
|
132
145
|
- examples/my_resume/templates/_hobbies.html.erb
|
146
|
+
- examples/my_resume/templates/_other.html.erb
|
133
147
|
- examples/my_resume/templates/_personal.html.erb
|
134
148
|
- examples/my_resume/templates/_skills.html.erb
|
135
149
|
- examples/my_resume/templates/resume.html.erb
|
136
150
|
- lib/resulang.rb
|
137
151
|
- lib/resulang/app.rb
|
138
|
-
- lib/resulang/dsl.rb
|
139
152
|
- lib/resulang/exec.rb
|
140
|
-
- lib/resulang/fields.rb
|
141
153
|
- lib/resulang/rendering.rb
|
142
154
|
- lib/resulang/resume.rb
|
143
155
|
- lib/resulang/section.rb
|
@@ -167,5 +179,5 @@ requirements: []
|
|
167
179
|
rubygems_version: 3.1.2
|
168
180
|
signing_key:
|
169
181
|
specification_version: 4
|
170
|
-
summary: Resulang is a simple
|
182
|
+
summary: Resulang is a simple tool to help create html resumes.
|
171
183
|
test_files: []
|
@@ -1,27 +0,0 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title>Peter Brindisi</title>
|
4
|
-
<link rel="stylesheet" href="assets/css/style.css" />
|
5
|
-
</head>
|
6
|
-
<body>
|
7
|
-
<div class="section">
|
8
|
-
<div>Name: Peter Brindisi</div>
|
9
|
-
<div>Phone: 555-555-5555</div>
|
10
|
-
<div>Email: superduperprivate@example.com</div>
|
11
|
-
<div><a href="https://github.com/npj" target="_blank">https://github.com/npj</a></div>
|
12
|
-
</div>
|
13
|
-
<div class="section">
|
14
|
-
<div>I am a guy that does things. Things are awesome and they are also cool.</div>
|
15
|
-
</div>
|
16
|
-
<div class="section">
|
17
|
-
<div>foo bar baz qux</div>
|
18
|
-
</div>
|
19
|
-
<div class="section">
|
20
|
-
<ul>
|
21
|
-
<li>Reading about Haskell</li>
|
22
|
-
<li>Evangelizing monads</li>
|
23
|
-
<li>Making beer</li>
|
24
|
-
</ul>
|
25
|
-
</div>
|
26
|
-
</body>
|
27
|
-
</html>
|
@@ -1,67 +0,0 @@
|
|
1
|
-
structure do
|
2
|
-
section :personal do
|
3
|
-
string :name, :phone
|
4
|
-
email :email
|
5
|
-
link :github
|
6
|
-
end
|
7
|
-
|
8
|
-
section :background do
|
9
|
-
string :description
|
10
|
-
end
|
11
|
-
|
12
|
-
section :skills do
|
13
|
-
list :things
|
14
|
-
end
|
15
|
-
|
16
|
-
section :hobbies do
|
17
|
-
list :points
|
18
|
-
end
|
19
|
-
|
20
|
-
section :other do
|
21
|
-
list :things do
|
22
|
-
string :name, :description
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
data do
|
28
|
-
personal do
|
29
|
-
name 'Peter Brindisi'
|
30
|
-
phone '555-555-5555'
|
31
|
-
email 'superduperprivate@example.com'
|
32
|
-
github 'https://github.com/npj'
|
33
|
-
end
|
34
|
-
|
35
|
-
background do
|
36
|
-
description <<-DESCRIPTION
|
37
|
-
I am a guy that does things. Things are awesome and they are also cool.
|
38
|
-
DESCRIPTION
|
39
|
-
end
|
40
|
-
|
41
|
-
skills do
|
42
|
-
thing %{foo bar baz qux}
|
43
|
-
end
|
44
|
-
|
45
|
-
hobbies do
|
46
|
-
point 'Reading about Haskell'
|
47
|
-
point 'Evangelizing monads'
|
48
|
-
point 'Making beer'
|
49
|
-
end
|
50
|
-
|
51
|
-
other do
|
52
|
-
thing do
|
53
|
-
name 'foo'
|
54
|
-
description 'foo desc'
|
55
|
-
end
|
56
|
-
|
57
|
-
thing do
|
58
|
-
name 'bar'
|
59
|
-
description 'bar desc'
|
60
|
-
end
|
61
|
-
|
62
|
-
thing do
|
63
|
-
name 'baz'
|
64
|
-
description 'baz desc'
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/lib/resulang/dsl.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Resulang
|
2
|
-
class Dsl
|
3
|
-
attr_reader :path, :resume
|
4
|
-
|
5
|
-
def initialize(path)
|
6
|
-
@resume = nil
|
7
|
-
@path = path
|
8
|
-
instance_eval(File.read(path))
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
# defines the sections and their typed fields
|
14
|
-
class Structure
|
15
|
-
def initialize(&block)
|
16
|
-
instance_eval(&block)
|
17
|
-
end
|
18
|
-
|
19
|
-
def section(name, &block)
|
20
|
-
Resume.declare_section!(name, &block)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def structure(&block)
|
25
|
-
Structure.new(&block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def data(&block)
|
29
|
-
@resume = Resume.new(&block)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/lib/resulang/fields.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'active_support/inflector'
|
2
|
-
|
3
|
-
module Resulang
|
4
|
-
module Fields
|
5
|
-
def self.included(base)
|
6
|
-
base.extend(ClassMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
class Email < String
|
10
|
-
end
|
11
|
-
|
12
|
-
class Link < String
|
13
|
-
end
|
14
|
-
|
15
|
-
module ClassMethods
|
16
|
-
protected def string(*attrs)
|
17
|
-
fields(*attrs) { |value| value }
|
18
|
-
end
|
19
|
-
|
20
|
-
protected def email(*attrs)
|
21
|
-
fields(*attrs) { |value| Email.new(value) }
|
22
|
-
end
|
23
|
-
|
24
|
-
protected def link(*attrs)
|
25
|
-
fields(*attrs) { |value| Link.new(value) }
|
26
|
-
end
|
27
|
-
|
28
|
-
protected def list(*attrs, &item_decl)
|
29
|
-
attrs.each do |name|
|
30
|
-
define_method(name) do |*args, &block|
|
31
|
-
field_get(name)
|
32
|
-
end
|
33
|
-
|
34
|
-
singular = ActiveSupport::Inflector.singularize(name)
|
35
|
-
|
36
|
-
define_method(singular) do |*args, &item_def|
|
37
|
-
if args.empty? && item_def.nil?
|
38
|
-
raise "no arguments or definition block given for list #{singular}"
|
39
|
-
end
|
40
|
-
|
41
|
-
items = field_get(name) || []
|
42
|
-
|
43
|
-
if item_def.nil?
|
44
|
-
args.each { |a| items.push(a) }
|
45
|
-
elsif
|
46
|
-
items.push(Class.new(Section, &item_decl).new(name: name, &item_def))
|
47
|
-
end
|
48
|
-
|
49
|
-
field_set(name, items)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
protected def range(*attrs)
|
55
|
-
fields(*attrs) { |*values| (values.first..values.last) }
|
56
|
-
end
|
57
|
-
|
58
|
-
private def fields(*names, &block)
|
59
|
-
names.each do |name|
|
60
|
-
define_method(name) do |*args, &b|
|
61
|
-
if args.empty? && b.nil?
|
62
|
-
field_get(name)
|
63
|
-
else
|
64
|
-
field_set(name, block.call(*args, &b))
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
# Instance Methods
|
73
|
-
#
|
74
|
-
private def field_set(attr, value)
|
75
|
-
instance_variable_set("@#{attr}", value)
|
76
|
-
end
|
77
|
-
|
78
|
-
private def field_get(attr)
|
79
|
-
instance_variable_get("@#{attr}")
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|