curriculum-generator 1.0.4 → 1.0.5
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/Gemfile +1 -1
- data/README.md +6 -6
- data/Rakefile +4 -3
- data/bin/{cgen → curriculum-generator} +23 -16
- data/curriculum-generator.gemspec +36 -0
- data/lib/curriculum-generator.rb +19 -0
- data/lib/curriculum-generator/compiler.rb +102 -0
- data/lib/curriculum-generator/curriculum.rb +63 -0
- data/lib/curriculum-generator/data_loader.rb +4 -0
- data/lib/{cgen → curriculum-generator}/data_loader/yaml_data_loader.rb +2 -2
- data/lib/curriculum-generator/generator.rb +13 -0
- data/lib/curriculum-generator/generator/basic_generator.rb +42 -0
- data/lib/curriculum-generator/generator/cv_column.rb +36 -0
- data/lib/curriculum-generator/generator/cv_double_item.rb +46 -0
- data/lib/curriculum-generator/generator/cv_entry.rb +37 -0
- data/lib/curriculum-generator/generator/cv_item.rb +33 -0
- data/lib/{cgen → curriculum-generator}/generator/cv_item_with_comment.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/cv_list_double_item.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/cv_list_item.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/list.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/macro_substitution.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/specific/education.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/specific/self_assessment.rb +1 -1
- data/lib/{cgen → curriculum-generator}/generator/specific/work_experience.rb +1 -1
- data/lib/curriculum-generator/util.rb +4 -0
- data/lib/{cgen → curriculum-generator}/util/latex_to_pdf.rb +3 -3
- data/lib/{cgen → curriculum-generator}/util/logging.rb +1 -1
- data/lib/{cgen → curriculum-generator}/util/shell_command.rb +2 -2
- data/lib/curriculum-generator/version.rb +6 -0
- metadata +30 -30
- data/cgen.gemspec +0 -35
- data/lib/cgen.rb +0 -27
- data/lib/cgen/compiler.rb +0 -96
- data/lib/cgen/curriculum.rb +0 -58
- data/lib/cgen/data_loader.rb +0 -6
- data/lib/cgen/generator.rb +0 -10
- data/lib/cgen/generator/basic_generator.rb +0 -37
- data/lib/cgen/generator/cv_column.rb +0 -32
- data/lib/cgen/generator/cv_double_item.rb +0 -42
- data/lib/cgen/generator/cv_entry.rb +0 -33
- data/lib/cgen/generator/cv_item.rb +0 -29
- data/lib/cgen/util.rb +0 -6
- data/lib/cgen/version.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35549f211438e86fe041498e882c7869b61d5f99
|
4
|
+
data.tar.gz: c11c2225c8bd3b934c33c1a0cd023b3d958efa9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d4364d64e1631b1c7d6cf3d45e3a169f16e14f9de4d8e971492cb3be51691a9a71f2a7c2eefe9b1a2bd1e75865215fcce175da24d7da7b61dd2f437c79f6d1c
|
7
|
+
data.tar.gz: 276ca0fbfe4463bb8b606aafcfe65a408e893461d178dbf0289ca0fc69a2ba6f7db0d3a03ae6e8e9fdae06122d02b6b7bf04c66ef0b69abcef17530a311abc97
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# CurriculumGenerator
|
2
2
|
|
3
|
-
|
3
|
+
CurriculumGenerator is the next **localized Curriculum Vitae** editor, both for hackers and end-users.
|
4
4
|
|
5
5
|
*Please note that this is still in early development stages, bug reporting is really welcome!*
|
6
6
|
|
@@ -12,7 +12,7 @@ Via rubygems
|
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
|
-
|
15
|
+
CurriculumGenerator provides two editing modes:
|
16
16
|
|
17
17
|
* **Hacking Mode**
|
18
18
|
* **Normal Mode**
|
@@ -21,7 +21,7 @@ CGen provides two editing modes:
|
|
21
21
|
|
22
22
|

|
23
23
|
|
24
|
-
This is where
|
24
|
+
This is where CurriculumGenerator shrines, by allowing users to **just provide the data** and let the system do the rest. This system comes with *extensibility* in mind, by providing different levels of customization:
|
25
25
|
|
26
26
|
1. **Data-level**:
|
27
27
|
The first level is the most commonly used.
|
@@ -51,7 +51,7 @@ In this mode the curriculum is edited by using a GUI.
|
|
51
51
|
|
52
52
|
The project follows the **Scrum Methodology**, using Trello as the main tool.
|
53
53
|
|
54
|
-
The board is available under: [
|
54
|
+
The board is available under: [CurriculumGenerator Trello Board](https://trello.com/b/8er5R7dK/curriculum-generator)
|
55
55
|
|
56
56
|
#### Report bugs / Request enhancements
|
57
57
|
|
@@ -64,7 +64,7 @@ Create a new card in the *Product Backlog* list:
|
|
64
64
|
|
65
65
|
The project contribution is commonly done by using the so-much-famous *fork-pull pattern*:
|
66
66
|
|
67
|
-
1. Fork it ( https://github.com/[my-github-username]/
|
67
|
+
1. Fork it ( https://github.com/[my-github-username]/curriculum-generator/fork )
|
68
68
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
69
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
70
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
1
|
+
require "rake"
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/clean"
|
@@ -1,10 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
|
4
|
-
|
4
|
+
begin
|
5
|
+
require "rubygems"
|
6
|
+
gem "curriculum-generator"
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
require "curriculum-generator"
|
5
11
|
|
6
12
|
|
7
|
-
# == Setup functions
|
13
|
+
# == Setup functions ===========================================================
|
8
14
|
|
9
15
|
def setup_opts
|
10
16
|
|
@@ -39,48 +45,49 @@ def setup_filesystem
|
|
39
45
|
end
|
40
46
|
|
41
47
|
|
42
|
-
# == Utilities
|
48
|
+
# == Utilities =================================================================
|
43
49
|
|
44
50
|
def create_log_file(name)
|
45
51
|
$log_dir.join("log_#{DateTime.now.strftime('%Y.%m.%d')}_#{name}.txt")
|
46
52
|
end
|
47
53
|
|
48
54
|
|
49
|
-
# ==
|
55
|
+
# == CurriculumGenerator entry point ==========================================================
|
50
56
|
|
51
57
|
puts '> Starting Curriculum'.green
|
52
58
|
|
53
59
|
setup_opts
|
54
60
|
setup_filesystem
|
55
61
|
|
56
|
-
$curriculum =
|
57
|
-
|
58
|
-
|
62
|
+
$curriculum = CurriculumGenerator::Curriculum.new(
|
63
|
+
CurriculumGenerator::DataLoader::YamlDataLoader.new, # TODO: Let the user choose the data loader
|
64
|
+
CurriculumGenerator::Compiler.new($tex_out_pth),
|
59
65
|
$data_pth,
|
60
66
|
$template_dir_pth,
|
61
67
|
$langs,
|
62
68
|
File.directory?($data_pth.join('en')) ? :en : nil)
|
63
69
|
|
64
70
|
unless $curriculum.validate_deps($template_deps_file_pth)
|
65
|
-
|
71
|
+
CurriculumGenerator::Util::Logging.log(:fatal_error, msg: "The dependencies are not satisfied.")
|
66
72
|
end
|
67
73
|
|
68
74
|
$curriculum.compile($langs)
|
69
75
|
|
70
|
-
puts
|
76
|
+
puts ">> Generating PDFs".green
|
71
77
|
|
72
78
|
$langs.each do |lang|
|
73
|
-
puts
|
79
|
+
puts ">> Generating PDF for language #{lang.to_s.light_black}".cyan
|
74
80
|
|
75
81
|
input_dir = $tex_out_pth.join(lang.to_s)
|
76
82
|
out_pth = $out_pth.join(lang.to_s)
|
77
83
|
FileUtils.mkdir_p(out_pth)
|
78
84
|
|
79
|
-
latex_to_pdf =
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
+
latex_to_pdf = CurriculumGenerator::Util::LatexToPdf.new(
|
86
|
+
$main_tex_file_name,
|
87
|
+
input_dir,
|
88
|
+
input_dir.join($resources_dir_name).join('*').to_s,
|
89
|
+
out_pth,
|
90
|
+
create_log_file('latex_to_pdf'))
|
85
91
|
|
92
|
+
latex_to_pdf.generate
|
86
93
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require "curriculum-generator/version"
|
7
|
+
|
8
|
+
|
9
|
+
Gem::Specification.new do |spec|
|
10
|
+
|
11
|
+
spec.name = "curriculum-generator"
|
12
|
+
spec.version = CurriculumGenerator::VERSION
|
13
|
+
spec.authors = ["Alessandro Molari"]
|
14
|
+
spec.email = ["molari.alessandro@gmail.com"]
|
15
|
+
spec.summary = %q{Curriculum Vitae generator}
|
16
|
+
spec.homepage = "http://github.com/alem0lars/curriculum-generator"
|
17
|
+
spec.license = "Apache v2.0"
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", '~> 1.6'
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
|
27
|
+
spec.add_runtime_dependency "hash-deep-merge"
|
28
|
+
spec.add_runtime_dependency "monadic"
|
29
|
+
|
30
|
+
spec.add_runtime_dependency "awesome_print"
|
31
|
+
spec.add_runtime_dependency "colorize"
|
32
|
+
spec.add_runtime_dependency "highline"
|
33
|
+
|
34
|
+
spec.add_runtime_dependency "erubis"
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# ==> Require the core dependencies.
|
2
|
+
require "tmpdir"
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
# ==> Require all of the external dependencies.
|
6
|
+
require "hash_deep_merge"
|
7
|
+
require "monadic"
|
8
|
+
require "awesome_print"
|
9
|
+
require "colorize"
|
10
|
+
require "highline/import"
|
11
|
+
require "erubis"
|
12
|
+
|
13
|
+
# ==> Require the project stuff.
|
14
|
+
require "curriculum-generator/version"
|
15
|
+
require "curriculum-generator/util"
|
16
|
+
require "curriculum-generator/compiler"
|
17
|
+
require "curriculum-generator/curriculum"
|
18
|
+
require "curriculum-generator/data_loader"
|
19
|
+
require "curriculum-generator/generator"
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
class Compiler
|
3
|
+
|
4
|
+
GENERATORS = {
|
5
|
+
# Generic.
|
6
|
+
cvitem: CurriculumGenerator::Generator::CvItem,
|
7
|
+
cventry: CurriculumGenerator::Generator::CvEntry,
|
8
|
+
cvitemwithcomment: CurriculumGenerator::Generator::CvItemWithComment,
|
9
|
+
cvdoubleitem: CurriculumGenerator::Generator::CvDoubleItem,
|
10
|
+
cvlistitem: CurriculumGenerator::Generator::CvListItem,
|
11
|
+
cvlistdoubleitem: CurriculumGenerator::Generator::CvListDoubleItem,
|
12
|
+
cvcolumn: CurriculumGenerator::Generator::CvColumn,
|
13
|
+
list: CurriculumGenerator::Generator::List,
|
14
|
+
# Specific.
|
15
|
+
work_experience: CurriculumGenerator::Generator::WorkExperience,
|
16
|
+
education: CurriculumGenerator::Generator::Education,
|
17
|
+
self_assessment: CurriculumGenerator::Generator::SelfAssessment,
|
18
|
+
# Macro.
|
19
|
+
macro_substitution: CurriculumGenerator::Generator::MacroSubstitution
|
20
|
+
}
|
21
|
+
|
22
|
+
def initialize(tex_out_pth)
|
23
|
+
@tex_out_pth = tex_out_pth
|
24
|
+
@generator_regex = /^generate\s*\(\s*(?<generator>[^,()]+)\s*,\s*(?<param>[^,()]+)\s*\)\s*$/i
|
25
|
+
@line_regex = /(?<re>\<=(?:(?<ctnt>(?>[^<>=]+)|\g<re>)+)\=\>)/
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_deps(deps_file_pth)
|
29
|
+
puts ">> Ensuring that the dependencies are satisfied."
|
30
|
+
|
31
|
+
# ==> Load the data from the YAML file.
|
32
|
+
data = {}
|
33
|
+
File.open(deps_file_pth.to_s, "r") do |deps_file|
|
34
|
+
data.merge!(YAML::load(deps_file))
|
35
|
+
end
|
36
|
+
|
37
|
+
# ==> Validate commands are available on the system.
|
38
|
+
data.has_key?('cmds') && data['cmds'].respond_to?(:all?) && data['cmds'].all? do |cmd|
|
39
|
+
CurriculumGenerator::Util::ShellCommand.exist?(cmd) ? true : puts(">> Command #{cmd} not found".red)
|
40
|
+
end
|
41
|
+
|
42
|
+
# ==> Validate that the required fonts are available.
|
43
|
+
data.has_key?('pkgs') && data['pkgs'].respond_to?(:all?) && data['pkgs'].all? do |pkg|
|
44
|
+
`tlmgr list --only-installed | grep "i #{pkg}:"`.strip.length > 0 ? true : puts(">> Package #{pkg} not found".red)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Outputs the manual dependencies.
|
48
|
+
data.has_key?("manual_deps") && data["manual_deps"].respond_to?(:each) do |manual_dep|
|
49
|
+
puts ">> Please ensure that the manual dependency is installed:".yellow + manual_dep.to_s.light_black
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def compile(data, template_pth, lang)
|
54
|
+
puts '>> Compiling the language '.cyan + ":#{lang}".light_black
|
55
|
+
puts ' against the template '.cyan + template_pth.to_s.light_black
|
56
|
+
puts ' into the output directory '.cyan + @tex_out_pth.to_s.light_black
|
57
|
+
|
58
|
+
Dir.glob(template_pth.join('**').join('*')) do |file_pth|
|
59
|
+
if File.file?(file_pth)
|
60
|
+
rel_file_pth = file_pth.to_s.gsub(/#{template_pth}[\/]?/, '')
|
61
|
+
out_file_pth = @tex_out_pth.join(lang.to_s).join(rel_file_pth)
|
62
|
+
|
63
|
+
if File.extname(file_pth) == ".tex"
|
64
|
+
out_lines = []
|
65
|
+
|
66
|
+
File.open(file_pth, 'r').each do |line|
|
67
|
+
out_lines << line.gsub(@line_regex) do |_|
|
68
|
+
req_str = $2.strip.dup
|
69
|
+
|
70
|
+
md = @generator_regex.match(req_str)
|
71
|
+
if md
|
72
|
+
# Generate command
|
73
|
+
handle_generate(md[:generator].to_sym, md[:param], data, lang)
|
74
|
+
else
|
75
|
+
# Macro substitution
|
76
|
+
handle_generate(:macro_substitution, req_str, data, lang)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
FileUtils.mkdir_p(out_file_pth.dirname)
|
82
|
+
File.open(out_file_pth, 'w') do |tex_out_file|
|
83
|
+
tex_out_file.write(out_lines.join(''))
|
84
|
+
end
|
85
|
+
else
|
86
|
+
FileUtils.mkdir_p(out_file_pth.dirname)
|
87
|
+
FileUtils.cp_r(file_pth, out_file_pth)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def handle_generate(generator, param, data, lang)
|
94
|
+
if GENERATORS.has_key?(generator)
|
95
|
+
GENERATORS[generator].new(param, data, lang).generate
|
96
|
+
else
|
97
|
+
fail("Invalid generator `#{generator}`: expected one of `#{GENERATORS}`.")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
class Curriculum
|
3
|
+
|
4
|
+
attr_accessor :langs, :master_lang, :data_loader, :compiler, :data_pth
|
5
|
+
|
6
|
+
def initialize(data_loader, compiler, data_pth, template_pth, langs=[], master_lang=nil)
|
7
|
+
# Preconditions
|
8
|
+
raise 'Invalid langs. It cannot be empty' if langs.empty?
|
9
|
+
|
10
|
+
@data_loader = data_loader
|
11
|
+
@compiler = compiler
|
12
|
+
@langs = {}
|
13
|
+
# If the master language is not provided, then defaults to the first
|
14
|
+
# provided language.
|
15
|
+
@master_lang = master_lang.nil? ? langs[0] : master_lang
|
16
|
+
|
17
|
+
@data_pth = data_pth
|
18
|
+
@template_pth = template_pth
|
19
|
+
|
20
|
+
puts "> Picking up the available languages.".green
|
21
|
+
|
22
|
+
langs.each do |lang|
|
23
|
+
lang_data_pth = @data_pth.join(lang.to_s)
|
24
|
+
|
25
|
+
inst = self
|
26
|
+
Either.chain do
|
27
|
+
bind -> { lang_data_pth.directory? }
|
28
|
+
bind -> {
|
29
|
+
lang_data = inst.data_loader.load_data(
|
30
|
+
inst.data_pth, lang.to_sym, inst.master_lang.to_sym)
|
31
|
+
lang_data.is_a?(Hash) ? Success(lang_data) : Failure("lang data")
|
32
|
+
}
|
33
|
+
bind ->(lang_data) {
|
34
|
+
inst.langs[lang.to_sym] = { data: lang_data }
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate_deps(template_deps_file_pth)
|
41
|
+
@compiler.validate_deps template_deps_file_pth
|
42
|
+
end
|
43
|
+
|
44
|
+
# Compile the curriculum for the provided languages.
|
45
|
+
def compile(langs)
|
46
|
+
puts ">> Compiling the curriculum for the languages: " \
|
47
|
+
"`#{langs.join(" ").light_black}`.".green
|
48
|
+
|
49
|
+
# TODO: Refactor into monads, with better error detection.
|
50
|
+
if langs.respond_to?(:each)
|
51
|
+
langs.each do |lang|
|
52
|
+
lang = lang.to_sym
|
53
|
+
@compiler.compile(@langs[lang][:data], @template_pth, lang)
|
54
|
+
end
|
55
|
+
elsif @langs.include? langs
|
56
|
+
@compiler.compile(@langs[lang][:data], @template_pth, langs)
|
57
|
+
else
|
58
|
+
raise "Invalid language."
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
|
4
|
-
class
|
4
|
+
class CurriculumGenerator::DataLoader::YamlDataLoader
|
5
5
|
|
6
6
|
# Load the localized data from the directory `data_dir_pth`, following the convention that the localized data for
|
7
7
|
# a language are in a subdirectory of `data_dir_pth` named with the same name of the language.
|
8
8
|
# The target language name (which is also the subdirectory name) is `trgt_lang`, which fallbacks to the `master_lang`
|
9
9
|
def load_data(data_dir_pth, trgt_lang, master_lang)
|
10
|
-
|
10
|
+
CurriculumGenerator::Util::Logging.log(:loading_curriculum_data, trgt_lang: trgt_lang, master_lang: master_lang)
|
11
11
|
|
12
12
|
trgt_lang_data_dir_pth = data_dir_pth.join(trgt_lang.to_s)
|
13
13
|
master_lang_data_dir_pth = data_dir_pth.join(master_lang.to_s)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Require the basic generator before the others, since they will inherit from it
|
2
|
+
# (assuming the class `BasicGenerator` is already available).
|
3
|
+
require "curriculum-generator/generator/basic_generator"
|
4
|
+
|
5
|
+
# Require the `generic` generators.
|
6
|
+
Dir.glob(File.join(File.dirname(__FILE__), "generator/*.rb")) do |mod|
|
7
|
+
require(mod) if mod != "basic_generator"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Require the `specific` generators.
|
11
|
+
Dir.glob(File.join(File.dirname(__FILE__), "generator/specific/*.rb")) do |mod|
|
12
|
+
require(mod)
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
module Generator
|
3
|
+
# Abstract class for a generator.
|
4
|
+
# All generators should inherit from this class.
|
5
|
+
class BasicGenerator
|
6
|
+
|
7
|
+
attr_accessor(:param)
|
8
|
+
attr_accessor(:data)
|
9
|
+
attr_accessor(:lang)
|
10
|
+
|
11
|
+
def initialize(param, data, lang)
|
12
|
+
@param = param
|
13
|
+
@data = data
|
14
|
+
@lang = lang
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
fail("Abstract class")
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_value(keys_str)
|
22
|
+
keys = keys_str.split('.').reverse
|
23
|
+
if keys.empty?
|
24
|
+
"" # Return
|
25
|
+
else
|
26
|
+
data_tmp = @data.dup
|
27
|
+
until keys.empty?
|
28
|
+
key = keys.pop
|
29
|
+
data_tmp = data_tmp[key]
|
30
|
+
end
|
31
|
+
data_tmp # Return
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def evaluate(input, context)
|
36
|
+
eruby = Erubis::Eruby.new(input)
|
37
|
+
eruby.evaluate(context) # Return
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
module Generator
|
3
|
+
class CvColumn < BasicGenerator
|
4
|
+
|
5
|
+
def initialize(param, data, lang)
|
6
|
+
super(param, data, lang)
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate
|
10
|
+
value = get_value(param)
|
11
|
+
unless value.is_a?(Array)
|
12
|
+
value = Array[value]
|
13
|
+
end
|
14
|
+
("\\begin{cvcolumns}" + (value.collect do |elem|
|
15
|
+
instance = self
|
16
|
+
result = Either.chain do
|
17
|
+
bind -> { elem.is_a?(Hash) }
|
18
|
+
bind -> { elem.has_key?('item_0') && elem.has_key?('item_1') }
|
19
|
+
bind -> {
|
20
|
+
instance.get_cv_list_double_item(elem['item_0'], elem['item_1'])
|
21
|
+
}
|
22
|
+
end
|
23
|
+
result.success? ? result.fetch : ''
|
24
|
+
end.join("\n")) +
|
25
|
+
"\\end{cvcolumns")
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def get_cv_list_double_item(item_0, item_1)
|
31
|
+
"\\cvcolumn{#{item_0}}{#{item_1}}"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
module Generator
|
3
|
+
class CvDoubleItem < BasicGenerator
|
4
|
+
|
5
|
+
def initialize(param, data, lang)
|
6
|
+
super(param, data, lang)
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate
|
10
|
+
value = get_value(param)
|
11
|
+
unless value.is_a?(Array)
|
12
|
+
value = Array[value]
|
13
|
+
end
|
14
|
+
value.collect do |elem|
|
15
|
+
instance = self
|
16
|
+
result = Either.chain do
|
17
|
+
bind -> { elem.is_a?(Hash) }
|
18
|
+
bind -> {
|
19
|
+
elem.has_key?('item_0') &&
|
20
|
+
elem['item_0'].has_key?('title') &&
|
21
|
+
elem['item_0'].has_key?('content')
|
22
|
+
}
|
23
|
+
bind -> {
|
24
|
+
elem.has_key?('item_1') &&
|
25
|
+
elem['item_1'].has_key?('title') &&
|
26
|
+
elem['item_1'].has_key?('content')
|
27
|
+
}
|
28
|
+
bind -> {
|
29
|
+
instance.get_cv_double_item(elem['item_0'], elem['item_1'])
|
30
|
+
}
|
31
|
+
end
|
32
|
+
result.success? ? result.fetch : ''
|
33
|
+
end.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
def get_cv_double_item(item_0, item_1)
|
39
|
+
"\\cvdoubleitem" +
|
40
|
+
"{#{item_0['title']}}{#{item_0['content']}}" +
|
41
|
+
"{#{item_1['title']}}{#{item_1['content']}}"
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
module Generator
|
3
|
+
class CvEntry < BasicGenerator
|
4
|
+
|
5
|
+
def initialize(param, data, lang)
|
6
|
+
super(param, data, lang)
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate
|
10
|
+
value = get_value(param)
|
11
|
+
unless value.is_a?(Array)
|
12
|
+
value = Array[value]
|
13
|
+
end
|
14
|
+
instance = self
|
15
|
+
result = Either.chain do
|
16
|
+
bind -> { value.is_a?(Array) }
|
17
|
+
bind -> { instance.get_cv_entry(value) }
|
18
|
+
end
|
19
|
+
result.success? ? result.fetch : ''
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def get_cv_entry(context)
|
25
|
+
result = "\\cventry"
|
26
|
+
context.each do |elem|
|
27
|
+
result += "{#{elem}}"
|
28
|
+
end
|
29
|
+
(6 - context.size).times do
|
30
|
+
result += '{}'
|
31
|
+
end
|
32
|
+
result # return
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module CurriculumGenerator
|
2
|
+
module Generator
|
3
|
+
class CvItem < BasicGenerator
|
4
|
+
|
5
|
+
def initialize(param, data, lang)
|
6
|
+
super(param, data, lang)
|
7
|
+
end
|
8
|
+
|
9
|
+
def generate
|
10
|
+
value = get_value(param)
|
11
|
+
unless value.is_a?(Array)
|
12
|
+
value = Array[value]
|
13
|
+
end
|
14
|
+
value.collect do |elem|
|
15
|
+
instance = self
|
16
|
+
result = Either.chain do
|
17
|
+
bind -> { elem.is_a?(Hash) }
|
18
|
+
bind -> { elem.has_key?('title') && elem.has_key?('content') }
|
19
|
+
bind -> { instance.get_cv_item(elem['title'], elem['content']) }
|
20
|
+
end
|
21
|
+
result.success? ? result.fetch : ''
|
22
|
+
end.join("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def get_cv_item(title, content)
|
28
|
+
"\\cvitem{#{title}}{#{content}}"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class CurriculumGenerator::Util::LatexToPdf
|
2
2
|
|
3
3
|
def initialize(
|
4
4
|
input_file_name, input_dir, resources_pths, out_dir, log_file,
|
@@ -20,9 +20,9 @@ class CGen::Util::LatexToPdf
|
|
20
20
|
starting_resources = resources_files
|
21
21
|
|
22
22
|
# Create the command used to generate the PDF
|
23
|
-
gen_pdf_cmd =
|
23
|
+
gen_pdf_cmd = CurriculumGenerator::Util::ShellCommand.new(get_tex_cmd, @input_dir, @log_file)
|
24
24
|
# Create the command used to generate the bibliography
|
25
|
-
gen_bib_cmd =
|
25
|
+
gen_bib_cmd = CurriculumGenerator::Util::ShellCommand.new(get_bibtex_cmd, @out_dir, @log_file)
|
26
26
|
|
27
27
|
Either.chain do
|
28
28
|
bind -> { gen_pdf_cmd.run }
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class
|
1
|
+
class CurriculumGenerator::Util::ShellCommand
|
2
2
|
|
3
3
|
def initialize(command, execution_dir, log_file=nil)
|
4
4
|
@command = command
|
@@ -7,7 +7,7 @@ class CGen::Util::ShellCommand
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def run
|
10
|
-
|
10
|
+
CurriculumGenerator::Util::Logging.log(:executing_command, cmd: @command, exec_dir: @execution_dir, log_file: @log_file)
|
11
11
|
|
12
12
|
status = true
|
13
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: curriculum-generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alessandro Molari
|
@@ -126,7 +126,7 @@ description:
|
|
126
126
|
email:
|
127
127
|
- molari.alessandro@gmail.com
|
128
128
|
executables:
|
129
|
-
-
|
129
|
+
- curriculum-generator
|
130
130
|
extensions: []
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
@@ -136,40 +136,40 @@ files:
|
|
136
136
|
- LICENSE.txt
|
137
137
|
- README.md
|
138
138
|
- Rakefile
|
139
|
-
- bin/
|
140
|
-
-
|
141
|
-
- lib/
|
142
|
-
- lib/
|
143
|
-
- lib/
|
144
|
-
- lib/
|
145
|
-
- lib/
|
146
|
-
- lib/
|
147
|
-
- lib/
|
148
|
-
- lib/
|
149
|
-
- lib/
|
150
|
-
- lib/
|
151
|
-
- lib/
|
152
|
-
- lib/
|
153
|
-
- lib/
|
154
|
-
- lib/
|
155
|
-
- lib/
|
156
|
-
- lib/
|
157
|
-
- lib/
|
158
|
-
- lib/
|
159
|
-
- lib/
|
160
|
-
- lib/
|
161
|
-
- lib/
|
162
|
-
- lib/
|
163
|
-
- lib/
|
164
|
-
- lib/
|
139
|
+
- bin/curriculum-generator
|
140
|
+
- curriculum-generator.gemspec
|
141
|
+
- lib/curriculum-generator.rb
|
142
|
+
- lib/curriculum-generator/compiler.rb
|
143
|
+
- lib/curriculum-generator/curriculum.rb
|
144
|
+
- lib/curriculum-generator/data_loader.rb
|
145
|
+
- lib/curriculum-generator/data_loader/yaml_data_loader.rb
|
146
|
+
- lib/curriculum-generator/generator.rb
|
147
|
+
- lib/curriculum-generator/generator/basic_generator.rb
|
148
|
+
- lib/curriculum-generator/generator/cv_column.rb
|
149
|
+
- lib/curriculum-generator/generator/cv_double_item.rb
|
150
|
+
- lib/curriculum-generator/generator/cv_entry.rb
|
151
|
+
- lib/curriculum-generator/generator/cv_item.rb
|
152
|
+
- lib/curriculum-generator/generator/cv_item_with_comment.rb
|
153
|
+
- lib/curriculum-generator/generator/cv_list_double_item.rb
|
154
|
+
- lib/curriculum-generator/generator/cv_list_item.rb
|
155
|
+
- lib/curriculum-generator/generator/list.rb
|
156
|
+
- lib/curriculum-generator/generator/macro_substitution.rb
|
157
|
+
- lib/curriculum-generator/generator/specific/education.rb
|
158
|
+
- lib/curriculum-generator/generator/specific/self_assessment.rb
|
159
|
+
- lib/curriculum-generator/generator/specific/work_experience.rb
|
160
|
+
- lib/curriculum-generator/util.rb
|
161
|
+
- lib/curriculum-generator/util/latex_to_pdf.rb
|
162
|
+
- lib/curriculum-generator/util/logging.rb
|
163
|
+
- lib/curriculum-generator/util/shell_command.rb
|
164
|
+
- lib/curriculum-generator/version.rb
|
165
165
|
- static/bundled_templates/moderncv/.gitkeep
|
166
166
|
- static/bundled_templates/moderncv/deps.yml
|
167
167
|
- static/bundled_templates/moderncv/main.tex
|
168
168
|
- static/bundled_templates/moderncv/publications.bib
|
169
169
|
- static/bundled_templates/moderncv/resources/AuthorPhoto.png
|
170
|
-
homepage: http://github.com/alem0lars/
|
170
|
+
homepage: http://github.com/alem0lars/curriculum-generator
|
171
171
|
licenses:
|
172
|
-
- Apache
|
172
|
+
- Apache v2.0
|
173
173
|
metadata: {}
|
174
174
|
post_install_message:
|
175
175
|
rdoc_options: []
|
data/cgen.gemspec
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
lib = File.expand_path('../lib', __FILE__)
|
4
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require 'cgen/version'
|
6
|
-
|
7
|
-
|
8
|
-
Gem::Specification.new do |spec|
|
9
|
-
|
10
|
-
spec.name = 'curriculum-generator'
|
11
|
-
spec.version = CGen::VERSION
|
12
|
-
spec.authors = ['Alessandro Molari']
|
13
|
-
spec.email = ['molari.alessandro@gmail.com']
|
14
|
-
spec.summary = %q{Curriculum Vitae generator}
|
15
|
-
spec.homepage = 'http://github.com/alem0lars/cgen'
|
16
|
-
spec.license = 'Apache 2'
|
17
|
-
|
18
|
-
spec.files = `git ls-files -z`.split("\x0")
|
19
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
-
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
21
|
-
spec.require_paths = ['lib']
|
22
|
-
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
24
|
-
spec.add_development_dependency 'rake'
|
25
|
-
|
26
|
-
spec.add_runtime_dependency 'hash-deep-merge'
|
27
|
-
spec.add_runtime_dependency 'monadic'
|
28
|
-
|
29
|
-
spec.add_runtime_dependency 'awesome_print'
|
30
|
-
spec.add_runtime_dependency 'colorize'
|
31
|
-
spec.add_runtime_dependency 'highline'
|
32
|
-
|
33
|
-
spec.add_runtime_dependency 'erubis'
|
34
|
-
|
35
|
-
end
|
data/lib/cgen.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# The common module for all of the CGen classes
|
2
|
-
module CGen; end
|
3
|
-
|
4
|
-
|
5
|
-
# ==> Setup RubyGems and Bundler
|
6
|
-
require 'rubygems'
|
7
|
-
require 'bundler/setup'
|
8
|
-
|
9
|
-
# ==> Require the core dependencies
|
10
|
-
require 'tmpdir'
|
11
|
-
require 'pathname'
|
12
|
-
|
13
|
-
# ==> Require all of the external dependencies
|
14
|
-
require 'hash_deep_merge'
|
15
|
-
require 'monadic'
|
16
|
-
require 'awesome_print'
|
17
|
-
require 'colorize'
|
18
|
-
require 'highline/import'
|
19
|
-
require 'erubis'
|
20
|
-
|
21
|
-
# ==> Require the project stuff
|
22
|
-
require 'cgen/version'
|
23
|
-
require 'cgen/util'
|
24
|
-
require 'cgen/compiler'
|
25
|
-
require 'cgen/curriculum'
|
26
|
-
require 'cgen/data_loader'
|
27
|
-
require 'cgen/generator'
|
data/lib/cgen/compiler.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
class CGen::Compiler
|
2
|
-
|
3
|
-
def initialize(tex_out_pth)
|
4
|
-
@tex_out_pth = tex_out_pth
|
5
|
-
@generator_regex = /^generate\s*\(\s*(?<generator>[^,()]+)\s*,\s*(?<param>[^,()]+)\s*\)\s*$/i
|
6
|
-
@line_regex = /(?<re>\<=(?:(?<ctnt>(?>[^<>=]+)|\g<re>)+)\=\>)/
|
7
|
-
end
|
8
|
-
|
9
|
-
def validate_deps(deps_file_pth)
|
10
|
-
puts '>> Ensuring that the dependencies are satisfied'
|
11
|
-
|
12
|
-
# ==> Load the data from the YAML file
|
13
|
-
data = {}
|
14
|
-
File.open(deps_file_pth.to_s, 'r') { |deps_file| data.merge!(YAML::load(deps_file)) }
|
15
|
-
|
16
|
-
# ==> Validate commands are available on the system
|
17
|
-
data.has_key?('cmds') && data['cmds'].respond_to?(:all?) && data['cmds'].all? do |cmd|
|
18
|
-
CGen::Util::ShellCommand.exist?(cmd) ? true : puts(">> Command #{cmd} not found".red)
|
19
|
-
end
|
20
|
-
|
21
|
-
# ==> Validate that the required fonts are available
|
22
|
-
data.has_key?('pkgs') && data['pkgs'].respond_to?(:all?) && data['pkgs'].all? do |pkg|
|
23
|
-
`tlmgr list --only-installed | grep "i #{pkg}:"`.strip.length > 0 ? true : puts(">> Package #{pkg} not found".red)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Outputs the manual dependencies
|
27
|
-
data.has_key?('manual_deps') && data['manual_deps'].respond_to?(:each) do |manual_dep|
|
28
|
-
puts '>> Please ensure that the manual dependency is installed:'.yellow + manual_dep.to_s.light_black
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def compile(data, template_pth, lang)
|
33
|
-
puts '>> Compiling the language '.cyan + ":#{lang}".light_black
|
34
|
-
puts ' against the template '.cyan + template_pth.to_s.light_black
|
35
|
-
puts ' into the output directory '.cyan + @tex_out_pth.to_s.light_black
|
36
|
-
|
37
|
-
Dir.glob(template_pth.join('**').join('*')) do |file_pth|
|
38
|
-
if File.file?(file_pth)
|
39
|
-
rel_file_pth = file_pth.to_s.gsub(/#{template_pth}[\/]?/, '')
|
40
|
-
out_file_pth = @tex_out_pth.join(lang.to_s).join(rel_file_pth)
|
41
|
-
|
42
|
-
if File.extname(file_pth) == '.tex'
|
43
|
-
out_lines = []
|
44
|
-
|
45
|
-
File.open(file_pth, 'r').each do |line|
|
46
|
-
out_lines << line.gsub(@line_regex) do |_|
|
47
|
-
req_str = $2.strip.dup
|
48
|
-
|
49
|
-
md = @generator_regex.match(req_str)
|
50
|
-
if md
|
51
|
-
# Generate command
|
52
|
-
handle_generate(md[:generator].to_sym, md[:param], data, lang)
|
53
|
-
else
|
54
|
-
# Macro substitution
|
55
|
-
handle_generate(:macro_substitution, req_str, data, lang)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
FileUtils.mkdir_p(out_file_pth.dirname)
|
61
|
-
File.open(out_file_pth, 'w') do |tex_out_file|
|
62
|
-
tex_out_file.write(out_lines.join(''))
|
63
|
-
end
|
64
|
-
else
|
65
|
-
FileUtils.mkdir_p(out_file_pth.dirname)
|
66
|
-
FileUtils.cp_r(file_pth, out_file_pth)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def handle_generate(generator, param, data, lang)
|
73
|
-
generators = {
|
74
|
-
# Generic
|
75
|
-
cvitem: CGen::Generator::CvItem,
|
76
|
-
cventry: CGen::Generator::CvEntry,
|
77
|
-
cvitemwithcomment: CGen::Generator::CvItemWithComment,
|
78
|
-
cvdoubleitem: CGen::Generator::CvDoubleItem,
|
79
|
-
cvlistitem: CGen::Generator::CvListItem,
|
80
|
-
cvlistdoubleitem: CGen::Generator::CvListDoubleItem,
|
81
|
-
cvcolumn: CGen::Generator::CvColumn,
|
82
|
-
list: CGen::Generator::List,
|
83
|
-
# Specific
|
84
|
-
work_experience: CGen::Generator::WorkExperience,
|
85
|
-
education: CGen::Generator::Education,
|
86
|
-
self_assessment: CGen::Generator::SelfAssessment,
|
87
|
-
# Macro
|
88
|
-
macro_substitution: CGen::Generator::MacroSubstitution
|
89
|
-
}
|
90
|
-
|
91
|
-
generators.has_key?(generator) ?
|
92
|
-
generators[generator].new(param, data, lang).generate :
|
93
|
-
raise("Invalid generator: #{generator}. Expected one of: #{generators}")
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
data/lib/cgen/curriculum.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
class CGen::Curriculum
|
2
|
-
|
3
|
-
attr_accessor :langs, :master_lang, :data_loader, :compiler, :data_pth
|
4
|
-
|
5
|
-
def initialize(data_loader, compiler, data_pth, template_pth, langs=[], master_lang=nil)
|
6
|
-
# Preconditions
|
7
|
-
raise 'Invalid langs. It cannot be empty' if langs.empty?
|
8
|
-
|
9
|
-
@data_loader = data_loader
|
10
|
-
@compiler = compiler
|
11
|
-
@langs = {}
|
12
|
-
# if the master language is not provided, then defaults to the first provided language
|
13
|
-
@master_lang = master_lang.nil? ? langs[0] : master_lang
|
14
|
-
|
15
|
-
@data_pth = data_pth
|
16
|
-
@template_pth = template_pth
|
17
|
-
|
18
|
-
puts '> Picking up the available languages'.green
|
19
|
-
|
20
|
-
langs.each do |lang|
|
21
|
-
lang_data_pth = @data_pth.join(lang.to_s)
|
22
|
-
|
23
|
-
inst = self
|
24
|
-
Either.chain do
|
25
|
-
bind -> { lang_data_pth.directory? }
|
26
|
-
bind -> {
|
27
|
-
lang_data = inst.data_loader.load_data(inst.data_pth, lang.to_sym, inst.master_lang.to_sym)
|
28
|
-
lang_data.is_a?(Hash) ? Success(lang_data) : Failure('lang data')
|
29
|
-
}
|
30
|
-
bind ->(lang_data) {
|
31
|
-
inst.langs[lang.to_sym] = { data: lang_data }
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def validate_deps(template_deps_file_pth)
|
38
|
-
@compiler.validate_deps template_deps_file_pth
|
39
|
-
end
|
40
|
-
|
41
|
-
# Compile the curriculum for the provided languages
|
42
|
-
def compile(langs)
|
43
|
-
puts '>> Compiling the curriculum for the languages: '.green + langs.join(' ').light_black
|
44
|
-
|
45
|
-
# TODO: Refactor into monads, with better error detection
|
46
|
-
if langs.respond_to?(:each)
|
47
|
-
langs.each do |lang|
|
48
|
-
lang = lang.to_sym
|
49
|
-
@compiler.compile(@langs[lang][:data], @template_pth, lang)
|
50
|
-
end
|
51
|
-
elsif @langs.include? langs
|
52
|
-
@compiler.compile(@langs[lang][:data], @template_pth, langs)
|
53
|
-
else
|
54
|
-
raise 'Invalid lang'
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
data/lib/cgen/data_loader.rb
DELETED
data/lib/cgen/generator.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# All of the classes under cgen/generator should be namespaced with this module
|
2
|
-
module CGen::Generator; end
|
3
|
-
|
4
|
-
|
5
|
-
# Require the basic generator before the others, since they will assume the BasicGenerator class is already available
|
6
|
-
require 'cgen/generator/basic_generator'
|
7
|
-
# Require the 'generic' generators
|
8
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'generator/*.rb')) { |mod| require(mod) if mod != 'basic_generator' }
|
9
|
-
# Require the 'specific' generators
|
10
|
-
Dir.glob(File.join(File.dirname(__FILE__), 'generator/specific/*.rb')) { |mod| require(mod) }
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# Abstract class for a generator. All generators should inherit from this class
|
2
|
-
class CGen::Generator::BasicGenerator
|
3
|
-
|
4
|
-
attr_accessor(:param)
|
5
|
-
attr_accessor(:data)
|
6
|
-
attr_accessor(:lang)
|
7
|
-
|
8
|
-
def initialize(param, data, lang)
|
9
|
-
@param = param
|
10
|
-
@data = data
|
11
|
-
@lang = lang
|
12
|
-
end
|
13
|
-
|
14
|
-
def generate
|
15
|
-
raise 'Abstract class'
|
16
|
-
end
|
17
|
-
|
18
|
-
def get_value(keys_str)
|
19
|
-
keys = keys_str.split('.').reverse
|
20
|
-
if keys.empty?
|
21
|
-
'' # return
|
22
|
-
else
|
23
|
-
data_tmp = @data.dup
|
24
|
-
until keys.empty?
|
25
|
-
key = keys.pop
|
26
|
-
data_tmp = data_tmp[key]
|
27
|
-
end
|
28
|
-
data_tmp # return
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def evaluate(input, context)
|
33
|
-
eruby = Erubis::Eruby.new(input)
|
34
|
-
eruby.evaluate(context) # return
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
class CGen::Generator::CvColumn < CGen::Generator::BasicGenerator
|
2
|
-
|
3
|
-
def initialize(param, data, lang)
|
4
|
-
super(param, data, lang)
|
5
|
-
end
|
6
|
-
|
7
|
-
def generate
|
8
|
-
value = get_value(param)
|
9
|
-
unless value.is_a?(Array)
|
10
|
-
value = Array[value]
|
11
|
-
end
|
12
|
-
("\\begin{cvcolumns}" + (value.collect do |elem|
|
13
|
-
instance = self
|
14
|
-
result = Either.chain do
|
15
|
-
bind -> { elem.is_a?(Hash) }
|
16
|
-
bind -> { elem.has_key?('item_0') && elem.has_key?('item_1') }
|
17
|
-
bind -> {
|
18
|
-
instance.get_cv_list_double_item(elem['item_0'], elem['item_1'])
|
19
|
-
}
|
20
|
-
end
|
21
|
-
result.success? ? result.fetch : ''
|
22
|
-
end.join("\n")) +
|
23
|
-
"\\end{cvcolumns")
|
24
|
-
end
|
25
|
-
|
26
|
-
protected
|
27
|
-
|
28
|
-
def get_cv_list_double_item(item_0, item_1)
|
29
|
-
"\\cvcolumn{#{item_0}}{#{item_1}}"
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
class CGen::Generator::CvDoubleItem < CGen::Generator::BasicGenerator
|
2
|
-
|
3
|
-
def initialize(param, data, lang)
|
4
|
-
super(param, data, lang)
|
5
|
-
end
|
6
|
-
|
7
|
-
def generate
|
8
|
-
value = get_value(param)
|
9
|
-
unless value.is_a?(Array)
|
10
|
-
value = Array[value]
|
11
|
-
end
|
12
|
-
value.collect do |elem|
|
13
|
-
instance = self
|
14
|
-
result = Either.chain do
|
15
|
-
bind -> { elem.is_a?(Hash) }
|
16
|
-
bind -> {
|
17
|
-
elem.has_key?('item_0') &&
|
18
|
-
elem['item_0'].has_key?('title') &&
|
19
|
-
elem['item_0'].has_key?('content')
|
20
|
-
}
|
21
|
-
bind -> {
|
22
|
-
elem.has_key?('item_1') &&
|
23
|
-
elem['item_1'].has_key?('title') &&
|
24
|
-
elem['item_1'].has_key?('content')
|
25
|
-
}
|
26
|
-
bind -> {
|
27
|
-
instance.get_cv_double_item(elem['item_0'], elem['item_1'])
|
28
|
-
}
|
29
|
-
end
|
30
|
-
result.success? ? result.fetch : ''
|
31
|
-
end.join("\n")
|
32
|
-
end
|
33
|
-
|
34
|
-
protected
|
35
|
-
|
36
|
-
def get_cv_double_item(item_0, item_1)
|
37
|
-
"\\cvdoubleitem" +
|
38
|
-
"{#{item_0['title']}}{#{item_0['content']}}" +
|
39
|
-
"{#{item_1['title']}}{#{item_1['content']}}"
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
class CGen::Generator::CvEntry < CGen::Generator::BasicGenerator
|
2
|
-
|
3
|
-
def initialize(param, data, lang)
|
4
|
-
super(param, data, lang)
|
5
|
-
end
|
6
|
-
|
7
|
-
def generate
|
8
|
-
value = get_value(param)
|
9
|
-
unless value.is_a?(Array)
|
10
|
-
value = Array[value]
|
11
|
-
end
|
12
|
-
instance = self
|
13
|
-
result = Either.chain do
|
14
|
-
bind -> { value.is_a?(Array) }
|
15
|
-
bind -> { instance.get_cv_entry(value) }
|
16
|
-
end
|
17
|
-
result.success? ? result.fetch : ''
|
18
|
-
end
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
22
|
-
def get_cv_entry(context)
|
23
|
-
result = "\\cventry"
|
24
|
-
context.each do |elem|
|
25
|
-
result += "{#{elem}}"
|
26
|
-
end
|
27
|
-
(6 - context.size).times do
|
28
|
-
result += '{}'
|
29
|
-
end
|
30
|
-
result # return
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class CGen::Generator::CvItem < CGen::Generator::BasicGenerator
|
2
|
-
|
3
|
-
def initialize(param, data, lang)
|
4
|
-
super(param, data, lang)
|
5
|
-
end
|
6
|
-
|
7
|
-
def generate
|
8
|
-
value = get_value(param)
|
9
|
-
unless value.is_a?(Array)
|
10
|
-
value = Array[value]
|
11
|
-
end
|
12
|
-
value.collect do |elem|
|
13
|
-
instance = self
|
14
|
-
result = Either.chain do
|
15
|
-
bind -> { elem.is_a?(Hash) }
|
16
|
-
bind -> { elem.has_key?('title') && elem.has_key?('content') }
|
17
|
-
bind -> { instance.get_cv_item(elem['title'], elem['content']) }
|
18
|
-
end
|
19
|
-
result.success? ? result.fetch : ''
|
20
|
-
end.join("\n")
|
21
|
-
end
|
22
|
-
|
23
|
-
protected
|
24
|
-
|
25
|
-
def get_cv_item(title, content)
|
26
|
-
"\\cvitem{#{title}}{#{content}}"
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
data/lib/cgen/util.rb
DELETED