resulang 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f77e7c4836d3b5579f4ab1389d961a70425894353419b91d4b41927a37581c25
4
- data.tar.gz: fdeb85325dc87404c955436154b388445e823ac44c10b044eb53833b513dbb2f
3
+ metadata.gz: 793e6930ec9d8dabd66b436ed63916b1e18ee3b0fcfaa1adce684a8bdb019119
4
+ data.tar.gz: 6c28b6a08207b1a37e4ba1d071cf0e05f616b7621c6712545b1ab8d95912a1b0
5
5
  SHA512:
6
- metadata.gz: 50dd554e11fccd5775d4be9da95aac13baf6e6eea07668d346940ad76ab26a2e3a950e288f974eb515088c53746adc6e01eb4123029eb7e0fb737871d4d3bc7b
7
- data.tar.gz: 3ca3093dec8e3873b6986ff8cd073acb8134908a070129bd178a7a1f6229a19675718b14bdb1e063cf3aef332131968893211fa32fadc375f34569107bc8be4d
6
+ metadata.gz: b43376f525f24a8f9d48cc15442b6f4c241a2202b4f712a1de8ad8e20e899c091de0bea20047b89871ae68e18996613e93189db2bb206b0950eaeb3bb6880dc2
7
+ data.tar.gz: 484df2a62449d87f4fa93056af0ea61c5d889bb4b73b09d68d29d650e3c36a8cd8057771d6c6a539b6c466e206afbbd8499acb1756c29f3202b67cb39cfb2100
@@ -1 +1 @@
1
- resulang
1
+ resulang
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Resulang
2
2
 
3
- Resulang is a simple DSL to help create html resumes. It can also be used to
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.rb`
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.rb
30
+ my_resume/data/resume.yaml
31
31
 
32
32
 
33
33
  A resume is broken into named sections. For example:
34
- ```ruby
35
- personal do
36
- name 'Peter Brindisi'
37
- phone '555-555-5555'
38
- email 'superduperprivate@example.com'
39
- github 'https://github.com/npj'
40
- end
41
-
42
- background do
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
- DESCRIPTION
46
- end
47
-
48
- skills do
49
- things %{foo bar baz qux}
50
- end
51
-
52
- hobbies do
53
- info do
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[:personal].name %></title>
67
- <link rel="stylesheet" href="assets/css/style.css" />
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
- <% info.points.each do |point| %>
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 `exmaples` directory of this project for a working example.
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
@@ -0,0 +1,6 @@
1
+ <ul>
2
+ <% things.each do |thing| %>
3
+ <li><%= thing.name %> (<%= thing.description %>)</li>
4
+ <% end %>
5
+ </ul>
6
+
@@ -1,6 +1,6 @@
1
1
  <html>
2
2
  <head>
3
- <title><%= sections[:personal].name %></title>
3
+ <title><%= sections.personal.name %></title>
4
4
  <link rel="stylesheet" href="assets/css/style.css" />
5
5
  </head>
6
6
  <body>
@@ -1,6 +1,4 @@
1
1
  require 'resulang/app'
2
- require 'resulang/dsl'
3
- require 'resulang/fields'
4
2
  require 'resulang/rendering'
5
3
  require 'resulang/resume'
6
4
  require 'resulang/section'
@@ -52,11 +52,11 @@ module Resulang
52
52
  end
53
53
 
54
54
  def load_resume
55
- @resume = Resulang::Dsl.new(resume_path).resume
55
+ @resume = Resulang::Resume.new(path: resume_path)
56
56
  end
57
57
 
58
58
  def resume_path
59
- File.join(path, 'resume.rb')
59
+ File.join(path, 'resume.yaml')
60
60
  end
61
61
  end
62
62
  end
@@ -17,28 +17,36 @@ module Resulang
17
17
  contents.join("\n")
18
18
  end
19
19
 
20
- create_file('resume.rb') do
21
- declarations = options[:sections].inject([]) do |list, s|
22
- list.push("section(:#{s}) do\n\n end")
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
- structure + "\n\n" + data
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
 
@@ -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(&block)
8
- @sections = { }
9
- instance_eval(&block)
7
+ def initialize(path:)
8
+ @sections = OpenStruct.new
9
+ load_yaml(path)
10
10
  end
11
11
 
12
- def self.declare_section!(name, &declaration_block)
13
- @@declared_sections[name] = Class.new(Section, &declaration_block)
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
@@ -1,17 +1,44 @@
1
+ require 'ostruct'
2
+
1
3
  module Resulang
2
- class Section
3
- attr_reader :name
4
+ class Section < OpenStruct
5
+ attr_reader :_section_name
4
6
 
5
- include Fields
6
7
  include Rendering
7
8
 
8
- def initialize(name:, &block)
9
- @name = name
10
- instance_eval(&block)
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
@@ -1,3 +1,3 @@
1
1
  module Resulang
2
- VERSION = "2.0.0"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -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 DSL to help create html resumes.}
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", "~> 2.1.4"
26
- spec.add_development_dependency "rake", "~> 12.3.3"
27
- spec.add_development_dependency "rspec", "~> 3.4.0"
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: 2.0.0
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-04 00:00:00.000000000 Z
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.html
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 DSL to help create html resumes.
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
@@ -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
@@ -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