# -*- mode: perl; -*- package parsePoLine; use strict; our(@EXPORT, @ISA); BEGIN { use Exporter (); @ISA = qw(Exporter); @EXPORT = qw(parse_po_file getLineSortedKeys); } # Prototypes sub parse_po_file($\%); sub parse_po_line($$$$$ ); sub getLineSortedKeys(\%); ############ my ($status, $foundline, $msgid, $msgstr, $fuzzy); my $alternative = 0; my @entry = (); my %entries = (); sub parse_po_file($\%) { $alternative = 0; @entry = (); %entries = (); my @result = (); my $resindex = 0; my ($file, $rMessages) = @_; if (open(FI, '<', $file)) { $status = "normal"; $fuzzy = 0; my $lineno = 0; while (my $line = ) { $lineno++; parse_po_line($line, $lineno, $rMessages, \@result, \$resindex); push(@entry, $line); } parse_po_line("", $lineno + 1, $rMessages, \@result, \$resindex); my @entr1 = @entry; $result[$resindex] = ["zzzzzzzzzzzz", \@entr1]; close(FI); } return(@result); } sub parse_po_line($$$$$) { my ($line, $lineno, $rMessages, $rresult, $rresindex) = @_; chomp($line); if ($status eq "normal") { if ($line =~ /^#, fuzzy/) { $fuzzy = 1; } elsif ($line =~ s/^msgid\s+//) { die("line alternate") if ($alternative); $foundline = $lineno; $status = "msgid"; $msgid = ""; parse_po_line($line, $lineno, $rMessages, $rresult, $rresindex); } elsif ($line =~ s/^\#\~ msgid\s+//) { $alternative = 1; $foundline = $lineno; $status = "msgid"; $msgid = ""; parse_po_line($line, $lineno, $rMessages, $rresult, $rresindex); } } elsif ($status eq "msgid") { if ($line =~ /^\s*"(.*)"\s*/) { $msgid .= $1; } elsif ($line =~ /^\#\~\s*"(.*)"\s*/) { die("line not alternate") if (! $alternative); $msgid .= $1; } elsif ($line =~ s/^msgstr\s+//) { $alternative = 0; $status = "msgstr"; $msgstr = ""; parse_po_line($line, $lineno, $rMessages, $rresult, $rresindex); } elsif ($line =~ s/^\#\~ msgstr\s+//) { $alternative = 1; $status = "msgstr"; $msgstr = ""; parse_po_line($line, $lineno, $rMessages, $rresult, $rresindex); } } elsif ($status eq "msgstr") { if ($line =~ /^\s*"(.*)"\s*/) { $msgstr .= $1; } elsif ($line =~ /^\#\~\s+"(.*)"\s*/) { die("line not alternate") if (! $alternative); $msgstr .= $1; } else { if (!defined($entries{$msgid})) { my @entr1 = @entry; $rresult->[${$rresindex}] = [$msgid, \@entr1]; $entries{$msgid} = $msgstr; } else { if ($alternative) { print "duplicated alternate entry: \"$msgid\"\n"; } else { print "duplicated entry: \"$msgid\"\n"; } print " on line: $foundline\n"; print " original on line: $rMessages->{$msgid}->{line}\n\n"; } @entry = (); $rMessages->{$msgid}->{line} = $foundline; $rMessages->{$msgid}->{fuzzy} = $fuzzy; $rMessages->{$msgid}->{msgstr} = $msgstr; $rMessages->{$msgid}->{alternative} = $alternative; $rMessages->{$msgid}->{entryidx} = ${$rresindex}; ${$rresindex} = ${$rresindex}+1; $fuzzy = 0; $status = "normal"; } } else { die("invalid status"); } } sub getLineSortedKeys(\%) { my ($rMessages) = @_; return sort {$rMessages->{$a}->{line} <=> $rMessages->{$b}->{line};} keys %{$rMessages}; } 1; __END__ =pod =encoding utf8 =head1 NAME parsePoLine =head1 SYNOPSIS use parsePoLine; #imports functions 'parse_po_file() and getLineSortedKeys()' my %Messages = (); my @entries = parse_po_file("sk.po", %Messages); =head1 DESCRIPTION This is used to parse a single po-file. Results: %Messages The keys in this hash are the msgid-strings the value is reference to a hash wit following values: msgstr: the translated string line: the line-no in the po-file fuzzy: boolean, if the string is fuzzy alternative: if set, so this entry is part of help-strings entryidx: The index in the correspondig @entries array @entries List of references to 2-valued arrays [0]: msgid-string [1]: The sequence of lines from the po-file belonging to this entry. To print the whole po-file: for my $entry (@entries) { print @{$entry->[1]}; } To get the index to a known $msgid: my $entriesidx = $Messages{$msgid}->{entryidx}; =head1 AUTHOR Kornel Benko