resme 0.4.0 → 0.5.1
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/CHANGELOG.org +60 -0
- data/Gemfile.lock +20 -0
- data/README.org +71 -58
- data/lib/resme/cli/command_semantics.rb +22 -17
- data/lib/resme/cli/command_syntax.rb +29 -0
- data/lib/resme/cli/resume_structure_validator.rb +293 -0
- data/lib/resme/renderer/renderer.rb +6 -52
- data/lib/resme/templates/resume.json.erb +148 -130
- data/lib/resme/templates/resume.md.erb +36 -36
- data/lib/resme/templates/resume.org.erb +45 -45
- data/lib/resme/templates/resume.xml.erb +108 -107
- data/lib/resme/version.rb +1 -1
- data/lib/resme.rb +1 -0
- data/resme.gemspec +7 -7
- metadata +21 -19
- data/lib/resme/templates/schema.yml +0 -494
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de3845cee948da0b1588b074a720662d5ea22a8c1cb1176aad2fa09f6f7cab3f
|
4
|
+
data.tar.gz: 83ae22f7d7731406fdd3940e97c9e39c9a61b07336e95f2efc369cae719687f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32d94c5d909f54888d2a8fa184aaa05f8a9d8075d6f3f19ff6654bf23e58f82e54e96d84ea08de148548ed0260396c6d9790b6dbc0e3992c295157b5713bb952
|
7
|
+
data.tar.gz: 41386481b15b5b14ba86efbd23b29331341b22f91ebcc70497d8293609414a15e8c06518ad441e0cd26f78b552a47e7d125c42bc495f17def2bbd16314fe52b5
|
data/CHANGELOG.org
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#+TITLE: CHANGELOG
|
2
|
+
#+AUTHOR: Adolfo Villafiorita
|
3
|
+
|
4
|
+
* Version 0.5.1
|
5
|
+
|
6
|
+
A bug-fixing release.
|
7
|
+
|
8
|
+
More in details:
|
9
|
+
|
10
|
+
- [bug] Add dependency to =classy_hash=
|
11
|
+
- [doc] Fix links to source code and Changelog.
|
12
|
+
- [doc] Merge Release History and Changelog.
|
13
|
+
- [doc] Fix version numbers in headers of Changelog (1.5.0 -> 0.5.0)
|
14
|
+
|
15
|
+
* Version 0.5.0
|
16
|
+
- [user] New command =view= allows to view the template used
|
17
|
+
for generating a resume in a specific format
|
18
|
+
- [user] Check command is now based on ClassyHash
|
19
|
+
- [code] Various changes to the code
|
20
|
+
|
21
|
+
* Version 0.4.0
|
22
|
+
|
23
|
+
Version 0.4.0 refactors all generation commands under =generate=, provides
|
24
|
+
new filtering options, adds =-e= option (for custom templates), and
|
25
|
+
refactors various portions of code. It also revises this document
|
26
|
+
and fixes some minor bugs.
|
27
|
+
|
28
|
+
More in details:
|
29
|
+
|
30
|
+
- [user] New option =--skip= allows to skip some top-level sections.
|
31
|
+
You mileage might vary, as some formats might require the
|
32
|
+
information you are trying to skip
|
33
|
+
- [user] New command =generate= is now used to generate the Resume
|
34
|
+
in different formats.
|
35
|
+
- [user] New option =--erb= allows to specify a custom template for
|
36
|
+
generating the resume. Use it in conjunction with =view= (released
|
37
|
+
in version 1.5.0) to jump-start your layout.
|
38
|
+
|
39
|
+
* Version 0.3.2 and 0.3.1
|
40
|
+
|
41
|
+
Version 0.3.2 and 0.3.1 fix errors with the Europass format: lists of
|
42
|
+
projects, interests, ... are now properly formatted.
|
43
|
+
|
44
|
+
* Version 0.3
|
45
|
+
|
46
|
+
Version 0.3 Introduces output to org-mode, introduces references for the CV,
|
47
|
+
improves output to JSON, adds a =check= command, removes useless blank
|
48
|
+
lines in the output, supports =-%>= in the ERB templates, fixes
|
49
|
+
various typos in the documentation, introduces various new formatting
|
50
|
+
functions, to simplify template generation
|
51
|
+
|
52
|
+
* Version 0.2
|
53
|
+
|
54
|
+
Version 0.2 improves output of volunteering activities and other information
|
55
|
+
in the Europass and *significantly improves error and warning
|
56
|
+
reporting*
|
57
|
+
|
58
|
+
* Version 0.1
|
59
|
+
|
60
|
+
Version 0.1 is the first release
|
data/Gemfile.lock
ADDED
data/README.org
CHANGED
@@ -17,20 +17,20 @@ needs).
|
|
17
17
|
|
18
18
|
Add this line to your application's Gemfile:
|
19
19
|
|
20
|
-
#+
|
21
|
-
|
22
|
-
#+
|
20
|
+
#+begin_example ruby
|
21
|
+
gem 'resme'
|
22
|
+
#+end_example
|
23
23
|
|
24
24
|
And then execute:
|
25
25
|
|
26
|
-
#+
|
27
|
-
|
28
|
-
#+
|
26
|
+
#+begin_example sh
|
27
|
+
bundle
|
28
|
+
#+end_example
|
29
29
|
|
30
30
|
Or install it yourself as:
|
31
31
|
|
32
|
-
#+
|
33
|
-
|
32
|
+
#+begin_example sh
|
33
|
+
gem install resme
|
34
34
|
#+END_EXAMPLE
|
35
35
|
|
36
36
|
** Usage
|
@@ -40,9 +40,9 @@ Or install it yourself as:
|
|
40
40
|
|
41
41
|
Start with:
|
42
42
|
|
43
|
-
#+
|
43
|
+
#+begin_example sh
|
44
44
|
resme init
|
45
|
-
#+
|
45
|
+
#+end_example
|
46
46
|
|
47
47
|
which generates a YML template for your resume in the current directory.
|
48
48
|
Comments in the YML file should help you fill the various entries.
|
@@ -51,7 +51,7 @@ are not relevant for your resume.
|
|
51
51
|
|
52
52
|
You can now generate a resume using one of the existing formats:
|
53
53
|
|
54
|
-
#+begin_example
|
54
|
+
#+begin_example sh
|
55
55
|
resme --to org resume.yml
|
56
56
|
#+end_example
|
57
57
|
|
@@ -64,18 +64,33 @@ Supported formats include:
|
|
64
64
|
- =json=: JSON format (https://jsonresume.org/)
|
65
65
|
|
66
66
|
If you are not satisfied with the provided templates, you can write
|
67
|
-
your own (see below).
|
68
|
-
renderer.
|
67
|
+
your own (see below).
|
69
68
|
|
70
|
-
|
69
|
+
Notice that you can specify more than one YML file in input. This allows you to
|
70
|
+
store data about your resume in different files, if you like to do so
|
71
|
+
(e.g., work experiences could be in one file and talks in another).
|
72
|
+
The YML files are merged before processing them.
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
Full syntax:
|
75
|
+
|
76
|
+
#+begin_src shell :results raw output :wrap example
|
77
|
+
resme help
|
78
|
+
#+end_src
|
79
|
+
|
80
|
+
#+RESULTS:
|
81
|
+
#+begin_example
|
82
|
+
resme command [options] [args]
|
83
|
+
Available commands:
|
84
|
+
check resume.yml # Check syntax of resume.yml
|
85
|
+
list resume.yml # List main sections in resume.yml
|
86
|
+
version # print version information
|
87
|
+
view --template FORMAT # Print template used for format
|
88
|
+
generate [options] resume.yml ... # output resume
|
89
|
+
console # enter the console
|
90
|
+
man # print resme manual page
|
91
|
+
help [command] # print command usage
|
92
|
+
init [options] # generate an empty resume.yml file
|
93
|
+
#+end_example
|
79
94
|
|
80
95
|
** Checking validity
|
81
96
|
:PROPERTIES:
|
@@ -85,9 +100,9 @@ Remarks:
|
|
85
100
|
Use the =check= command to verify whether your YAML file conforms with
|
86
101
|
the intended syntax.
|
87
102
|
|
88
|
-
#+
|
103
|
+
#+begin_example sh
|
89
104
|
resme check resume.yaml
|
90
|
-
#+
|
105
|
+
#+end_example
|
91
106
|
|
92
107
|
** Dates in the resume
|
93
108
|
:PROPERTIES:
|
@@ -110,28 +125,36 @@ The third and the forth format allows you to enter "partial" dates
|
|
110
125
|
:END:
|
111
126
|
|
112
127
|
The resumes are generated from the YML matter using ERB templates. The
|
113
|
-
provided output formats should support different back ends
|
114
|
-
and Markdown easily allow for generation of PDFs, HTML,
|
115
|
-
mention a few
|
116
|
-
|
117
|
-
However, if you want, you can define your own templates.
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
#+
|
123
|
-
|
124
|
-
|
125
|
-
|
128
|
+
provided output formats should support different back ends. Org Mode
|
129
|
+
and Markdown, for instance, easily allow for generation of PDFs, HTML,
|
130
|
+
and ODT, to mention a few.
|
131
|
+
|
132
|
+
However, if you want, you can define your own templates.
|
133
|
+
|
134
|
+
Use the command =view= to print one of the templates used by =resme=
|
135
|
+
and build from that.
|
136
|
+
|
137
|
+
#+begin_example sh
|
138
|
+
resme view --template md
|
139
|
+
#+end_example
|
140
|
+
|
141
|
+
Notice that all the data in the resume is made available in the =data=
|
142
|
+
variable. Thus, for instance, the following code snippets generates a
|
143
|
+
list of all the work experiences:
|
144
|
+
|
145
|
+
#+begin_example xml
|
146
|
+
<% data["work"] each do |exp| %>
|
147
|
+
- <%= exp["who"] %>
|
148
|
+
From: <%= exp["from"] %> till: <%= exp["till"] %>
|
126
149
|
<% end %>
|
127
|
-
#+
|
150
|
+
#+end_example
|
128
151
|
|
129
|
-
To specify your own ERB template use the option
|
130
|
-
for instance:
|
152
|
+
To specify your own ERB template to build your resume use the option
|
153
|
+
=-e= (=--erb=). Thus, for instance:
|
131
154
|
|
132
|
-
#+
|
133
|
-
|
134
|
-
#+
|
155
|
+
#+begin_example sh
|
156
|
+
resme render -e template.md.erb [-o output_filename] file.yaml ...
|
157
|
+
#+end_example
|
135
158
|
|
136
159
|
uses =template.md.erb= to generate the resume.
|
137
160
|
|
@@ -200,12 +223,16 @@ https://github.com/avillafiorita/resme.
|
|
200
223
|
The gem is available as open source under the terms of the
|
201
224
|
[[http://opensource.org/licenses/MIT][MIT License]].
|
202
225
|
|
226
|
+
** Change Log
|
227
|
+
|
228
|
+
In [[file:./CHANGELOG.org][CHANGELOG.org]]
|
229
|
+
|
203
230
|
** Roadmap
|
204
231
|
:PROPERTIES:
|
205
232
|
:CUSTOM_ID: roadmap
|
206
233
|
:END:
|
207
234
|
|
208
|
-
In
|
235
|
+
In [[file:./doc/todo.org][todo.org]] ... guess what is my preferred editor!
|
209
236
|
|
210
237
|
** Bugs
|
211
238
|
:PROPERTIES:
|
@@ -228,18 +255,4 @@ Unknown number of unknown bugs.
|
|
228
255
|
:CUSTOM_ID: release-history
|
229
256
|
:END:
|
230
257
|
|
231
|
-
|
232
|
-
new filtering options, adds =-e= option (for custom templates), and
|
233
|
-
refactors various portions of code. It also revises this document
|
234
|
-
and fixes some minor bugs.
|
235
|
-
- *0.3.2* and *0.3.1* fix errors with the Europass format: lists of
|
236
|
-
projects, interests, ... are now properly formatted.
|
237
|
-
- *0.3* introduces output to org-mode, introduces references for the CV,
|
238
|
-
improves output to JSON, adds a =check= command, removes useless blank
|
239
|
-
lines in the output, supports =-%>= in the ERB templates, fixes
|
240
|
-
various typos in the documentation, introduces various new formatting
|
241
|
-
functions, to simplify template generation
|
242
|
-
- *0.2* improves output of volunteering activities and other information
|
243
|
-
in the Europass and *significantly improves error and warning
|
244
|
-
reporting*
|
245
|
-
- *0.1* is the first release
|
258
|
+
Moved to [[file:./CHANGELOG.org][CHANGELOG.org]].
|
@@ -5,7 +5,6 @@ require "date"
|
|
5
5
|
require "yaml"
|
6
6
|
require "erb"
|
7
7
|
require "json"
|
8
|
-
require "kwalify"
|
9
8
|
|
10
9
|
module Resme
|
11
10
|
module CommandSemantics
|
@@ -93,24 +92,24 @@ module Resme
|
|
93
92
|
# APP SPECIFIC COMMANDS
|
94
93
|
#
|
95
94
|
def self.check(opts, argv)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
puts "
|
95
|
+
begin
|
96
|
+
document = YAML.load_file(argv[0], permitted_classes: [Date])
|
97
|
+
rescue Psych::SyntaxError => ex
|
98
|
+
puts "The file #{argv[0]} has an invalid structure."
|
99
|
+
puts ex.message
|
100
|
+
exit 1
|
101
|
+
end
|
102
|
+
|
103
|
+
begin
|
104
|
+
errors = ResumeStructureValidator.validate(document)
|
105
|
+
rescue Exception => ex
|
106
|
+
puts "The files #{argv[0]} does not validate"
|
107
|
+
ex.entries.each do |error|
|
108
|
+
puts "#{error[:full_path]}: #{error[:message]}"
|
110
109
|
end
|
111
|
-
|
112
|
-
puts "The file #{argv[0]} validates."
|
110
|
+
exit 1
|
113
111
|
end
|
112
|
+
puts "The file #{argv[0]} has a valid structure."
|
114
113
|
end
|
115
114
|
|
116
115
|
def self.init(opts, argv)
|
@@ -141,6 +140,12 @@ module Resme
|
|
141
140
|
end
|
142
141
|
end
|
143
142
|
|
143
|
+
def self.view(opts, argv)
|
144
|
+
format = opts[:template] == "europass" ? "xml" : opts[:template]
|
145
|
+
template = File.join(File.dirname(__FILE__), "/../templates/resume.#{format}.erb")
|
146
|
+
puts File.read template
|
147
|
+
end
|
148
|
+
|
144
149
|
def self.generate(opts, argv)
|
145
150
|
format = opts[:to] == "europass" ? "xml" : opts[:to]
|
146
151
|
output = opts[:output] || "resume-#{Date.today}.#{format}"
|
@@ -217,6 +217,35 @@ module Resme
|
|
217
217
|
}
|
218
218
|
end
|
219
219
|
|
220
|
+
def self.view_opts
|
221
|
+
opts = OptionParser.new do |o|
|
222
|
+
o.banner = "view --template FORMAT # Print template used for format"
|
223
|
+
o.on("-t", "--template FORMAT", String, "View template for FORMAT")
|
224
|
+
end
|
225
|
+
|
226
|
+
help = <<-EOS
|
227
|
+
NAME
|
228
|
+
#{opts.banner}
|
229
|
+
|
230
|
+
SYNOPSYS
|
231
|
+
#{opts.to_s}
|
232
|
+
|
233
|
+
DESCRIPTION
|
234
|
+
Print template used for FORMAT
|
235
|
+
|
236
|
+
EXAMPLES
|
237
|
+
resme view --template md
|
238
|
+
EOS
|
239
|
+
|
240
|
+
{
|
241
|
+
view: {
|
242
|
+
name: :view,
|
243
|
+
options: opts,
|
244
|
+
help: help.gsub(" ", "")
|
245
|
+
}
|
246
|
+
}
|
247
|
+
end
|
248
|
+
|
220
249
|
def self.generate_opts
|
221
250
|
opts = OptionParser.new do |o|
|
222
251
|
o.banner = "generate [options] resume.yml ... # output resume"
|
@@ -0,0 +1,293 @@
|
|
1
|
+
require "classy_hash"
|
2
|
+
require "date"
|
3
|
+
|
4
|
+
module Resme
|
5
|
+
module ResumeStructureValidator
|
6
|
+
OPTIONAL_STRING = [:optional, String, NilClass]
|
7
|
+
OPTIONAL_PARTIAL_DATE = [:optional, Date, String, Integer, NilClass]
|
8
|
+
PARTIAL_DATE = [Date, String, Integer]
|
9
|
+
|
10
|
+
def self.validate(loaded_yaml)
|
11
|
+
errors = []
|
12
|
+
ClassyHash.validate(
|
13
|
+
loaded_yaml,
|
14
|
+
SCHEMA,
|
15
|
+
errors: errors,
|
16
|
+
strict: true,
|
17
|
+
raise_errors: true,
|
18
|
+
full: true
|
19
|
+
)
|
20
|
+
errors
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# This defines the structure of resume.yml
|
25
|
+
# We validate it with ClassyHash
|
26
|
+
#
|
27
|
+
SCHEMA = {
|
28
|
+
"basics" => {
|
29
|
+
"first_name" => String,
|
30
|
+
"middle_name" => OPTIONAL_STRING,
|
31
|
+
"last_name" => String,
|
32
|
+
"title" => OPTIONAL_STRING,
|
33
|
+
"picture" => OPTIONAL_STRING,
|
34
|
+
"birthdate" => [:optional, Date, NilClass],
|
35
|
+
"nationality" => OPTIONAL_STRING,
|
36
|
+
"marital_status" => OPTIONAL_STRING,
|
37
|
+
"gender" => OPTIONAL_STRING
|
38
|
+
},
|
39
|
+
"contacts" => [[ {
|
40
|
+
"label" => String,
|
41
|
+
"value" => String
|
42
|
+
} ]],
|
43
|
+
"addresses" => [[ {
|
44
|
+
"label" => String,
|
45
|
+
"street" => OPTIONAL_STRING,
|
46
|
+
"zip_code" => [:optional, String, Integer, NilClass],
|
47
|
+
"city" => OPTIONAL_STRING,
|
48
|
+
"country" => OPTIONAL_STRING
|
49
|
+
} ]],
|
50
|
+
"web_presence" => [:optional,
|
51
|
+
[[
|
52
|
+
{
|
53
|
+
"label" => String,
|
54
|
+
"value" => String
|
55
|
+
},
|
56
|
+
]],
|
57
|
+
NilClass
|
58
|
+
],
|
59
|
+
"summary" => OPTIONAL_STRING,
|
60
|
+
"work" => [:optional,
|
61
|
+
[[
|
62
|
+
{
|
63
|
+
"who" => OPTIONAL_STRING,
|
64
|
+
"website" => OPTIONAL_STRING,
|
65
|
+
"address" => OPTIONAL_STRING,
|
66
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
67
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
68
|
+
"role" => String,
|
69
|
+
"summary" => String,
|
70
|
+
"details" => OPTIONAL_STRING
|
71
|
+
},
|
72
|
+
]],
|
73
|
+
NilClass
|
74
|
+
],
|
75
|
+
"teaching" => [:optional,
|
76
|
+
[[
|
77
|
+
{
|
78
|
+
"who" => String,
|
79
|
+
"school" => OPTIONAL_STRING,
|
80
|
+
"address" => OPTIONAL_STRING,
|
81
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
82
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
83
|
+
"role" => String,
|
84
|
+
"subject" => String,
|
85
|
+
"summary" => OPTIONAL_STRING,
|
86
|
+
"details" => OPTIONAL_STRING
|
87
|
+
}
|
88
|
+
]],
|
89
|
+
NilClass
|
90
|
+
],
|
91
|
+
"projects" => [:optional,
|
92
|
+
[[
|
93
|
+
{
|
94
|
+
"name" => String,
|
95
|
+
"size" => OPTIONAL_STRING,
|
96
|
+
"who" => OPTIONAL_STRING,
|
97
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
98
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
99
|
+
"role" => String,
|
100
|
+
"summary" => OPTIONAL_STRING,
|
101
|
+
}
|
102
|
+
]],
|
103
|
+
NilClass
|
104
|
+
],
|
105
|
+
"other" => [:optional,
|
106
|
+
[[
|
107
|
+
{
|
108
|
+
"who" => OPTIONAL_STRING,
|
109
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
110
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
111
|
+
"role" => String,
|
112
|
+
"summary" => OPTIONAL_STRING,
|
113
|
+
}
|
114
|
+
]],
|
115
|
+
NilClass
|
116
|
+
],
|
117
|
+
"committees" => [:optional,
|
118
|
+
[[
|
119
|
+
{
|
120
|
+
"who" => String,
|
121
|
+
"role" => String,
|
122
|
+
"editions" => [String, Integer],
|
123
|
+
"url" => OPTIONAL_STRING,
|
124
|
+
}
|
125
|
+
]],
|
126
|
+
NilClass
|
127
|
+
],
|
128
|
+
"volunteer" => [:optional,
|
129
|
+
[[
|
130
|
+
{
|
131
|
+
"who" => String,
|
132
|
+
"where" => OPTIONAL_STRING,
|
133
|
+
"date" => OPTIONAL_PARTIAL_DATE,
|
134
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
135
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
136
|
+
"role" => String,
|
137
|
+
"summary" => OPTIONAL_STRING,
|
138
|
+
}
|
139
|
+
]],
|
140
|
+
NilClass
|
141
|
+
],
|
142
|
+
"visits" => [:optional,
|
143
|
+
[[
|
144
|
+
{
|
145
|
+
"who" => String,
|
146
|
+
"address" => OPTIONAL_STRING,
|
147
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
148
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
149
|
+
"role" => String,
|
150
|
+
"summary" => OPTIONAL_STRING,
|
151
|
+
}
|
152
|
+
]],
|
153
|
+
NilClass
|
154
|
+
],
|
155
|
+
"education" => [:optional,
|
156
|
+
[[
|
157
|
+
{
|
158
|
+
"degree" => OPTIONAL_STRING,
|
159
|
+
"topic" => OPTIONAL_STRING,
|
160
|
+
"school" => String,
|
161
|
+
"address" => OPTIONAL_STRING,
|
162
|
+
"date" => OPTIONAL_PARTIAL_DATE,
|
163
|
+
"till" => OPTIONAL_PARTIAL_DATE,
|
164
|
+
"from" => OPTIONAL_PARTIAL_DATE,
|
165
|
+
"publish" => TrueClass,
|
166
|
+
"score" => [:optional, String, Integer, NilClass],
|
167
|
+
}
|
168
|
+
]],
|
169
|
+
NilClass
|
170
|
+
],
|
171
|
+
"publications" => [:optional,
|
172
|
+
[[
|
173
|
+
{
|
174
|
+
"title" => String,
|
175
|
+
"authors" => String,
|
176
|
+
"publisher" => String,
|
177
|
+
"date" => PARTIAL_DATE,
|
178
|
+
"url" => OPTIONAL_STRING,
|
179
|
+
}
|
180
|
+
]],
|
181
|
+
NilClass
|
182
|
+
],
|
183
|
+
"talks" => [:optional,
|
184
|
+
[[
|
185
|
+
{
|
186
|
+
"title" => String,
|
187
|
+
"venue" => String,
|
188
|
+
"date" => PARTIAL_DATE,
|
189
|
+
"url" => OPTIONAL_STRING,
|
190
|
+
}
|
191
|
+
]],
|
192
|
+
NilClass
|
193
|
+
],
|
194
|
+
"awards" => [:optional,
|
195
|
+
[[
|
196
|
+
{
|
197
|
+
"who" => String,
|
198
|
+
"address" => OPTIONAL_STRING,
|
199
|
+
"date" => PARTIAL_DATE,
|
200
|
+
"title" => String,
|
201
|
+
"summary" => OPTIONAL_STRING
|
202
|
+
}
|
203
|
+
]],
|
204
|
+
NilClass
|
205
|
+
],
|
206
|
+
"achievements" => [:optional,
|
207
|
+
[[
|
208
|
+
{
|
209
|
+
"who" => String,
|
210
|
+
"address" => OPTIONAL_STRING,
|
211
|
+
"date" => OPTIONAL_PARTIAL_DATE,
|
212
|
+
"title" => String,
|
213
|
+
"summary" => OPTIONAL_STRING
|
214
|
+
}
|
215
|
+
]],
|
216
|
+
NilClass
|
217
|
+
],
|
218
|
+
"software" => [:optional,
|
219
|
+
[[
|
220
|
+
{
|
221
|
+
"title" => String,
|
222
|
+
"url" => OPTIONAL_STRING,
|
223
|
+
"programming_language" => OPTIONAL_STRING,
|
224
|
+
"license" => OPTIONAL_STRING,
|
225
|
+
"role" => OPTIONAL_STRING,
|
226
|
+
"summary" => OPTIONAL_STRING,
|
227
|
+
}
|
228
|
+
]],
|
229
|
+
NilClass
|
230
|
+
],
|
231
|
+
"skills" => [:optional,
|
232
|
+
[[
|
233
|
+
{
|
234
|
+
"name" => String,
|
235
|
+
"level" => OPTIONAL_STRING,
|
236
|
+
"summary" => OPTIONAL_STRING,
|
237
|
+
}
|
238
|
+
]],
|
239
|
+
NilClass
|
240
|
+
],
|
241
|
+
"driving" => [:optional,
|
242
|
+
[[ { "license" => String, } ]],
|
243
|
+
NilClass
|
244
|
+
],
|
245
|
+
"languages" => [:optional,
|
246
|
+
{
|
247
|
+
"mother_tongues" => [[
|
248
|
+
{
|
249
|
+
"code" => OPTIONAL_STRING,
|
250
|
+
"language" => String,
|
251
|
+
}
|
252
|
+
]],
|
253
|
+
"foreign" => [:optional,
|
254
|
+
[[
|
255
|
+
{
|
256
|
+
"code" => OPTIONAL_STRING,
|
257
|
+
"language" => String,
|
258
|
+
"level" => OPTIONAL_STRING,
|
259
|
+
"listening" => OPTIONAL_STRING,
|
260
|
+
"reading" => OPTIONAL_STRING,
|
261
|
+
"spoken_interaction" => OPTIONAL_STRING,
|
262
|
+
"spoken_production" => OPTIONAL_STRING,
|
263
|
+
"writing" => OPTIONAL_STRING
|
264
|
+
}
|
265
|
+
]],
|
266
|
+
NilClass
|
267
|
+
]
|
268
|
+
},
|
269
|
+
NilClass
|
270
|
+
],
|
271
|
+
"interests" => [:optional,
|
272
|
+
[[
|
273
|
+
{
|
274
|
+
"name" => String,
|
275
|
+
"level" => OPTIONAL_STRING,
|
276
|
+
"summary" => OPTIONAL_STRING,
|
277
|
+
}
|
278
|
+
]],
|
279
|
+
NilClass
|
280
|
+
],
|
281
|
+
"references" => [:optional,
|
282
|
+
[[
|
283
|
+
{
|
284
|
+
"name" => String,
|
285
|
+
"reference" => String,
|
286
|
+
"contacts" => [[ {"label" => String, "value" => String} ]]
|
287
|
+
}
|
288
|
+
]],
|
289
|
+
NilClass
|
290
|
+
]
|
291
|
+
}
|
292
|
+
end
|
293
|
+
end
|