curriculum-generator 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.ruby-version +1 -0
- data/CGen.gemspec +35 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +3 -0
- data/bin/cgen.rb +86 -0
- data/lib/CGen.rb +27 -0
- data/lib/cgen/compiler.rb +96 -0
- data/lib/cgen/curriculum.rb +57 -0
- data/lib/cgen/data_loader/yaml_data_loader.rb +31 -0
- data/lib/cgen/data_loader.rb +6 -0
- data/lib/cgen/generator/basic_generator.rb +37 -0
- data/lib/cgen/generator/cv_column.rb +32 -0
- data/lib/cgen/generator/cv_double_item.rb +42 -0
- data/lib/cgen/generator/cv_entry.rb +33 -0
- data/lib/cgen/generator/cv_item.rb +29 -0
- data/lib/cgen/generator/cv_item_with_comment.rb +32 -0
- data/lib/cgen/generator/cv_list_double_item.rb +31 -0
- data/lib/cgen/generator/cv_list_item.rb +23 -0
- data/lib/cgen/generator/list.rb +25 -0
- data/lib/cgen/generator/macro_substitution.rb +11 -0
- data/lib/cgen/generator/specific/education.rb +95 -0
- data/lib/cgen/generator/specific/self_assessment.rb +61 -0
- data/lib/cgen/generator/specific/work_experience.rb +81 -0
- data/lib/cgen/generator.rb +10 -0
- data/lib/cgen/util/latex_to_pdf.rb +61 -0
- data/lib/cgen/util/logging.rb +27 -0
- data/lib/cgen/util/shell_command.rb +48 -0
- data/lib/cgen/util.rb +6 -0
- data/lib/cgen/version.rb +6 -0
- data/static/bundled_templates/moderncv/.gitkeep +0 -0
- data/static/bundled_templates/moderncv/deps.yml +15 -0
- data/static/bundled_templates/moderncv/main.tex +208 -0
- data/static/bundled_templates/moderncv/publications.bib +40 -0
- data/static/bundled_templates/moderncv/resources/AuthorPhoto.png +0 -0
- metadata +194 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
class CGen::Generator::CvItemWithComment < 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
|
+
value = Array[value] unless value.is_a?(Array)
|
10
|
+
|
11
|
+
inst = self
|
12
|
+
value.collect do |elem|
|
13
|
+
result = Either.chain do
|
14
|
+
bind -> { elem.is_a?(Hash) }
|
15
|
+
bind -> {
|
16
|
+
elem.has_key?('title') &&
|
17
|
+
elem.has_key?('content') &&
|
18
|
+
elem.has_key?('comment')
|
19
|
+
}
|
20
|
+
bind -> {
|
21
|
+
inst.get_cv_item_with_comment(elem['title'], elem['content'], elem['comment'])
|
22
|
+
}
|
23
|
+
end
|
24
|
+
result.success? ? result.fetch : ''
|
25
|
+
end.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_cv_item_with_comment(title, content, comment)
|
29
|
+
"\\cvitemwithcomment{#{title}}{#{content}}{#{comment}}"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class CGen::Generator::CvListDoubleItem < 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?('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
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def get_cv_list_double_item(item_0, item_1)
|
28
|
+
"\\cvlistdoubleitem{#{item_0}}{#{item_1}}"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class CGen::Generator::CvListItem < 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 |content|
|
13
|
+
get_cv_list_item(content)
|
14
|
+
end.join("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def get_cv_list_item(content)
|
20
|
+
"\\cvlistitem{#{content}}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class CGen::Generator::List < 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{itemize}' +
|
13
|
+
value.collect do |item|
|
14
|
+
get_list(item)
|
15
|
+
end.join('') +
|
16
|
+
'\end{itemize}'
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def get_list(item)
|
22
|
+
"\\item #{item}"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class CGen::Generator::Education < 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
|
+
value.collect do |elem|
|
10
|
+
get_education(elem)
|
11
|
+
end.join('')
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def get_education(context)
|
17
|
+
context.merge!({'titles' => get_value('titles')})
|
18
|
+
|
19
|
+
input = <<-CODE
|
20
|
+
|
21
|
+
\\cventry
|
22
|
+
|
23
|
+
<% if @date.nil? %>
|
24
|
+
{}
|
25
|
+
<% elsif @date.is_a?(Hash) && @date.has_key?('from') && @date.has_key?('to') %>
|
26
|
+
{<%= @date['from'] %>\\\\<%= @date['to'] %>}
|
27
|
+
<% else %>
|
28
|
+
{<%= @date %>}
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
{<%= @title.nil? ? '' : @title %>}
|
32
|
+
|
33
|
+
{}{}{}
|
34
|
+
|
35
|
+
{\\begin{itemize}
|
36
|
+
|
37
|
+
<% if @qualification %>
|
38
|
+
\\item \\textit{<%= @titles['S_4']['qualification'] %>}: <%= @qualification %>
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
<% if @organisation %>
|
42
|
+
\\item \\textit{<%= @titles['S_4']['organisation'] %>}: <%= @organisation %>
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
<% if @level %>
|
46
|
+
\\item \\textit{<%= @titles['S_4']['level'] %>}: <%= @level %>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
<% if @lessons %>
|
50
|
+
\\item \\textit{<%= @titles['S_4']['lessons'] %>}: <%= @lessons %>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
<% if @validity %>
|
54
|
+
\\item \\textit{<%= @titles['S_4']['validity'] %>}: <%= @validity %>
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
<% if @location %>
|
58
|
+
\\item \\textit{<%= @titles['S_4']['location'] %>}: <%= @location %>
|
59
|
+
<% end %>
|
60
|
+
|
61
|
+
<% if @teacher %>
|
62
|
+
\\item \\textit{<%= @titles['S_4']['teacher'] %>}: <%= @teacher %>
|
63
|
+
<% end %>
|
64
|
+
|
65
|
+
<% if @skills_covered %>
|
66
|
+
|
67
|
+
<% unless @skills_covered.is_a?(Array) %>
|
68
|
+
<% @skills_covered = Array[@skills_covered] %>
|
69
|
+
<% end %>
|
70
|
+
|
71
|
+
<% @skills_covered.compact! %>
|
72
|
+
|
73
|
+
<% if @skills_covered.length > 0 %>
|
74
|
+
|
75
|
+
\\item \\textit{<%= @titles['S_4']['skills_covered'] %>}:
|
76
|
+
\\begin{itemize}
|
77
|
+
|
78
|
+
<% @skills_covered.each do |skill_covered| %>
|
79
|
+
\\item <%= skill_covered %>
|
80
|
+
<% end %>
|
81
|
+
|
82
|
+
\\end{itemize}
|
83
|
+
|
84
|
+
<% end %>
|
85
|
+
|
86
|
+
<% end %>
|
87
|
+
|
88
|
+
\\end{itemize}}
|
89
|
+
|
90
|
+
CODE
|
91
|
+
|
92
|
+
evaluate(input, context).gsub(/^\s+/,'').gsub(/\n/,'') + "\n\n"
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class CGen::Generator::SelfAssessment < CGen::Generator::BasicGenerator
|
2
|
+
|
3
|
+
def initialize(param, data, lang)
|
4
|
+
super(param, data, lang)
|
5
|
+
end
|
6
|
+
|
7
|
+
def generate
|
8
|
+
get_self_assessment(get_value(param))
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def get_self_assessment(context)
|
14
|
+
context.merge!({'titles' => get_value('titles')})
|
15
|
+
|
16
|
+
input = <<-CODE
|
17
|
+
|
18
|
+
\\cvitem{<%= @titles['S_5']['self_assessment'] %>}
|
19
|
+
|
20
|
+
{
|
21
|
+
\\scriptsize
|
22
|
+
\\begin{tabular}{l|l|l|l|l|l|l|l|l|l|l}
|
23
|
+
|
24
|
+
\\multicolumn{1}{c|}{<%= ' ' %>} &
|
25
|
+
\\multicolumn{4}{|c|}{\\textbf{<%= @titles['S_5']['understanding'] %>}} &
|
26
|
+
\\multicolumn{4}{|c|}{\\textbf{<%= @titles['S_5']['speaking'] %>}} &
|
27
|
+
\\multicolumn{2}{|c|}{\\textbf{<%= @titles['S_5']['writing'] %>}} \\\\
|
28
|
+
|
29
|
+
\\multicolumn{1}{c|}{<%= ' ' %>} &
|
30
|
+
\\multicolumn{2}{|c|}{<%= @titles['S_5']['listening'] %>} &
|
31
|
+
\\multicolumn{2}{|c|}{<%= @titles['S_5']['reading'] %>} &
|
32
|
+
\\multicolumn{2}{|c|}{<%= @titles['S_5']['spoken_interaction'] %>} &
|
33
|
+
\\multicolumn{2}{|c|}{<%= @titles['S_5']['spoken_production'] %>} &
|
34
|
+
\\multicolumn{2}{|c|}{<%= @titles['S_5']['written_production'] %>} \\\\
|
35
|
+
\\hline
|
36
|
+
|
37
|
+
<% @languages.each do |language| %>
|
38
|
+
\\hline
|
39
|
+
\\textbf{<%= language['name'] %>} &
|
40
|
+
<%= language['listening']['level'] %> &
|
41
|
+
<%= language['listening']['description'] %> &
|
42
|
+
<%= language['reading']['level'] %> &
|
43
|
+
<%= language['reading']['description'] %> &
|
44
|
+
<%= language['spoken_interaction']['level'] %> &
|
45
|
+
<%= language['spoken_interaction']['description'] %> &
|
46
|
+
<%= language['spoken_production']['level'] %> &
|
47
|
+
<%= language['spoken_production']['description'] %> &
|
48
|
+
<%= language['written_production']['level'] %> &
|
49
|
+
<%= language['written_production']['description'] %> \\\\
|
50
|
+
<% end %>
|
51
|
+
\\hline
|
52
|
+
|
53
|
+
\\end{tabular}
|
54
|
+
}
|
55
|
+
|
56
|
+
CODE
|
57
|
+
|
58
|
+
evaluate(input, context).gsub(/^\s+/,'').gsub(/\n/,'') + "\n\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
class CGen::Generator::WorkExperience < 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
|
+
value.collect do |elem|
|
10
|
+
get_work_experience(elem)
|
11
|
+
end.join("\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def get_work_experience(context)
|
17
|
+
|
18
|
+
context.merge!({'titles' => get_value('titles')})
|
19
|
+
|
20
|
+
input = <<-CODE
|
21
|
+
|
22
|
+
\\cventry
|
23
|
+
|
24
|
+
<% if @date.nil? %>
|
25
|
+
{}
|
26
|
+
<% elsif @date.is_a?(Hash) && @date.has_key?('from') && @date.has_key?('to') %>
|
27
|
+
{<%= @date['from'] %>\\\\<%= @date['to'] %>}
|
28
|
+
<% else %>
|
29
|
+
{<%= @date %>}
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
{<%= @occupation.nil? ? '' : @occupation %>}
|
33
|
+
|
34
|
+
<% if @employer_name %>
|
35
|
+
|
36
|
+
{
|
37
|
+
<%= @employer_name %>
|
38
|
+
<% if @type_of_business %>
|
39
|
+
(<%= @type_of_business %>)
|
40
|
+
<% end %>
|
41
|
+
}
|
42
|
+
|
43
|
+
<% if @employer_address %>
|
44
|
+
{<%= @employer_address %>}
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
{}
|
50
|
+
|
51
|
+
{
|
52
|
+
<% if @main_activities %>
|
53
|
+
|
54
|
+
<% unless @main_activities.is_a?(Array) %>
|
55
|
+
<% @main_activities = Array[@main_activities] %>
|
56
|
+
<% end %>
|
57
|
+
|
58
|
+
<% @main_activities.compact! %>
|
59
|
+
|
60
|
+
<% if @main_activities.length > 0 %>
|
61
|
+
|
62
|
+
\\textit{<%= @titles['S_3']['main_activities'] %>}:
|
63
|
+
\\begin{itemize}
|
64
|
+
|
65
|
+
<% @main_activities.each do |main_activity| %>
|
66
|
+
\\item <%= main_activity %>
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
\\end{itemize}
|
70
|
+
|
71
|
+
<% end %>
|
72
|
+
|
73
|
+
<% end %>
|
74
|
+
}
|
75
|
+
|
76
|
+
CODE
|
77
|
+
|
78
|
+
evaluate(input, context).gsub(/^\s+/,'').gsub(/\n/,'') + "\n\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,10 @@
|
|
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) }
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class CGen::Util::LatexToPdf
|
2
|
+
|
3
|
+
def initialize(
|
4
|
+
input_file_name, input_dir, resources_pths, out_dir, log_file,
|
5
|
+
halt_on_error=true, shell_enabled=true, interpreter='xelatex', additional_args=[])
|
6
|
+
@interpreter = interpreter
|
7
|
+
@halt_on_error = !!halt_on_error
|
8
|
+
@shell_enabled = !!shell_enabled
|
9
|
+
@out_dir = out_dir
|
10
|
+
@input_file_name = input_file_name
|
11
|
+
@input_dir = input_dir
|
12
|
+
@resources_pths = resources_pths
|
13
|
+
@log_file = log_file
|
14
|
+
@additional_args = additional_args.is_a?(Array) ? additional_args : []
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
|
19
|
+
# Store the starting resources for later cleanup
|
20
|
+
starting_resources = resources_files
|
21
|
+
|
22
|
+
# Create the command used to generate the PDF
|
23
|
+
gen_pdf_cmd = CGen::Util::ShellCommand.new(get_tex_cmd, @input_dir, @log_file)
|
24
|
+
# Create the command used to generate the bibliography
|
25
|
+
gen_bib_cmd = CGen::Util::ShellCommand.new(get_bibtex_cmd, @out_dir, @log_file)
|
26
|
+
|
27
|
+
Either.chain do
|
28
|
+
bind -> { gen_pdf_cmd.run }
|
29
|
+
bind -> { gen_bib_cmd.run }
|
30
|
+
bind -> { gen_pdf_cmd.run }
|
31
|
+
bind -> { gen_pdf_cmd.run }
|
32
|
+
bind -> {
|
33
|
+
# ==> Cleanup resources files
|
34
|
+
dirty_files = resources_files - starting_resources
|
35
|
+
dirty_files.length > 0 ? system("rm #{dirty_files.join(' ')}") : false
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def get_tex_cmd
|
43
|
+
args = %w(-synctex=1 -interaction=batchmode) # default arguments
|
44
|
+
args << '-halt-on-error' if @halt_on_error # halt on error
|
45
|
+
args += %w(-shell-escape --enable-write18) if @shell_enabled # shell escape
|
46
|
+
args << "-output-directory=#{@out_dir}" # output directory
|
47
|
+
args += @additional_args # add the additional arguments to the computed ones
|
48
|
+
args << @input_file_name
|
49
|
+
|
50
|
+
"#{@interpreter} #{args.join(' ')}" # build the tex command and return it
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_bibtex_cmd
|
54
|
+
"BIBINPUTS=\"#{@input_dir}\" " + "bibtex #{@input_file_name}" # build the bibtex command and return it
|
55
|
+
end
|
56
|
+
|
57
|
+
def resources_files
|
58
|
+
Dir.glob(@resources_pths)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module CGen::Util::Logging
|
2
|
+
|
3
|
+
def self.log(name, opts={})
|
4
|
+
case name
|
5
|
+
when :fatal_error
|
6
|
+
puts "#{prefix} Fatal error: #{opts[:msg].light_black}. Aborting...".red
|
7
|
+
when :loading_curriculum_data
|
8
|
+
puts "#{prefix} Loading the curriculum data for ".cyan + opts[:trgt_lang].to_s.light_black
|
9
|
+
puts "#{indent} using ".cyan + opts[:master_lang].to_s.light_black + ' as the default'.cyan
|
10
|
+
when :executing_command
|
11
|
+
puts "#{prefix} Executing ".cyan + opts[:cmd].to_s.light_black
|
12
|
+
puts "#{indent} from the directory ".cyan + opts[:exec_dir].to_s.light_black if opts.has_key? :exec_dir
|
13
|
+
puts "#{indent} logging to ".cyan + opts[:log_file].to_s.light_black if opts.has_key? :log_file
|
14
|
+
else
|
15
|
+
# nothing to do
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.prefix
|
20
|
+
'>>'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.indent
|
24
|
+
' '
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class CGen::Util::ShellCommand
|
2
|
+
|
3
|
+
def initialize(command, execution_dir, log_file=nil)
|
4
|
+
@command = command
|
5
|
+
@execution_dir = execution_dir
|
6
|
+
@log_file = log_file
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
CGen::Util::Logging.log(:executing_command, cmd: @command, exec_dir: @execution_dir, log_file: @log_file)
|
11
|
+
|
12
|
+
status = true
|
13
|
+
|
14
|
+
Process.waitpid(
|
15
|
+
fork do
|
16
|
+
original_stdout, original_stderr = $stdout, $stderr
|
17
|
+
FileUtils.chdir @execution_dir do
|
18
|
+
File.open(@log_file, 'a') do |log_file|
|
19
|
+
$stderr = $stdout = log_file
|
20
|
+
system @command
|
21
|
+
$stdout, $stderr = original_stdout, original_stderr
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end)
|
25
|
+
|
26
|
+
status # return
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.exist?(command)
|
30
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
31
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
32
|
+
exts.collect do |ext|
|
33
|
+
exe = File.join(path, "#{command}#{ext}")
|
34
|
+
return true if File.executable? exe
|
35
|
+
end
|
36
|
+
end
|
37
|
+
false # return
|
38
|
+
end
|
39
|
+
|
40
|
+
def exist?
|
41
|
+
self.class.exist? @command
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_executable_part(command)
|
45
|
+
command.split(' ').first
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/lib/cgen/util.rb
ADDED
data/lib/cgen/version.rb
ADDED
File without changes
|