multiformat-cv 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/multiformatcv.rb +44 -0
- data/lib/multiformatcv/contact.rb +32 -0
- data/lib/multiformatcv/job.rb +40 -0
- data/lib/multiformatcv/personal.rb +26 -0
- data/lib/multiformatcv/project.rb +46 -0
- data/lib/multiformatcv/resume.rb +41 -0
- data/lib/multiformatcv/templates/cv.html.erb +66 -0
- data/lib/multiformatcv/templates/cv.tex.erb +66 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b6677b813b81fb570431de8d0879e0fd7f03688d
|
4
|
+
data.tar.gz: 5341b0590756511b160d9ea80af26122d8ed423a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7d2d60c6602c4583ea0f7745f735e1019655306457d8622c972d668aea42c59d6af380a2e46e8fe864c0a7d898a08370a0cc28bad2b6170878d483ce23f701d
|
7
|
+
data.tar.gz: 8b7e24762a0cf2e6a096bf7a396b746758264f072129805ece8b59c2af43b7fd71102ae785851b33d6b5f7085c091ea3f4f589ae29ccde9ed5677a92b6f5ca1a
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erubi'
|
3
|
+
|
4
|
+
module MultiformatCV
|
5
|
+
|
6
|
+
# YAML files that will be read from the specified directory
|
7
|
+
YML_FILES = %w( contact jobs personal )
|
8
|
+
|
9
|
+
# Parse yaml files located at data directory
|
10
|
+
#
|
11
|
+
# @param [Hash] opts Options to specify format and templates source
|
12
|
+
# @option opts [String] :data_dir Directory where the YAML files are located.
|
13
|
+
# @option opts [Symbol] :format One of [ :html, :tex ]
|
14
|
+
# @option opts [String] :templates Directory where templates are located,
|
15
|
+
# expected template files are `cv.#{ format }.erb`
|
16
|
+
#
|
17
|
+
# @return [String] Evaluated Erubi::Engine's source
|
18
|
+
# @see https://www.rubydoc.info/gems/erubi/1.8.0 Erubi documentation
|
19
|
+
# @see Erubi::Engine
|
20
|
+
def self.generate(opts = {})
|
21
|
+
opts[:format] ||= :html
|
22
|
+
opts[:data_dir] ||= 'data'
|
23
|
+
opts[:templates] ||= File.expand_path("../multiformatcv/templates", __FILE__)
|
24
|
+
|
25
|
+
template = File.read("#{ opts[:templates] }/cv.#{ opts[:format].to_s }.erb")
|
26
|
+
resume = Resume.new
|
27
|
+
yml = nil
|
28
|
+
|
29
|
+
YML_FILES.each do |f|
|
30
|
+
yml = YAML.load_file("#{ opts[:data_dir] }/#{ f }.yml")
|
31
|
+
if yml then
|
32
|
+
resume.send("add_#{ f }", yml[f])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
eval Erubi::Engine.new(template).src
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
require 'multiformatcv/contact'
|
41
|
+
require 'multiformatcv/job'
|
42
|
+
require 'multiformatcv/personal'
|
43
|
+
require 'multiformatcv/project'
|
44
|
+
require 'multiformatcv/resume'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class MultiformatCV::Contact
|
2
|
+
attr_accessor :name,
|
3
|
+
:title,
|
4
|
+
:phone,
|
5
|
+
:email
|
6
|
+
|
7
|
+
# Hash of links
|
8
|
+
#
|
9
|
+
# == Example:
|
10
|
+
# links = { github: 'https://www.github.com/john.doe/personal-dashboard' }
|
11
|
+
attr_accessor :links
|
12
|
+
|
13
|
+
# Create Contact instance
|
14
|
+
#
|
15
|
+
# == Example:
|
16
|
+
# contact = MultiformatCV::Contact.new(title: 'Accountant', name: 'John Doe')
|
17
|
+
#
|
18
|
+
# @param [Hash] h Instance initializer; keys *MUST* be strings
|
19
|
+
# @option h [String] 'name'
|
20
|
+
# @option h [String] 'title'
|
21
|
+
# @option h [String] 'email'
|
22
|
+
# @option h [String] 'phone'
|
23
|
+
# @option h [Hash<String, String>] 'links'
|
24
|
+
|
25
|
+
def initialize(h = {})
|
26
|
+
@name = h['name']
|
27
|
+
@title = h['title']
|
28
|
+
@email = h['email']
|
29
|
+
@phone = h['phone']
|
30
|
+
@links = h['links']
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class MultiformatCV::Job
|
2
|
+
attr_accessor :position,
|
3
|
+
:company,
|
4
|
+
:start_date,
|
5
|
+
:end_date,
|
6
|
+
:summary
|
7
|
+
|
8
|
+
# List of projects that you worked on during this job
|
9
|
+
# @return [Array<MultiformatCV::Project>]
|
10
|
+
attr_accessor :projects
|
11
|
+
|
12
|
+
# Create Job instance
|
13
|
+
#
|
14
|
+
# == Example:
|
15
|
+
# job = MultiformatCV::Job.new(position: 'Accountant', company: 'Accountants Inc.')
|
16
|
+
#
|
17
|
+
# @param [Hash] h Instance initializer; keys *MUST* be strings
|
18
|
+
# @option h [String] 'position'
|
19
|
+
# @option h [String] 'company'
|
20
|
+
# @option h [String] 'start_date'
|
21
|
+
# @option h [String] 'end_date'
|
22
|
+
# @option h [String] 'summary'
|
23
|
+
# @option h [Array<Hash>] 'projects' List of hashes that will be used to
|
24
|
+
# initialize new MultiformatCV::Porject entries
|
25
|
+
#
|
26
|
+
# @see MultiformatCV::Project
|
27
|
+
|
28
|
+
def initialize(h = {})
|
29
|
+
@position = h['position']
|
30
|
+
@company = h['company']
|
31
|
+
@start_date = h['start_date']
|
32
|
+
@end_date = h['end_date']
|
33
|
+
@summary = h['summary']
|
34
|
+
@projects = []
|
35
|
+
|
36
|
+
h['projects'].each do |p|
|
37
|
+
@projects << MultiformatCV::Project.new(p)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class MultiformatCV::Personal
|
2
|
+
attr_accessor :summary
|
3
|
+
|
4
|
+
# List of personal projects
|
5
|
+
# @return [Array<MultiformatCV::Project>]
|
6
|
+
attr_accessor :projects
|
7
|
+
|
8
|
+
# Create Personal information instance
|
9
|
+
#
|
10
|
+
# == Example:
|
11
|
+
# personal = MultiformatCV::Personal.new(summary: 'Volunteer at...', projects: [])
|
12
|
+
#
|
13
|
+
# @param [Hash] h Instance initializer; keys *MUST* be strings
|
14
|
+
# @option h [String] 'summary'
|
15
|
+
# @option h [Array<Hash>] 'projects' List of hashes that will be used to
|
16
|
+
# initialize new MultiformatCV::Porject entries
|
17
|
+
#
|
18
|
+
# @see MultiformatCV::Project
|
19
|
+
|
20
|
+
def initialize(h = {})
|
21
|
+
@summary = h['summary']
|
22
|
+
@projects = []
|
23
|
+
|
24
|
+
h['projects'].each { |p| @projects << MultiformatCV::Project.new(p) }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class MultiformatCV::Project
|
2
|
+
attr_accessor :name,
|
3
|
+
:start_date,
|
4
|
+
:end_date,
|
5
|
+
:position,
|
6
|
+
:summary,
|
7
|
+
:tasks,
|
8
|
+
:technologies
|
9
|
+
|
10
|
+
# Repository URL for the project
|
11
|
+
attr_accessor :repo
|
12
|
+
|
13
|
+
# Page or site URL for the project
|
14
|
+
attr_accessor :url
|
15
|
+
|
16
|
+
# Create Project instance
|
17
|
+
#
|
18
|
+
# == Example:
|
19
|
+
# project = MultiformatCV::Project.new(name: 'Life Solver (TM)', summary: '...', ...)
|
20
|
+
#
|
21
|
+
# @param [Hash] h Instance initializer; keys *MUST* be strings
|
22
|
+
# @option h [String] 'name'
|
23
|
+
# @option h [String] 'position'
|
24
|
+
# @option h [String] 'start_date'
|
25
|
+
# @option h [String] 'end_date'
|
26
|
+
# @option h [String] 'repo' Repository URL
|
27
|
+
# @option h [String] 'url' URL for the project
|
28
|
+
# @option h [String] 'summary' Project description, goals, etc.
|
29
|
+
# @option h [Array<String>] 'tasks' Tasks done for the project
|
30
|
+
# @option h [Array<String>] 'technologies' Technologies used in the project
|
31
|
+
|
32
|
+
def initialize(h = {})
|
33
|
+
@name = h['name']
|
34
|
+
@position = h['position']
|
35
|
+
@start_date = h['start_date']
|
36
|
+
@end_date = h['end_date']
|
37
|
+
@repo = h['repo']
|
38
|
+
@summary = h['summary']
|
39
|
+
@url = h['url']
|
40
|
+
@tasks = []
|
41
|
+
@technologies = []
|
42
|
+
|
43
|
+
h['tasks'].each { |t| @tasks << t } if h['tasks']
|
44
|
+
h['technologies'].each { |t| @technologies << t } if h['technologies']
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class MultiformatCV::Resume
|
2
|
+
# Contact information
|
3
|
+
# @return [MultiformatCV::Contact]
|
4
|
+
attr_accessor :contact
|
5
|
+
|
6
|
+
# List of jobs
|
7
|
+
# @return [Array<MultiformatCV::Job>]
|
8
|
+
attr_accessor :jobs
|
9
|
+
|
10
|
+
# Personal accomplishments and projects
|
11
|
+
# @return [MultiformatCV::Personal]
|
12
|
+
attr_accessor :personal
|
13
|
+
|
14
|
+
def initialize(h = {})
|
15
|
+
@jobs = []
|
16
|
+
end
|
17
|
+
|
18
|
+
# Set contact information
|
19
|
+
# @param [Hash] h Hash used to initialize new MultiformatCV::Contact
|
20
|
+
# @see MultiformatCV::Contact
|
21
|
+
def add_contact(h = {})
|
22
|
+
@contact = MultiformatCV::Contact.new(h)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Add list of job entries to @jobs list
|
26
|
+
#
|
27
|
+
# @param [Array<Hash>] arr List of hashes that will be used to initialize new
|
28
|
+
# MultiformatCV::Job entries
|
29
|
+
#
|
30
|
+
# @see MultiformatCV::Job
|
31
|
+
def add_jobs(arr = [])
|
32
|
+
arr.each { |j| @jobs << MultiformatCV::Job.new(j) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set personal information
|
36
|
+
# @param [Hash] h Hash used to initialize new MultiformatCV::Personal
|
37
|
+
# @see MultiformatCV::Personal
|
38
|
+
def add_personal(h = {})
|
39
|
+
@personal = MultiformatCV::Personal.new(h)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
5
|
+
<title><%= "#{ resume.contact.name } - #{ resume.contact.title }" %></title>
|
6
|
+
<style>
|
7
|
+
html {
|
8
|
+
font: normal 16px/20px sans-serif, serif;
|
9
|
+
max-width: 90%;
|
10
|
+
margin: 2rem auto;
|
11
|
+
}
|
12
|
+
h1 { font-size: 1.6rem; line-height: 1.8rem; color: #000; }
|
13
|
+
h2 { font-size: 1.5rem; line-height: 1.7rem; color: #222; }
|
14
|
+
h3 { font-size: 1.4rem; line-height: 1.6rem; color: #444; }
|
15
|
+
h4 { font-size: 1.3rem; line-height: 1.5rem; color: #555; }
|
16
|
+
h5 { font-size: 1.2rem; line-height: 1.4rem; color: #666; }
|
17
|
+
h6 { font-size: 1.1rem; line-height: 1.3rem; color: #777; }
|
18
|
+
.text-right { text-align: right; }
|
19
|
+
|
20
|
+
.job {
|
21
|
+
border-bottom: 1px solid #666;
|
22
|
+
}
|
23
|
+
.project {}
|
24
|
+
</style>
|
25
|
+
</head>
|
26
|
+
<body>
|
27
|
+
<header>
|
28
|
+
<h1><%= "#{ resume.contact.name } - #{ resume.contact.title }" %></h1>
|
29
|
+
<div class="text-right">
|
30
|
+
<a href="mailto:<%= resume.contact.email %>" class="email"><%= resume.contact.email %></a><br>
|
31
|
+
<a href="tel:<%= resume.contact.phone %>" class="phone"><%= resume.contact.phone %></a>
|
32
|
+
</div>
|
33
|
+
</header>
|
34
|
+
|
35
|
+
<section id="jobs">
|
36
|
+
<h2>Work Experience</h2>
|
37
|
+
<% resume.jobs.each do |job| %>
|
38
|
+
<article class="job">
|
39
|
+
<header>
|
40
|
+
<h3><%= "#{ job.position } — #{ job.company }" %></h3>
|
41
|
+
</header>
|
42
|
+
<p><%= job.summary.chomp %></p>
|
43
|
+
<% job.projects.each do |project| %>
|
44
|
+
<article class="project">
|
45
|
+
<h4><%= project.name %></h4>
|
46
|
+
|
47
|
+
<h5>Technologies</h5>
|
48
|
+
<ul class="technologies">
|
49
|
+
<% project.technologies.each do |tech| %>
|
50
|
+
<li><%= tech %></li>
|
51
|
+
<% end %>
|
52
|
+
</ul>
|
53
|
+
|
54
|
+
<h5>Tasks</h5>
|
55
|
+
<ul class="tasks">
|
56
|
+
<% project.tasks.each do |task| %>
|
57
|
+
<li><%= task %></li>
|
58
|
+
<% end %>
|
59
|
+
</ul>
|
60
|
+
</article>
|
61
|
+
<% end %>
|
62
|
+
</article>
|
63
|
+
<% end %>
|
64
|
+
</section>
|
65
|
+
</body>
|
66
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
\documentclass{article}
|
2
|
+
|
3
|
+
\title{<%= resume.contact.name %>}
|
4
|
+
\author{<%= resume.contact.name %>}
|
5
|
+
|
6
|
+
\begin{document}
|
7
|
+
|
8
|
+
\maketitle
|
9
|
+
|
10
|
+
\section{\centerline{Proffesional Experience}}
|
11
|
+
|
12
|
+
\vspace{8pt}
|
13
|
+
|
14
|
+
<% resume.jobs.each do |job| %>
|
15
|
+
|
16
|
+
\subsection{<%= job.company %> -- <%= job.position %>}
|
17
|
+
\hfill <%= job.start_date %> -- <%= job.end_date or 'present' %>
|
18
|
+
|
19
|
+
<%- if job.summary %><%= job.summary %><% end -%>
|
20
|
+
|
21
|
+
<% job.projects.each do |project| %>
|
22
|
+
\subsubsection{<%= project.name %>}
|
23
|
+
|
24
|
+
<%- if project.summary %><%= project.summary %><% end -%>
|
25
|
+
|
26
|
+
|
27
|
+
\noindent Technologies
|
28
|
+
|
29
|
+
\begin{itemize}
|
30
|
+
<% project.technologies.each do |tech| %>
|
31
|
+
\item <%= tech %>
|
32
|
+
<% end %>
|
33
|
+
\end{itemize}
|
34
|
+
|
35
|
+
\noindent Tasks
|
36
|
+
|
37
|
+
\begin{itemize}
|
38
|
+
<% project.tasks.each do |task| %>
|
39
|
+
\item <%= task %>
|
40
|
+
<% end %>
|
41
|
+
\end{itemize}
|
42
|
+
<% end %>
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
\section{\centerline{Personal Projects}}
|
46
|
+
|
47
|
+
\vspace{8pt}
|
48
|
+
|
49
|
+
<%- if resume.personal and resume.personal.summary %>
|
50
|
+
<%= resume.personal.summary %>
|
51
|
+
<% end -%>
|
52
|
+
|
53
|
+
<% resume.personal.projects.each do |project| %>
|
54
|
+
\subsubsection{<%= project.name %>}
|
55
|
+
|
56
|
+
<%- if project.summary %><%= project.summary %><% end -%>
|
57
|
+
|
58
|
+
\noindent Technologies
|
59
|
+
|
60
|
+
\begin{itemize}
|
61
|
+
<% project.technologies.each do |tech| %>
|
62
|
+
\item <%= tech %>
|
63
|
+
<% end %>
|
64
|
+
\end{itemize}
|
65
|
+
<% end %>
|
66
|
+
\end{document}
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multiformat-cv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- JuanKman94
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: erubi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
description: Multi-format CV generator from YAML files
|
28
|
+
email: juan.carlos.menonita@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/multiformatcv.rb
|
34
|
+
- lib/multiformatcv/contact.rb
|
35
|
+
- lib/multiformatcv/job.rb
|
36
|
+
- lib/multiformatcv/personal.rb
|
37
|
+
- lib/multiformatcv/project.rb
|
38
|
+
- lib/multiformatcv/resume.rb
|
39
|
+
- lib/multiformatcv/templates/cv.html.erb
|
40
|
+
- lib/multiformatcv/templates/cv.tex.erb
|
41
|
+
homepage: https://www.gitlab.com/juankman94/multiformat-cv
|
42
|
+
licenses:
|
43
|
+
- MIT
|
44
|
+
metadata: {}
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 2.6.14.3
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: Generate your CV in different formats
|
65
|
+
test_files: []
|