presume 0.0.2
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/Gemfile +4 -0
- data/README.Rdoc +104 -0
- data/Rakefile +7 -0
- data/lib/classes/bullet.rb +18 -0
- data/lib/classes/classifide.rb +81 -0
- data/lib/classes/header.rb +170 -0
- data/lib/classes/resume_builder.rb +375 -0
- data/lib/classes/resume_classifier.rb +137 -0
- data/lib/classes/resume_searcher.rb +4 -0
- data/lib/classes/searchable.rb +40 -0
- data/lib/classes/searchables.rb +24 -0
- data/lib/definitions/classifications.rb +24 -0
- data/lib/definitions/machines.rb +11 -0
- data/lib/definitions/regex.rb +79 -0
- data/lib/presume.rb +123 -0
- data/sample_resume.docx +0 -0
- data/spec/classifide_spec.rb +17 -0
- data/spec/header_spec.rb +73 -0
- data/spec/presume_spec.rb +72 -0
- data/spec/resume_builder_spec.rb +213 -0
- data/spec/resume_classifier_spec.rb +140 -0
- data/spec/searchable_spec.rb +34 -0
- data/spec/searchables_spec.rb +22 -0
- data/spec/spec_helper.rb +1 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b80339c1863dc69cf2e8be22e594a58bde43dbda
|
4
|
+
data.tar.gz: b7c250b6fb461ade98ee62d194aac7c9c8f5532a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3048dc8d33cca2e7c141a6dafb89c4ff769ca2a3ba029c5159abda211ac334f8cd7ad8f1030441743ed7e2232f9ca9b6788a8eff77f88bafb1ec0246731c225c
|
7
|
+
data.tar.gz: 3b50bf15404471cb27cfaded216de75cffcd053e4fdc822065a01c7e6650988655ccafb5b8b460f0c46b8f7ab8d35865c85307456bee3cecc0fbe2d55699b8ef
|
data/Gemfile
ADDED
data/README.Rdoc
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Presume
|
2
|
+
|
3
|
+
A resume parser coupled with fundamental Applicant Tracking System Technology
|
4
|
+
|
5
|
+
### Description
|
6
|
+
|
7
|
+
Presume is the first open-source Applicant Tracking System technology for Ruby-on-Rails developers. It works by parsing the resume into the CVSTOM.org resume format Section >> Header >> Bullets, and then taking an input of skills and their expected duration to check for in that resume.
|
8
|
+
|
9
|
+
### Features
|
10
|
+
|
11
|
+
Parse resumes
|
12
|
+
Checks resumes for specific skills, positions, and their duration
|
13
|
+
|
14
|
+
### Resume Parser:
|
15
|
+
|
16
|
+
require 'presume'
|
17
|
+
|
18
|
+
# Sample input
|
19
|
+
resume_text = "Leigh Silverstein\n123 Ave.\n\nWork Experience\nProject Coordinator"
|
20
|
+
|
21
|
+
# Parse resume with string input
|
22
|
+
presume = Presume.new(resume_text)
|
23
|
+
|
24
|
+
# Retrieve Sections
|
25
|
+
Presume.sections
|
26
|
+
|
27
|
+
#=> {0 => SectionObject1, 1 => SectionObject2}
|
28
|
+
|
29
|
+
# SectionObject Functions
|
30
|
+
|
31
|
+
SectionObject.text
|
32
|
+
|
33
|
+
#=> "Work Experience"
|
34
|
+
|
35
|
+
SectionObject.children
|
36
|
+
|
37
|
+
#=> [ HeaderObject1, HeaderObject2 ]
|
38
|
+
|
39
|
+
# HeaderObject Functions
|
40
|
+
|
41
|
+
SectionObject.text
|
42
|
+
|
43
|
+
#=> "Project Coordinator, Projects4Ever Inc., Toronto, Ontario, Jan 2011-Jul 2012
|
44
|
+
|
45
|
+
SectionObject.duration
|
46
|
+
|
47
|
+
#=> 1.5 (In Years)
|
48
|
+
|
49
|
+
SectionObject.start_time_text
|
50
|
+
|
51
|
+
#=> Jan 2011
|
52
|
+
|
53
|
+
SectionObject.end_time_text
|
54
|
+
|
55
|
+
#=> Jul 2012
|
56
|
+
|
57
|
+
HeaderObject.children
|
58
|
+
|
59
|
+
#=> [ BulletObject1, BulletObject2 ]
|
60
|
+
|
61
|
+
# BulletObject inherits all functions from the HeaderObject except children
|
62
|
+
|
63
|
+
|
64
|
+
### ATS:
|
65
|
+
|
66
|
+
# After parsing a resume
|
67
|
+
|
68
|
+
# Checking for certain position or education ("name", expected_minimum_duration_in_years)
|
69
|
+
intake_hash = {"Project Coordinator|Project Assistant" => 1, "Bachelors Finance|BF|B.F." => 4}
|
70
|
+
|
71
|
+
# Check for positions
|
72
|
+
presume.positions?(intake_hash)
|
73
|
+
|
74
|
+
#=> {"Project Coordinator|Project Assistant" => [ MatchedHeaderObject1 ], "Bachelors Finance|BF|B.F." => [ MatchedHeaderObject2 ]}
|
75
|
+
|
76
|
+
# Checking for certain skills ("name", expected_minimum_duration_in_years)
|
77
|
+
intake_hash = {"database management" => 1, "clear communication" => 0}
|
78
|
+
|
79
|
+
# Check for positions
|
80
|
+
presume.skills?(intake_hash)
|
81
|
+
|
82
|
+
#=> {"database management" => [ MatchedBulletObject1 ], "clear communication" => [ MatchedBulletObject2 ]}
|
83
|
+
|
84
|
+
#Note that matched headers and bullets are the same classes as the headers and bullets discussed in the resume parsing section
|
85
|
+
|
86
|
+
### Requirements
|
87
|
+
|
88
|
+
* EngTagger
|
89
|
+
* Ruby-Stemmer
|
90
|
+
* Docx (for testing)
|
91
|
+
|
92
|
+
### Install
|
93
|
+
|
94
|
+
(sudo) gem install presume
|
95
|
+
|
96
|
+
### Author
|
97
|
+
|
98
|
+
of this Ruby library
|
99
|
+
|
100
|
+
* Leigh Silverstein (lsilversteinto [at] gmail.com)
|
101
|
+
|
102
|
+
### License
|
103
|
+
|
104
|
+
This library is distributed under the GPL. Please see the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class Bullet < Header
|
2
|
+
|
3
|
+
attr_accessor :text, :id
|
4
|
+
|
5
|
+
def initialize(classifide, header)
|
6
|
+
|
7
|
+
both_classifications.each do |classification|
|
8
|
+
instance_variable_set(("@" + classification).to_sym, header.send(classification))
|
9
|
+
end
|
10
|
+
|
11
|
+
@header_text = @text
|
12
|
+
@header_id = @id
|
13
|
+
|
14
|
+
@text = classifide.text
|
15
|
+
@id = classifide.id
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Classifide
|
4
|
+
|
5
|
+
attr_accessor *both_classifications_symboled
|
6
|
+
|
7
|
+
def initialize(classifide)
|
8
|
+
both_classifications.each do |classification|
|
9
|
+
instance_variable_set(("@" + classification).to_sym, classifide[classification.to_sym])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def more_words_than?(number)
|
14
|
+
@number_of_words > number
|
15
|
+
end
|
16
|
+
|
17
|
+
def name?
|
18
|
+
@name.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def many_words?
|
22
|
+
@many_words
|
23
|
+
end
|
24
|
+
|
25
|
+
def email?
|
26
|
+
!@email.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def type?
|
30
|
+
@type.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def address?
|
34
|
+
!@address.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def phone?
|
38
|
+
!@phone.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def verbs?
|
42
|
+
!@verbs.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def date?
|
46
|
+
if @dates.nil? and @dates_2.nil?
|
47
|
+
false
|
48
|
+
else
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def institution?
|
55
|
+
if @schools.nil? and @companies.nil?
|
56
|
+
false
|
57
|
+
else
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def profession?
|
63
|
+
!@professions.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
def city?
|
67
|
+
!@cities.nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
def section?
|
71
|
+
!@section.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_new_value(attribute, new_value)
|
75
|
+
instance_variable_set(("@" + attribute).to_sym, new_value)
|
76
|
+
end
|
77
|
+
|
78
|
+
def children
|
79
|
+
@presume.all_types[@id].drop(1)
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
class Header < Classifide
|
2
|
+
|
3
|
+
attr_accessor :clean_profession
|
4
|
+
|
5
|
+
def initialize(classifide)
|
6
|
+
both_classifications.each do |classification|
|
7
|
+
instance_variable_set(("@" + classification).to_sym, classifide.send(classification))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def remove_date
|
12
|
+
@clean_profession = @text.gsub(regex_dates, "")
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove_city
|
16
|
+
@clean_profession.gsub!(regex_cities, "")
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_institution
|
20
|
+
@clean_profession.gsub!(regex_companies, "")
|
21
|
+
@clean_profession.gsub!(regex_schools, "")
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_professions
|
25
|
+
@clean_profession.gsub!(regex_companies, "")
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove_all_but_profession
|
29
|
+
@clean_profession = @clean_profession[regex_professions]
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def season?
|
34
|
+
!@text[regex_season].nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def split_date
|
38
|
+
@prepare_split_date = @dates.gsub(Regexp.new('( |)(to\\b|-|–)( |)', 'i'), "{+)")
|
39
|
+
@split_date = @prepare_split_date.split("{+)")
|
40
|
+
if @split_date.kind_of?(Array)
|
41
|
+
@split_date
|
42
|
+
else
|
43
|
+
@split_date = [@dates]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def start_time_text?
|
48
|
+
if date?
|
49
|
+
split_date[0]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def start_time_number
|
54
|
+
if date?
|
55
|
+
@start_time_number = start_year.to_i + convert_month_to_number(start_month)
|
56
|
+
else
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def end_time_text?
|
62
|
+
if @end_time_text.nil?
|
63
|
+
if date?
|
64
|
+
if end_date_exists?
|
65
|
+
@end_time_text = split_date[1]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
@end_time_text
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def current?
|
74
|
+
|
75
|
+
!end_time_text?[regex_current].nil?
|
76
|
+
end
|
77
|
+
|
78
|
+
def end_time_number
|
79
|
+
if date?
|
80
|
+
if end_date_exists?
|
81
|
+
if current?
|
82
|
+
@end_time_number = Date.today.strftime("%Y").to_i + (Date.today.strftime("%m")).to_i/12
|
83
|
+
else
|
84
|
+
@end_time_number = end_year.to_i + convert_month_to_number(end_month)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def end_date_exists?
|
91
|
+
split_date.length == 2
|
92
|
+
end
|
93
|
+
|
94
|
+
def start_year
|
95
|
+
@start_year = split_date[0][regex_year]
|
96
|
+
end
|
97
|
+
|
98
|
+
def start_month
|
99
|
+
@start_month = split_date[0][regex_month]
|
100
|
+
if @start_month.nil?
|
101
|
+
@start_month = split_date[0][regex_season]
|
102
|
+
if @start_month.nil?
|
103
|
+
@start_month = "Jan"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
@start_month
|
107
|
+
end
|
108
|
+
|
109
|
+
def end_year
|
110
|
+
@end_year = split_date[1][regex_year]
|
111
|
+
end
|
112
|
+
|
113
|
+
def end_month
|
114
|
+
if @end_month.nil?
|
115
|
+
@end_month = split_date[1][regex_month]
|
116
|
+
if @end_month.nil?
|
117
|
+
@end_month = "Jan"
|
118
|
+
end
|
119
|
+
@end_month
|
120
|
+
else
|
121
|
+
@end_month
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def duration
|
126
|
+
if season?
|
127
|
+
@duration = 3/12
|
128
|
+
else
|
129
|
+
@duration = end_time_number - start_time_number
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def convert_season_to_number(season)
|
134
|
+
case season.downcase
|
135
|
+
when "winter"
|
136
|
+
0
|
137
|
+
when "spring"
|
138
|
+
3
|
139
|
+
when "summer"
|
140
|
+
6
|
141
|
+
when "fall"
|
142
|
+
9
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def convert_month_to_number(month)
|
148
|
+
if season?
|
149
|
+
@converted_month = convert_season_to_number(month)
|
150
|
+
else
|
151
|
+
@converted_month = Date::ABBR_MONTHNAMES.index(month[0..2])
|
152
|
+
end
|
153
|
+
|
154
|
+
@converted_month_of_12 = (@converted_month / 12).to_f
|
155
|
+
end
|
156
|
+
|
157
|
+
def split_cities
|
158
|
+
@location = @cities.split(", ")
|
159
|
+
end
|
160
|
+
|
161
|
+
def just_city
|
162
|
+
|
163
|
+
split_cities[0]
|
164
|
+
end
|
165
|
+
|
166
|
+
def just_state
|
167
|
+
split_cities[1]
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
@@ -0,0 +1,375 @@
|
|
1
|
+
class ResumeBuilder
|
2
|
+
|
3
|
+
attr_accessor :classifides, :resume
|
4
|
+
|
5
|
+
def initialize(classified_lines)
|
6
|
+
@classifides = classified_lines
|
7
|
+
@length = classified_lines.length
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_classifide(line_number)
|
11
|
+
@classifide = @classifides[line_number]
|
12
|
+
@line_number = line_number
|
13
|
+
end
|
14
|
+
|
15
|
+
def header_line_number?
|
16
|
+
((@line_number + 1)/@length).to_f <= 0.10
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_for_name_in_header
|
20
|
+
if !@classifide.many_words? and !@classifide.name? and @classifide.type?
|
21
|
+
@classifide.type = "name"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_for_email_in_header
|
26
|
+
if !@classifide.many_words? and @classifide.email? and @classifide.type?
|
27
|
+
@classifide.type = "email"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_for_address_in_header
|
32
|
+
if @classifide.address? and @classifide.type?
|
33
|
+
@classifide.type = "address"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_for_phone_in_header
|
38
|
+
if !@classifide.many_words? and @classifide.phone? and @classifide.type?
|
39
|
+
@classifide.type = "phone"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def check_header
|
44
|
+
if header_line_number?
|
45
|
+
check_for_name_in_header
|
46
|
+
check_for_email_in_header
|
47
|
+
check_for_address_in_header
|
48
|
+
check_for_phone_in_header
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def classifide_after
|
53
|
+
if @line_number == @length - 1
|
54
|
+
@classifide_after = @classifides[@line_number]
|
55
|
+
else
|
56
|
+
@classifide_after = @classifides[@line_number + 1]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def classifide_after_after
|
61
|
+
if @line_number >= @length - 2
|
62
|
+
@classifide_after = @classifides[@line_number]
|
63
|
+
else
|
64
|
+
@classifide_after = @classifides[@line_number + 2]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def classifide_before
|
69
|
+
@classifide_before = @classifides[@line_number - 1]
|
70
|
+
end
|
71
|
+
|
72
|
+
def check_obvious_types
|
73
|
+
|
74
|
+
if !@classifide.institution? and @classifide.type? and !@classifide.date? and !@classifide.city? and !@classifide.profession? and !@classifide.many_words? and @classifide.section?
|
75
|
+
@classifide.type = "section"
|
76
|
+
end
|
77
|
+
|
78
|
+
if @classifide.many_words? and @classifide.verbs? and @classifide.type? and !@classifide.date?
|
79
|
+
@classifide.type = "bullet"
|
80
|
+
end
|
81
|
+
|
82
|
+
if !@classifide.institution? and @classifide.type? and !@classifide.date? and !@classifide.city? and !@classifide.profession? and !@classifide.section?
|
83
|
+
@classifide.type = "bullet"
|
84
|
+
end
|
85
|
+
|
86
|
+
if @classifide.institution? and @classifide.type? and @classifide.date? and @classifide.city? and @classifide.profession?
|
87
|
+
@classifide.type = "header"
|
88
|
+
end
|
89
|
+
|
90
|
+
if @classifide.type? and ((@classifide.institution? and @classifide.date? and @classifide.city? and @classifide.profession?) or (@classifide.institution? and @classifide.date? and @classifide.city?) or (@classifide.institution? and @classifide.date? and !@classifide.many_words?) or (@classifide.date? and @classifide.city? and @classifide.profession? and !@classifide.many_words?))
|
91
|
+
@classifide.type = "header_x"
|
92
|
+
end
|
93
|
+
|
94
|
+
if @classifide.type? and @classifide.many_words? and !@classifide.verbs? and (@classifide.profession? or @classifide.city? or @classifide.institution?)
|
95
|
+
@classifide.type = "header_x"
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def first_pass
|
102
|
+
@length.times do |n|
|
103
|
+
set_classifide(n)
|
104
|
+
check_header
|
105
|
+
check_obvious_types
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def second_pass
|
110
|
+
@length.times do |n|
|
111
|
+
set_classifide(n)
|
112
|
+
if !@classifide.institution? and @classifide.type? and !@classifide.date? and !@classifide.city? and !@classifide.profession? and !@classifide.many_words?
|
113
|
+
if (@classifide_after.institution? and @classifide_after.profession?) or (!@classifide_after.institution? and !@classifide_after.profession?)
|
114
|
+
@classifide.type = "section"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
if (@classifide.institution? or @classifide.profession?) and !@classifide.many_words? and @classifide.type?
|
119
|
+
@classifide.type = "header_x"
|
120
|
+
end
|
121
|
+
|
122
|
+
if !@classifide.institution? and @classifide.profession? and @classifide.type?
|
123
|
+
@classifide.type = "header_x"
|
124
|
+
end
|
125
|
+
|
126
|
+
if @classifide.type? and @classifide.more_words_than?(10)
|
127
|
+
@classifide.type = "bullet"
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def reset_header_x_start
|
135
|
+
@header_x_start = true
|
136
|
+
end
|
137
|
+
|
138
|
+
def build_resume
|
139
|
+
reset_header_x_start
|
140
|
+
@length.times do |n|
|
141
|
+
set_classifide(n)
|
142
|
+
unless @classifide.type?
|
143
|
+
unless @classifide.type == "name" or @classifide.type == "email" or @classifide.type == "phone" or @classifide.type == "address"
|
144
|
+
send(@classifide.type + "_build")
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_to_all_types(id)
|
151
|
+
if all_types[id].nil?
|
152
|
+
all_types[id] = [@all_type]
|
153
|
+
else
|
154
|
+
all_types[id] += [@all_type]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def section_build
|
159
|
+
@header_number = nil
|
160
|
+
@header_x_start = true
|
161
|
+
@section_number = @line_number
|
162
|
+
@all_type = @classifide
|
163
|
+
add_section_to_resume
|
164
|
+
end
|
165
|
+
|
166
|
+
def add_section_to_resume
|
167
|
+
sections.merge!({@line_number => @all_type})
|
168
|
+
add_to_all_types(@line_number)
|
169
|
+
end
|
170
|
+
|
171
|
+
def add_header_to_resume
|
172
|
+
headers.merge!({@line_number => @header})
|
173
|
+
|
174
|
+
add_to_all_types(@line_number)
|
175
|
+
add_to_all_types(@section_number)
|
176
|
+
end
|
177
|
+
|
178
|
+
def add_bullet_to_resume
|
179
|
+
bullets.merge!({@line_number => @bullet})
|
180
|
+
add_to_all_types(@line_number)
|
181
|
+
add_to_all_types(header_number?)
|
182
|
+
end
|
183
|
+
|
184
|
+
def section_number?
|
185
|
+
if @section_number.nil?
|
186
|
+
@section_number = -1
|
187
|
+
|
188
|
+
else
|
189
|
+
@section_number
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def previous_section_headers?
|
194
|
+
!headers[@section_number].nil?
|
195
|
+
end
|
196
|
+
|
197
|
+
def header_build
|
198
|
+
@bullet = nil
|
199
|
+
@header_number = @line_number
|
200
|
+
@header = Header.new(@classifide)
|
201
|
+
@header_x_start = true
|
202
|
+
@all_type = @header
|
203
|
+
add_header_to_resume
|
204
|
+
end
|
205
|
+
|
206
|
+
def create_blank_classifide
|
207
|
+
@blank_classifide = Classifide.new(id: -1)
|
208
|
+
end
|
209
|
+
def bullet_parent
|
210
|
+
if all_types[header_number?].nil?
|
211
|
+
@all_type = create_blank_classifide
|
212
|
+
add_to_all_types(-1)
|
213
|
+
all_types[-1][0]
|
214
|
+
else
|
215
|
+
all_types[header_number?][0]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def bullet_build
|
220
|
+
@header_x_start = true
|
221
|
+
@bullet = Bullet.new(@classifide, bullet_parent)
|
222
|
+
@all_type = @bullet
|
223
|
+
add_bullet_to_resume
|
224
|
+
end
|
225
|
+
|
226
|
+
def header_number?
|
227
|
+
if @header_number.nil?
|
228
|
+
section_number?
|
229
|
+
else
|
230
|
+
@header_number
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def check_for_gaps
|
235
|
+
header_classifications.each do |classification|
|
236
|
+
if @classifide.send(classification).nil?
|
237
|
+
if !classifide_after_after.send(classification).nil?
|
238
|
+
@classifide.set_new_value(classification, classifide_after_after.send(classification))
|
239
|
+
@header_x_start = "almost"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def combine_text()
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
def header_x_build
|
250
|
+
|
251
|
+
@header_number = @line_number
|
252
|
+
if @header_x_start == true
|
253
|
+
if classifide_after.type == "header_x"
|
254
|
+
header_classifications.each do |classification|
|
255
|
+
if @classifide.send(classification).nil?
|
256
|
+
@classifide.set_new_value(classification, classifide_after.send(classification))
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
@classifide.set_new_value("text", @classifide.text + ", " + classifide_after.text)
|
262
|
+
|
263
|
+
if classifide_after_after.type == "header_x"
|
264
|
+
check_for_gaps
|
265
|
+
if @header_x_start == 'almost'
|
266
|
+
@classifide.set_new_value("text", @classifide.text + ", " + classifide_after_after.text)
|
267
|
+
end
|
268
|
+
|
269
|
+
@header_x_start = false unless @header_x_start == "almost"
|
270
|
+
else
|
271
|
+
|
272
|
+
|
273
|
+
|
274
|
+
@header_x_start = false
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
@header = Header.new(@classifide)
|
279
|
+
@all_type = @header
|
280
|
+
add_header_to_resume
|
281
|
+
|
282
|
+
else
|
283
|
+
if @header_x_start == "almost"
|
284
|
+
@header_x_start == "almost_closer"
|
285
|
+
else
|
286
|
+
@header_x_start = true
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def resume
|
292
|
+
resume = {sections: sections, headers: headers, bullets: bullets, all_types: all_types}
|
293
|
+
end
|
294
|
+
|
295
|
+
def sections
|
296
|
+
@sections ||= {}
|
297
|
+
end
|
298
|
+
|
299
|
+
def headers
|
300
|
+
@headers ||= {}
|
301
|
+
end
|
302
|
+
|
303
|
+
def bullets
|
304
|
+
@bullets ||= {}
|
305
|
+
end
|
306
|
+
|
307
|
+
def all_types
|
308
|
+
@all_types ||= {}
|
309
|
+
end
|
310
|
+
=begin
|
311
|
+
@length.times do |n|
|
312
|
+
|
313
|
+
set_classifide(n)
|
314
|
+
|
315
|
+
if type?
|
316
|
+
|
317
|
+
#check following types
|
318
|
+
if n < @n - 2 and n > 1
|
319
|
+
|
320
|
+
if !many_words? and @p_hash[n+1][:type] == "resume_post" and @p[:type].nil?
|
321
|
+
@p[:type] = "resume_group"
|
322
|
+
end
|
323
|
+
|
324
|
+
if @p[:word_length] == false and @p_hash[n+1][:type] == "resume_post_x" and @p_hash[n-1][:type] != "resume_post_x" and @p[:type].nil?
|
325
|
+
@p[:type] = "resume_group"
|
326
|
+
end
|
327
|
+
if @p[:word_length] == false and @p_hash[n+1][:type] == "resume_line" and /resume_post/.match(@p_hash[n-1][:type]).nil? and @p[:type].nil?
|
328
|
+
@p[:type] = "resume_group"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
#pass 4
|
335
|
+
|
336
|
+
(@n -1).times do |n|
|
337
|
+
|
338
|
+
@p = @p_hash[n]
|
339
|
+
|
340
|
+
if @p[:type].nil?
|
341
|
+
#check following types
|
342
|
+
if n < @n - 2 and n > 1
|
343
|
+
|
344
|
+
if (@p_hash[n+1][:type] == "resume_post" or @p_hash[n+1][:type] == "resume_group") and @p_hash[n-1][:type] == "resume_post" and @p[:type].nil?
|
345
|
+
@p[:type] = "resume_line"
|
346
|
+
end
|
347
|
+
|
348
|
+
if @p_hash[n-1][:type] == "resume_post" and @p_hash[n+1][:type] == "resume_line" and @p[:type].nil?
|
349
|
+
@p[:type] = "resume_post_x"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
=end
|
355
|
+
|
356
|
+
=begin
|
357
|
+
@current_user_2 = current_user
|
358
|
+
#@current_user_2 = User.find(2)
|
359
|
+
@resume_line_shoot = 0
|
360
|
+
@resume_line_build = 0
|
361
|
+
(@n -1).times do |n|
|
362
|
+
|
363
|
+
@p = @p_hash[n]
|
364
|
+
|
365
|
+
puts @p[:type]
|
366
|
+
unless /resume/.match(@p[:type]).nil?
|
367
|
+
puts @p[:type]
|
368
|
+
construct_resume_object(args = {n: n, p_hash: @p_hash, resume_group: @resume_group, resume_post: @resume_post, resume_line: @resume_line})
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
redirect_to current_user
|
373
|
+
=end
|
374
|
+
|
375
|
+
end
|