email_signature_parser 0.1.1
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/README.md +105 -0
- data/lib/email_signature_parser/data/job_titles/acronyms.yaml +440 -0
- data/lib/email_signature_parser/data/job_titles/titles.yaml +182 -0
- data/lib/email_signature_parser/data/job_titles/titles_es.yaml +417 -0
- data/lib/email_signature_parser/html_text_parser.rb +181 -0
- data/lib/email_signature_parser/parser.rb +885 -0
- data/lib/email_signature_parser/utils.rb +19 -0
- data/lib/email_signature_parser.rb +32 -0
- metadata +233 -0
@@ -0,0 +1,417 @@
|
|
1
|
+
---
|
2
|
+
- abogada
|
3
|
+
- abogado
|
4
|
+
- académica
|
5
|
+
- académico
|
6
|
+
- acondicionado
|
7
|
+
- actor
|
8
|
+
- actriz
|
9
|
+
- administrador
|
10
|
+
- administradora
|
11
|
+
- administrativa
|
12
|
+
- administrativo
|
13
|
+
- aire
|
14
|
+
- almacenista
|
15
|
+
- almacén
|
16
|
+
- analista
|
17
|
+
- animador
|
18
|
+
- animadora
|
19
|
+
- aplicaciones
|
20
|
+
- archivo
|
21
|
+
- arquitecta
|
22
|
+
- arquitecto
|
23
|
+
- artista
|
24
|
+
- aseadora
|
25
|
+
- aseo
|
26
|
+
- asesor
|
27
|
+
- asesora
|
28
|
+
- asistente
|
29
|
+
- auditor
|
30
|
+
- auditora
|
31
|
+
- automotriz
|
32
|
+
- auxiliar
|
33
|
+
- ayuda
|
34
|
+
- ayudante
|
35
|
+
- bacterióloga
|
36
|
+
- bacteriólogo
|
37
|
+
- bailarina
|
38
|
+
- bailarín
|
39
|
+
- barbera
|
40
|
+
- barbero
|
41
|
+
- bartender
|
42
|
+
- base
|
43
|
+
- bibliotecaria
|
44
|
+
- bibliotecario
|
45
|
+
- bienestar
|
46
|
+
- bilingüe
|
47
|
+
- blogger
|
48
|
+
- bloggera
|
49
|
+
- bodeguera
|
50
|
+
- bodeguero
|
51
|
+
- brigadista
|
52
|
+
- bus
|
53
|
+
- caja
|
54
|
+
- cajera
|
55
|
+
- cajero
|
56
|
+
- calidad
|
57
|
+
- camarera
|
58
|
+
- camarógrada
|
59
|
+
- camarógrafo
|
60
|
+
- camión
|
61
|
+
- cantante
|
62
|
+
- capacitador
|
63
|
+
- capacitadora
|
64
|
+
- capturista
|
65
|
+
- cargador
|
66
|
+
- cargadora
|
67
|
+
- certificada
|
68
|
+
- certificado
|
69
|
+
- chef
|
70
|
+
- chofer
|
71
|
+
- choferes
|
72
|
+
- cine
|
73
|
+
- civil
|
74
|
+
- coach
|
75
|
+
- cocina
|
76
|
+
- cocinera
|
77
|
+
- cocinero
|
78
|
+
- colegio
|
79
|
+
- comercial
|
80
|
+
- community
|
81
|
+
- compras
|
82
|
+
- conductor
|
83
|
+
- conductora
|
84
|
+
- conserje
|
85
|
+
- constructor
|
86
|
+
- constructora
|
87
|
+
- consultor
|
88
|
+
- consultora
|
89
|
+
- contable
|
90
|
+
- contador
|
91
|
+
- contadora
|
92
|
+
- content
|
93
|
+
- contratista
|
94
|
+
- control
|
95
|
+
- controller
|
96
|
+
- coordinador
|
97
|
+
- coordinadora
|
98
|
+
- copywriter
|
99
|
+
- correctivo
|
100
|
+
- corrector
|
101
|
+
- correctora
|
102
|
+
- correspondencia
|
103
|
+
- cosmetóloga
|
104
|
+
- cosmetólogo
|
105
|
+
- crédito
|
106
|
+
- cuentas
|
107
|
+
- datos
|
108
|
+
- decana
|
109
|
+
- decano
|
110
|
+
- defensor
|
111
|
+
- defensora
|
112
|
+
- demostrador
|
113
|
+
- demostradora
|
114
|
+
- departamento
|
115
|
+
- dependienta
|
116
|
+
- dependiente
|
117
|
+
- desarrollador
|
118
|
+
- desarrolladora
|
119
|
+
- desk
|
120
|
+
- despachador
|
121
|
+
- despachadora
|
122
|
+
- dibujante
|
123
|
+
- diesel
|
124
|
+
- digitador
|
125
|
+
- digitadora
|
126
|
+
- digital
|
127
|
+
- director
|
128
|
+
- directora
|
129
|
+
- disc
|
130
|
+
- diseñador
|
131
|
+
- diseñadora
|
132
|
+
- documental
|
133
|
+
- domiciliaria
|
134
|
+
- domiciliario
|
135
|
+
- editor
|
136
|
+
- editora
|
137
|
+
- ejecutiva
|
138
|
+
- ejecutivo
|
139
|
+
- electricista
|
140
|
+
- electrónica
|
141
|
+
- electrónico
|
142
|
+
- eléctrica
|
143
|
+
- eléctrico
|
144
|
+
- empacador
|
145
|
+
- empacadora
|
146
|
+
- enfermera
|
147
|
+
- enfermero
|
148
|
+
- enfermería
|
149
|
+
- entrenador
|
150
|
+
- entrenadora
|
151
|
+
- escenógrafa
|
152
|
+
- escenógrafo
|
153
|
+
- escolar
|
154
|
+
- especialista
|
155
|
+
- especializada
|
156
|
+
- especializado
|
157
|
+
- esteticista
|
158
|
+
- estibador
|
159
|
+
- estibadora
|
160
|
+
- estilista
|
161
|
+
- estilo
|
162
|
+
- externa
|
163
|
+
- externo
|
164
|
+
- facilitador
|
165
|
+
- facilitadora
|
166
|
+
- farmacéutica
|
167
|
+
- farmacéutico
|
168
|
+
- financiera
|
169
|
+
- financiero
|
170
|
+
- fiscal
|
171
|
+
- fisioterapeuta
|
172
|
+
- fotógrafa
|
173
|
+
- fotógrafo
|
174
|
+
- gamer
|
175
|
+
- general
|
176
|
+
- generales
|
177
|
+
- gerencia
|
178
|
+
- gerente
|
179
|
+
- gestor
|
180
|
+
- gestora
|
181
|
+
- gráfica
|
182
|
+
- gráfico
|
183
|
+
- grúa
|
184
|
+
- guardia
|
185
|
+
- guionista
|
186
|
+
- headhunter
|
187
|
+
- help
|
188
|
+
- higienista
|
189
|
+
- humanos
|
190
|
+
- iluminador
|
191
|
+
- iluminadora
|
192
|
+
- implementador
|
193
|
+
- implementadora
|
194
|
+
- impulsor
|
195
|
+
- impulsora
|
196
|
+
- industrial
|
197
|
+
- influencer
|
198
|
+
- ingeniera
|
199
|
+
- ingeniero
|
200
|
+
- inspector
|
201
|
+
- inspectora
|
202
|
+
- instalador
|
203
|
+
- instaladora
|
204
|
+
- instructor
|
205
|
+
- instructora
|
206
|
+
- interiores
|
207
|
+
- interna
|
208
|
+
- interno
|
209
|
+
- intérprete
|
210
|
+
- inventarista
|
211
|
+
- iso
|
212
|
+
- jardinera
|
213
|
+
- jardinero
|
214
|
+
- jefa
|
215
|
+
- jefe
|
216
|
+
- jockey
|
217
|
+
- joyera
|
218
|
+
- joyero
|
219
|
+
- judicial
|
220
|
+
- juez
|
221
|
+
- jueza
|
222
|
+
- junior
|
223
|
+
- laboratorio
|
224
|
+
- laboratorista
|
225
|
+
- lavador
|
226
|
+
- lavadora
|
227
|
+
- legal
|
228
|
+
- liquidador
|
229
|
+
- liquidadora
|
230
|
+
- locutor
|
231
|
+
- locutora
|
232
|
+
- logística
|
233
|
+
- lubricador
|
234
|
+
- lubricadora
|
235
|
+
- líder
|
236
|
+
- maestra
|
237
|
+
- maestro
|
238
|
+
- manager
|
239
|
+
- manicurista
|
240
|
+
- mantenimiento
|
241
|
+
- marketing
|
242
|
+
- masajista
|
243
|
+
- mecánica
|
244
|
+
- mecánico
|
245
|
+
- media
|
246
|
+
- mejoramiento
|
247
|
+
- mensajera
|
248
|
+
- mensajero
|
249
|
+
- mentor
|
250
|
+
- mentora
|
251
|
+
- mercaderista
|
252
|
+
- mesa
|
253
|
+
- mesera
|
254
|
+
- mesero
|
255
|
+
- modista
|
256
|
+
- modisto
|
257
|
+
- montacargas
|
258
|
+
- mostrador
|
259
|
+
- motorizada
|
260
|
+
- motorizado
|
261
|
+
- mucama
|
262
|
+
- máquina
|
263
|
+
- médica
|
264
|
+
- médico
|
265
|
+
- música
|
266
|
+
- músico
|
267
|
+
- negocios
|
268
|
+
- notaria
|
269
|
+
- notario
|
270
|
+
- nutricionista
|
271
|
+
- nómina
|
272
|
+
- obra
|
273
|
+
- ocupacional
|
274
|
+
- odontóloga
|
275
|
+
- odontólogo
|
276
|
+
- operaciones
|
277
|
+
- operador
|
278
|
+
- operadora
|
279
|
+
- operaria
|
280
|
+
- operario
|
281
|
+
- organizacional
|
282
|
+
- orientador
|
283
|
+
- orientadora
|
284
|
+
- paralegale
|
285
|
+
- paramédica
|
286
|
+
- paramédico
|
287
|
+
- parqueadera
|
288
|
+
- parqueadero
|
289
|
+
- pedicurista
|
290
|
+
- peluquera
|
291
|
+
- peluquero
|
292
|
+
- periodista
|
293
|
+
- personal
|
294
|
+
- plomera
|
295
|
+
- plomero
|
296
|
+
- portera
|
297
|
+
- portero
|
298
|
+
- presentador
|
299
|
+
- presentadora
|
300
|
+
- prevencionista
|
301
|
+
- preventivo
|
302
|
+
- primaria
|
303
|
+
- principal
|
304
|
+
- procesos
|
305
|
+
- procurador
|
306
|
+
- procuradora
|
307
|
+
- producción
|
308
|
+
- productor
|
309
|
+
- productora
|
310
|
+
- profesional
|
311
|
+
- profesor
|
312
|
+
- profesora
|
313
|
+
- programador
|
314
|
+
- programadora
|
315
|
+
- promotor
|
316
|
+
- promotora
|
317
|
+
- proyectos
|
318
|
+
- psicopedagoga
|
319
|
+
- psicopedagogo
|
320
|
+
- psicóloga
|
321
|
+
- psicólogo
|
322
|
+
- pública
|
323
|
+
- público
|
324
|
+
- química
|
325
|
+
- químico
|
326
|
+
- radióloga
|
327
|
+
- radiólogo
|
328
|
+
- recepcionista
|
329
|
+
- recibidor
|
330
|
+
- recibidora
|
331
|
+
- reclutador
|
332
|
+
- reclutadora
|
333
|
+
- rector
|
334
|
+
- rectora
|
335
|
+
- recursos
|
336
|
+
- red
|
337
|
+
- redactor
|
338
|
+
- redactora
|
339
|
+
- refrigeración
|
340
|
+
- regional
|
341
|
+
- registrador
|
342
|
+
- registradora
|
343
|
+
- relojera
|
344
|
+
- relojero
|
345
|
+
- repartidor
|
346
|
+
- repartidora
|
347
|
+
- reportera
|
348
|
+
- reportero
|
349
|
+
- repositor
|
350
|
+
- repositora
|
351
|
+
- representante
|
352
|
+
- riesgos
|
353
|
+
- salud
|
354
|
+
- sastre
|
355
|
+
- sección
|
356
|
+
- secretaria
|
357
|
+
- secretario
|
358
|
+
- seguridad
|
359
|
+
- selección
|
360
|
+
- sem
|
361
|
+
- senior
|
362
|
+
- seo
|
363
|
+
- servicios
|
364
|
+
- sistemas
|
365
|
+
- social
|
366
|
+
- socorrista
|
367
|
+
- software
|
368
|
+
- soldador
|
369
|
+
- soldadora
|
370
|
+
- sonidista
|
371
|
+
- soporte
|
372
|
+
- sous
|
373
|
+
- streamer
|
374
|
+
- subdirector
|
375
|
+
- subdirectora
|
376
|
+
- sucursal
|
377
|
+
- supervisor
|
378
|
+
- supervisora
|
379
|
+
- surtidor
|
380
|
+
- surtidora
|
381
|
+
- taxista
|
382
|
+
- telefonista
|
383
|
+
- tesorera
|
384
|
+
- tesorero
|
385
|
+
- topógrafa
|
386
|
+
- topógrafo
|
387
|
+
- trabajador
|
388
|
+
- trabajadora
|
389
|
+
- traductor
|
390
|
+
- traductora
|
391
|
+
- tramitador
|
392
|
+
- tramitadora
|
393
|
+
- transportador
|
394
|
+
- transportadora
|
395
|
+
- turno
|
396
|
+
- técnica
|
397
|
+
- técnico
|
398
|
+
- universitaria
|
399
|
+
- universitario
|
400
|
+
- urbanista
|
401
|
+
- vehículos
|
402
|
+
- vendedor
|
403
|
+
- vendedora
|
404
|
+
- ventas
|
405
|
+
- vicerrector
|
406
|
+
- vicerrectora
|
407
|
+
- video
|
408
|
+
- vigilante
|
409
|
+
- web
|
410
|
+
- webmaster
|
411
|
+
- youtuber
|
412
|
+
- zapatera
|
413
|
+
- zapatero
|
414
|
+
- zona
|
415
|
+
- área
|
416
|
+
- óptica
|
417
|
+
- óptico
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module EmailSignatureParser
|
2
|
+
class HtmlTextParser < ::Ox::Sax
|
3
|
+
attr_reader :parsed_text
|
4
|
+
|
5
|
+
def initialize()
|
6
|
+
@parsed_text = ''
|
7
|
+
@discard = false
|
8
|
+
@current_element = ''
|
9
|
+
|
10
|
+
@current_list_index = -1
|
11
|
+
@lists = []
|
12
|
+
|
13
|
+
|
14
|
+
@table_columns = 0
|
15
|
+
@parsing_link = false
|
16
|
+
@link_text = ""
|
17
|
+
@link_href = ""
|
18
|
+
end
|
19
|
+
|
20
|
+
def start_element(name)
|
21
|
+
|
22
|
+
if name == :b || name == :strong
|
23
|
+
@parsed_text << " "
|
24
|
+
elsif name == :i || name == :em
|
25
|
+
@parsed_text << " "
|
26
|
+
end
|
27
|
+
|
28
|
+
if name == :script || name == :style || name == :head || name == :meta || name == :title
|
29
|
+
@discard = true
|
30
|
+
else
|
31
|
+
@discard = false
|
32
|
+
end
|
33
|
+
|
34
|
+
@current_element = name
|
35
|
+
if name == :br
|
36
|
+
@parsed_text << "\n"
|
37
|
+
end
|
38
|
+
if name== :hr
|
39
|
+
@parsed_text << "\n-------------------------------------------------------------------------------------------------------------------------------------------------\n"
|
40
|
+
end
|
41
|
+
if name == :ul || name == :ol
|
42
|
+
@parsed_text << "\n"
|
43
|
+
@lists << {
|
44
|
+
list_type: name,
|
45
|
+
ordered_list_level: 1,
|
46
|
+
ordered_list_type: "1", #If its an unordered list, this is not used.
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
if name == :a
|
51
|
+
@parsing_link = true
|
52
|
+
@link_text = ""
|
53
|
+
@link_href = ""
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def end_element(name)
|
58
|
+
@discard = false
|
59
|
+
|
60
|
+
if name == :b || name == :strong
|
61
|
+
@parsed_text << " "
|
62
|
+
elsif name == :i || name == :em
|
63
|
+
@parsed_text << " "
|
64
|
+
end
|
65
|
+
|
66
|
+
if name == :p || name == :div || name.match(/h[1-6]/) || name == :br || name == :hr || name == :table || name == :tr
|
67
|
+
@parsed_text << "\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
if name == :a
|
71
|
+
@parsed_text << "<a href=\"#{@link_href}\">#{@link_text}</a>" #leave links in html format
|
72
|
+
@parsing_link = false
|
73
|
+
@link_text = ""
|
74
|
+
@link_href = ""
|
75
|
+
end
|
76
|
+
|
77
|
+
if name == :li
|
78
|
+
@parsed_text << "\n"
|
79
|
+
if @lists.last && @lists.last[:list_type] == :ol
|
80
|
+
@lists.last[:ordered_list_level] += 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if name == :ul || name == :ol
|
85
|
+
@lists.pop
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def attr(name, value)
|
90
|
+
|
91
|
+
if (@current_element == :a && name == :href)
|
92
|
+
@link_href << value
|
93
|
+
end
|
94
|
+
|
95
|
+
if (@current_element == :div && name == :style && value.match?(/border-\w*:\s*solid/))
|
96
|
+
@parsed_text << "\n-------------------------------------------------------------------------------------------------------------------------------------------------\n"
|
97
|
+
end
|
98
|
+
|
99
|
+
if (@current_element == :ol && name == :start)
|
100
|
+
@lists.last[:ordered_list_level] = value.to_i
|
101
|
+
end
|
102
|
+
if (@current_element == :ol && name == :type)
|
103
|
+
@lists.last[:ordered_list_type] = value
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def attrs_done()
|
108
|
+
if @current_element == :li
|
109
|
+
current_list = @lists.last
|
110
|
+
if current_list.nil?
|
111
|
+
#sometimes we encounter a <li> outside of a list, so we just ignore it
|
112
|
+
return
|
113
|
+
end
|
114
|
+
if @lists.size > 1
|
115
|
+
# We are inside a nested list, so we need to indent
|
116
|
+
@parsed_text << " " * 2 * (@lists.size - 1)
|
117
|
+
end
|
118
|
+
|
119
|
+
if current_list[:list_type] == :ol
|
120
|
+
if current_list[:ordered_list_type] == "A"
|
121
|
+
@parsed_text << "#{('A'.ord + current_list[:ordered_list_level] - 1).chr}. "
|
122
|
+
elsif current_list[:ordered_list_type] == "a"
|
123
|
+
@parsed_text << "#{('a'.ord + current_list[:ordered_list_level] - 1).chr}. "
|
124
|
+
elsif current_list[:ordered_list_type] == "I"
|
125
|
+
@parsed_text << "#{roman_numeral(current_list[:ordered_list_level])}. "
|
126
|
+
elsif current_list[:ordered_list_type] == "i"
|
127
|
+
@parsed_text << "#{roman_numeral(current_list[:ordered_list_level]).downcase}. "
|
128
|
+
else
|
129
|
+
@parsed_text << "#{current_list[:ordered_list_level]}. "
|
130
|
+
end
|
131
|
+
else
|
132
|
+
@parsed_text << "* "
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
def text(value)
|
139
|
+
if @parsing_link
|
140
|
+
@link_text << value
|
141
|
+
return
|
142
|
+
end
|
143
|
+
unless value.nil? || value.empty? || @discard
|
144
|
+
if value.include?("-----------------------------")
|
145
|
+
@parsed_text << "\n-------------------------------------------------------------------------------------------------------------------------------------------------\n"
|
146
|
+
else
|
147
|
+
@parsed_text << value
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def postprocess()
|
153
|
+
|
154
|
+
# remove linefeeds (\r\n and \r -> \n)
|
155
|
+
@parsed_text.gsub!(/\r\n?/, "\n")
|
156
|
+
|
157
|
+
# strip extra spaces
|
158
|
+
@parsed_text.gsub!(/[ \t]*\302\240+[ \t]*/, " ") # non-breaking spaces -> spaces
|
159
|
+
@parsed_text.gsub!(/\n[\t]+/, "\n") # space at start of lines
|
160
|
+
@parsed_text.gsub!(/[ \t]+\n/, "\n") # space at end of lines
|
161
|
+
|
162
|
+
|
163
|
+
@parsed_text = @parsed_text.split("\n").map(&:strip).join("\n") # strip lines
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
def roman_numeral(number)
|
168
|
+
roman_mapping = {
|
169
|
+
1000 => "M", 900 => "CM", 500 => "D", 400 => "CD", 100 => "C",
|
170
|
+
90 => "XC", 50 => "L", 40 => "XL", 10 => "X", 9 => "IX",
|
171
|
+
5 => "V", 4 => "IV", 1 => "I"
|
172
|
+
}
|
173
|
+
result = ""
|
174
|
+
roman_mapping.each do |value, letter|
|
175
|
+
result << letter * (number / value)
|
176
|
+
number = number % value
|
177
|
+
end
|
178
|
+
result
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|