xmlresume2x 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ index.html:
2
+ en:
3
+ title: Home
4
+ inMenu: true
5
+ directoryName: XMLResume2x
6
+ menuOrder: 1
7
+
8
+ download.html:
9
+ en:
10
+ title: Download & Installation
11
+ inMenu: true
12
+ menuOrder: 3
13
+
14
+ features.html:
15
+ en:
16
+ title: Features
17
+ inMenu: true
18
+ menuOrder: 5
19
+
20
+ manual.html:
21
+ en:
22
+ title: Manual
23
+ inMenu: true
24
+ menuOrder: 6
25
+
26
+ examples.html:
27
+ en:
28
+ title: Examples
29
+ inMenu: true
30
+ menuOrder: 7
31
+
32
+ api.html:
33
+ en:
34
+ dest: rdoc/index.html
35
+ title: API Reference
36
+ menuOrder: 8
37
+ inMenu: true
@@ -0,0 +1,24 @@
1
+
2
+ require 'rpa/install'
3
+
4
+ class Install_xmlresume2x < RPA::Install::FullInstaller
5
+ name 'xmlresume2x'
6
+ version '0.2.0-1'
7
+ classification Application
8
+ build do
9
+ installdocs %w[COPYING ChangeLog TODO]
10
+ installdocs 'docs'
11
+ installrdoc %w[README] + Dir['lib/**/*.rb']
12
+ installdata
13
+ end
14
+ description <<-EOF
15
+ Converts an xml resume to various output formats
16
+
17
+ xmlresume2x can convert CVs written in the XML Resume
18
+ Library format (http://xmlresume.sourceforge.net) to a number
19
+ of formats, including LaTeX markup which uses the europecv
20
+ (http://www.ctan.org/tex-archive/help/Catalogue/entries/europecv.html)
21
+ class which is based on the 'standard' European Curriculum Vitae
22
+ format at http://www.cedefop.eu.int/transparency/cv.asp.
23
+ EOF
24
+ end
@@ -0,0 +1,86 @@
1
+ #
2
+ # $Id: converter.rb 23 2004-12-20 11:08:39Z thomas $
3
+ #
4
+ #--
5
+ #
6
+ # xmlresume2x: converts an xml resume to various output formats
7
+ # Copyright (C) 2004 Thomas Leitner
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10
+ # General Public License as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along with this program; if not,
18
+ # write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+ #
22
+
23
+ require 'rbconfig'
24
+ require 'erb'
25
+ require 'rexml/document'
26
+ require 'xmlresume2x/processor'
27
+
28
+ module XMLResume2x
29
+
30
+ VERSION = [0, 2, 0]
31
+
32
+ class Converter
33
+
34
+ CONFIG_EXT = '.cfg'
35
+
36
+ attr_accessor :data_dir
37
+
38
+ def initialize
39
+ @data_dir = File.join( Config::CONFIG["datadir"], "xmlresume2x" )
40
+ if defined? Gem::Cache
41
+ gem = Gem::Cache.from_installed_gems.search( "xmlresume2x", "=#{VERSION.join('.')}" ).last
42
+ @data_dir = File.join( gem.full_gem_path, "data", "xmlresume2x" ) if gem
43
+ end
44
+ end
45
+
46
+ def available_formats
47
+ dir_list( format_dir )
48
+ end
49
+
50
+ def available_langs
51
+ dir_list( lang_dir )
52
+ end
53
+
54
+ def load_config( format, lang, userconfig = nil )
55
+ @processor = ResumeProcessor.new( lang )
56
+
57
+ filename = File.join( format_dir, format + CONFIG_EXT )
58
+ @processor.load_config( File.read( filename ), filename)
59
+
60
+ filename = File.join( lang_dir, lang + CONFIG_EXT )
61
+ @processor.load_config( File.read( filename ), filename )
62
+
63
+ @processor.load_config( File.read( userconfig ), userconfig ) if userconfig
64
+ end
65
+
66
+ def convert( resume )
67
+ ElementWrapper.new( REXML::Document.new( File.new( resume ) ).root, @processor, {} ).process!
68
+ end
69
+
70
+ private
71
+
72
+ def format_dir
73
+ File.join( @data_dir, 'format' )
74
+ end
75
+
76
+ def lang_dir
77
+ File.join( @data_dir, 'lang' )
78
+ end
79
+
80
+ def dir_list( dir )
81
+ Dir[File.join( dir, '*' + CONFIG_EXT )].collect {|name| File.basename( name, CONFIG_EXT ) }
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,135 @@
1
+ #
2
+ # $Id: processor.rb 21 2004-12-09 17:44:52Z thomas $
3
+ #
4
+ #--
5
+ #
6
+ # xmlresume2x: converts an xml resume to various output formats
7
+ # Copyright (C) 2004 Thomas Leitner
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10
+ # General Public License as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along with this program; if not,
18
+ # write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+ #
22
+
23
+ require 'xmlresume2x/wrapper'
24
+
25
+ module XMLResume2x
26
+
27
+ # This class serves as container for processors and keywords. Therefore it defines the methods
28
+ # which can be used in the configuration files.
29
+ class ResumeProcessor
30
+
31
+ # A hash of processors
32
+ attr_reader :processors
33
+
34
+ # A hash containing the assignments of XML elements to processors
35
+ attr_reader :assignments
36
+
37
+ # The language used for this ResumeProcessor
38
+ attr_accessor :lang
39
+
40
+ def initialize( lang )
41
+ @lang = lang
42
+ @keywords = Hash.new( '<UNDEFINED>' )
43
+ @processors = Hash.new( Proc.new {|e, options| get_children_value( e, options ) } )
44
+ @assignments = Hash.new
45
+ processor( :textItem => 'REXMLTextProcessor' ) {|e, options| get_value( e.value, options ) }
46
+ end
47
+
48
+ # Loads the configuration defined by the given string +src+.
49
+ def load_config( src, filename = '(eval)' )
50
+ instance_eval( src, filename )
51
+ end
52
+
53
+ # Adds a processor which should be defined using a block. +name+ is the name of the processor.
54
+ def add_processor( name, &block )
55
+ raise ArgumentError, "No block given" unless block_given?
56
+ @processors[name.to_s] = block
57
+ end
58
+
59
+ # Assigns elements to processors. +assignment+ has to be a Hash where the keys are XML resume
60
+ # element names and the values are processor names. If a block is supplied, then the XML resume
61
+ # elements are processed by the given block.
62
+ def processor( assignment, &block )
63
+ raise ArgumentError, "Argument has to be a Hash" unless Hash === assignment
64
+ assignment.each do |key, value|
65
+ add_processor( value, &block ) if block_given?
66
+ case key
67
+ when Array
68
+ key.each {|name| @assignments[name.to_s] = value }
69
+ when String
70
+ @assignments[key.to_s] = value
71
+ when Symbol
72
+ @assignments[key] = value
73
+ else
74
+ raise ArgumentError, "Key for assignment has to be Array or String or Symbol"
75
+ end
76
+ end
77
+ end
78
+
79
+ # Calls the processor +name+ on the element +item+ and optionally with +options+.
80
+ def call_processor( name, item, options = {} )
81
+ proc = @processors[name]
82
+ if proc.arity == 1
83
+ proc.call( item )
84
+ else
85
+ proc.call( item, options )
86
+ end
87
+ end
88
+
89
+ # Defines or retrieves a keyword. If +arg+ is a Hash, then the keywords in this Hash are added.
90
+ # If +arg+ is a Symbol, then the specified keyword is retrieved. The parameter +processed+
91
+ # specifies if the keyword should be processed as any other text.
92
+ def keyword( arg, processed = true )
93
+ case arg
94
+ when Symbol
95
+ processed ? get_value( @keywords[arg] ) : @keywords[arg]
96
+ when Hash
97
+ @keywords.update( arg )
98
+ else
99
+ raise ArgumentError, "Argument has to be a Symbol or a Hash"
100
+ end
101
+ end
102
+
103
+ # Returns the value of +item+ after being processed by the assigned processor.
104
+ def get_value( item, options = {} )
105
+ name, item = case item
106
+ when ElementWrapper
107
+ options = item.options.merge( options )
108
+ [item.__element.name, item]
109
+ when REXML::Element
110
+ [item.name, ElementWrapper.new( item, self, options )]
111
+ when REXML::Text
112
+ [:textItem, item]
113
+ when String
114
+ [:text, item]
115
+ when NilClass
116
+ return nil
117
+ else
118
+ raise ArgumentError, "Not a valid argument class (#{item.class})"
119
+ end
120
+ call_processor( @assignments[name], item, options )
121
+ end
122
+
123
+ # Returns the values of the processed children of +element+.
124
+ # *Returns*:: an array with all the values or if the <tt>:to_s</tt>
125
+ # option is set, the array converted to a string, i.e. <tt>array.to_s</tt>
126
+ def get_children_value( element, options = {} )
127
+ arr = []
128
+ new_options = element.options.merge( options )
129
+ element.__element.each_child {|child| arr << get_value( child, new_options ) }
130
+ new_options[:to_s] ? arr.to_s : arr
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,113 @@
1
+ #
2
+ # $Id: wrapper.rb 22 2004-12-10 18:21:39Z thomas $
3
+ #
4
+ #--
5
+ #
6
+ # xmlresume2x: converts an xml resume to various output formats
7
+ # Copyright (C) 2004 Thomas Leitner
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10
+ # General Public License as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along with this program; if not,
18
+ # write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+ #
22
+
23
+ class Array
24
+
25
+ alias_method :old_join, :join
26
+ def join( sep = $, )
27
+ if sep.instance_of?( String ) || sep.instance_of?( NilClass )
28
+ old_join( sep )
29
+ else
30
+ arr = []
31
+ self.each_with_index {|e, i| arr << sep.clone if i > 0; arr << e}
32
+ arr
33
+ end
34
+ end
35
+
36
+ def separate_by( sep, sepLast )
37
+ result = self[0..-2].join( sep )
38
+ case self.length
39
+ when 0 then result
40
+ when 1 then self.last
41
+ when 2
42
+ if result.kind_of? String
43
+ result << sepLast.to_s << self.last.to_s
44
+ else
45
+ result << sepLast << self.last
46
+ end
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ module XMLResume2x
53
+
54
+ class ElementWrapperList < Array
55
+
56
+ def method_missing( name, *args )
57
+ return nil if self.length == 0
58
+ self[0].send( name.to_s, *args )
59
+ end
60
+
61
+ def process_all!( options = {} )
62
+ self.collect {|e| e.process!( options ) }
63
+ end
64
+
65
+ end
66
+
67
+ class ElementWrapper
68
+
69
+ attr_reader :options
70
+
71
+ def initialize( element, processor, options )
72
+ @element = element
73
+ @processor = processor
74
+ @options = options
75
+ end
76
+
77
+ def method_missing( name, *args )
78
+ name = name.to_s
79
+ if name =~ /^_/
80
+ name.sub!( /^_/, '' )
81
+ @processor.get_value( @element.attributes[name], @options )
82
+ elsif @element.elements[name]
83
+ list = ElementWrapperList.new
84
+ @element.each_element( name ) {|e| list << ElementWrapper.new( e, @processor, @options ) }
85
+ list
86
+ else
87
+ nil
88
+ end
89
+ end
90
+
91
+ def __element
92
+ @element
93
+ end
94
+
95
+ def process!( options = {} )
96
+ @processor.get_value( self, options )
97
+ end
98
+
99
+ def process_children!( options = {} )
100
+ @processor.get_children_value( self, options )
101
+ end
102
+
103
+ def text!
104
+ @processor.get_value( @element.text, @options )
105
+ end
106
+
107
+ def to_s
108
+ process!.to_s
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,104 @@
1
+ #
2
+ # $Id: xmlmarkup.rb 22 2004-12-10 18:21:39Z thomas $
3
+ #
4
+ #--
5
+ #
6
+ # xmlresume2x: converts an xml resume to various output formats
7
+ # Copyright (C) 2004 Thomas Leitner
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10
+ # General Public License as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License along with this program; if not,
18
+ # write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+ #
22
+
23
+
24
+ class XMLResume2x::ResumeProcessor
25
+
26
+ def tag( name, attr = nil, context = nil )
27
+ e = REXML::Element.new( name, context )
28
+ attr.each {|key, value| e.add_attribute( key, value )} if attr
29
+ e
30
+ end
31
+
32
+ end
33
+
34
+ class REXML::Parent
35
+
36
+ alias_method :old_add, :add
37
+
38
+ def add( object, *others )
39
+ if object.instance_of?( XMLResume2x::ElementWrapper ) || object.instance_of?( XMLResume2x::ElementWrapperList )
40
+ add( object.process! )
41
+ elsif object.instance_of? XMLResume2x::REXMLBuilder
42
+ add( object.element! )
43
+ elsif object.instance_of? Array
44
+ object.each {|o| add( o )}
45
+ elsif object.instance_of? String
46
+ old_add( REXML::Text.new( object ) )
47
+ else
48
+ old_add( object )
49
+ end
50
+ others.each {|o| add( o )}
51
+ self
52
+ end
53
+
54
+ end
55
+
56
+ class REXML::Element
57
+
58
+ def builder
59
+ XMLResume2x::REXMLBuilder.new( self )
60
+ end
61
+
62
+ end
63
+
64
+
65
+ class XMLResume2x::REXMLBuilder
66
+
67
+ instance_methods.each {|m| undef_method( m ) unless m =~ /^(__|instance_eval)|\?$/}
68
+
69
+ def initialize( element )
70
+ @element = element
71
+ end
72
+
73
+ def method_missing( name, *args, &block )
74
+ attrs = {}
75
+ content = nil
76
+ args.each do |a|
77
+ if a.instance_of? Hash
78
+ attrs.merge!( a )
79
+ else
80
+ content ||= []
81
+ content << a
82
+ end
83
+ end
84
+ new_elem = @element.add_element( name.to_s, attrs )
85
+ new_elem.add( content ) unless content.nil?
86
+ yield XMLResume2x::REXMLBuilder.new( new_elem ) if block_given?
87
+ self
88
+ end
89
+
90
+ def text!( str )
91
+ @element.add_text( str )
92
+ self
93
+ end
94
+
95
+ def add!( object, *others )
96
+ @element.add( object, *others )
97
+ self
98
+ end
99
+
100
+ def element!
101
+ @element
102
+ end
103
+
104
+ end