summaryrefslogtreecommitdiffstats
path: root/manpo/mantranslate.pl
diff options
context:
space:
mode:
Diffstat (limited to 'manpo/mantranslate.pl')
-rw-r--r--manpo/mantranslate.pl227
1 files changed, 227 insertions, 0 deletions
diff --git a/manpo/mantranslate.pl b/manpo/mantranslate.pl
new file mode 100644
index 0000000..713da10
--- /dev/null
+++ b/manpo/mantranslate.pl
@@ -0,0 +1,227 @@
+#! /usr/bin/perl
+# This script extracts translateable strings from a manpage and/or
+# translates a manpage using gettext.
+# Copyright (C) 2006 Henning Makholm
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+use strict ; use warnings ;
+
+my ($gettext,$shipout) ;
+
+sub fontexpand1($$) {
+ my ($kinds,$text) = @_ ;
+ return "\\f$kinds$text\\fP" if 1 == length $kinds ;
+ my $out = "" ;
+ my $last = "R" ;
+ while( $text ) {
+ $kinds =~ s/^(.)(.*)/$2$1/ ;
+ $last = $1 ;
+ if( $text =~ s/^([^\" ]+)\s*// ||
+ $text =~ s/^"([^\"]+)"\s*// ) {
+ $out .= "\\f$last$1" ;
+ } else {
+ die "Bad font-change tail '$text'" ;
+ }
+ }
+ $out .= "\\fR" unless $last eq "R" ;
+ return $out ;
+}
+
+
+sub ggettext($$$) {
+ my ($filename,$lineno,$text) = @_ ;
+ return $text if $text =~ /^\d*$/ ;
+ $text =~ s/\\\".*//g ;
+ $text =~ s/\\\*p/%s/g ;
+ $text =~ s/([^-])\\(-[a-zA-Z])/$1$2/g ;
+ $text =~ s/^\.([BIR]+)\s+(.*)$/ fontexpand1($1,$2) /mge ;
+ my $fontcode = $text !~ /[{}]/ ;
+ if( $fontcode ) {
+ $text =~ s/\\f([BI])(([^\\]|\\[^f])*)\\f[RP]/$1\{$2\}/mg ;
+ }
+ my $newline = $text =~ s/\n$//s ;
+ if( $text !~ /^[.\']/m || $text =~ /\n/ ) {
+ $text =~ s/\s+/ /gs ;
+ my $pre = "" ;
+ while( length($text) > 65 ) {
+ $text =~ s/^(.{1,65}) // or $text =~ s/^([^ ]*) // ;
+ $pre .= "$1\n" ;
+ }
+ $text = "$pre$text" ;
+ $text =~ s/\s*$// ;
+ }
+ $text = $gettext->($filename,$lineno,$text);
+ $text .= "\n" if $newline ;
+ if( $fontcode ) {
+ $text =~ s/([BI])\{([^{}]*)\}/\\f$1$2\\fP/g ;
+ }
+ $text =~ s/([^-])(-[a-zA-Z])/$1\\$2/g ;
+ $text =~ s/%s/\\*p/g ;
+ return $text ;
+}
+
+sub partraverse {
+ my ($filename,$lineno,@lines) = @_ ;
+ return unless @lines ;
+ my @front ;
+ foreach my $line ( @lines ) {
+ if( @front &&
+ $front[$#front] =~ /\.\)?\s*$/ &&
+ $line =~ /^\(?[A-Z]/ ) {
+ $shipout->(ggettext($filename,$lineno,join "",@front));
+ $lineno += @front ;
+ @front = () ;
+ }
+ push @front, $line ;
+ }
+ $shipout->(ggettext($filename,$lineno,join "",@front));
+}
+
+sub traverser($) {
+ my ($filename) = @_ ;
+ open MAN, "<", $filename or die "Cannot open $filename" ;
+ my $lineno = 0 ;
+ my @saved = () ;
+ while( <MAN> ) {
+ $lineno++ ;
+ if( /^([^.\'\#]|.([BI]|[BRI][IRB]) )/ ) {
+ push @saved, $_ ;
+ next ;
+ }
+ if( @saved ) {
+ partraverse($filename,$lineno-@saved,@saved);
+ @saved = () ;
+ }
+ if( /^#line (\d+) \"(.*)\"/ ) {
+ my ($newline,$newfile) = ($1,$2);
+ $filename = $newfile ;
+ $lineno = $newline-1 ;
+ } elsif( /^\#/ ) {
+ # Ok, breaking the translation block is all we need.
+ } elsif( /^\.\\\"-+$/ ){
+ # Another way to request block breaking.
+ } elsif( /^\.(\\\"|TH|so|P|IP|ds)($| )/ ) {
+ $shipout->($_) ;
+ } elsif( /^\.(SH) (.*)$/ ) {
+ $shipout->(".$1 ".ggettext($filename,$lineno,$2)."\n") ;
+ } elsif( /^\.TP/ ) {
+ $shipout->($_) ;
+ $_ = <MAN> ; $lineno++ ;
+ if( /^\\fB\\-/ ) {
+ s/\\fI(.*?)\\fR/
+ "\\fI".ggettext($filename,$lineno,$1)."\\fR"/ge ;
+ $shipout->($_) ;
+ } else {
+ partraverse($filename,$lineno,$_) ;
+ }
+ } else {
+ /^.?(.?.?)/ ;
+ die "$filename:$lineno: unsupported request .$1\n" ;
+ }
+ }
+ if( @saved ) {
+ partraverse($filename,$lineno-@saved,@saved);
+ }
+ close MAN ;
+}
+
+
+if( @ARGV && $ARGV[0] eq '-x' ) {
+ shift @ARGV ;
+ my %seenwhere = () ;
+ my @strings = () ;
+ $gettext = sub {
+ my ($file,$line,$text) = @_ ;
+ push @strings, $text unless exists $seenwhere{$text} ;
+ push @{$seenwhere{$text}}, "$file:$line" ;
+ };
+ $shipout = sub {} ;
+ for my $filename ( @ARGV ) {
+ traverser($filename) ;
+ }
+ my $date = `date "+%Y-%m-%d %H:%M%z"` ;
+ chomp $date ;
+ print << "EOF" ;
+# SOME DESCRIPTIVE TITLE.
+# This file is put in the public domain.
+# FIRST AUTHOR <EMAIL\@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Xcftools-manpages VERSION\\n"
+"Report-Msgid-Bugs-To: henning\@makholm.net\\n"
+"POT-Creation-Date: $date\\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
+"Last-Translator: FULL NAME <EMAIL\@ADDRESS>\\n"
+"Language-Team: LANGUAGE <LL\@li.org>\\n"
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=CHARSET\\n"
+"Content-Transfer-Encoding: 8bit\\n"
+
+EOF
+;
+ for my $string ( @strings ) {
+ print(join(" ","#:",@{$seenwhere{$string}}),"\n");
+ $string =~ s/([\\\"])/\\$1/g ;
+ $string =~ s/\n$/\\n/ ;
+ print "msgid \"" ;
+ print(join "\\n\"\n \"",split /\n/, $string) ;
+ print "\"\n";
+ print "msgstr \"\"\n\n" ;
+ }
+ exit 0 ;
+}
+
+if( @ARGV == 2 ) {
+ my ($pofile,$manfile) = @ARGV ;
+ open PO, "<", $pofile or die "Pofile $pofile not found" ;
+ my %catalog ;
+ my $msgid ;
+ my $addto ;
+ while( <PO> ) {
+ # This is an extremely simple-minded parser.
+ if( s/^\s*msgid\s+\"/\"/ ) {
+ $msgid = "" ;
+ $addto = \$msgid ;
+ } elsif( s/^\s*msgstr\s+\"/\"/ ) {
+ $catalog{$msgid} = "" ;
+ $addto = \$catalog{$msgid} ;
+ }
+ if( /^\s*\"(.*)\"\s*$/ ) {
+ $_ = $1 ;
+ s/\\(.)/$1 eq 'n' ? "\n" : $1/ge ;
+ $$addto .= $_ ;
+ }
+ }
+ close PO ;
+ $gettext = sub {
+ my ($file,$line,$text) = @_ ;
+ return $catalog{$text} if $catalog{$text} ;
+ return $text ;
+ };
+ $shipout = sub {
+ print @_ ;
+ };
+ traverser($manfile) ;
+ exit 0 ;
+}
+
+print STDERR "Usage: $0 -x man-source-files\n" ;
+print STDERR " or: $0 pofile manfile\n" ;
+
+
+
+