presume 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/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
|