Ce script Perl génère mon CV :
#!/usr/bin/perl -w use strict; use Date::Parse; use Data::Dumper; use Getopt::Long; use POSIX qw{strftime}; use POSIX qw{setlocale LC_TIME}; use Template; use Text::Iconv; use XML::Simple; my $lang; my $template; my $output; my $plain_email; my $flavor; my $input = 'resume.xml'; my $result = GetOptions('lang=s' => \$lang, 'template=s' => \$template, 'output=s' => \$output, 'plain-email!' => \$plain_email, 'flavor=s' => \$flavor, 'input=s' => \$input); my $converter = Text::Iconv->new("UTF8", "ISO_8859-1"); my $resume = process_xml($lang, $template, $input); $resume = $converter->convert($resume); open (OUTPUT, '> ' . $output) or die "can't open $output for writing"; print OUTPUT $resume; close (OUTPUT); sub process_xml { my ($lang, $template, $input) = @_; my $tt = Template->new(RELATIVE => 1); my $res = XMLin($input); my $return; my $email; # strip whitespaces enumerate_hashref($res); $res->{lang} = $lang; # Localize strings localise_key (\$res->{intro}->{title}, $lang); foreach my $key ($res->{history}->{title}, $res->{education}->{title}, $res->{language}->{title}, $res->{skill}->{title}, $res->{other}->{title}) { localise_key (\$key, $lang); } foreach my $job (@{$res->{history}->{job}}) { localise_key(\$job->{title}, $lang); localise_array($job->{duty}, $lang); } localise_array($res->{education}->{p}, $lang); localise_array($res->{language}->{p}, $lang); localise_array($res->{highlight}->{p}, $lang); foreach my $skillset (@{$res->{skill}->{skillset}}) { localise_key (\$skillset->{title}, $lang); } foreach my $skillset (@{$res->{skill}->{skillset}}) { localise_skill(\$skillset); } localise_array($res->{other}->{p}, $lang); # Find localised country name foreach my $country ('us', 'jp', 'fr', 'uk') { localise_key(\$res->{glueword}->{countryname}->{$country}, $lang); } # Localis misc stuff localise_key(\$res->{glueword}->{misc}->{print}, $lang); # Localise punctuation localise_key(\$res->{glueword}->{punctuation}->{colon}, $lang); localise_key(\$res->{glueword}->{punctuation}->{at}, $lang); # Now substitute localised country name in place of abbreviation if ($res->{intro}->{country} eq $lang) { $res->{intro}->{country} = ""; } else { $res->{intro}->{country} = $res->{glueword}->{countryname}->{$res->{intro}->{country}}; } # add a date field for each job my $from = localise_key(\$res->{glueword}->{dateseparator}->{from}, $lang); my $to = localise_key(\$res->{glueword}->{dateseparator}->{to}, $lang); foreach my $job (@{ $res->{history}->{job}}) { my $year_from = (split(/-/, $job->{from}))[0]; my $year_to = (split(/-/, $job->{to}))[0]; $job->{shortdate} = ($year_from eq $year_to) ? $year_from : "$year_from-$year_to"; # Change ISO date to a given language # TBD to be removed localise_date(\$job->{from}, $lang); localise_date(\$job->{to}, $lang); $job->{date} = $from . " " . $job->{from} . " " . $to . " " . $job->{to}; # Substitute localised country name in place of abbreviation $job->{country} = $res->{glueword}->{countryname}->{$job->{country}}; } # Calculate and localize age my $format = localise_key(\$res->{glueword}->{dateseparator}->{age}, $lang); $res->{intro}->{age} = localise_age($res->{intro}->{birthdate}, $format); # Fix items in skills in alphabetical order foreach my $sortme (@{$res->{skill}->{skillset}}) { my @sort = sort @{$sortme->{i}}; $sortme->{i} = \@sort; } # Localise e-mail separatores my $at = localise_key(\$res->{glueword}->{emailseparator}->{at}, $lang); my $dot =localise_key(\$res->{glueword}->{emailseparator}->{dot}, $lang); # Don't show if ($plain_email) { $email = $res->{intro}->{email}->{name} . "@" . $res->{intro}->{email}->{domain}; } else { # Obfuscate e-mail, spammers will burn in hell $email = $res->{intro}->{email}->{name} . " $at " . $res->{intro}->{email}->{domain}; $email =~ s/(.*)\.(.*)/$1 $dot $2/; } $res->{intro}->{email} = $email; # let template script know if it's a one page resume $res->{flavor} = $flavor; # pass the language to the template script $res->{lang} = $lang; # debugging #print Dumper($res); $tt->process($template, $res, \$return) || die $tt->error; return $return; } # Turn ISO date to a human readable date sub localise_date { my ($time, $lang) = @_; my ($year, $month, $day) = split (/-/, ${$time}); my %locale = ( en => 'en_US', fr => 'fr_FR'); my $old_locale = setlocale(LC_TIME); setlocale(LC_TIME, $locale{$lang}); $year = $year - 1900; ${$time} = strftime("%B %Y", 0, 0, 0, 0, $month, $year); setlocale(LC_TIME, $old_locale); } # Put age in a given language sub localise_age { my ($birthday, $format_age) = @_; my ($b_year, $b_month, $b_day) = split (/-/, $birthday); my ($now_year, $now_month, $now_day) = (localtime)[5,4,3]; $now_year += 1900; $now_month++; my $age = $now_year - $b_year; if ($now_month < $b_month || ($now_month == $b_month && $now_day < $b_day) ) { $age--; } return sprintf($format_age, $age); } # Turn a key in xml to a localised value sub localise_key { my ($key, $lang) = @_; if (ref(${$key}) eq "ARRAY") { foreach my $item (@{${$key}}) { if ($item->{lang} eq $lang) { ${$key} = $item->{content}; return $item->{content}; } } } } sub localise_array { my ($array, $lang) = @_; @{$array} = grep($_->{lang} eq $lang, @{$array}); } sub localise_skill { my ($skillset) = @_; my @newskill; foreach my $skill (@{${$skillset}->{i}}) { if (ref ($skill) eq "HASH") { if ($skill->{lang} eq $lang) { push (@newskill, $skill->{content}); } } else { push (@newskill, $skill); } } ${$skillset}->{i} = \@newskill; } sub enumerate_hashref { my ($node) = @_; my $ref = ref($node); if ($ref eq "ARRAY") { foreach my $element (@{$node}) { enumerate_hashref(\$element); } } elsif ($ref eq "HASH") { for (values %{$node}) { enumerate_hashref(\$_); } } elsif ($ref eq "SCALAR") { remove_whitespace($node) . "\n"; } elsif ($ref eq "REF") { enumerate_hashref(${$node}); } else { print "Unhandled ref = $ref"; } } sub remove_whitespace { my ($string) = @_; my @line = split (/\n/, ${$string}); # Remove all space before and after line # Actually leave one space in front for rtf, grrrr for (@line) { s/^\s+/ /; s/\s+$//; } ${$string} = join ("\n", @line); }