resme 0.3.0 → 0.4.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.
@@ -1,234 +1,253 @@
1
- require 'slop'
1
+ require "optparse"
2
2
 
3
3
  module Resme
4
4
  module CommandSyntax
5
- # return a hash with all the commands and their options
5
+ # Return a hash of hashes. Each key is the name of a command and
6
+ # includes useful information, such as an Option object to
7
+ # parse options and a documentation string.
6
8
  def self.commands
7
- h = Hash.new
8
- self.methods.each do |method|
9
- if method.to_s.include?("_opts") then
10
- h = h.merge(eval(method.to_s))
11
- end
9
+ cmd_spec = {}
10
+ methods.each do |method|
11
+ cmd_spec = cmd_spec.merge eval(method.to_s) if method.to_s.include?("_opts")
12
12
  end
13
- return h
13
+ cmd_spec
14
14
  end
15
15
 
16
- private
17
-
18
16
  def self.version_opts
19
- opts = Slop::Options.new
20
- opts.banner = "version -- print version information"
21
- help = <<EOS
22
- NAME
23
- #{opts.banner}
24
-
25
- SYNOPSYS
26
- #{opts.to_s}
27
-
28
- DESCRIPTION
29
- return version information
30
-
31
- EXAMPLES
32
- # resme version
33
- resme version #{VERSION}
34
- EOS
35
- return { :version => [opts, :version, help] }
17
+ opts = OptionParser.new do |opts|
18
+ opts.banner = "version # print version information"
19
+ end
20
+
21
+ help = <<-EOS
22
+ NAME
23
+ #{opts.banner}
24
+
25
+ SYNOPSYS
26
+ #{opts.to_s}
27
+
28
+ DESCRIPTION
29
+ return version information
30
+
31
+ EXAMPLES
32
+ # resme version
33
+ resme version #{VERSION}
34
+ EOS
35
+
36
+ {
37
+ version: {
38
+ name: :version,
39
+ options: opts,
40
+ help: help.gsub(" ", "")
41
+ }
42
+ }
36
43
  end
37
44
 
38
45
  def self.console_opts
39
- opts = Slop::Options.new
40
- opts.banner = "console [options] -- Enter the console"
41
- help = <<EOS
42
- NAME
43
- #{opts.banner}
44
-
45
- SYNOPSYS
46
- #{opts.to_s}
47
-
48
- DESCRIPTION
49
- Invoke a console, from which you can more easily run
50
- resme commands.
51
-
52
- EXAMPLES
53
- resme console
54
- resme:000>
55
- resme:001>
56
- resme:002>
57
- EOS
58
- return { :console => [opts, :console, help] }
46
+ opts = OptionParser.new do |opts|
47
+ opts.banner = "console # enter the console"
48
+ end
49
+
50
+ help = <<-EOS
51
+ NAME
52
+ #{opts.banner}
53
+
54
+ SYNOPSYS
55
+ #{opts.to_s}
56
+
57
+ DESCRIPTION
58
+ Invoke a console, from which you can more easily run
59
+ resme commands.
60
+
61
+ EXAMPLES
62
+ resme console
63
+ resme:000> check
64
+ resme:001> generate -t md
65
+ resme:002>
66
+ EOS
67
+
68
+ {
69
+ console: {
70
+ name: :console,
71
+ options: opts,
72
+ help: help.gsub(" ", "")
73
+ }
74
+ }
59
75
  end
60
76
 
61
77
  def self.man_opts
62
- opts = Slop::Options.new
63
- opts.banner = "man -- print a manual page"
64
- help = <<EOS
65
- NAME
66
- #{opts.banner}
67
-
68
- SYNOPSYS
69
- #{opts.to_s}
70
-
71
- DESCRIPTION
72
- Print the README file of this gem
73
-
74
- EXAMPLES
75
- resme man
76
- EOS
77
- return { :man => [opts, :man, help] }
78
+ opts = OptionParser.new do |opts|
79
+ opts.banner = "man # print resme manual page"
80
+ end
81
+
82
+ help = <<-EOS
83
+ NAME
84
+ #{opts.banner}
85
+
86
+ SYNOPSYS
87
+ #{opts.to_s}
88
+
89
+ DESCRIPTION
90
+ Print the README file of this gem
91
+
92
+ EXAMPLES
93
+ resme man
94
+ EOS
95
+
96
+ {
97
+ man: {
98
+ name: :man,
99
+ options: opts,
100
+ help: help.gsub(" ", "")
101
+ }
102
+ }
78
103
  end
79
104
 
80
105
  def self.help_opts
81
- opts = Slop::Options.new
82
- opts.banner = "help [command] -- print usage string"
83
- help = <<EOS
84
- NAME
85
- #{opts.banner}
86
-
87
- SYNOPSYS
88
- #{opts.to_s}
89
-
90
- DESCRIPTION
91
- Print help about a command
92
-
93
- EXAMPLES
94
- resme help
95
- resme help generate
96
- EOS
97
- return { :help => [opts, :help, help] }
98
- end
99
-
100
- def self.check_opts
101
- opts = Slop::Options.new
102
- opts.banner = "check -- Check whether a YAML file conforms with the RESME syntax"
103
- help = <<EOS
104
- NAME
105
- #{opts.banner}
106
-
107
- SYNOPSYS
108
- #{opts.to_s}
109
-
110
- DESCRIPTION
111
- Check whether a YAML file conforms with the RESME syntax.
112
-
106
+ opts = OptionParser.new do |opts|
107
+ opts.banner = "help [command] # print command usage"
108
+ end
113
109
 
114
- EXAMPLES
115
- resme file.yml
116
- EOS
117
- return { :check => [opts, :check, help] }
110
+ help = <<-EOS
111
+ NAME
112
+ #{opts.banner}
113
+
114
+ SYNOPSYS
115
+ #{opts.to_s}
116
+
117
+ DESCRIPTION
118
+ Print help about a command
119
+
120
+ EXAMPLES
121
+ resme help
122
+ resme help generate
123
+ EOS
124
+ {
125
+ help: {
126
+ name: :help,
127
+ options: opts,
128
+ help: help.gsub(" ", "")
129
+ }
130
+ }
118
131
  end
119
132
 
120
133
  def self.init_opts
121
- opts = Slop::Options.new
122
- opts.banner = "init [-o output_filename]"
123
- opts.string "-o", "--output", "Output filename"
124
- opts.boolean "-f", "--force", "Overwrite existing file (if present)"
125
- help = <<EOS
126
- NAME
127
- #{opts.banner}
128
-
129
- SYNOPSYS
130
- #{opts.to_s}
131
-
132
- DESCRIPTION
133
-
134
- Generate a YAML template for your resume in the current directory.
135
-
136
- EXAMPLES
137
-
138
- resme init
139
- resme -o r.yml
140
- resme -o r.yml --force
141
- EOS
142
- return { init: [opts, :init, help] }
143
- end
144
-
145
- def self.md_opts
146
- opts = Slop::Options.new
147
- opts.banner = "md [-o output_filename] file.yml ..."
148
- opts.string "-o", "--output", "Output filename"
149
- help = <<EOS
150
- NAME
151
- #{opts.banner}
152
-
153
- SYNOPSYS
154
- #{opts.to_s}
155
-
156
- DESCRIPTION
157
-
158
- Generate a markdown resume from the YAML input files.
159
-
160
- EXAMPLES
161
-
162
- resme md -o r.md resume.yml
163
- EOS
164
- return { md: [opts, :md, help] }
165
- end
166
-
167
- def self.org_opts
168
- opts = Slop::Options.new
169
- opts.banner = "org [-o output_filename] file.yml ..."
170
- opts.string "-o", "--output", "Output filename"
171
- help = <<EOS
172
- NAME
173
- #{opts.banner}
174
-
175
- SYNOPSYS
176
- #{opts.to_s}
177
-
178
- DESCRIPTION
179
-
180
- Generate an org-mode resume from the YAML input files.
181
-
182
- EXAMPLES
183
-
184
- resme md -o r.md resume.yml
185
- EOS
186
- return { org: [opts, :org, help] }
187
- end
188
-
189
- def self.json_opts
190
- opts = Slop::Options.new
191
- opts.banner = "json [-o output_filename] file.yml ..."
192
- opts.string "-o", "--output", "Output filename"
193
- help = <<EOS
194
- NAME
195
- #{opts.banner}
196
-
197
- SYNOPSYS
198
- #{opts.to_s}
199
-
200
- DESCRIPTION
201
-
202
- Generate a JSON resume from the YAML input files.
203
-
204
- EXAMPLES
205
-
206
- resme json -o r.md resume.yml
207
- EOS
208
- return { json: [opts, :json, help] }
134
+ opts = OptionParser.new do |opts|
135
+ opts.banner = "init [options] # generate an empty resume.yml file"
136
+ opts.on("-o", "--output FILENAME", String, "Output filename")
137
+ opts.on("-f", "--force", FalseClass, "Overwrite existing file (if present)")
138
+ end
139
+
140
+ help = <<-EOS
141
+ NAME
142
+ #{opts.banner}
143
+
144
+ SYNOPSYS
145
+ #{opts.to_s}
146
+
147
+ DESCRIPTION
148
+ Generate a YAML template for your resume in the current directory.
149
+
150
+ EXAMPLES
151
+ resme init
152
+ resme init -o r.yml
153
+ resme init -o r.yml --force
154
+ EOS
155
+ {
156
+ init: {
157
+ name: :init,
158
+ options: opts,
159
+ help: help.gsub(" ", "")
160
+ }
161
+ }
209
162
  end
210
163
 
211
- def self.europass_opts
212
- opts = Slop::Options.new
213
- opts.banner = "europass [-o output_filename] file.yml ..."
214
- opts.string "-o", "--output", "Output filename"
215
- help = <<EOS
216
- NAME
217
- #{opts.banner}
164
+ def self.check_opts
165
+ opts = OptionParser.new do |opts|
166
+ opts.banner = "check resume.yml # Check syntax of resume.yml"
167
+ end
218
168
 
219
- SYNOPSYS
220
- #{opts.to_s}
169
+ help = <<-EOS
170
+ NAME
171
+ #{opts.banner}
172
+
173
+ SYNOPSYS
174
+ #{opts.to_s}
175
+
176
+ DESCRIPTION
177
+ Check whether a YAML file conforms with the RESME syntax.
178
+
179
+ EXAMPLES
180
+ resme check file.yml
181
+ EOS
182
+
183
+ {
184
+ check: {
185
+ name: :check,
186
+ options: opts,
187
+ help: help.gsub(" ", "")
188
+ }
189
+ }
190
+ end
221
191
 
222
- DESCRIPTION
192
+ def self.list_opts
193
+ opts = OptionParser.new do |opts|
194
+ opts.banner = "list resume.yml # List main sections in resume.yml"
195
+ end
223
196
 
224
- Generate a Europass XML resume from the YAML input files.
197
+ help = <<-EOS
198
+ NAME
199
+ #{opts.banner}
200
+
201
+ SYNOPSYS
202
+ #{opts.to_s}
203
+
204
+ DESCRIPTION
205
+ List main sections in resume.yml.
206
+
207
+ EXAMPLES
208
+ resme list file.yml
209
+ EOS
210
+
211
+ {
212
+ list: {
213
+ name: :list,
214
+ options: opts,
215
+ help: help.gsub(" ", "")
216
+ }
217
+ }
218
+ end
225
219
 
226
- EXAMPLES
227
-
228
- resme europass -o r.md resume.yml
229
- EOS
230
- return { europass: [opts, :europass, help] }
231
- end
220
+ def self.generate_opts
221
+ opts = OptionParser.new do |o|
222
+ o.banner = "generate [options] resume.yml ... # output resume"
223
+ o.on("-e", "--erb FILENAME", String, "Template to use")
224
+ o.on("-t", "--to FORMAT", String, "Output format")
225
+ o.on("-o", "--output FILENAME", String, "Output filename")
226
+ o.on("-s", "--skip SECTION,SECTION", Array, "Sections to skip")
227
+ end
232
228
 
229
+ help = <<-EOS
230
+ NAME
231
+ #{opts.banner}
232
+
233
+ SYNOPSYS
234
+ #{opts.to_s}
235
+
236
+ DESCRIPTION
237
+ Generate a resume from the YAML input files.
238
+
239
+ EXAMPLES
240
+ resme generate -t org resume.yml
241
+ resme generate -t md -o r.md section-1.yml section-2.yml
242
+ EOS
243
+
244
+ {
245
+ generate: {
246
+ name: :generate,
247
+ options: opts,
248
+ help: help.gsub(" ", "")
249
+ }
250
+ }
251
+ end
233
252
  end
234
253
  end
@@ -133,23 +133,26 @@ def has_day input
133
133
  end
134
134
  end
135
135
 
136
- # Access hash keys like they were class methods
137
- # hash["key"] -> hash.key
136
+ # Access hash keys like they were class methods (hash["key"] -> hash.key) and
137
+ # report errors if key is missing
138
138
  class Hash
139
139
  def method_missing(m)
140
140
  key = m.to_s
141
141
 
142
+ # we put a bit of info about the top level structure of a resume to avoid
143
+ # extra-long error messages I don't want to print detailed information
144
+ # about top-level entries missing in the resume
145
+ top_level_entries = %w[
146
+ contacts addresses web_presence summary work teaching projects other
147
+ committees volunteer visits education publications talks awards
148
+ achievements software skills languages driving interests references
149
+ ]
150
+
142
151
  # error: nil value
143
152
  if self.has_key? key and self[key] == nil
144
153
  $stderr.puts "[W] The value of key '#{key}' is nil in the following entry:"
145
154
 
146
- # we put a bit of info about the top level structure of a resume to avoid extra-long error messages
147
- # I don't want to print detailed information about top-level entries missing in the resume
148
- top_level_entries = [
149
- "contacts", "addresses", "web_presence", "summary", "work", "teaching", "projects", "other",
150
- "committees", "volunteer", "visits", "education", "publications", "talks", "awards", "achievements",
151
- "software", "skills", "languages", "driving", "interests", "references"]
152
- if not top_level_entries.include?(key) then
155
+ unless top_level_entries.include?(key)
153
156
  # $stderr.puts self.to_s
154
157
  self.keys.each do |k|
155
158
  $stderr.puts " #{k}: #{self[k]}"
@@ -160,18 +163,17 @@ class Hash
160
163
 
161
164
  return self[key] if self.has_key? key
162
165
 
163
- # we get here if the key is not found
164
- # we report an error, return "" and continue
165
- # the actual mileage might vary
166
+ # we get here if the key is not found we report an error, return
167
+ # "" and continue the actual mileage might vary
166
168
 
167
- # more error reporting: key not found
168
169
  $stderr.puts "[E] Key '#{key}' not found in the following entry:"
169
- # $stderr.puts self.to_s
170
- self.keys.each do |k|
171
- $stderr.puts " #{k}: #{self[k]}"
170
+ unless top_level_entries.include?(key)
171
+ self.keys.each do |k|
172
+ $stderr.puts " #{k}: #{self[k]}"
173
+ end
174
+ $stderr.puts ""
172
175
  end
173
- $stderr.puts ""
174
-
176
+
175
177
  return ""
176
178
  end
177
179
  end
@@ -1,8 +1,8 @@
1
- # <%= full_name data %>, <%= data.basics.title %>
1
+ # <%= full_name data %>, <%= data.basics&.title %>
2
2
 
3
3
  <%
4
- addresses = data.addresses.map { |x| "**#{x.label}**: #{x.street}, #{x.zip_code} #{x.city}" }
5
- presence = data.contacts.map { |x| "**#{x.label}:** #{x.value}" } + data.web_presence.map { |x| "<" + x.value + ">" }
4
+ addresses = (data["addresses"] || []).map { |x| "**#{x.label}**: #{x.street}, #{x.zip_code} #{x.city}" }
5
+ presence = (data["contacts"] || []).map { |x| "**#{x.label}:** #{x.value}" } + (data["web_presence"] || []).map { |x| "<" + x.value + ">" }
6
6
  -%>
7
7
  <%= presence.map { |x| "* #{x}" }.join("\n") %>
8
8
  <%= addresses.map { |x| "* #{x}" }.join("\n") %>
@@ -1,26 +1,29 @@
1
- #+TITLE: <%= full_name data %>, <%= data.basics.title %>
2
- #+AUTHOR: <%= data.contacts.select { |x| x.label == "email" }.first.value %>
1
+ #+TITLE: Curriculum Vitae
2
+ #+AUTHOR: <%= full_name data %>, <%= data.basics&.title %>
3
+ #+EMAIL: <%= (data["contacts"] || []).select { |x| x.label == "email" }.first&.value %>
3
4
  #+DATE: <<%= Date.today %>>
4
5
  #+STARTUP: showall
5
6
  #+OPTIONS: toc:nil num:nil
6
7
  #+OPTIONS: h:1
7
8
  #+OPTIONS: prop:nil
8
9
 
10
+ <% if data["addresses"] or data["contacts"] %>
9
11
  * Contacts
10
12
  :PROPERTIES:
11
- <% data.addresses.each do |x| -%>
13
+ <% (data["addresses"] || []).each do |x| -%>
12
14
  <%= ":#{x.label.upcase}: #{x.street}, #{x.zip_code} #{x.city}" %>
13
15
  <% end -%>
14
- <% data.contacts.each do |x| -%>
16
+ <% (data["contacts"] || []).each do |x| -%>
15
17
  <%= ":#{x.label.upcase}: #{x.value}" %>
16
18
  <% end -%>
17
19
  :END:
18
20
 
19
- <% data.contacts.each do |x| -%>
21
+ <% (data["contacts"] || []).each do |x| -%>
20
22
  | <%= "%-30s" % x.label %> | <%= "%-40s" % x.value %> |
21
23
  <% end -%>
24
+ <% end %>
22
25
 
23
- <% if data["work"] -%>
26
+ <% if data["summary"] -%>
24
27
  * Summary
25
28
 
26
29
  <%= reflow_to_string data.summary, 78 -%>
@@ -40,7 +43,7 @@
40
43
  * Work Experience
41
44
 
42
45
  <% (data.work || []).each do |item| -%>
43
- ** *<%= period item %>: <%= clean [item.role, item.who].join(", ") %>*
46
+ ** <%= period item %>: <%= clean [item.role, item.who].join(", ") %>
44
47
  <%= propertify item, " " %>
45
48
 
46
49
  <%= reflow_to_string item["summary"], 72, " " -%>
@@ -52,7 +55,7 @@
52
55
  * Teaching
53
56
 
54
57
  <% (data.teaching || []).each do |item| -%>
55
- ** *<%= period item %>: <%= item.subject %>*
58
+ ** <%= period item %>: <%= item.subject %>
56
59
  <%= propertify item, " " %>
57
60
 
58
61
  <%= [item["role"], item["school"], item["who"]].join(", ") %>
@@ -64,7 +67,7 @@
64
67
  * Projects
65
68
 
66
69
  <% (data.projects || []).each do |item| -%>
67
- ** *<%= period item %>: <%= [item.name, item.role].join(", ") %>*
70
+ ** <%= period item %>: <%= [item.name, item.role].join(", ") %>
68
71
  <%= propertify item, " " %>
69
72
 
70
73
  <%= reflow_to_string item["summary"], 72, " " -%>
@@ -73,10 +76,10 @@
73
76
  <% end -%>
74
77
 
75
78
  <% if data["other"] -%>
76
- * Other Initiatives
79
+ * Other
77
80
 
78
81
  <% (data.other || []).each do |item| -%>
79
- ** *<%= period item %>: <%= [item["who"], item["role"]].join(", ") %>*
82
+ ** <%= period item %>: <%= [item["who"], item["role"]].join(", ") %>
80
83
  <%= propertify item, " " %>
81
84
 
82
85
  <%= reflow_to_string item["summary"], 72, " " -%>
@@ -150,7 +153,7 @@
150
153
  * <%= group.capitalize %>
151
154
 
152
155
  <% (group || []).each do |item| -%>
153
- ** *<%= item.date %>: <%= [item.title, item.who, item.address].join(", ") %>*
156
+ ** <%= item.date %>: <%= [item.title, item.who, item.address].join(", ") %>
154
157
  <%= propertify item, " " %>
155
158
 
156
159
  <%= reflow_to_string item.summary, 72, " " -%>