# # Utility functions you might want to use in your ERB # templates # # remove spaces at the beginning of string # replace extra spaces and special chars with a single space def clean string string.gsub(/^[\t\n ]+/, "").gsub(/[\t\n ]+/, " ") end def full_name data [data.basics["first_name"], data.basics["middle_name"], data.basics["last_name"]].join(" ") end # break a string into substrings of length chars breaking at spaces # and newlines # # * `string` string to reflow # * `chars` number of characters to break the string at # * returns an array of strings of length < chars (with exceptions # for special cases) # # special cases: if one line is longer than chars characters, then # break at the first space after chars # def reflow_to_array string, chars if string.length < chars return [clean(string)] else chars.downto(0).each do |index| if string[index] == " " or string[index] == "\n" or string[index] == "\t" return [clean(string[0..index-1])] + reflow_to_array(string[index+1..-1], chars) end end chars.upto(string.length).each do |index| if string[index] == " " or string[index] == "\n" or string[index] == "\t" return [clean(string[0..index-1])] + reflow_to_array(string[index+1..-1], chars) end end return [clean(string)] end end def reflow_to_string string, chars, indentation = "" array = reflow_to_array string, chars output = "" array.each do |line| output << indentation + line + "\n" end output end # manage dates of an entry flexibly supporting the following formats: # # - from - till (with `from` or `till` possibly partial or empty) # - date (possibly partial) # # abstract dates at the year level, taking care of periods if from and # till are in two different years def period entry if entry["date"] then "#{year entry.date}" else from_year = entry["from"] ? year(entry.from.to_s) : nil till_year = entry["till"] ? year(entry.till.to_s) : nil if from_year and till_year and from_year == till_year then from_year else "#{from_year} -- #{till_year ? till_year : "today"}" end end end # make an entry into an item of a list # - first argument, entry, is a hash containing the symbols specified in header and # the following fields: summary and then from, till, or date # - second argument, header, is an array of symbols, whose values, comma-separated will generate the # header line # # The output is along the lines of: # # - value of key1, value of key2 # period # reflowed summary def itemize entry, header = ["role", "who", "address"] <= 7 end end def has_day input if input.class == Date true else input.size == 10 end end # Access hash keys like they were class methods (hash["key"] -> hash.key) and # report errors if key is missing class Hash def method_missing(m) key = m.to_s # we put a bit of info about the top level structure of a resume to avoid # extra-long error messages I don't want to print detailed information # about top-level entries missing in the resume top_level_entries = %w[ contacts addresses web_presence summary work teaching projects other committees volunteer visits education publications talks awards achievements software skills languages driving interests references ] # error: nil value if self.has_key? key and self[key] == nil $stderr.puts "[W] The value of key '#{key}' is nil in the following entry:" unless top_level_entries.include?(key) # $stderr.puts self.to_s self.keys.each do |k| $stderr.puts " #{k}: #{self[k]}" end $stderr.puts "" end end return self[key] if self.has_key? key # we get here if the key is not found we report an error, return # "" and continue the actual mileage might vary $stderr.puts "[E] Key '#{key}' not found in the following entry:" unless top_level_entries.include?(key) self.keys.each do |k| $stderr.puts " #{k}: #{self[k]}" end $stderr.puts "" end return "" end end