xmlresume2x 0.2.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.
@@ -0,0 +1,413 @@
1
+ # Configuration for the resume converter -*- ruby -*-
2
+
3
+ require 'xmlresume2x/xmlmarkup'
4
+
5
+ common_file = File.join( File.dirname( __FILE__ ), '..', 'common', "common#{Converter::CONFIG_EXT}" )
6
+ load_config( File.read( common_file ), common_file )
7
+
8
+ #####################################################
9
+ # Global Constants and Methods
10
+
11
+ def newline
12
+ tag( 'br' )
13
+ end
14
+
15
+ SEPARATOR= ''
16
+ GAP='5pt'
17
+
18
+ #####################################################
19
+ # Processors for simple elements
20
+
21
+ add_processor 'SubParaProcessor' do |element|
22
+ element.para.collect {|p| tag( 'p' ).add( p.process! )}
23
+ end
24
+
25
+ #####################################################
26
+ # Inline elements
27
+
28
+ processor 'link' => 'LinkProcessor' do |link|
29
+ tag( 'a', 'href' => link._href ).add( link.process_children! )
30
+ end
31
+
32
+ processor 'emphasis' => 'EmphasisProcessor' do |em|
33
+ tag( 'em' ).add( em.process_children! )
34
+ end
35
+
36
+ processor 'citation' => 'CitationProcessor' do |citation|
37
+ tag( 'cite' ).add( citation.process_children! )
38
+ end
39
+
40
+ processor 'url' => 'UrlProcessor' do |url|
41
+ tag( 'a', 'href' => url.text! ).add( url.process_children! )
42
+ end
43
+
44
+ processor 'email' => 'EmailProcessor' do |email|
45
+ tag( 'a', 'href' => "mailto:#{email.text!}" ).add( email.process_children! )
46
+ end
47
+
48
+ processor 'period' => 'PeriodProcessor' do |period|
49
+ [period.from, REXML::Text.new( " – ", false, nil, true) ,period.to]
50
+ end
51
+
52
+ processor( :textItem => 'REXMLTextProcessor' ) do |e, options|
53
+ text = get_value( e.value, options )
54
+ if options[:verbatim]
55
+ texts = []
56
+ text.split( /\n/ ).each_with_index {|t, i| texts << tag( 'br' ) if i > 0; texts << t}
57
+ texts
58
+ else
59
+ text
60
+ end
61
+ end
62
+
63
+ processor :text => 'TextProcessor' do |text, options|
64
+ options[:verbatim] ? text.dup : text.dup.gsub( /\s+/, ' ' )
65
+ end
66
+
67
+ #####################################################
68
+ # General elements
69
+
70
+ processor 'projects' => 'ProjectsProcessor' do |projects|
71
+ tag( 'ul' ).add( projects.project.process_all! )
72
+ end
73
+
74
+ processor 'project' => 'ProjectProcessor' do |project|
75
+ t = tag( 'li' )
76
+ t.add( tag( 'span', 'class' => 'projectTitle' ).add( project._title ) ).add(': ') unless project._title.nil?
77
+ t.add( project.process_children! )
78
+ end
79
+
80
+
81
+ #####################################################
82
+ # Resume elements
83
+
84
+ processor 'resume' => 'ResumeProcessor' do |resume|
85
+ language = case self.lang
86
+ when 'de' then 'german'
87
+ when 'en' then 'english'
88
+ when 'fr' then 'french'
89
+ when 'da' then 'danish'
90
+ when 'it' then 'italian'
91
+ when 'es' then 'spanish'
92
+ when 'fi' then 'finnish'
93
+ when 'pt' then 'portuguese'
94
+ when 'sv' then 'swedish'
95
+ else 'english'
96
+ end
97
+ doc = REXML::Document.new
98
+ doc << REXML::XMLDecl.new( "1.0", "UTF-8" )
99
+ doc << REXML::DocType.new( ['html', 'PUBLIC', '"-//W3C//DTD XHTML 1.1//EN"', '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"' ] )
100
+ html = doc.add_element( 'html' )
101
+ html.add_namespace( 'http://www.w3.org/1999/xhtml' )
102
+ b = html.builder
103
+ b.head do |h|
104
+ h.meta( 'http-equiv'=>'Content-Type', 'content'=>'text/html; charset=utf-8' )
105
+ h.title( "#{keyword(:Resume)} #{keyword(:Of)} #{resume.header.name}" )
106
+ h.link( 'href'=>'cv.css', 'rel'=>'stylesheet' )
107
+ end
108
+ b.body do |b|
109
+ b.div( 'class'=>'resume' ) do |d|
110
+ d.div( 'class'=>'nameSection' ) do |e|
111
+ e.h1( resume.header.name, 'class'=>'nameHeading' )
112
+ e.p( resume.header.address, 'class'=>'address' )
113
+ e.p( resume.header.contact, 'class'=>'contact' )
114
+ end
115
+
116
+ d.div( 'class'=>'historySection' ) do |e|
117
+ e.h1( keyword(:History_Title ), 'class'=>'sectionHeading' )
118
+ e.add!( resume.history.process_all! )
119
+ end if resume.history
120
+
121
+ d.div( 'class'=>'academicsSection' ) do |e|
122
+ e.h1( keyword(:Education_Title ), 'class'=>'sectionHeading' )
123
+ e.add!( resume.academics.process_all! )
124
+ end if resume.academics
125
+
126
+ d.div( 'class'=>'skillsSection' ) do |e|
127
+ e.h1( keyword(:Skills_Title ), 'class'=>'sectionHeading' )
128
+ e.add!( resume.skillarea.process_all! )
129
+ end if resume.skillarea
130
+
131
+ d.div( 'class'=>'interestsSection' ) do |e|
132
+ e.h1( keyword(:Interests_Title ), 'class'=>'sectionHeading' )
133
+ e.add!( resume.interests.process_all! )
134
+ end if resume.interests
135
+
136
+ if resume.pubs || resume.memberships || resume.awards || resume.clearances || resume.referees
137
+ d.div( 'class'=>'addInfoSection' ) do |e|
138
+ e.h1( keyword(:AdditionalInformation ), 'class'=>'sectionHeading' )
139
+ e.add!( resume.memberships.process_all! ) if resume.memberships
140
+ e.add!( resume.awards.process_all! ) if resume.awards
141
+ e.add!( resume.clearances.process_all! ) if resume.clearances
142
+ e.add!( resume.pubs.process_all! ) if resume.pubs
143
+ e.add!( resume.referees.process_all! ) if resume.referees
144
+ end
145
+ end
146
+
147
+ d.p( resume.lastModified, 'class'=>'lastModified' ) if resume.lastModified
148
+ d.div( resume.copyright, 'class'=>'copyright' ) if resume.copyright
149
+ end
150
+ end
151
+
152
+ output = ''
153
+ doc.write( output, 0 )
154
+ output
155
+ end
156
+
157
+ #####################################################
158
+ # Job specific elements
159
+
160
+ processor 'history' => 'HistoryProcessor' do |history|
161
+ history.job.process_all!
162
+ end
163
+
164
+ processor 'job' => 'JobProcessor' do |job|
165
+ b = tag( 'div', 'class'=>'job' ).builder
166
+ b.h2( job.jobtitle, 'class'=>'jobTitle' )
167
+ b.span( job.employer, 'class'=>'employer' )
168
+ b.span( ' (', job.location, ')', 'class'=>'location' ) if job.location
169
+ b.br
170
+ b.span( job.period || job.date, 'class'=>'date' ).br
171
+ b.div( job.description, 'class'=>'jobDescription' ) if job.description
172
+ b.div( 'class'=>'projects' ) do |div|
173
+ div.p( keyword(:Projects), ':' )
174
+ div.add!( job.projects )
175
+ end if job.projects
176
+ b.div( 'class'=>'achievements') do |div|
177
+ div.p( keyword(:History_Achievements), ':' )
178
+ div.add!( job.achievements )
179
+ end if job.achievements
180
+ b
181
+ end
182
+
183
+ processor 'achievements' => 'AchievementsProcessor' do |achievements|
184
+ tag( 'ul' ).add( achievements.achievement.process_all! )
185
+ end
186
+
187
+ processor 'achievement' => 'AchievementProcessor' do |achievement|
188
+ tag( 'li' ).add( achievement.process_children! )
189
+ end
190
+
191
+
192
+ #####################################################
193
+ # Academics specific elements
194
+
195
+ processor 'academics' => 'AcademicsProcessor' do |academics|
196
+ academics.degrees.degree.process_all!
197
+ end
198
+
199
+ def gpa_type( type )
200
+ if type == 'major'
201
+ keyword( :Education_Gpa_Major )
202
+ else
203
+ keyword( :Education_Gpa_Overall )
204
+ end
205
+ end
206
+
207
+ processor 'degree' => 'DegreeProcessor' do |degree|
208
+ b = tag( 'div', 'class'=>'degree' ).builder
209
+
210
+ b.span( 'class'=>'degreeTitle' ) do |s|
211
+ s.add!( degree.level )
212
+ s.add!( ' ', keyword( :In ), ' ', degree.major.separate_by( ', ', " #{keyword(:And)} " ) ) if degree.major
213
+ end
214
+ b.add!( ' (', (degree.minor.length > 1 ? keyword(:Education_Minors) : keyword(:Education_Minor) ), ': ',
215
+ degree.minor.separate_by( ', ', " #{keyword(:And)} " ), ')' ) if degree.minor
216
+ b.add!( ", ").span( degree.period || degree.date, 'class'=>'date' ) if degree.period || degree.date
217
+ b.add!( '. ', degree.annotation ) if degree.annotation
218
+
219
+ if degree.institution
220
+ b.br
221
+ b.span( degree.institution, 'class'=>'institution' )
222
+ b.span( ' (', degree.location, ')', 'class'=>'location' ) if degree.location
223
+ end
224
+
225
+ b.add!( degree.gpa ) if degree.gpa
226
+ b.p( keyword(:Education_Subjects), ': ', degree.subjects ) if degree.subjects
227
+
228
+ b.div( 'class'=>'projects' ) do |div|
229
+ div.p( keyword(:Projects), ':' )
230
+ div.add!( degree.projects )
231
+ end if degree.projects
232
+
233
+ b
234
+ end
235
+
236
+ processor 'subjects' => 'SubjectsProcessor' do |subjects|
237
+ subjects.subject.join( ', ' )
238
+ end
239
+
240
+ processor 'subject' => 'SubjectProcessor' do |subject|
241
+ "#{subject.title} (#{subject.result})"
242
+ end
243
+
244
+ processor 'gpa' => 'GpaProcessor' do |gpa|
245
+ b = tag( 'div' ).builder
246
+ b.p do |p|
247
+ p.span( gpa_type( gpa._type ), 'class'=>'gpaPreamble' ).add!( ': ', gpa.score )
248
+ p.add!( " #{keyword(:Education_Gpa_Outof)} #{gpa.possible}" ) if gpa.possible
249
+ end
250
+ b.add!( gpa.note ) if gpa.note
251
+ b
252
+ end
253
+
254
+ #####################################################
255
+ # Skill specific elements
256
+
257
+ processor 'skillarea' => 'SkillareaProcessor' do |skillarea|
258
+ b = tag( 'div', 'class'=>'skillarea' ).builder
259
+ b.h2( skillarea.title || keyword(:Skills_Title), 'class'=>'skillareaTitle' )
260
+ b.ul {|ul| ul.add!( skillarea.skillset.process_all! )}
261
+ b
262
+ end
263
+
264
+ processor 'skillset' => 'SkillsetProcessor' do |skillset|
265
+ b = tag( 'li' ).builder
266
+ b.span( skillset.title, ': ', 'class'=>'skillsetTitle' ) if skillset.title
267
+ b.add!( skillset.skill.collect {|skill| "#{skill}#{skill._level ? " (#{skill._level})" : "" }"}.join( ', ' ) )
268
+ b
269
+ end
270
+
271
+ #####################################################
272
+ # Interest specific elements
273
+
274
+ processor 'interests' => 'InterestsProcessor' do |interests|
275
+ b = tag( 'div', 'class'=>'interests' ).builder
276
+ b.h2( interests.title || keyword(:Interests_Title), 'class'=>'interestsTitle' )
277
+ b.ul {|ul| ul.add!( interests.interest.process_all! )}
278
+ b
279
+ end
280
+
281
+ processor 'interest' => 'InterestProcessor' do |interest|
282
+ b = tag( 'li' ).builder
283
+ b.span( interest.title, 'class'=>'interestTitle' )
284
+ b.add!( interest.description ) if interest.description
285
+ b
286
+ end
287
+
288
+ #####################################################
289
+ # Publication specific elements
290
+
291
+ processor 'pubs' => 'PubsProcessor' do |pubs|
292
+ b = tag( 'div', 'class'=>'pubs' ).builder
293
+ b.h2( keyword(:Publications_Title), 'class'=>'publicationsTitle' )
294
+ b.ul {|ul| ul.add!( pubs.pub.process_all! )}
295
+ b
296
+ end
297
+
298
+ processor 'pub' => 'PubProcessor' do |pub|
299
+ t = tag( 'li' )
300
+
301
+ title = pub.artTitle ? [tag( 'span', 'class'=>'artTitle' ).add( pub.artTitle )] : []
302
+ title << [ ". #{keyword(:Publications_In).capitalize} ", tag( 'span', 'class'=>'bookTitle' ).add( pub.bookTitle ) ] if pub.bookTitle
303
+
304
+ t.add( pub.author.join( ', ' ), ': ' ) if pub.author
305
+ t.add( title ) if title
306
+ t.add( '. ', pub.publisher ) if pub.publisher
307
+ t.add( ', ', pub.date ) if pub.date
308
+ t.add( '. ', pub.pageNums ) if pub.pageNums
309
+ t
310
+ end
311
+
312
+ processor 'author' => 'AuthorProcessor' do |author|
313
+ if author._name.nil?
314
+ get_children_value( author )
315
+ else
316
+ get_value( author.__element.elements["//name[@id='#{author._name}']"] )
317
+ end
318
+ end
319
+
320
+ #####################################################
321
+ # Keyword specific elements
322
+
323
+ processor 'keywords' => 'KeywordsProcessor' do |keywords|
324
+ keywords.keyword.join(', ')
325
+ end
326
+
327
+ #####################################################
328
+ # Membership specific elements
329
+
330
+ processor 'memberships' => 'MembershipsProcessor' do |memberships|
331
+ b = tag( 'div', 'class'=>'memberships' ).builder
332
+ b.h2( memberships.title, 'class'=>'membershipsTitle' )
333
+ b.ul {|ul| ul.add!( memberships.membership.process_all! )}
334
+ b
335
+ end
336
+
337
+ processor 'membership' => 'MembershipProcessor' do |m|
338
+ organization = if m.organization
339
+ arr = [ m.organization ]
340
+ arr << " (" << tag( 'span', 'class'=>'location' ).add( m.location ) << ")" if m.location
341
+ arr
342
+ end
343
+ t = tag( 'li' ).add( [m.title, organization ].compact.join( newline ) )
344
+ t.add( tag( 'br' ), tag( 'span', 'class'=>'date' ).add( m.date || m.period ) ) if m.date || m.period
345
+ t.add( m.description ) if m.description
346
+ t
347
+ end
348
+
349
+ #####################################################
350
+ # Clearance specific elements
351
+
352
+ processor 'clearances' => 'ClearancesProcessor' do |clearances|
353
+ b = tag( 'div', 'class'=>'clearances' ).builder
354
+ b.h2( clearances.title || keyword(:SecurityClearances_Title), 'class'=>'clearancesTitle' )
355
+ b.ul {|ul| ul.add!( clearances.clearance.process_all! )}
356
+ b
357
+ end
358
+
359
+ processor 'clearance' => 'ClearanceProcessor' do |c|
360
+ t = tag( 'li' )
361
+ t.add( [c.level, c.organization].compact.join( ', ' ) )
362
+ t.add( ", ", tag( 'span', 'class'=>'date' ).add( c.date || c.period ) ) if c.date || c.period
363
+ t.add( c.note ) if c.note
364
+ t
365
+ end
366
+
367
+ #####################################################
368
+ # Award specific elements
369
+
370
+ processor 'awards' => 'AwardsProcessor' do |awards|
371
+ b = tag( 'div', 'class'=>'awards' ).builder
372
+ b.h2( awards.title || keyword(:Awards_Title), 'class'=>'awardsTitle' )
373
+ b.ul {|ul| ul.add!( awards.award.process_all! )}
374
+ b
375
+ end
376
+
377
+ processor 'award' => 'AwardProcessor' do |a|
378
+ t = tag( 'li' )
379
+ t.add( [a.title, a.organization].compact.join( ', ' ) )
380
+ t.add( ", ", tag( 'span', 'class'=>'date' ).add( a.date || a.period ) ) if a.date || a.period
381
+ t.add( a.description ) if a.description
382
+ t
383
+ end
384
+
385
+ #####################################################
386
+ # Referee specific elements
387
+
388
+ processor 'referees' => 'RefereesProcessor' do |referees|
389
+ b = tag( 'div', 'class'=>'referees' ).builder
390
+ b.h2( keyword(:Referees_Title), 'class'=>'refereesTitle' )
391
+ b.ul {|ul| ul.add!( referees.referee.process_all! )}
392
+ b
393
+ end
394
+
395
+ processor 'referee' => 'RefereeProcessor' do |r|
396
+ tag( 'li' ).add( [r.name, r.title, r.organization, r.address, r.contact].compact.join( newline ) )
397
+ end
398
+
399
+ #####################################################
400
+ # Copyright specific elements
401
+
402
+ processor 'copyright' => 'CopyrightProcessor' do |c|
403
+ arr = ["Copyright © #{c.year} #{c.name}" ]
404
+ arr << c.legalnotice if c.legalnotice
405
+ arr
406
+ end
407
+
408
+ #####################################################
409
+ # LastModified specific elements
410
+
411
+ processor 'lastModified' => 'LastModifiedProcessor' do |l|
412
+ [ keyword(:LastModified), ' ', tag( 'span', 'class'=>'date' ).add( l.date ) ]
413
+ end
@@ -0,0 +1,72 @@
1
+ # Configuration for the resume converter -*- ruby -*-
2
+ # Language file
3
+
4
+ keyword(
5
+ # general keywords
6
+ :Resume => 'Lebenslauf',
7
+ :Of => 'von',
8
+ :In => 'in',
9
+ :And => 'und',
10
+ :AdditionalInformation => 'Zusätzliche Informationen',
11
+ :Phone => 'Telefon',
12
+ :Phone_Home => 'Telefon Privat',
13
+ :Phone_Work => 'Telefon Geschäft',
14
+ :Phone_Mobile => 'Telefon Mobil',
15
+ :Fax => 'Fax',
16
+ :Fax_Home => 'Fax Privat',
17
+ :Fax_Work => 'Fax Geschäft',
18
+ :Pager => 'Pager',
19
+ :IM_Aim => 'AIM',
20
+ :IM_Icq => 'ICQ',
21
+ :IM_Irc => 'IRC',
22
+ :IM_Jabber => 'Jabber',
23
+ :IM_Msn => 'MSN Messenger',
24
+ :IM_Yahoo => 'Yahoo! Messenger',
25
+ :Email => 'Email',
26
+ :Url => 'URL',
27
+ :Projects => 'Projekte',
28
+ :Dates => 'Datum',
29
+ :LastModified => 'Zuletzt geändert',
30
+ :Present => 'Gegenwart',
31
+
32
+ # for job history
33
+ :History_Title => 'Arbeitserfahrung',
34
+ :History_Employer => 'Name und Adresse des Arbeitgebers',
35
+ :History_Occupation => 'Beruf oder Funktion',
36
+ :History_MainActivities => 'Wichtigste Tätigkeiten und Zuständigkeiten',
37
+ :History_Achievements => 'Erreichte Ziele',
38
+
39
+ # for education
40
+ :Education_Title => 'Schul- und Berufsbildung',
41
+ :Education_Organization => 'Name und Art der Bildungs- oder Ausbildungseinrichtung',
42
+ :Education_Level => 'Bezeichnung der erworbenen Qualifikation',
43
+ :Education_MajorStudies => 'Hauptfächer',
44
+ :Education_MinorStudies => 'Nebenfächer',
45
+ :Education_Minor => 'Nebenfach',
46
+ :Education_Minors => 'Nebenfächer',
47
+ :Education_Gpa => 'Notendurchschnitt',
48
+ :Education_Gpa_Overall => 'Gesamtnotendurchschnitt',
49
+ :Education_Gpa_Major => 'Notendurchschnitt der Hauptfächer',
50
+ :Education_Gpa_Outof => 'von',
51
+ :Education_Subjects => 'Fächer',
52
+
53
+ # for skills
54
+ :Skills_Title => 'Fähigkeiten',
55
+
56
+ # for publications
57
+ :Publications_Title => 'Publikationen',
58
+ :Publications_In => 'in',
59
+
60
+ # for interests
61
+ :Interests_Title => 'Interessen',
62
+
63
+ # for security clearances
64
+ :SecurityClearances_Title => 'Leumundszeugnis',
65
+
66
+ # for awards
67
+ :Awards_Title => 'Auszeichnungen',
68
+
69
+ # for referees
70
+ :Referees_Title => 'Referenzen'
71
+
72
+ )