hgbook
changeset 657:1e020cb7d417
Remove tools
author | Dongsheng Song <songdongsheng@live.cn> |
---|---|
date | Mon Mar 30 21:36:31 2009 +0800 (2009-03-30) |
parents | 4e8f302ae313 |
children | 433040113eaf |
files | .hgignore Makefile Makefile.vars.tmpl en/figs/kdiff3.png en/figs/note.png tools/po4a/lib/Locale/Po4a/Chooser.pm tools/po4a/lib/Locale/Po4a/Common.pm tools/po4a/lib/Locale/Po4a/Docbook.pm tools/po4a/lib/Locale/Po4a/Po.pm tools/po4a/lib/Locale/Po4a/TransTractor.pm tools/po4a/lib/Locale/Po4a/Xml.pm tools/po4a/po4a-translate tools/po4a/po4a-updatepo |
line diff
1.1 --- a/.hgignore Mon Mar 30 17:50:48 2009 +0800 1.2 +++ b/.hgignore Mon Mar 30 21:36:31 2009 +0800 1.3 @@ -23,4 +23,7 @@ 1.4 build 1.5 en/html 1.6 en/examples/results 1.7 -tools 1.8 \ No newline at end of file 1.9 +tools 1.10 +Makefile.vars 1.11 +*.mo 1.12 +*-tmp.*
2.1 --- a/Makefile Mon Mar 30 17:50:48 2009 +0800 2.2 +++ b/Makefile Mon Mar 30 21:36:31 2009 +0800 2.3 @@ -1,6 +1,7 @@ 2.4 # 2.5 # Makefile for the hgbook, top-level 2.6 # 2.7 +include Makefile.vars 2.8 2.9 FORMATS=html html-single pdf 2.10 2.11 @@ -8,11 +9,11 @@ 2.12 DBK_LANGUAGES := en 2.13 LANGUAGES := $(DBK_LANGUAGES) $(PO_LANGUAGES) 2.14 2.15 -UPDATEPO = PERLLIB=../tools/po4a/lib/ ../tools/po4a/po4a-updatepo -M UTF-8 \ 2.16 +UPDATEPO = PERLLIB=$(PO4A_LIB) $(PO4A_HOME)/po4a-updatepo -M UTF-8 \ 2.17 -f docbook -o doctype='docbook' -o includeexternal \ 2.18 -o nodefault='<programlisting> <screen>' \ 2.19 -o untranslated='<programlisting> <screen>' 2.20 -TRANSLATE = PERLLIB=tools/po4a/lib/ tools/po4a/po4a-translate -M UTF-8 \ 2.21 +TRANSLATE = PERLLIB=$(PO4A_LIB) $(PO4A_HOME)/po4a-translate -M UTF-8 \ 2.22 -f docbook -o doctype='docbook' \ 2.23 -k 0 2.24 2.25 @@ -150,6 +151,7 @@ 2.26 2.27 build/$(LINGUA)/source/hgbook.xml: build/en/source/hgbook.xml po/$(LINGUA).po $(images) 2.28 mkdir -p build/$(LINGUA)/source/figs 2.29 + cp en/figs/*.png build/$(LINGUA)/source/figs 2.30 $(TRANSLATE) -m build/en/source/hgbook.xml -p po/$(LINGUA).po -l $@.tmp 2.31 cat $@.tmp | sed 's/\$$rev_id\$$/${rev_id}/' > $@ 2.32 endif 2.33 @@ -198,7 +200,7 @@ 2.34 2.35 build/$(LINGUA)/pdf/hgbook.pdf: build/$(LINGUA)/source/hgbook.xml stylesheets/fo.xsl stylesheets/$(LINGUA)/fo.xsl 2.36 mkdir -p build/$(LINGUA)/pdf 2.37 - java -classpath tools/fop/lib/saxon65.jar:tools/fop/lib/saxon65-dbxsl.jar:tools/fop/lib/xml-commons-resolver-1.2.jar:tools/fop/conf \ 2.38 + java -classpath $(JAVA_SHARE)/saxon65.jar:$(JAVA_SHARE)/saxon65-dbxsl.jar:$(JAVA_SHARE)/xml-commons-resolver-1.2.jar:$(JAVA_SHARE) \ 2.39 com.icl.saxon.StyleSheet \ 2.40 -x org.apache.xml.resolver.tools.ResolvingXMLReader \ 2.41 -y org.apache.xml.resolver.tools.ResolvingXMLReader \ 2.42 @@ -208,7 +210,7 @@ 2.43 stylesheets/$(LINGUA)/fo.xsl \ 2.44 fop1.extensions=1 2.45 2.46 - (cd build/$(LINGUA)/source && ../../../tools/fop/fop.sh hgbook.fo ../pdf/hgbook.pdf) 2.47 + (cd build/$(LINGUA)/source && $(FOP_HOME)/fop.sh hgbook.fo ../pdf/hgbook.pdf) 2.48 endif 2.49 2.50 en/figs/%.png: en/figs/%.svg en/fixsvg
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/Makefile.vars.tmpl Mon Mar 30 21:36:31 2009 +0800 3.3 @@ -0,0 +1,20 @@ 3.4 +# 3.5 +# Please create your Makefile.vars file from this template file. 3.6 +# 3.7 +# Please use absolute path, DO NOT use relative path ! 3.8 +# 3.9 + 3.10 +# po4a (>= 0.36.1): Only for PO based Makefile ! 3.11 +# po4A_HOME=/usr/bin 3.12 +# PO4A_LIB=/usr/share/perl5 3.13 +PO4A_HOME=/home/dongsheng/var/svn/i18n-zh/trunk/lib/po4a 3.14 +PO4A_LIB=$(PO4A_HOME)/lib 3.15 + 3.16 +# saxon65.jar, saxon65-dbxsl.jar, xml-commons-resolver-1.2.jar: Only for pdf format ! 3.17 +JAVA_SHARE=/home/dongsheng/var/svn/i18n-zh/trunk/lib/share/java 3.18 + 3.19 +# fop (>= 0.9.6): Only for pdf format ! 3.20 +FOP_HOME=/home/dongsheng/var/svn/i18n-zh/trunk/lib/fop 3.21 + 3.22 +# docbook-xsl (>= 1.74.3): Only for ePub format ! 3.23 +DB2EPUB=/home/dongsheng/var/svn/i18n-zh/trunk/lib/docbook/docbook-xsl/epub/bin/dbtoepub
4.1 Binary file en/figs/kdiff3.png has changed
5.1 Binary file en/figs/note.png has changed
6.1 --- a/tools/po4a/lib/Locale/Po4a/Chooser.pm Mon Mar 30 17:50:48 2009 +0800 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,148 +0,0 @@ 6.4 -# Locale::Po4a::Pod -- Convert POD data to PO file, for translation. 6.5 -# $Id: Chooser.pm,v 1.41 2008-07-20 16:31:55 nekral-guest Exp $ 6.6 -# 6.7 -# This program is free software; you may redistribute it and/or modify it 6.8 -# under the terms of GPL (see COPYING). 6.9 -# 6.10 -# This module converts POD to PO file, so that it becomes possible to 6.11 -# translate POD formatted documentation. See gettext documentation for 6.12 -# more info about PO files. 6.13 - 6.14 -############################################################################ 6.15 -# Modules and declarations 6.16 -############################################################################ 6.17 - 6.18 - 6.19 -package Locale::Po4a::Chooser; 6.20 - 6.21 -use 5.006; 6.22 -use strict; 6.23 -use warnings; 6.24 -use Locale::Po4a::Common; 6.25 - 6.26 -sub new { 6.27 - my ($module)=shift; 6.28 - my (%options)=@_; 6.29 - 6.30 - die wrap_mod("po4a::chooser", gettext("Need to provide a module name")) 6.31 - unless defined $module; 6.32 - 6.33 - my $modname; 6.34 - if ($module eq 'kernelhelp') { 6.35 - $modname = 'KernelHelp'; 6.36 - } elsif ($module eq 'newsdebian') { 6.37 - $modname = 'NewsDebian'; 6.38 - } elsif ($module eq 'latex') { 6.39 - $modname = 'LaTeX'; 6.40 - } elsif ($module eq 'bibtex') { 6.41 - $modname = 'BibTex'; 6.42 - } elsif ($module eq 'tex') { 6.43 - $modname = 'TeX'; 6.44 - } else { 6.45 - $modname = ucfirst($module); 6.46 - } 6.47 - if (! UNIVERSAL::can("Locale::Po4a::$modname", 'new')) { 6.48 - eval qq{use Locale::Po4a::$modname}; 6.49 - if ($@) { 6.50 - my $error=$@; 6.51 - warn wrap_msg(gettext("Unknown format type: %s."), $module); 6.52 - warn wrap_mod("po4a::chooser", 6.53 - gettext("Module loading error: %s"), $error) 6.54 - if defined $options{'verbose'} && $options{'verbose'} > 0; 6.55 - list(1); 6.56 - } 6.57 - } 6.58 - return "Locale::Po4a::$modname"->new(%options); 6.59 -} 6.60 - 6.61 -sub list { 6.62 - warn wrap_msg(gettext("List of valid formats:") 6.63 -# ."\n - ".gettext("bibtex: BibTex bibliography format.") 6.64 - ."\n - ".gettext("dia: uncompressed Dia diagrams.") 6.65 - ."\n - ".gettext("docbook: Docbook XML.") 6.66 - ."\n - ".gettext("guide: Gentoo Linux's xml documentation format.") 6.67 -# ."\n - ".gettext("html: HTML documents (EXPERIMENTAL).") 6.68 - ."\n - ".gettext("ini: .INI format.") 6.69 - ."\n - ".gettext("kernelhelp: Help messages of each kernel compilation option.") 6.70 - ."\n - ".gettext("latex: LaTeX format.") 6.71 - ."\n - ".gettext("man: Good old manual page format.") 6.72 - ."\n - ".gettext("pod: Perl Online Documentation format.") 6.73 - ."\n - ".gettext("sgml: either debiandoc or docbook DTD.") 6.74 - ."\n - ".gettext("texinfo: The info page format.") 6.75 - ."\n - ".gettext("tex: generic TeX documents (see also latex).") 6.76 - ."\n - ".gettext("text: simple text document.") 6.77 - ."\n - ".gettext("wml: WML documents.") 6.78 - ."\n - ".gettext("xhtml: XHTML documents.") 6.79 - ."\n - ".gettext("xml: generic XML documents (see also docbook).") 6.80 - ); 6.81 - exit shift; 6.82 -} 6.83 -############################################################################## 6.84 -# Module return value and documentation 6.85 -############################################################################## 6.86 - 6.87 -1; 6.88 -__END__ 6.89 - 6.90 -=head1 NAME 6.91 - 6.92 -Locale::Po4a::Chooser - Manage po4a modules 6.93 - 6.94 -=head1 DESCRIPTION 6.95 - 6.96 -Locale::Po4a::Chooser is a module to manage po4a modules. Before, all po4a 6.97 -binaries used to know all po4a modules (pod, man, sgml, etc). This made the 6.98 -add of a new module boring, to make sure the documentation is synchronized 6.99 -in all modules, and that each of them can access the new module. 6.100 - 6.101 -Now, you just have to call the Locale::Po4a::Chooser::new() function, 6.102 -passing the name of module as argument. 6.103 - 6.104 -You also have the Locale::Po4a::Chooser::list() function which lists the 6.105 -available format and exits on the value passed as argument. 6.106 - 6.107 -=head1 SEE ALSO 6.108 - 6.109 -=over 4 6.110 - 6.111 -=item About po4a: 6.112 - 6.113 -L<po4a(7)|po4a.7>, 6.114 -L<Locale::Po4a::TransTractor(3pm)>, 6.115 -L<Locale::Po4a::Po(3pm)> 6.116 - 6.117 -=item About modules: 6.118 - 6.119 -L<Locale::Po4a::Dia(3pm)>, 6.120 -L<Locale::Po4a::Docbook(3pm)>, 6.121 -L<Locale::Po4a::Guide(3pm)>, 6.122 -L<Locale::Po4a::Halibut(3pm)>, 6.123 -L<Locale::Po4a::Ini(3pm)>, 6.124 -L<Locale::Po4a::KernelHelp(3pm)>, 6.125 -L<Locale::Po4a::LaTeX(3pm)>, 6.126 -L<Locale::Po4a::Man(3pm)>, 6.127 -L<Locale::Po4a::Pod(3pm)>, 6.128 -L<Locale::Po4a::Sgml(3pm)>, 6.129 -L<Locale::Po4a::TeX(3pm)>, 6.130 -L<Locale::Po4a::Texinfo(3pm)>, 6.131 -L<Locale::Po4a::Text(3pm)>, 6.132 -L<Locale::Po4a::Wml(3pm)>. 6.133 -L<Locale::Po4a::Xhtml(3pm)>, 6.134 -L<Locale::Po4a::Xml(3pm)>, 6.135 -L<Locale::Po4a::Wml(3pm)>. 6.136 - 6.137 -=back 6.138 - 6.139 -=head1 AUTHORS 6.140 - 6.141 - Denis Barbier <barbier@linuxfr.org> 6.142 - Martin Quinson (mquinson#debian.org) 6.143 - 6.144 -=head1 COPYRIGHT AND LICENSE 6.145 - 6.146 -Copyright 2002,2003,2004,2005 by SPI, inc. 6.147 - 6.148 -This program is free software; you may redistribute it and/or modify it 6.149 -under the terms of GPL (see the COPYING file). 6.150 - 6.151 -=cut
7.1 --- a/tools/po4a/lib/Locale/Po4a/Common.pm Mon Mar 30 17:50:48 2009 +0800 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,246 +0,0 @@ 7.4 -# Locale::Po4a::Common -- Common parts of the po4a scripts and utils 7.5 -# $Id: Common.pm,v 1.20 2009-02-13 23:16:44 nekral-guest Exp $ 7.6 -# 7.7 -# Copyright 2005 by Jordi Vilalta <jvprat@gmail.com> 7.8 -# 7.9 -# This program is free software; you may redistribute it and/or modify it 7.10 -# under the terms of GPL (see COPYING). 7.11 -# 7.12 -# This module has common utilities for the various scripts of po4a 7.13 - 7.14 -=head1 NAME 7.15 - 7.16 -Locale::Po4a::Common - Common parts of the po4a scripts and utils 7.17 - 7.18 -=head1 DESCRIPTION 7.19 - 7.20 -Locale::Po4a::Common contains common parts of the po4a scripts and some useful 7.21 -functions used along the other modules. 7.22 - 7.23 -In order to use Locale::Po4a programatically, one may want to disable 7.24 -the use of Text::WrapI18N, by writing e.g. 7.25 - 7.26 - use Locale::Po4a::Common qw(nowrapi18n); 7.27 - use Locale::Po4a::Text; 7.28 - 7.29 -instead of: 7.30 - 7.31 - use Locale::Po4a::Text; 7.32 - 7.33 -Ordering is important here: as most Locale::Po4a modules themselves 7.34 -load Locale::Po4a::Common, the first time this module is loaded 7.35 -determines whether Text::WrapI18N is used. 7.36 - 7.37 -=cut 7.38 - 7.39 -package Locale::Po4a::Common; 7.40 - 7.41 -require Exporter; 7.42 -use vars qw(@ISA @EXPORT); 7.43 -@ISA = qw(Exporter); 7.44 -@EXPORT = qw(wrap_msg wrap_mod wrap_ref_mod textdomain gettext dgettext); 7.45 - 7.46 -use 5.006; 7.47 -use strict; 7.48 -use warnings; 7.49 - 7.50 -sub import { 7.51 - my $class=shift; 7.52 - 7.53 - my $wrapi18n=1; 7.54 - if (exists $_[0] && defined $_[0] && $_[0] eq 'nowrapi18n') { 7.55 - shift; 7.56 - $wrapi18n=0; 7.57 - } 7.58 - $class->export_to_level(1, $class, @_); 7.59 - 7.60 - return if defined &wrapi18n; 7.61 - 7.62 - if ($wrapi18n && -t STDERR && -t STDOUT && eval { require Text::WrapI18N }) { 7.63 - 7.64 - # Don't bother determining the wrap column if we cannot wrap. 7.65 - my $col=$ENV{COLUMNS}; 7.66 - if (!defined $col) { 7.67 - my @term=eval "use Term::ReadKey; Term::ReadKey::GetTerminalSize()"; 7.68 - $col=$term[0] if (!$@); 7.69 - # If GetTerminalSize() failed we will fallback to a safe default. 7.70 - # This can happen if Term::ReadKey is not available 7.71 - # or this is a terminal-less build or such strange condition. 7.72 - } 7.73 - $col=76 if (!defined $col); 7.74 - 7.75 - eval ' use Text::WrapI18N qw($columns); 7.76 - $columns = $col; 7.77 - '; 7.78 - 7.79 - eval ' sub wrapi18n($$$) { Text::WrapI18N::wrap($_[0],$_[1],$_[2]) } ' 7.80 - } else { 7.81 - 7.82 - # If we cannot wrap, well, that's too bad. Survive anyway. 7.83 - eval ' sub wrapi18n($$$) { $_[0].$_[2] } ' 7.84 - } 7.85 -} 7.86 - 7.87 -sub min($$) { 7.88 - return $_[0] < $_[1] ? $_[0] : $_[1]; 7.89 -} 7.90 - 7.91 -=head1 FUNCTIONS 7.92 - 7.93 -=head2 Showing output messages 7.94 - 7.95 -=over 7.96 - 7.97 -=item 7.98 - 7.99 -show_version($) 7.100 - 7.101 -Shows the current version of the script, and a short copyright message. It 7.102 -takes the name of the script as an argument. 7.103 - 7.104 -=cut 7.105 - 7.106 -sub show_version { 7.107 - my $name = shift; 7.108 - 7.109 - print sprintf(gettext( 7.110 - "%s version %s.\n". 7.111 - "written by Martin Quinson and Denis Barbier.\n\n". 7.112 - "Copyright (C) 2002, 2003, 2004 Software of Public Interest, Inc.\n". 7.113 - "This is free software; see source code for copying\n". 7.114 - "conditions. There is NO warranty; not even for\n". 7.115 - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 7.116 - ), $name, $Locale::Po4a::TransTractor::VERSION)."\n"; 7.117 -} 7.118 - 7.119 -=item 7.120 - 7.121 -wrap_msg($@) 7.122 - 7.123 -This function displays a message the same way than sprintf() does, but wraps 7.124 -the result so that they look nice on the terminal. 7.125 - 7.126 -=cut 7.127 - 7.128 -sub wrap_msg($@) { 7.129 - my $msg = shift; 7.130 - my @args = @_; 7.131 - 7.132 - return wrapi18n("", "", sprintf($msg, @args))."\n"; 7.133 -} 7.134 - 7.135 -=item 7.136 - 7.137 -wrap_mod($$@) 7.138 - 7.139 -This function works like wrap_msg(), but it takes a module name as the first 7.140 -argument, and leaves a space at the left of the message. 7.141 - 7.142 -=cut 7.143 - 7.144 -sub wrap_mod($$@) { 7.145 - my ($mod, $msg) = (shift, shift); 7.146 - my @args = @_; 7.147 - 7.148 - $mod .= ": "; 7.149 - my $spaces = " " x min(length($mod), 15); 7.150 - return wrapi18n($mod, $spaces, sprintf($msg, @args))."\n"; 7.151 -} 7.152 - 7.153 -=item 7.154 - 7.155 -wrap_ref_mod($$$@) 7.156 - 7.157 -This function works like wrap_msg(), but it takes a file:line reference as the 7.158 -first argument, a module name as the second one, and leaves a space at the left 7.159 -of the message. 7.160 - 7.161 -=back 7.162 - 7.163 -=cut 7.164 - 7.165 -sub wrap_ref_mod($$$@) { 7.166 - my ($ref, $mod, $msg) = (shift, shift, shift); 7.167 - my @args = @_; 7.168 - 7.169 - if (!$mod) { 7.170 - # If we don't get a module name, show the message like wrap_mod does 7.171 - return wrap_mod($ref, $msg, @args); 7.172 - } else { 7.173 - $ref .= ": "; 7.174 - my $spaces = " " x min(length($ref), 15); 7.175 - $msg = "$ref($mod)\n$msg"; 7.176 - return wrapi18n("", $spaces, sprintf($msg, @args))."\n"; 7.177 - } 7.178 -} 7.179 - 7.180 -=head2 Wrappers for other modules 7.181 - 7.182 -=over 7.183 - 7.184 -=item 7.185 - 7.186 -Locale::Gettext 7.187 - 7.188 -When the Locale::Gettext module cannot be loaded, this module provide dummy 7.189 -(empty) implementation of the following functions. In that case, po4a 7.190 -messages won't get translated but the program will continue to work. 7.191 - 7.192 -If Locale::gettext is present, this wrapper also calls 7.193 -setlocale(LC_MESSAGES, "") so callers don't depend on the POSIX module 7.194 -either. 7.195 - 7.196 -=over 7.197 - 7.198 -=item 7.199 - 7.200 -bindtextdomain($$) 7.201 - 7.202 -=item 7.203 - 7.204 -textdomain($) 7.205 - 7.206 -=item 7.207 - 7.208 -gettext($) 7.209 - 7.210 -=item 7.211 - 7.212 -dgettext($$) 7.213 - 7.214 -=back 7.215 - 7.216 -=back 7.217 - 7.218 -=cut 7.219 - 7.220 -BEGIN { 7.221 - if (eval { require Locale::gettext }) { 7.222 - import Locale::gettext; 7.223 - require POSIX; 7.224 - POSIX::setlocale(&POSIX::LC_MESSAGES, ''); 7.225 - } else { 7.226 - eval ' 7.227 - sub bindtextdomain($$) { } 7.228 - sub textdomain($) { } 7.229 - sub gettext($) { shift } 7.230 - sub dgettext($$) { return $_[1] } 7.231 - ' 7.232 - } 7.233 -} 7.234 - 7.235 -1; 7.236 -__END__ 7.237 - 7.238 -=head1 AUTHORS 7.239 - 7.240 - Jordi Vilalta <jvprat@gmail.com> 7.241 - 7.242 -=head1 COPYRIGHT AND LICENSE 7.243 - 7.244 -Copyright 2005 by SPI, inc. 7.245 - 7.246 -This program is free software; you may redistribute it and/or modify it 7.247 -under the terms of GPL (see the COPYING file). 7.248 - 7.249 -=cut
8.1 --- a/tools/po4a/lib/Locale/Po4a/Docbook.pm Mon Mar 30 17:50:48 2009 +0800 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,2040 +0,0 @@ 8.4 -#!/usr/bin/perl 8.5 -# aptitude: cmdsynopsis => missing removal of leading spaces 8.6 - 8.7 -# Po4a::Docbook.pm 8.8 -# 8.9 -# extract and translate translatable strings from Docbook XML documents. 8.10 -# 8.11 -# This code extracts plain text from tags and attributes on Docbook XML 8.12 -# documents. 8.13 -# 8.14 -# Copyright (c) 2004 by Jordi Vilalta <jvprat@gmail.com> 8.15 -# Copyright (c) 2007-2009 by Nicolas François <nicolas.francois@centraliens.net> 8.16 -# 8.17 -# This program is free software; you can redistribute it and/or modify 8.18 -# it under the terms of the GNU General Public License as published by 8.19 -# the Free Software Foundation; either version 2 of the License, or 8.20 -# (at your option) any later version. 8.21 -# 8.22 -# This program is distributed in the hope that it will be useful, 8.23 -# but WITHOUT ANY WARRANTY; without even the implied warranty of 8.24 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.25 -# GNU General Public License for more details. 8.26 -# 8.27 -# You should have received a copy of the GNU General Public License 8.28 -# along with this program; if not, write to the Free Software 8.29 -# Foundation, Inc., 8.30 -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 8.31 -# 8.32 -######################################################################## 8.33 - 8.34 -=head1 NAME 8.35 - 8.36 -Locale::Po4a::Docbook - Convert Docbook XML documents from/to PO files 8.37 - 8.38 -=head1 DESCRIPTION 8.39 - 8.40 -The po4a (po for anything) project goal is to ease translations (and more 8.41 -interestingly, the maintenance of translations) using gettext tools on 8.42 -areas where they were not expected like documentation. 8.43 - 8.44 -Locale::Po4a::Docbook is a module to help the translation of DocBook XML 8.45 -documents into other [human] languages. 8.46 - 8.47 -Please note that this module is still under heavy development, and not 8.48 -distributed in official po4a release since we don't feel it to be mature 8.49 -enough. If you insist on trying, check the CVS out. 8.50 - 8.51 -=head1 STATUS OF THIS MODULE 8.52 - 8.53 -This module is fully functional, as it relies in the L<Locale::Po4a::Xml> 8.54 -module. This only defines the translatable tags and attributes. 8.55 - 8.56 -The only known issue is that it doesn't handle entities yet, and this includes 8.57 -the file inclusion entities, but you can translate most of those files alone 8.58 -(except the typical entities files), and it's usually better to maintain them 8.59 -separated. 8.60 - 8.61 -=head1 SEE ALSO 8.62 - 8.63 -L<po4a(7)|po4a.7>, L<Locale::Po4a::TransTractor(3pm)>, L<Locale::Po4a::Xml(3pm)>. 8.64 - 8.65 -=head1 AUTHORS 8.66 - 8.67 - Jordi Vilalta <jvprat@gmail.com> 8.68 - 8.69 -=head1 COPYRIGHT AND LICENSE 8.70 - 8.71 - Copyright (c) 2004 by Jordi Vilalta <jvprat@gmail.com> 8.72 - Copyright (c) 2007-2009 by Nicolas François <nicolas.francois@centraliens.net> 8.73 - 8.74 -This program is free software; you may redistribute it and/or modify it 8.75 -under the terms of GPL (see the COPYING file). 8.76 - 8.77 -=cut 8.78 - 8.79 -package Locale::Po4a::Docbook; 8.80 - 8.81 -use 5.006; 8.82 -use strict; 8.83 -use warnings; 8.84 - 8.85 -use Locale::Po4a::Xml; 8.86 - 8.87 -use vars qw(@ISA); 8.88 -@ISA = qw(Locale::Po4a::Xml); 8.89 - 8.90 -sub initialize { 8.91 - my $self = shift; 8.92 - my %options = @_; 8.93 - 8.94 - $self->SUPER::initialize(%options); 8.95 - $self->{options}{'wrap'}=1; 8.96 - $self->{options}{'doctype'}=$self->{options}{'doctype'} || 'docbook xml'; 8.97 - 8.98 -# AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 8.99 - 8.100 - # abbrev; contains text; Formatted inline 8.101 - $self->{options}{'_default_translated'} .= " <abbrev>"; 8.102 - $self->{options}{'_default_inline'} .= " <abbrev>"; 8.103 - 8.104 - # abstract; does not contain text; Formatted as a displayed block 8.105 - $self->{options}{'_default_untranslated'} .= " <abstract>"; 8.106 - $self->{options}{'_default_break'} .= " <abstract>"; 8.107 - 8.108 - # accel; contains text; Formatted inline 8.109 - $self->{options}{'_default_translated'} .= " <accel>"; 8.110 - $self->{options}{'_default_inline'} .= " <accel>"; 8.111 - 8.112 - # ackno; does not contain text; Formatted as a displayed block 8.113 - # Replaced by acknowledgements in Docbook v5.0 8.114 - $self->{options}{'_default_untranslated'} .= " <ackno>"; 8.115 - $self->{options}{'_default_break'} .= " <ackno>"; 8.116 - # acknowledgements; does not contain text; Formatted as a displayed block 8.117 - $self->{options}{'_default_untranslated'} .= " <acknowledgements>"; 8.118 - $self->{options}{'_default_break'} .= " <acknowledgements>"; 8.119 - 8.120 - # acronym; contains text; Formatted inline 8.121 - $self->{options}{'_default_translated'} .= " <acronym>"; 8.122 - $self->{options}{'_default_inline'} .= " <acronym>"; 8.123 - 8.124 - # action; contains text; Formatted inline; v4, not in v5 8.125 - $self->{options}{'_default_translated'} .= " <action>"; 8.126 - $self->{options}{'_default_inline'} .= " <action>"; 8.127 - 8.128 - # address; contains text; Formatted as a displayed block; verbatim 8.129 - $self->{options}{'_default_translated'} .= " W<address>"; 8.130 - $self->{options}{'_default_placeholder'} .= " <address>"; 8.131 - 8.132 - # affiliation; does not contain text; Formatted inline or as a 8.133 - # displayed block depending on context 8.134 - $self->{options}{'_default_untranslated'} .= " <affiliation>"; 8.135 - $self->{options}{'_default_inline'} .= " <affiliation>"; 8.136 - 8.137 - # alt; contains text; Formatted inline or as a 8.138 - # displayed block depending on context 8.139 - $self->{options}{'_default_translated'} .= " <alt>"; 8.140 - $self->{options}{'_default_inline'} .= " <alt>"; 8.141 - 8.142 - # anchor; does not contain text; Produces no output 8.143 - $self->{options}{'_default_untranslated'} .= " <anchor>"; 8.144 - $self->{options}{'_default_inline'} .= " <anchor>"; 8.145 - 8.146 - # annotation; does not contain text; 8.147 - $self->{options}{'_default_untranslated'} .= " <annotation>"; 8.148 - $self->{options}{'_default_placeholder'} .= " <annotation>"; 8.149 - 8.150 - # answer; does not contain text; 8.151 - $self->{options}{'_default_untranslated'} .= " <answer>"; 8.152 - $self->{options}{'_default_break'} .= " <answer>"; 8.153 - 8.154 - # appendix; does not contain text; Formatted as a displayed block 8.155 - $self->{options}{'_default_untranslated'} .= " <appendix>"; 8.156 - $self->{options}{'_default_break'} .= " <appendix>"; 8.157 - 8.158 - # appendixinfo; does not contain text; v4, not in v5 8.159 - $self->{options}{'_default_untranslated'} .= " <appendixinfo>"; 8.160 - $self->{options}{'_default_placeholder'} .= " <appendixinfo>"; 8.161 - 8.162 - # application; contains text; Formatted inline 8.163 - $self->{options}{'_default_translated'} .= " <application>"; 8.164 - $self->{options}{'_default_inline'} .= " <application>"; 8.165 - 8.166 - # arc; does not contain text; 8.167 - $self->{options}{'_default_untranslated'} .= " <arc>"; 8.168 - $self->{options}{'_default_inline'} .= " <arc>"; 8.169 - 8.170 - # area; does not contain text; 8.171 - # NOTE: the area is not translatable as is, but the coords 8.172 - # attribute might be. 8.173 - $self->{options}{'_default_untranslated'} .= " <area>"; 8.174 - $self->{options}{'_default_inline'} .= " <area>"; 8.175 - 8.176 - # areaset; does not contain text; 8.177 - # NOTE: the areaset is not translatable as is. depending on the 8.178 - # language there might be more or less area tags inside. 8.179 - $self->{options}{'_default_untranslated'} .= " <areaset>"; 8.180 - $self->{options}{'_default_inline'} .= " <areaset>"; 8.181 - 8.182 - # areaspec; does not contain text; 8.183 - # NOTE: see area and areaset 8.184 - $self->{options}{'_default_translated'} .= " <areaspec>"; 8.185 - $self->{options}{'_default_break'} .= " <areaspec>"; 8.186 - 8.187 - # arg; contains text; Formatted inline or as a 8.188 - # displayed block depending on context 8.189 - $self->{options}{'_default_translated'} .= " <arg>"; 8.190 - $self->{options}{'_default_inline'} .= " <arg>"; 8.191 - 8.192 - # artheader; does not contain text; renamed to articleinfo in v4.0 8.193 - $self->{options}{'_default_untranslated'} .= " <artheader>"; 8.194 - $self->{options}{'_default_placeholder'} .= " <artheader>"; 8.195 - 8.196 - # article; does not contain text; Formatted as a displayed block 8.197 - $self->{options}{'_default_untranslated'} .= " <article>"; 8.198 - $self->{options}{'_default_break'} .= " <article>"; 8.199 - 8.200 - # articleinfo; does not contain text; v4 only 8.201 - $self->{options}{'_default_untranslated'} .= " <articleinfo>"; 8.202 - $self->{options}{'_default_placeholder'} .= " <articleinfo>"; 8.203 - 8.204 - # artpagenums; contains text; Formatted inline 8.205 - # NOTE: could be in the break class 8.206 - $self->{options}{'_default_translated'} .= " <artpagenums>"; 8.207 - $self->{options}{'_default_inline'} .= " <artpagenums>"; 8.208 - 8.209 - # attribution; contains text; Formatted inline or as a 8.210 - # displayed block depending on context 8.211 - $self->{options}{'_default_translated'} .= " <attribution>"; 8.212 - $self->{options}{'_default_inline'} .= " <attribution>"; 8.213 - 8.214 - # audiodata; does not contain text; 8.215 - # NOTE: the attributes might be translated 8.216 - $self->{options}{'_default_translated'} .= " <audiodata>"; 8.217 - $self->{options}{'_default_placeholder'} .= " <audiodata>"; 8.218 - $self->{options}{'_default_attributes'}.=' <audiodata>fileref'; 8.219 - 8.220 - # audioobject; does not contain text; 8.221 - # NOTE: might be contaioned in a inlinemediaobject 8.222 - $self->{options}{'_default_translated'} .= " <audioobject>"; 8.223 - $self->{options}{'_default_placeholder'} .= " <audioobject>"; 8.224 - 8.225 - # author; does not contain text; Formatted inline or as a 8.226 - # displayed block depending on context 8.227 - $self->{options}{'_default_untranslated'} .= " <author>"; 8.228 - $self->{options}{'_default_inline'} .= " <author>"; 8.229 - 8.230 - # authorblurb; does not contain text; Formatted as a displayed block. 8.231 - # v4, not in v5 8.232 - $self->{options}{'_default_untranslated'} .= " <authorblurb>"; 8.233 - $self->{options}{'_default_placeholder'} .= " <authorblurb>"; 8.234 - 8.235 - # authorgroup; does not contain text; Formatted inline or as a 8.236 - # displayed block depending on context 8.237 - # NOTE: given the possible parents, it is probably very rarely 8.238 - # inlined 8.239 - $self->{options}{'_default_untranslated'} .= " <authorgroup>"; 8.240 - $self->{options}{'_default_break'} .= " <authorgroup>"; 8.241 - 8.242 - # authorinitials; contains text; Formatted inline 8.243 - $self->{options}{'_default_translated'} .= " <authorinitials>"; 8.244 - $self->{options}{'_default_inline'} .= " <authorinitials>"; 8.245 - 8.246 -# BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 8.247 - 8.248 - # beginpage; does not contain text; v4, not in v5 8.249 - $self->{options}{'_default_untranslated'} .= " <beginpage>"; 8.250 - $self->{options}{'_default_break'} .= " <beginpage>"; 8.251 - 8.252 - # bibliocoverage; contains text; Formatted inline 8.253 - # NOTE: could be in the break class 8.254 - $self->{options}{'_default_translated'} .= " <bibliocoverage>"; 8.255 - $self->{options}{'_default_inline'} .= " <bibliocoverage>"; 8.256 - 8.257 - # bibliodiv; does not contain text; Formatted as a displayed block 8.258 - $self->{options}{'_default_untranslated'} .= " <bibliodiv>"; 8.259 - $self->{options}{'_default_break'} .= " <bibliodiv>"; 8.260 - 8.261 - # biblioentry; does not contain text; Formatted as a displayed block 8.262 - $self->{options}{'_default_untranslated'} .= " <biblioentry>"; 8.263 - $self->{options}{'_default_break'} .= " <biblioentry>"; 8.264 - 8.265 - # bibliography; does not contain text; Formatted as a displayed block 8.266 - $self->{options}{'_default_untranslated'} .= " <bibliography>"; 8.267 - $self->{options}{'_default_break'} .= " <bibliography>"; 8.268 - 8.269 - # bibliographyinfo; does not contain text; v4, not in v5 8.270 - $self->{options}{'_default_untranslated'} .= " <bibliographyinfo>"; 8.271 - $self->{options}{'_default_placeholder'} .= " <bibliographyinfo>"; 8.272 - 8.273 - # biblioid; contains text; Formatted inline 8.274 - # NOTE: could be in the break class 8.275 - $self->{options}{'_default_translated'} .= " <biblioid>"; 8.276 - $self->{options}{'_default_inline'} .= " <biblioid>"; 8.277 - 8.278 - # bibliolist; does not contain text; Formatted as a displayed block 8.279 - $self->{options}{'_default_untranslated'} .= " <bibliolist>"; 8.280 - $self->{options}{'_default_break'} .= " <bibliolist>"; 8.281 - 8.282 - # bibliomisc; contains text; Formatted inline 8.283 - # NOTE: could be in the break class 8.284 - $self->{options}{'_default_translated'} .= " <bibliomisc>"; 8.285 - $self->{options}{'_default_inline'} .= " <bibliomisc>"; 8.286 - 8.287 - # bibliomixed; contains text; Formatted as a displayed block 8.288 - $self->{options}{'_default_translated'} .= " <bibliomixed>"; 8.289 - $self->{options}{'_default_placeholder'} .= " <bibliomixed>"; 8.290 - 8.291 - # bibliomset; contains text; Formatted as a displayed block 8.292 - # NOTE: content might need to be inlined, e.g. <bibliomset><title> 8.293 - $self->{options}{'_default_translated'} .= " <bibliomset>"; 8.294 - $self->{options}{'_default_placeholder'} .= " <bibliomset>"; 8.295 - 8.296 - # biblioref; does not contain text; Formatted inline 8.297 - $self->{options}{'_default_untranslated'} .= " <biblioref>"; 8.298 - $self->{options}{'_default_inline'} .= " <biblioref>"; 8.299 - 8.300 - # bibliorelation; does not contain text; Formatted inline 8.301 - $self->{options}{'_default_translated'} .= " <bibliorelation>"; 8.302 - $self->{options}{'_default_inline'} .= " <bibliorelation>"; 8.303 - 8.304 - # biblioset; does not contain text; Formatted as a displayed block 8.305 - $self->{options}{'_default_untranslated'} .= " <biblioset>"; 8.306 - $self->{options}{'_default_break'} .= " <biblioset>"; 8.307 - 8.308 - # bibliosource; contains text; Formatted inline 8.309 - # NOTE: could be in the break class 8.310 - $self->{options}{'_default_translated'} .= " <bibliosource>"; 8.311 - $self->{options}{'_default_inline'} .= " <bibliosource>"; 8.312 - 8.313 - # blockinfo; does not contain text; v4.2, not in v5 8.314 - $self->{options}{'_default_untranslated'} .= " <blockinfo>"; 8.315 - $self->{options}{'_default_placeholder'} .= " <blockinfo>"; 8.316 - 8.317 - # blockquote; does not contain text; Formatted as a displayed block 8.318 - $self->{options}{'_default_untranslated'} .= " <blockquote>"; 8.319 - $self->{options}{'_default_break'} .= " <blockquote>"; 8.320 - 8.321 - # book; does not contain text; Formatted as a displayed block 8.322 - $self->{options}{'_default_untranslated'} .= " <book>"; 8.323 - $self->{options}{'_default_break'} .= " <book>"; 8.324 - 8.325 - # bookbiblio; does not contain text; Formatted as a displayed block 8.326 - # Removed in v4.0 8.327 - $self->{options}{'_default_untranslated'} .= " <bookbiblio>"; 8.328 - $self->{options}{'_default_break'} .= " <bookbiblio>"; 8.329 - 8.330 - # bookinfo; does not contain text; v4, not in v5 8.331 - $self->{options}{'_default_untranslated'} .= " <bookinfo>"; 8.332 - $self->{options}{'_default_placeholder'} .= " <bookinfo>"; 8.333 - 8.334 - # bridgehead; contains text; Formatted as a displayed block 8.335 - $self->{options}{'_default_translated'} .= " <bridgehead>"; 8.336 - $self->{options}{'_default_break'} .= " <bridgehead>"; 8.337 - 8.338 -# CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 8.339 - 8.340 - # callout; does not contain text; Formatted as a displayed block 8.341 - $self->{options}{'_default_untranslated'} .= " <callout>"; 8.342 - $self->{options}{'_default_break'} .= " <callout>"; 8.343 - 8.344 - # calloutlist; does not contain text; Formatted as a displayed block 8.345 - $self->{options}{'_default_untranslated'} .= " <calloutlist>"; 8.346 - $self->{options}{'_default_break'} .= " <calloutlist>"; 8.347 - 8.348 - # caption; does not contain text; Formatted as a displayed block 8.349 - $self->{options}{'_default_untranslated'} .= " <caption>"; 8.350 - $self->{options}{'_default_break'} .= " <caption>"; 8.351 - 8.352 - # caption (db.html.caption); contains text; Formatted as a displayed block 8.353 - # TODO: Check if this works 8.354 - $self->{options}{'_default_translated'} .= " <table><caption>"; 8.355 - $self->{options}{'_default_break'} .= " <table><caption>"; 8.356 - 8.357 - # caution; does not contain text; Formatted as a displayed block 8.358 - $self->{options}{'_default_untranslated'} .= " <caution>"; 8.359 - $self->{options}{'_default_break'} .= " <caution>"; 8.360 - 8.361 - # chapter; does not contain text; Formatted as a displayed block 8.362 - $self->{options}{'_default_untranslated'} .= " <chapter>"; 8.363 - $self->{options}{'_default_break'} .= " <chapter>"; 8.364 - 8.365 - # chapterinfo; does not contain text; v4, not in v5 8.366 - $self->{options}{'_default_untranslated'} .= " <chapterinfo>"; 8.367 - $self->{options}{'_default_placeholder'} .= " <chapterinfo>"; 8.368 - 8.369 - # citation; contains text; Formatted inline 8.370 - $self->{options}{'_default_translated'} .= " <citation>"; 8.371 - $self->{options}{'_default_inline'} .= " <citation>"; 8.372 - 8.373 - # citebiblioid; contains text; Formatted inline 8.374 - # NOTE: maybe untranslated? 8.375 - $self->{options}{'_default_translated'} .= " <citebiblioid>"; 8.376 - $self->{options}{'_default_inline'} .= " <citebiblioid>"; 8.377 - 8.378 - # citerefentry; contains text; Formatted inline 8.379 - $self->{options}{'_default_translated'} .= " <citerefentry>"; 8.380 - $self->{options}{'_default_inline'} .= " <citerefentry>"; 8.381 - 8.382 - # citetitle; contains text; Formatted inline 8.383 - $self->{options}{'_default_translated'} .= " <citetitle>"; 8.384 - $self->{options}{'_default_inline'} .= " <citetitle>"; 8.385 - 8.386 - # city; contains text; Formatted inline 8.387 - $self->{options}{'_default_translated'} .= " <city>"; 8.388 - $self->{options}{'_default_inline'} .= " <city>"; 8.389 - 8.390 - # classname; contains text; Formatted inline 8.391 - $self->{options}{'_default_translated'} .= " <classname>"; 8.392 - $self->{options}{'_default_inline'} .= " <classname>"; 8.393 - 8.394 - # classsynopsis; does not contain text; may be in a para 8.395 - # NOTE: It may contain a classsynopsisinfo, which should be 8.396 - # verbatim 8.397 - # XXX: since it is in untranslated class, does the W flag takes 8.398 - # effect? 8.399 - $self->{options}{'_default_untranslated'} .= " W<classsynopsis>"; 8.400 - $self->{options}{'_default_placeholder'} .= " <classsynopsis>"; 8.401 - 8.402 - # classsynopsisinfo; contains text; 8.403 - # NOTE: see above 8.404 - $self->{options}{'_default_translated'} .= " W<classsynopsisinfo>"; 8.405 - $self->{options}{'_default_inline'} .= " <classsynopsisinfo>"; 8.406 - 8.407 - # cmdsynopsis; does not contain text; may be in a para 8.408 - # NOTE: It may be clearer as a verbatim block 8.409 - # XXX: since it is in untranslated class, does the W flag takes 8.410 - # effect? => not completely. Rewrap afterward? 8.411 - $self->{options}{'_default_untranslated'} .= " W<cmdsynopsis>"; 8.412 - $self->{options}{'_default_placeholder'} .= " <cmdsynopsis>"; 8.413 - 8.414 - # co; does not contain text; Formatted inline 8.415 - # XXX: tranlsated or not? (label attribute) 8.416 - $self->{options}{'_default_translated'} .= " <co>"; 8.417 - $self->{options}{'_default_inline'} .= " <co>"; 8.418 - 8.419 - # code; contains text; Formatted inline 8.420 - $self->{options}{'_default_translated'} .= " <code>"; 8.421 - $self->{options}{'_default_inline'} .= " <code>"; 8.422 - 8.423 - # col; does not contain text; 8.424 - # NOTE: could be translated to change the layout in a translation 8.425 - # To be done on colgroup in that case. 8.426 - $self->{options}{'_default_untranslated'} .= " <col>"; 8.427 - $self->{options}{'_default_break'} .= " <col>"; 8.428 - 8.429 - # colgroup; does not contain text; 8.430 - # NOTE: could be translated to change the layout in a translation 8.431 - $self->{options}{'_default_untranslated'} .= " <colgroup>"; 8.432 - $self->{options}{'_default_break'} .= " <colgroup>"; 8.433 - 8.434 - # collab; does not contain text; Formatted inline or as a 8.435 - # displayed block depending on context 8.436 - # NOTE: could be in the break class 8.437 - $self->{options}{'_default_untranslated'} .= " <collab>"; 8.438 - $self->{options}{'_default_inline'} .= " <collab>"; 8.439 - 8.440 - # collabname; contains text; Formatted inline or as a 8.441 - # displayed block depending on context; v4, not in v5 8.442 - $self->{options}{'_default_translated'} .= " <collabname>"; 8.443 - $self->{options}{'_default_inline'} .= " <collabname>"; 8.444 - 8.445 - # colophon; does not contain text; Formatted as a displayed block 8.446 - $self->{options}{'_default_untranslated'} .= " <colophon>"; 8.447 - $self->{options}{'_default_break'} .= " <colophon>"; 8.448 - 8.449 - # colspec; does not contain text; 8.450 - # NOTE: could be translated to change the layout in a translation 8.451 - $self->{options}{'_default_untranslated'} .= " <colspec>"; 8.452 - $self->{options}{'_default_break'} .= " <colspec>"; 8.453 - 8.454 - # command; contains text; Formatted inline 8.455 - $self->{options}{'_default_translated'} .= " <command>"; 8.456 - $self->{options}{'_default_inline'} .= " <command>"; 8.457 - 8.458 - # comment; contains text; Formatted inline or as a displayed block 8.459 - # Renamed to remark in v4.0 8.460 - $self->{options}{'_default_translated'} .= " <comment>"; 8.461 - $self->{options}{'_default_inline'} .= " <comment>"; 8.462 - 8.463 - # computeroutput; contains text; Formatted inline 8.464 - # NOTE: "is not a verbatim environment, but an inline." 8.465 - $self->{options}{'_default_translated'} .= " <computeroutput>"; 8.466 - $self->{options}{'_default_inline'} .= " <computeroutput>"; 8.467 - 8.468 - # confdates; contains text; Formatted inline or as a 8.469 - # displayed block depending on context 8.470 - $self->{options}{'_default_translated'} .= " <confdates>"; 8.471 - $self->{options}{'_default_inline'} .= " <confdates>"; 8.472 - 8.473 - # confgroup; does not contain text; Formatted inline or as a 8.474 - # displayed block depending on context 8.475 - # NOTE: could be in the break class 8.476 - $self->{options}{'_default_untranslated'} .= " <confgroup>"; 8.477 - $self->{options}{'_default_inline'} .= " <confgroup>"; 8.478 - 8.479 - # confnum; contains text; Formatted inline or as a 8.480 - # displayed block depending on context 8.481 - $self->{options}{'_default_translated'} .= " <confnum>"; 8.482 - $self->{options}{'_default_inline'} .= " <confnum>"; 8.483 - 8.484 - # confsponsor; contains text; Formatted inline or as a 8.485 - # displayed block depending on context 8.486 - $self->{options}{'_default_translated'} .= " <confsponsor>"; 8.487 - $self->{options}{'_default_inline'} .= " <confsponsor>"; 8.488 - 8.489 - # conftitle; contains text; Formatted inline or as a 8.490 - # displayed block depending on context 8.491 - $self->{options}{'_default_translated'} .= " <conftitle>"; 8.492 - $self->{options}{'_default_inline'} .= " <conftitle>"; 8.493 - 8.494 - # constant; contains text; Formatted inline 8.495 - $self->{options}{'_default_translated'} .= " <constant>"; 8.496 - $self->{options}{'_default_inline'} .= " <constant>"; 8.497 - 8.498 - # constraint; does not contain text; 8.499 - # NOTE: it might be better to have the production as verbatim 8.500 - # Keeping the constrainst inline to have it close to the 8.501 - # lhs or rhs. 8.502 - # The attribute is translatable 8.503 - $self->{options}{'_default_untranslated'} .= " <constraint>"; 8.504 - $self->{options}{'_default_break'} .= " <constraint>"; 8.505 - 8.506 - # constraintdef; does not contain text; Formatted as a displayed block 8.507 - $self->{options}{'_default_untranslated'} .= " <constraintdef>"; 8.508 - $self->{options}{'_default_break'} .= " <constraintdef>"; 8.509 - 8.510 - # constructorsynopsis; does not contain text; may be in a para 8.511 - # NOTE: It may be clearer as a verbatim block 8.512 - # XXX: since it is in untranslated class, does the W flag takes 8.513 - # effect? 8.514 - $self->{options}{'_default_untranslated'} .= " W<constructorsynopsis>"; 8.515 - $self->{options}{'_default_placeholder'} .= " <constructorsynopsis>"; 8.516 - 8.517 - # contractnum; contains text; Formatted inline or as a displayed block 8.518 - # NOTE: could be in the break class 8.519 - $self->{options}{'_default_translated'} .= " <contractnum>"; 8.520 - $self->{options}{'_default_inline'} .= " <contractnum>"; 8.521 - 8.522 - # contractsponsor; contains text; Formatted inline or as a displayed block 8.523 - # NOTE: could be in the break class 8.524 - $self->{options}{'_default_translated'} .= " <contractsponsor>"; 8.525 - $self->{options}{'_default_inline'} .= " <contractsponsor>"; 8.526 - 8.527 - # contrib; contains text; Formatted inline or as a displayed block 8.528 - $self->{options}{'_default_translated'} .= " <contrib>"; 8.529 - $self->{options}{'_default_inline'} .= " <contrib>"; 8.530 - 8.531 - # copyright; contains text; Formatted inline or as a displayed block 8.532 - # NOTE: could be in the break class 8.533 - $self->{options}{'_default_translated'} .= " <copyright>"; 8.534 - $self->{options}{'_default_inline'} .= " <copyright>"; 8.535 - 8.536 - # coref; does not contain text; Formatted inline 8.537 - # XXX: tranlsated or not? (label attribute) 8.538 - $self->{options}{'_default_translated'} .= " <coref>"; 8.539 - $self->{options}{'_default_inline'} .= " <coref>"; 8.540 - 8.541 - # corpauthor; contains text; Formatted inline or as a 8.542 - # displayed block depending on context; v4, not in v5 8.543 - $self->{options}{'_default_translated'} .= " <corpauthor>"; 8.544 - $self->{options}{'_default_inline'} .= " <corpauthor>"; 8.545 - 8.546 - # corpcredit; contains text; Formatted inline or as a 8.547 - # displayed block depending on context; v4, not in v5 8.548 - $self->{options}{'_default_translated'} .= " <corpcredit>"; 8.549 - $self->{options}{'_default_inline'} .= " <corpcredit>"; 8.550 - 8.551 - # corpname; contains text; Formatted inline or as a 8.552 - # displayed block depending on context; v4, not in v5 8.553 - $self->{options}{'_default_translated'} .= " <corpname>"; 8.554 - $self->{options}{'_default_inline'} .= " <corpname>"; 8.555 - 8.556 - # country; contains text; Formatted inline 8.557 - $self->{options}{'_default_translated'} .= " <country>"; 8.558 - $self->{options}{'_default_inline'} .= " <country>"; 8.559 - 8.560 - # cover; does not contain text; Formatted as a displayed block 8.561 - $self->{options}{'_default_untranslated'} .= " <cover>"; 8.562 - $self->{options}{'_default_break'} .= " <cover>"; 8.563 - 8.564 -# DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 8.565 - 8.566 - # database; contains text; Formatted inline 8.567 - $self->{options}{'_default_translated'} .= " <database>"; 8.568 - $self->{options}{'_default_inline'} .= " <database>"; 8.569 - 8.570 - # date; contains text; Formatted inline 8.571 - $self->{options}{'_default_translated'} .= " <date>"; 8.572 - $self->{options}{'_default_inline'} .= " <date>"; 8.573 - 8.574 - # dedication; contains text; Formatted as a displayed block 8.575 - $self->{options}{'_default_translated'} .= " <dedication>"; 8.576 - $self->{options}{'_default_break'} .= " <dedication>"; 8.577 - 8.578 - # destructorsynopsis; does not contain text; may be in a para 8.579 - # NOTE: It may be clearer as a verbatim block 8.580 - # XXX: since it is in untranslated class, does the W flag takes 8.581 - # effect? 8.582 - $self->{options}{'_default_untranslated'} .= " W<destructorsynopsis>"; 8.583 - $self->{options}{'_default_placeholder'} .= " <destructorsynopsis>"; 8.584 - 8.585 - # docinfo; does not contain text; removed in v4.0 8.586 - $self->{options}{'_default_untranslated'} .= " <docinfo>"; 8.587 - $self->{options}{'_default_placeholder'} .= " <docinfo>"; 8.588 - 8.589 -# EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 8.590 - 8.591 - # edition; contains text; Formatted inline or as a displayed block 8.592 - # NOTE: could be in the break class 8.593 - $self->{options}{'_default_translated'} .= " <edition>"; 8.594 - $self->{options}{'_default_inline'} .= " <edition>"; 8.595 - 8.596 - # editor; does not contain text; Formatted inline or as a 8.597 - # displayed block depending on context 8.598 - $self->{options}{'_default_untranslated'} .= " <editor>"; 8.599 - $self->{options}{'_default_inline'} .= " <editor>"; 8.600 - 8.601 - # email; contains text; Formatted inline 8.602 - $self->{options}{'_default_translated'} .= " <email>"; 8.603 - $self->{options}{'_default_inline'} .= " <email>"; 8.604 - 8.605 - # emphasis; contains text; Formatted inline 8.606 - $self->{options}{'_default_translated'} .= " <emphasis>"; 8.607 - $self->{options}{'_default_inline'} .= " <emphasis>"; 8.608 - 8.609 - # entry; contains text; 8.610 - $self->{options}{'_default_translated'} .= " <entry>"; 8.611 - $self->{options}{'_default_break'} .= " <entry>"; 8.612 - 8.613 - # entrytbl; does not contain text; 8.614 - $self->{options}{'_default_untranslated'} .= " <entrytbl>"; 8.615 - $self->{options}{'_default_break'} .= " <entrytbl>"; 8.616 - 8.617 - # envar; contains text; Formatted inline 8.618 - $self->{options}{'_default_translated'} .= " <envar>"; 8.619 - $self->{options}{'_default_inline'} .= " <envar>"; 8.620 - 8.621 - # epigraph; contains text; Formatted as a displayed block. 8.622 - # NOTE: maybe contained in a para 8.623 - $self->{options}{'_default_translated'} .= " <epigraph>"; 8.624 - $self->{options}{'_default_placeholder'} .= " <epigraph>"; 8.625 - 8.626 - # equation; does not contain text; Formatted as a displayed block. 8.627 - $self->{options}{'_default_untranslated'} .= " <equation>"; 8.628 - $self->{options}{'_default_break'} .= " <equation>"; 8.629 - 8.630 - # errorcode; contains text; Formatted inline 8.631 - $self->{options}{'_default_translated'} .= " <errorcode>"; 8.632 - $self->{options}{'_default_inline'} .= " <errorcode>"; 8.633 - 8.634 - # errorname; contains text; Formatted inline 8.635 - $self->{options}{'_default_translated'} .= " <errorname>"; 8.636 - $self->{options}{'_default_inline'} .= " <errorname>"; 8.637 - 8.638 - # errortext; contains text; Formatted inline 8.639 - $self->{options}{'_default_translated'} .= " <errortext>"; 8.640 - $self->{options}{'_default_inline'} .= " <errortext>"; 8.641 - 8.642 - # errortype; contains text; Formatted inline 8.643 - $self->{options}{'_default_translated'} .= " <errortype>"; 8.644 - $self->{options}{'_default_inline'} .= " <errortype>"; 8.645 - 8.646 - # example; does not contain text; Formatted as a displayed block. 8.647 - # NOTE: maybe contained in a para 8.648 - $self->{options}{'_default_untranslated'} .= " <example>"; 8.649 - $self->{options}{'_default_placeholder'} .= " <example>"; 8.650 - 8.651 - # exceptionname; contains text; Formatted inline 8.652 - $self->{options}{'_default_translated'} .= " <exceptionname>"; 8.653 - $self->{options}{'_default_inline'} .= " <exceptionname>"; 8.654 - 8.655 - # extendedlink; does not contain text; 8.656 - $self->{options}{'_default_untranslated'} .= " <extendedlink>"; 8.657 - $self->{options}{'_default_inline'} .= " <extendedlink>"; 8.658 - 8.659 -# FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 8.660 - 8.661 - # fax; contains text; Formatted inline 8.662 - $self->{options}{'_default_translated'} .= " <fax>"; 8.663 - $self->{options}{'_default_inline'} .= " <fax>"; 8.664 - 8.665 - # fieldsynopsis; does not contain text; may be in a para 8.666 - $self->{options}{'_default_untranslated'} .= " <fieldsynopsis>"; 8.667 - $self->{options}{'_default_inline'} .= " <fieldsynopsis>"; 8.668 - 8.669 - # figure; does not contain text; Formatted as a displayed block. 8.670 - # NOTE: maybe contained in a para 8.671 - $self->{options}{'_default_untranslated'} .= " <figure>"; 8.672 - $self->{options}{'_default_placeholder'} .= " <figure>"; 8.673 - 8.674 - # filename; contains text; Formatted inline 8.675 - $self->{options}{'_default_translated'} .= " <filename>"; 8.676 - $self->{options}{'_default_inline'} .= " <filename>"; 8.677 - 8.678 - # firstname; contains text; Formatted inline 8.679 - $self->{options}{'_default_translated'} .= " <firstname>"; 8.680 - $self->{options}{'_default_inline'} .= " <firstname>"; 8.681 - 8.682 - # firstterm; contains text; Formatted inline 8.683 - $self->{options}{'_default_translated'} .= " <firstterm>"; 8.684 - $self->{options}{'_default_inline'} .= " <firstterm>"; 8.685 - 8.686 - # footnote; contains text; 8.687 - $self->{options}{'_default_translated'} .= " <footnote>"; 8.688 - $self->{options}{'_default_placeholder'} .= " <footnote>"; 8.689 - 8.690 - # footnoteref; contains text; 8.691 - $self->{options}{'_default_translated'} .= " <footnoteref>"; 8.692 - $self->{options}{'_default_inline'} .= " <footnoteref>"; 8.693 - 8.694 - # foreignphrase; contains text; 8.695 - $self->{options}{'_default_translated'} .= " <foreignphrase>"; 8.696 - $self->{options}{'_default_inline'} .= " <foreignphrase>"; 8.697 - 8.698 - # formalpara; does not contain text; Formatted as a displayed block. 8.699 - $self->{options}{'_default_untranslated'} .= " <formalpara>"; 8.700 - $self->{options}{'_default_break'} .= " <formalpara>"; 8.701 - 8.702 - # funcdef; contains text; Formatted inline 8.703 - $self->{options}{'_default_translated'} .= " <funcdef>"; 8.704 - $self->{options}{'_default_inline'} .= " <funcdef>"; 8.705 - 8.706 - # funcparams; contains text; Formatted inline 8.707 - $self->{options}{'_default_translated'} .= " <funcparams>"; 8.708 - $self->{options}{'_default_inline'} .= " <funcparams>"; 8.709 - 8.710 - # funcprototype; does not contain text; 8.711 - # NOTE: maybe contained in a funcsynopsis, contained in a para 8.712 - $self->{options}{'_default_untranslated'} .= " <funcprototype>"; 8.713 - $self->{options}{'_default_placeholder'} .= " <funcprototype>"; 8.714 - 8.715 - # funcsynopsis; does not contain text; 8.716 - # NOTE: maybe contained in a para 8.717 - $self->{options}{'_default_untranslated'} .= " <funcsynopsis>"; 8.718 - $self->{options}{'_default_placeholder'} .= " <funcsynopsis>"; 8.719 - 8.720 - # funcsynopsisinfo; contains text; verbatim 8.721 - # NOTE: maybe contained in a funcsynopsis, contained in a para 8.722 - $self->{options}{'_default_translated'} .= " W<funcsynopsisinfo>"; 8.723 - $self->{options}{'_default_placeholder'} .= " <funcsynopsisinfo>"; 8.724 - 8.725 - # function; contains text; Formatted inline 8.726 - $self->{options}{'_default_translated'} .= " <function>"; 8.727 - $self->{options}{'_default_inline'} .= " <function>"; 8.728 - 8.729 -# GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG 8.730 - 8.731 - # glossary; does not contain text; Formatted as a displayed block. 8.732 - $self->{options}{'_default_untranslated'} .= " <glossary>"; 8.733 - $self->{options}{'_default_break'} .= " <glossary>"; 8.734 - 8.735 - # glossaryinfo; does not contain text; v4, not in v5 8.736 - $self->{options}{'_default_untranslated'} .= " <glossaryinfo>"; 8.737 - $self->{options}{'_default_placeholder'} .= " <glossaryinfo>"; 8.738 - 8.739 - # glossdef; does not contain text; Formatted as a displayed block. 8.740 - $self->{options}{'_default_untranslated'} .= " <glossdef>"; 8.741 - $self->{options}{'_default_break'} .= " <glossdef>"; 8.742 - 8.743 - # glossdiv; does not contain text; Formatted as a displayed block. 8.744 - $self->{options}{'_default_untranslated'} .= " <glossdiv>"; 8.745 - $self->{options}{'_default_break'} .= " <glossdiv>"; 8.746 - 8.747 - # glossentry; does not contain text; Formatted as a displayed block. 8.748 - $self->{options}{'_default_untranslated'} .= " <glossentry>"; 8.749 - $self->{options}{'_default_break'} .= " <glossentry>"; 8.750 - 8.751 - # glosslist; does not contain text; Formatted as a displayed block. 8.752 - $self->{options}{'_default_untranslated'} .= " <glosslist>"; 8.753 - $self->{options}{'_default_break'} .= " <glosslist>"; 8.754 - 8.755 - # glosssee; contains text; Formatted as a displayed block. 8.756 - $self->{options}{'_default_translated'} .= " <glosssee>"; 8.757 - $self->{options}{'_default_break'} .= " <glosssee>"; 8.758 - 8.759 - # glossseealso; contains text; Formatted as a displayed block. 8.760 - $self->{options}{'_default_translated'} .= " <glossseealso>"; 8.761 - $self->{options}{'_default_break'} .= " <glossseealso>"; 8.762 - 8.763 - # glossterm; contains text; Formatted inline 8.764 - $self->{options}{'_default_translated'} .= " <glossterm>"; 8.765 - $self->{options}{'_default_inline'} .= " <glossterm>"; 8.766 - 8.767 - # graphic; does not contain text; Formatted as a displayed block 8.768 - # v4, not in v5 8.769 - $self->{options}{'_default_untranslated'} .= " <graphic>"; 8.770 - $self->{options}{'_default_inline'} .= " <graphic>"; 8.771 - $self->{options}{'_default_attributes'}.=' <graphic>fileref'; 8.772 - 8.773 - # graphicco; does not contain text; Formatted as a displayed block. 8.774 - # v4, not in v5 8.775 - $self->{options}{'_default_untranslated'} .= " <graphicco>"; 8.776 - $self->{options}{'_default_placeholder'} .= " <graphicco>"; 8.777 - 8.778 - # group; does not contain text; Formatted inline 8.779 - $self->{options}{'_default_untranslated'} .= " W<group>"; 8.780 - $self->{options}{'_default_inline'} .= " <group>"; 8.781 - 8.782 - # guibutton; contains text; Formatted inline 8.783 - $self->{options}{'_default_translated'} .= " <guibutton>"; 8.784 - $self->{options}{'_default_inline'} .= " <guibutton>"; 8.785 - 8.786 - # guiicon; contains text; Formatted inline 8.787 - $self->{options}{'_default_translated'} .= " <guiicon>"; 8.788 - $self->{options}{'_default_inline'} .= " <guiicon>"; 8.789 - 8.790 - # guilabel; contains text; Formatted inline 8.791 - $self->{options}{'_default_translated'} .= " <guilabel>"; 8.792 - $self->{options}{'_default_inline'} .= " <guilabel>"; 8.793 - 8.794 - # guimenu; contains text; Formatted inline 8.795 - $self->{options}{'_default_translated'} .= " <guimenu>"; 8.796 - $self->{options}{'_default_inline'} .= " <guimenu>"; 8.797 - 8.798 - # guimenuitem; contains text; Formatted inline 8.799 - $self->{options}{'_default_translated'} .= " <guimenuitem>"; 8.800 - $self->{options}{'_default_inline'} .= " <guimenuitem>"; 8.801 - 8.802 - # guisubmenu; contains text; Formatted inline 8.803 - $self->{options}{'_default_translated'} .= " <guisubmenu>"; 8.804 - $self->{options}{'_default_inline'} .= " <guisubmenu>"; 8.805 - 8.806 -# HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH 8.807 - 8.808 - # hardware; contains text; Formatted inline 8.809 - $self->{options}{'_default_translated'} .= " <hardware>"; 8.810 - $self->{options}{'_default_inline'} .= " <hardware>"; 8.811 - 8.812 - # highlights; does not contain text; Formatted inline 8.813 - # v4, not in v5 8.814 - $self->{options}{'_default_untranslated'} .= " <highlights>"; 8.815 - $self->{options}{'_default_break'} .= " <highlights>"; 8.816 - 8.817 - # holder; contains text; 8.818 - # NOTE: may depend on the copyright container 8.819 - $self->{options}{'_default_translated'} .= " <holder>"; 8.820 - $self->{options}{'_default_inline'} .= " <holder>"; 8.821 - 8.822 - # honorific; contains text; Formatted inline 8.823 - $self->{options}{'_default_translated'} .= " <honorific>"; 8.824 - $self->{options}{'_default_inline'} .= " <honorific>"; 8.825 - 8.826 - # html:button; contains text; Formatted inline 8.827 - $self->{options}{'_default_translated'} .= " <html:button>"; 8.828 - $self->{options}{'_default_inline'} .= " <html:button>"; 8.829 - 8.830 - # html:fieldset; contains text; Formatted inline 8.831 - $self->{options}{'_default_translated'} .= " <html:fieldset>"; 8.832 - $self->{options}{'_default_inline'} .= " <html:fieldset>"; 8.833 - 8.834 - # html:form; does not contain text; 8.835 - $self->{options}{'_default_translated'} .= " <html:form>"; 8.836 - $self->{options}{'_default_inline'} .= " <html:form>"; 8.837 - 8.838 - # html:input; does not contain text; Formatted inline 8.839 - # NOTE: attributes are translatable 8.840 - $self->{options}{'_default_translated'} .= " <html:input>"; 8.841 - $self->{options}{'_default_inline'} .= " <html:input>"; 8.842 - 8.843 - # html:label; contains text; Formatted inline 8.844 - $self->{options}{'_default_translated'} .= " <html:label>"; 8.845 - $self->{options}{'_default_inline'} .= " <html:label>"; 8.846 - 8.847 - # html:legend; contains text; Formatted inline 8.848 - $self->{options}{'_default_translated'} .= " <html:legend>"; 8.849 - $self->{options}{'_default_inline'} .= " <html:legend>"; 8.850 - 8.851 - # html:option; contains text; Formatted inline 8.852 - $self->{options}{'_default_translated'} .= " <html:option>"; 8.853 - $self->{options}{'_default_inline'} .= " <html:option>"; 8.854 - 8.855 - # html:select; does not contain text; Formatted inline 8.856 - $self->{options}{'_default_translated'} .= " <html:select>"; 8.857 - $self->{options}{'_default_inline'} .= " <html:select>"; 8.858 - 8.859 - # html:textarea; contains text; Formatted as a displayed block. 8.860 - $self->{options}{'_default_translated'} .= " <html:textarea>"; 8.861 - $self->{options}{'_default_placeholder'} .= " <html:textarea>"; 8.862 - 8.863 - # imagedata; does not contain text; May be formatted inline or 8.864 - # as a displayed block, depending on context 8.865 - $self->{options}{'_default_translated'} .= " <imagedata>"; 8.866 - $self->{options}{'_default_inline'} .= " <imagedata>"; 8.867 - $self->{options}{'_default_attributes'}.=' <imagedata>fileref'; 8.868 - 8.869 - # imageobject; does not contain text; May be formatted inline or 8.870 - # as a displayed block, depending on context 8.871 - $self->{options}{'_default_untranslated'} .= " <imageobject>"; 8.872 - $self->{options}{'_default_inline'} .= " <imageobject>"; 8.873 - 8.874 - # imageobjectco; does not contain text; Formatted as a displayed block 8.875 - # NOTE: may be in a inlinemediaobject 8.876 - # TODO: check if this works when the inlinemediaobject is defined 8.877 - # as inline 8.878 - $self->{options}{'_default_untranslated'} .= " <imageobjectco>"; 8.879 - $self->{options}{'_default_break'} .= " <imageobjectco>"; 8.880 - 8.881 - # important; does not contain text; Formatted as a displayed block. 8.882 - $self->{options}{'_default_untranslated'} .= " <important>"; 8.883 - $self->{options}{'_default_break'} .= " <important>"; 8.884 - 8.885 - # index; does not contain text; Formatted as a displayed block. 8.886 - $self->{options}{'_default_untranslated'} .= " <index>"; 8.887 - $self->{options}{'_default_break'} .= " <index>"; 8.888 - 8.889 - # indexdiv; does not contain text; Formatted as a displayed block. 8.890 - $self->{options}{'_default_untranslated'} .= " <indexdiv>"; 8.891 - $self->{options}{'_default_break'} .= " <indexdiv>"; 8.892 - 8.893 - # indexentry; does not contain text; Formatted as a displayed block. 8.894 - $self->{options}{'_default_untranslated'} .= " <indexentry>"; 8.895 - $self->{options}{'_default_break'} .= " <indexentry>"; 8.896 - 8.897 - # indexinfo; does not contain text; v4, not in v5 8.898 - $self->{options}{'_default_untranslated'} .= " <indexinfo>"; 8.899 - $self->{options}{'_default_placeholder'} .= " <indexinfo>"; 8.900 - 8.901 - # indexterm; does not contain text; 8.902 - $self->{options}{'_default_untranslated'} .= " <indexterm>"; 8.903 - $self->{options}{'_default_placeholder'} .= " <indexterm>"; 8.904 - 8.905 - # info; does not contain text; 8.906 - $self->{options}{'_default_untranslated'} .= " <info>"; 8.907 - $self->{options}{'_default_placeholder'} .= " <info>"; 8.908 - 8.909 - # informalequation; does not contain text; Formatted as a displayed block. 8.910 - $self->{options}{'_default_untranslated'} .= " <informalequation>"; 8.911 - $self->{options}{'_default_placeholder'} .= " <informalequation>"; 8.912 - 8.913 - # informalexample; does not contain text; Formatted as a displayed block. 8.914 - # NOTE: can be in a para 8.915 - $self->{options}{'_default_untranslated'} .= " <informalexample>"; 8.916 - $self->{options}{'_default_break'} .= " <informalexample>"; 8.917 - 8.918 - # informalfigure; does not contain text; Formatted as a displayed block. 8.919 - # NOTE: can be in a para 8.920 - $self->{options}{'_default_untranslated'} .= " <informalfigure>"; 8.921 - $self->{options}{'_default_break'} .= " <informalfigure>"; 8.922 - 8.923 - # informaltable; does not contain text; Formatted as a displayed block. 8.924 - # NOTE: can be in a para 8.925 - $self->{options}{'_default_untranslated'} .= " <informaltable>"; 8.926 - $self->{options}{'_default_break'} .= " <informaltable>"; 8.927 - 8.928 - # initializer; contains text; Formatted inline 8.929 - $self->{options}{'_default_translated'} .= " <initializer>"; 8.930 - $self->{options}{'_default_inline'} .= " <initializer>"; 8.931 - 8.932 - # inlineequation; does not contain text; Formatted inline 8.933 - $self->{options}{'_default_translated'} .= " W<inlineequation>"; 8.934 - $self->{options}{'_default_placeholder'} .= " <inlineequation>"; 8.935 - 8.936 - # inlinegraphic; does not contain text; Formatted inline 8.937 - # empty; v4, not in v5 8.938 - $self->{options}{'_default_translated'} .= " W<inlinegraphic>"; 8.939 - $self->{options}{'_default_inline'} .= " <inlinegraphic>"; 8.940 - 8.941 - # inlinemediaobject; does not contain text; Formatted inline 8.942 - $self->{options}{'_default_translated'} .= " <inlinemediaobject>"; 8.943 - $self->{options}{'_default_placeholder'} .= " <inlinemediaobject>"; 8.944 - 8.945 - # interface; contains text; Formatted inline; v4, not in v5 8.946 - $self->{options}{'_default_translated'} .= " <interface>"; 8.947 - $self->{options}{'_default_inline'} .= " <interface>"; 8.948 - 8.949 - # interfacedefinition; contains text; Formatted inline 8.950 - # Removed in v4.0 8.951 - $self->{options}{'_default_translated'} .= " <interfacedefinition>"; 8.952 - $self->{options}{'_default_inline'} .= " <interfacedefinition>"; 8.953 - 8.954 - # interfacename; contains text; Formatted inline 8.955 - $self->{options}{'_default_translated'} .= " <interfacename>"; 8.956 - $self->{options}{'_default_inline'} .= " <interfacename>"; 8.957 - 8.958 - # invpartnumber; contains text; Formatted inline; v4, not in v5 8.959 - $self->{options}{'_default_translated'} .= " <invpartnumber>"; 8.960 - $self->{options}{'_default_inline'} .= " <invpartnumber>"; 8.961 - 8.962 - # isbn; contains text; Formatted inline; v4, not in v5 8.963 - $self->{options}{'_default_translated'} .= " <isbn>"; 8.964 - $self->{options}{'_default_inline'} .= " <isbn>"; 8.965 - 8.966 - # issn; contains text; Formatted inline; v4, not in v5 8.967 - $self->{options}{'_default_translated'} .= " <issn>"; 8.968 - $self->{options}{'_default_inline'} .= " <issn>"; 8.969 - 8.970 - # issuenum; contains text; Formatted inline or as a displayed block 8.971 - # NOTE: could be in the break class 8.972 - $self->{options}{'_default_translated'} .= " <issuenum>"; 8.973 - $self->{options}{'_default_inline'} .= " <issuenum>"; 8.974 - 8.975 - # itemizedlist; does not contain text; Formatted as a displayed block. 8.976 - $self->{options}{'_default_untranslated'} .= " <itemizedlist>"; 8.977 - $self->{options}{'_default_break'} .= " <itemizedlist>"; 8.978 - 8.979 - # itermset; does not contain text; 8.980 - # FIXME 8.981 - $self->{options}{'_default_untranslated'} .= " <itermset>"; 8.982 - $self->{options}{'_default_inline'} .= " <itermset>"; 8.983 - 8.984 -# JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ 8.985 - 8.986 - # jobtitle; contains text; Formatted inline or as a displayed block 8.987 - # NOTE: can be in a para 8.988 - $self->{options}{'_default_translated'} .= " <jobtitle>"; 8.989 - $self->{options}{'_default_inline'} .= " <jobtitle>"; 8.990 - 8.991 -# KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 8.992 - 8.993 - # keycap; contains text; Formatted inline 8.994 - $self->{options}{'_default_translated'} .= " <keycap>"; 8.995 - $self->{options}{'_default_inline'} .= " <keycap>"; 8.996 - 8.997 - # keycode; contains text; Formatted inline 8.998 - $self->{options}{'_default_translated'} .= " <keycode>"; 8.999 - $self->{options}{'_default_inline'} .= " <keycode>"; 8.1000 - 8.1001 - # keycombo; does not contain text; Formatted inline 8.1002 - $self->{options}{'_default_translated'} .= " <keycombo>"; 8.1003 - $self->{options}{'_default_inline'} .= " <keycombo>"; 8.1004 - 8.1005 - # keysym; contains text; Formatted inline 8.1006 - $self->{options}{'_default_translated'} .= " <keysym>"; 8.1007 - $self->{options}{'_default_inline'} .= " <keysym>"; 8.1008 - 8.1009 - # keyword; contains text; 8.1010 - # NOTE: could be inline 8.1011 - $self->{options}{'_default_translated'} .= " <keyword>"; 8.1012 - $self->{options}{'_default_break'} .= " <keyword>"; 8.1013 - 8.1014 - # keywordset; contains text; Formatted inline or as a displayed block 8.1015 - # NOTE: could be placeholder/break 8.1016 - $self->{options}{'_default_translated'} .= " <keywordset>"; 8.1017 - $self->{options}{'_default_break'} .= " <keywordset>"; 8.1018 - 8.1019 -# LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL 8.1020 - 8.1021 - # label; contains text; Formatted as a displayed block 8.1022 - $self->{options}{'_default_translated'} .= " <label>"; 8.1023 - $self->{options}{'_default_break'} .= " <label>"; 8.1024 - 8.1025 - # legalnotice; contains text; Formatted as a displayed block 8.1026 - $self->{options}{'_default_translated'} .= " <legalnotice>"; 8.1027 - $self->{options}{'_default_break'} .= " <legalnotice>"; 8.1028 - 8.1029 - # lhs; contains text; Formatted as a displayed block. 8.1030 - # NOTE: it might be better to have the production as verbatim 8.1031 - # Keeping the constrainst inline to have it close to the 8.1032 - # lhs or rhs. 8.1033 - $self->{options}{'_default_translated'} .= " <lhs>"; 8.1034 - $self->{options}{'_default_break'} .= " <lhs>"; 8.1035 - 8.1036 - # lineage; contains text; Formatted inline 8.1037 - $self->{options}{'_default_translated'} .= " <lineage>"; 8.1038 - $self->{options}{'_default_inline'} .= " <lineage>"; 8.1039 - 8.1040 - # lineannotation; contains text; Formatted inline 8.1041 - $self->{options}{'_default_translated'} .= " <lineannotation>"; 8.1042 - $self->{options}{'_default_inline'} .= " <lineannotation>"; 8.1043 - 8.1044 - # link; contains text; Formatted inline 8.1045 - $self->{options}{'_default_translated'} .= " <link>"; 8.1046 - $self->{options}{'_default_inline'} .= " <link>"; 8.1047 - 8.1048 - # listitem; does not contain text; Formatted as a displayed block. 8.1049 - $self->{options}{'_default_untranslated'} .= " <listitem>"; 8.1050 - $self->{options}{'_default_break'} .= " <listitem>"; 8.1051 - 8.1052 - # literal; contains text; Formatted inline 8.1053 - $self->{options}{'_default_translated'} .= " <literal>"; 8.1054 - $self->{options}{'_default_inline'} .= " <literal>"; 8.1055 - 8.1056 - # literallayout; contains text; verbatim 8.1057 - $self->{options}{'_default_translated'} .= " W<literallayout>"; 8.1058 - $self->{options}{'_default_placeholder'} .= " <literallayout>"; 8.1059 - 8.1060 - # locator; does not contain text; 8.1061 - $self->{options}{'_default_untranslated'} .= " <locator>"; 8.1062 - $self->{options}{'_default_inline'} .= " <locator>"; 8.1063 - 8.1064 - # lot; does not contain text; Formatted as a displayed block. 8.1065 - # v4, not in v5 8.1066 - $self->{options}{'_default_untranslated'} .= " <lot>"; 8.1067 - $self->{options}{'_default_break'} .= " <lot>"; 8.1068 - 8.1069 - # lotentry; contains text; Formatted as a displayed block. 8.1070 - # v4, not in v5 8.1071 - $self->{options}{'_default_translated'} .= " <lotentry>"; 8.1072 - $self->{options}{'_default_break'} .= " <lotentry>"; 8.1073 - 8.1074 -# MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 8.1075 - 8.1076 - # manvolnum; contains text; 8.1077 - $self->{options}{'_default_translated'} .= " <manvolnum>"; 8.1078 - $self->{options}{'_default_inline'} .= " <manvolnum>"; 8.1079 - 8.1080 - # markup; contains text; Formatted inline 8.1081 - $self->{options}{'_default_translated'} .= " <markup>"; 8.1082 - $self->{options}{'_default_inline'} .= " <markup>"; 8.1083 - 8.1084 - # mathphrase; contains text; Formatted inline 8.1085 - $self->{options}{'_default_translated'} .= " <mathphrase>"; 8.1086 - $self->{options}{'_default_inline'} .= " <mathphrase>"; 8.1087 - 8.1088 - # medialabel; contains text; Formatted inline 8.1089 - # v4, not in v5 8.1090 - $self->{options}{'_default_translated'} .= " <medialabel>"; 8.1091 - $self->{options}{'_default_inline'} .= " <medialabel>"; 8.1092 - 8.1093 - # mediaobject; does not contain text; Formatted as a displayed block. 8.1094 - $self->{options}{'_default_untranslated'} .= " <mediaobject>"; 8.1095 - $self->{options}{'_default_placeholder'} .= " <mediaobject>"; 8.1096 - 8.1097 - # mediaobjectco; does not contain text; Formatted as a displayed block. 8.1098 - $self->{options}{'_default_untranslated'} .= " <mediaobjectco>"; 8.1099 - $self->{options}{'_default_placeholder'} .= " <mediaobjectco>"; 8.1100 - 8.1101 - # member; contains text; Formatted inline 8.1102 - $self->{options}{'_default_translated'} .= " <member>"; 8.1103 - $self->{options}{'_default_inline'} .= " <member>"; 8.1104 - 8.1105 - # menuchoice; does not contain text; Formatted inline 8.1106 - $self->{options}{'_default_translated'} .= " <menuchoice>"; 8.1107 - $self->{options}{'_default_inline'} .= " <menuchoice>"; 8.1108 - 8.1109 - # methodname; contains text; Formatted inline 8.1110 - $self->{options}{'_default_translated'} .= " <methodname>"; 8.1111 - $self->{options}{'_default_inline'} .= " <methodname>"; 8.1112 - 8.1113 - # methodparam; does not contain text; Formatted inline 8.1114 - $self->{options}{'_default_translated'} .= " <methodparam>"; 8.1115 - $self->{options}{'_default_inline'} .= " <methodparam>"; 8.1116 - 8.1117 - # methodsynopsis; does not contain text; Formatted inline 8.1118 - $self->{options}{'_default_translated'} .= " <methodsynopsis>"; 8.1119 - $self->{options}{'_default_inline'} .= " <methodsynopsis>"; 8.1120 - 8.1121 - # modifier; contains text; Formatted inline 8.1122 - $self->{options}{'_default_translated'} .= " <modifier>"; 8.1123 - $self->{options}{'_default_inline'} .= " <modifier>"; 8.1124 - 8.1125 - # mousebutton; contains text; Formatted inline 8.1126 - $self->{options}{'_default_translated'} .= " <mousebutton>"; 8.1127 - $self->{options}{'_default_inline'} .= " <mousebutton>"; 8.1128 - 8.1129 - # msg; does not contain text; Formatted as a displayed block. 8.1130 - $self->{options}{'_default_untranslated'} .= " <msg>"; 8.1131 - $self->{options}{'_default_break'} .= " <msg>"; 8.1132 - 8.1133 - # msgaud; contains text; Formatted as a displayed block. 8.1134 - $self->{options}{'_default_translated'} .= " <msgaud>"; 8.1135 - $self->{options}{'_default_break'} .= " <msgaud>"; 8.1136 - 8.1137 - # msgentry; does not contain text; Formatted as a displayed block. 8.1138 - $self->{options}{'_default_untranslated'} .= " <msgentry>"; 8.1139 - $self->{options}{'_default_break'} .= " <msgentry>"; 8.1140 - 8.1141 - # msgexplan; does not contain text; Formatted as a displayed block. 8.1142 - $self->{options}{'_default_untranslated'} .= " <msgexplan>"; 8.1143 - $self->{options}{'_default_break'} .= " <msgexplan>"; 8.1144 - 8.1145 - # msginfo; does not contain text; Formatted as a displayed block. 8.1146 - $self->{options}{'_default_untranslated'} .= " <msginfo>"; 8.1147 - $self->{options}{'_default_break'} .= " <msginfo>"; 8.1148 - 8.1149 - # msglevel; contains text; Formatted as a displayed block. 8.1150 - $self->{options}{'_default_translated'} .= " <msglevel>"; 8.1151 - $self->{options}{'_default_break'} .= " <msglevel>"; 8.1152 - 8.1153 - # msgmain; does not contain text; Formatted as a displayed block. 8.1154 - $self->{options}{'_default_untranslated'} .= " <msgmain>"; 8.1155 - $self->{options}{'_default_break'} .= " <msgmain>"; 8.1156 - 8.1157 - # msgorig; contains text; Formatted as a displayed block. 8.1158 - $self->{options}{'_default_translated'} .= " <msgorig>"; 8.1159 - $self->{options}{'_default_break'} .= " <msgorig>"; 8.1160 - 8.1161 - # msgrel; does not contain text; Formatted as a displayed block. 8.1162 - $self->{options}{'_default_untranslated'} .= " <msgrel>"; 8.1163 - $self->{options}{'_default_break'} .= " <msgrel>"; 8.1164 - 8.1165 - # msgset; does not contain text; Formatted as a displayed block. 8.1166 - $self->{options}{'_default_untranslated'} .= " <msgset>"; 8.1167 - $self->{options}{'_default_placeholder'} .= " <msgset>"; 8.1168 - 8.1169 - # msgsub; does not contain text; Formatted as a displayed block. 8.1170 - $self->{options}{'_default_untranslated'} .= " <msgsub>"; 8.1171 - $self->{options}{'_default_break'} .= " <msgsub>"; 8.1172 - 8.1173 - # msgtext; does not contain text; Formatted as a displayed block. 8.1174 - $self->{options}{'_default_untranslated'} .= " <msgtext>"; 8.1175 - $self->{options}{'_default_break'} .= " <msgtext>"; 8.1176 - 8.1177 -# NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN 8.1178 - 8.1179 - # nonterminal; contains text; Formatted inline 8.1180 - $self->{options}{'_default_translated'} .= " <nonterminal>"; 8.1181 - $self->{options}{'_default_inline'} .= " <nonterminal>"; 8.1182 - 8.1183 - # note; does not contain text; Formatted inline 8.1184 - # NOTE: can be in a para 8.1185 - $self->{options}{'_default_untranslated'} .= " <note>"; 8.1186 - $self->{options}{'_default_inline'} .= " <note>"; 8.1187 - 8.1188 -# OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO 8.1189 - 8.1190 - # objectinfo; does not contain text; v3.1 -> v4, not in v5 8.1191 - $self->{options}{'_default_untranslated'} .= " <objectinfo>"; 8.1192 - $self->{options}{'_default_placeholder'} .= " <objectinfo>"; 8.1193 - 8.1194 - # olink; contains text; Formatted inline 8.1195 - $self->{options}{'_default_translated'} .= " <olink>"; 8.1196 - $self->{options}{'_default_inline'} .= " <olink>"; 8.1197 - 8.1198 - # ooclass; does not contain text; Formatted inline 8.1199 - $self->{options}{'_default_translated'} .= " <ooclass>"; 8.1200 - $self->{options}{'_default_inline'} .= " <ooclass>"; 8.1201 - 8.1202 - # ooexception; contains text; Formatted inline 8.1203 - $self->{options}{'_default_translated'} .= " <ooexception>"; 8.1204 - $self->{options}{'_default_inline'} .= " <ooexception>"; 8.1205 - 8.1206 - # oointerface; contains text; Formatted inline 8.1207 - $self->{options}{'_default_translated'} .= " <oointerface>"; 8.1208 - $self->{options}{'_default_inline'} .= " <oointerface>"; 8.1209 - 8.1210 - # option; contains text; Formatted inline 8.1211 - $self->{options}{'_default_translated'} .= " <option>"; 8.1212 - $self->{options}{'_default_inline'} .= " <option>"; 8.1213 - 8.1214 - # optional; contains text; Formatted inline 8.1215 - $self->{options}{'_default_translated'} .= " <optional>"; 8.1216 - $self->{options}{'_default_inline'} .= " <optional>"; 8.1217 - 8.1218 - # orderedlist; does not contain text; Formatted as a displayed block. 8.1219 - $self->{options}{'_default_untranslated'} .= " <orderedlist>"; 8.1220 - $self->{options}{'_default_placeholder'} .= " <orderedlist>"; 8.1221 - 8.1222 - # org; does not contain text; Formatted inline or as a 8.1223 - # displayed block depending on context 8.1224 - $self->{options}{'_default_untranslated'} .= " <org>"; 8.1225 - $self->{options}{'_default_inline'} .= " <org>"; 8.1226 - 8.1227 - # orgdiv; contains text; Formatted inline 8.1228 - $self->{options}{'_default_translated'} .= " <orgdiv>"; 8.1229 - $self->{options}{'_default_inline'} .= " <orgdiv>"; 8.1230 - 8.1231 - # orgname; contains text; Formatted inline 8.1232 - $self->{options}{'_default_translated'} .= " <orgname>"; 8.1233 - $self->{options}{'_default_inline'} .= " <orgname>"; 8.1234 - 8.1235 - # otheraddr; contains text; Formatted inline 8.1236 - $self->{options}{'_default_translated'} .= " <otheraddr>"; 8.1237 - $self->{options}{'_default_inline'} .= " <otheraddr>"; 8.1238 - 8.1239 - # othercredit; does not contain text; Formatted inline or as a 8.1240 - # displayed block depending on context 8.1241 - $self->{options}{'_default_untranslated'} .= " <othercredit>"; 8.1242 - $self->{options}{'_default_inline'} .= " <othercredit>"; 8.1243 - 8.1244 - # othername; contains text; Formatted inline 8.1245 - $self->{options}{'_default_translated'} .= " <othername>"; 8.1246 - $self->{options}{'_default_inline'} .= " <othername>"; 8.1247 - 8.1248 -# PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP 8.1249 - 8.1250 - # package; contains text; Formatted inline 8.1251 - $self->{options}{'_default_translated'} .= " <package>"; 8.1252 - $self->{options}{'_default_inline'} .= " <package>"; 8.1253 - 8.1254 - # pagenums; contains text; Formatted inline 8.1255 - $self->{options}{'_default_translated'} .= " <pagenums>"; 8.1256 - $self->{options}{'_default_inline'} .= " <pagenums>"; 8.1257 - 8.1258 - # para; contains text; Formatted as a displayed block 8.1259 - $self->{options}{'_default_translated'} .= " <para>"; 8.1260 - $self->{options}{'_default_break'} .= " <para>"; 8.1261 - 8.1262 - # paramdef; contains text; Formatted inline 8.1263 - $self->{options}{'_default_translated'} .= " <paramdef>"; 8.1264 - $self->{options}{'_default_inline'} .= " <paramdef>"; 8.1265 - 8.1266 - # parameter; contains text; Formatted inline 8.1267 - $self->{options}{'_default_translated'} .= " <parameter>"; 8.1268 - $self->{options}{'_default_inline'} .= " <parameter>"; 8.1269 - 8.1270 - # part; does not contain text; Formatted as a displayed block. 8.1271 - $self->{options}{'_default_untranslated'} .= " <part>"; 8.1272 - $self->{options}{'_default_break'} .= " <part>"; 8.1273 - 8.1274 - # partinfo; does not contain text; v4, not in v5 8.1275 - $self->{options}{'_default_untranslated'} .= " <partinfo>"; 8.1276 - $self->{options}{'_default_placeholder'} .= " <partinfo>"; 8.1277 - 8.1278 - # partintro; does not contain text; Formatted as a displayed block. 8.1279 - $self->{options}{'_default_untranslated'} .= " <partintro>"; 8.1280 - $self->{options}{'_default_break'} .= " <partintro>"; 8.1281 - 8.1282 - # person; does not contain text; Formatted inline or as a 8.1283 - # displayed block depending on context 8.1284 - $self->{options}{'_default_untranslated'} .= " <person>"; 8.1285 - $self->{options}{'_default_inline'} .= " <person>"; 8.1286 - 8.1287 - # personblurb; does not contain text; Formatted as a displayed block. 8.1288 - $self->{options}{'_default_untranslated'} .= " <personblurb>"; 8.1289 - $self->{options}{'_default_placeholder'} .= " <personblurb>"; 8.1290 - 8.1291 - # personname; contains text; Formatted inline 8.1292 - $self->{options}{'_default_translated'} .= " <personname>"; 8.1293 - $self->{options}{'_default_inline'} .= " <personname>"; 8.1294 - 8.1295 - # phone; contains text; Formatted inline 8.1296 - $self->{options}{'_default_translated'} .= " <phone>"; 8.1297 - $self->{options}{'_default_inline'} .= " <phone>"; 8.1298 - 8.1299 - # phrase; contains text; Formatted inline 8.1300 - $self->{options}{'_default_translated'} .= " <phrase>"; 8.1301 - $self->{options}{'_default_inline'} .= " <phrase>"; 8.1302 - 8.1303 - # pob; contains text; Formatted inline 8.1304 - $self->{options}{'_default_translated'} .= " <pob>"; 8.1305 - $self->{options}{'_default_inline'} .= " <pob>"; 8.1306 - 8.1307 - # postcode; contains text; Formatted inline 8.1308 - $self->{options}{'_default_translated'} .= " <postcode>"; 8.1309 - $self->{options}{'_default_inline'} .= " <postcode>"; 8.1310 - 8.1311 - # preface; does not contain text; Formatted as a displayed block. 8.1312 - $self->{options}{'_default_untranslated'} .= " <preface>"; 8.1313 - $self->{options}{'_default_break'} .= " <preface>"; 8.1314 - 8.1315 - # prefaceinfo; does not contain text; v4, not in v5 8.1316 - $self->{options}{'_default_untranslated'} .= " <prefaceinfo>"; 8.1317 - $self->{options}{'_default_placeholder'} .= " <prefaceinfo>"; 8.1318 - 8.1319 - # primary; contains text; 8.1320 - $self->{options}{'_default_translated'} .= " <primary>"; 8.1321 - $self->{options}{'_default_break'} .= " <primary>"; 8.1322 - 8.1323 - # primaryie; contains text; Formatted as a displayed block. 8.1324 - $self->{options}{'_default_translated'} .= " <primaryie>"; 8.1325 - $self->{options}{'_default_break'} .= " <primaryie>"; 8.1326 - 8.1327 - # printhistory; does not contain text; Formatted as a displayed block. 8.1328 - $self->{options}{'_default_untranslated'} .= " <printhistory>"; 8.1329 - $self->{options}{'_default_break'} .= " <printhistory>"; 8.1330 - 8.1331 - # procedure; does not contain text; Formatted as a displayed block. 8.1332 - $self->{options}{'_default_untranslated'} .= " <procedure>"; 8.1333 - $self->{options}{'_default_placeholder'} .= " <procedure>"; 8.1334 - 8.1335 - # production; doesnot contain text; 8.1336 - # NOTE: it might be better to have the production as verbatim 8.1337 - # Keeping the constrainst inline to have it close to the 8.1338 - # lhs or rhs. 8.1339 - $self->{options}{'_default_untranslated'} .= " <production>"; 8.1340 - $self->{options}{'_default_break'} .= " <production>"; 8.1341 - 8.1342 - # productionrecap; does not contain text; like production 8.1343 - $self->{options}{'_default_untranslated'} .= " <productionrecap>"; 8.1344 - $self->{options}{'_default_break'} .= " <productionrecap>"; 8.1345 - 8.1346 - # productionset; does not contain text; Formatted as a displayed block. 8.1347 - $self->{options}{'_default_untranslated'} .= " <productionset>"; 8.1348 - $self->{options}{'_default_placeholder'} .= " <productionset>"; 8.1349 - 8.1350 - # productname; contains text; Formatted inline 8.1351 - $self->{options}{'_default_translated'} .= " <productname>"; 8.1352 - $self->{options}{'_default_inline'} .= " <productname>"; 8.1353 - 8.1354 - # productnumber; contains text; Formatted inline 8.1355 - $self->{options}{'_default_translated'} .= " <productnumber>"; 8.1356 - $self->{options}{'_default_inline'} .= " <productnumber>"; 8.1357 - 8.1358 - # programlisting; contains text; Formatted as a displayed block. 8.1359 - $self->{options}{'_default_translated'} .= " W<programlisting>"; 8.1360 - $self->{options}{'_default_placeholder'} .= " <programlisting>"; 8.1361 - 8.1362 - # programlistingco; contains text; Formatted as a displayed block. 8.1363 - $self->{options}{'_default_untranslated'} .= " <programlistingco>"; 8.1364 - $self->{options}{'_default_placeholder'} .= " <programlistingco>"; 8.1365 - 8.1366 - # prompt; contains text; Formatted inline 8.1367 - $self->{options}{'_default_translated'} .= " <prompt>"; 8.1368 - $self->{options}{'_default_inline'} .= " <prompt>"; 8.1369 - 8.1370 - # property; contains text; Formatted inline 8.1371 - $self->{options}{'_default_translated'} .= " <property>"; 8.1372 - $self->{options}{'_default_inline'} .= " <property>"; 8.1373 - 8.1374 - # pubdate; contains text; Formatted inline 8.1375 - $self->{options}{'_default_translated'} .= " <pubdate>"; 8.1376 - $self->{options}{'_default_inline'} .= " <pubdate>"; 8.1377 - 8.1378 - # publisher; does not contain text; Formatted inline or as a displayed block 8.1379 - # NOTE: could be in the break class 8.1380 - $self->{options}{'_default_translated'} .= " <publisher>"; 8.1381 - $self->{options}{'_default_inline'} .= " <publisher>"; 8.1382 - 8.1383 - # publishername; contains text; Formatted inline or as a displayed block 8.1384 - $self->{options}{'_default_translated'} .= " <publishername>"; 8.1385 - $self->{options}{'_default_inline'} .= " <publishername>"; 8.1386 - 8.1387 -# QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ 8.1388 - 8.1389 - # qandadiv; does not contain text; Formatted as a displayed block. 8.1390 - $self->{options}{'_default_untranslated'} .= " <qandadiv>"; 8.1391 - $self->{options}{'_default_break'} .= " <qandadiv>"; 8.1392 - 8.1393 - # qandaentry; does not contain text; Formatted as a displayed block. 8.1394 - $self->{options}{'_default_untranslated'} .= " <qandaentry>"; 8.1395 - $self->{options}{'_default_break'} .= " <qandaentry>"; 8.1396 - 8.1397 - # qandaset; does not contain text; Formatted as a displayed block. 8.1398 - $self->{options}{'_default_untranslated'} .= " <qandaset>"; 8.1399 - $self->{options}{'_default_break'} .= " <qandaset>"; 8.1400 - 8.1401 - # question; does not contain text; 8.1402 - $self->{options}{'_default_untranslated'} .= " <question>"; 8.1403 - $self->{options}{'_default_break'} .= " <question>"; 8.1404 - 8.1405 - # quote; contains text; Formatted inline 8.1406 - $self->{options}{'_default_translated'} .= " <quote>"; 8.1407 - $self->{options}{'_default_inline'} .= " <quote>"; 8.1408 - 8.1409 -# RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR 8.1410 - 8.1411 - # refclass; contains text; Formatted inline or as a displayed block 8.1412 - # NOTE: could be in the inline class 8.1413 - $self->{options}{'_default_translated'} .= " <refclass>"; 8.1414 - $self->{options}{'_default_break'} .= " <refclass>"; 8.1415 - 8.1416 - # refdescriptor; contains text; Formatted inline or as a displayed block 8.1417 - # NOTE: could be in the inline class 8.1418 - $self->{options}{'_default_translated'} .= " <refdescriptor>"; 8.1419 - $self->{options}{'_default_break'} .= " <refdescriptor>"; 8.1420 - 8.1421 - # refentry; does not contain text; Formatted as a displayed block 8.1422 - $self->{options}{'_default_untranslated'} .= " <refentry>"; 8.1423 - $self->{options}{'_default_break'} .= " <refentry>"; 8.1424 - 8.1425 - # refentryinfo; does not contain text; v4, not in v5 8.1426 - $self->{options}{'_default_untranslated'} .= " <refentryinfo>"; 8.1427 - $self->{options}{'_default_placeholder'} .= " <refentryinfo>"; 8.1428 - 8.1429 - # refentrytitle; contains text; Formatted as a displayed block 8.1430 -# FIXME: do not seems to be a block 8.1431 - $self->{options}{'_default_translated'} .= " <refentrytitle>"; 8.1432 - $self->{options}{'_default_inline'} .= " <refentrytitle>"; 8.1433 - 8.1434 - # reference; does not contain text; Formatted as a displayed block 8.1435 - $self->{options}{'_default_untranslated'} .= " <reference>"; 8.1436 - $self->{options}{'_default_break'} .= " <reference>"; 8.1437 - 8.1438 - # referenceinfo; does not contain text; v4, not in v5 8.1439 - $self->{options}{'_default_untranslated'} .= " <referenceinfo>"; 8.1440 - $self->{options}{'_default_placeholder'} .= " <referenceinfo>"; 8.1441 - 8.1442 - # refmeta; does not contains text; 8.1443 - # NOTE: could be in the inline class 8.1444 - $self->{options}{'_default_untranslated'} .= " <refmeta>"; 8.1445 - $self->{options}{'_default_break'} .= " <refmeta>"; 8.1446 - 8.1447 - # refmiscinfo; contains text; Formatted inline or as a displayed block 8.1448 - # NOTE: could be in the inline class 8.1449 - $self->{options}{'_default_translated'} .= " <refmiscinfo>"; 8.1450 - $self->{options}{'_default_break'} .= " <refmiscinfo>"; 8.1451 - 8.1452 - # refname; contains text; Formatted inline or as a displayed block 8.1453 - # NOTE: could be in the inline class 8.1454 - $self->{options}{'_default_translated'} .= " <refname>"; 8.1455 - $self->{options}{'_default_break'} .= " <refname>"; 8.1456 - 8.1457 - # refnamediv; does not contain text; Formatted as a displayed block 8.1458 - $self->{options}{'_default_untranslated'} .= " <refnamediv>"; 8.1459 - $self->{options}{'_default_break'} .= " <refnamediv>"; 8.1460 - 8.1461 - # refpurpose; contains text; Formatted inline 8.1462 - $self->{options}{'_default_translated'} .= " <refpurpose>"; 8.1463 - $self->{options}{'_default_inline'} .= " <refpurpose>"; 8.1464 - 8.1465 - # refsect1; does not contain text; Formatted as a displayed block 8.1466 - $self->{options}{'_default_untranslated'} .= " <refsect1>"; 8.1467 - $self->{options}{'_default_break'} .= " <refsect1>"; 8.1468 - 8.1469 - # refsect1info; does not contain text; v4, not in v5 8.1470 - $self->{options}{'_default_untranslated'} .= " <refsect1info>"; 8.1471 - $self->{options}{'_default_placeholder'} .= " <refsect1info>"; 8.1472 - 8.1473 - # refsect2; does not contain text; Formatted as a displayed block 8.1474 - $self->{options}{'_default_untranslated'} .= " <refsect2>"; 8.1475 - $self->{options}{'_default_break'} .= " <refsect2>"; 8.1476 - 8.1477 - # refsect2info; does not contain text; v4, not in v5 8.1478 - $self->{options}{'_default_untranslated'} .= " <refsect2info>"; 8.1479 - $self->{options}{'_default_placeholder'} .= " <refsect2info>"; 8.1480 - 8.1481 - # refsect3; does not contain text; Formatted as a displayed block 8.1482 - $self->{options}{'_default_untranslated'} .= " <refsect3>"; 8.1483 - $self->{options}{'_default_break'} .= " <refsect3>"; 8.1484 - 8.1485 - # refsect3info; does not contain text; v4, not in v5 8.1486 - $self->{options}{'_default_untranslated'} .= " <refsect3info>"; 8.1487 - $self->{options}{'_default_placeholder'} .= " <refsect3info>"; 8.1488 - 8.1489 - # refsection; does not contain text; Formatted as a displayed block 8.1490 - $self->{options}{'_default_untranslated'} .= " <refsection>"; 8.1491 - $self->{options}{'_default_break'} .= " <refsection>"; 8.1492 - 8.1493 - # refsectioninfo; does not contain text; v4, not in v5 8.1494 - $self->{options}{'_default_untranslated'} .= " <refsectioninfo>"; 8.1495 - $self->{options}{'_default_placeholder'} .= " <refsectioninfo>"; 8.1496 - 8.1497 - # refsynopsisdiv; does not contain text; Formatted as a displayed block 8.1498 - $self->{options}{'_default_untranslated'} .= " <refsynopsisdiv>"; 8.1499 - $self->{options}{'_default_break'} .= " <refsynopsisdiv>"; 8.1500 - 8.1501 - # refsynopsisdivinfo; does not contain text; v4, not in v5 8.1502 - $self->{options}{'_default_untranslated'} .= " <refsynopsisdivinfo>"; 8.1503 - $self->{options}{'_default_placeholder'} .= " <refsynopsisdivinfo>"; 8.1504 - 8.1505 - # releaseinfo; contains text; Formatted inline or as a displayed block 8.1506 - # NOTE: could be in the inline class 8.1507 - $self->{options}{'_default_translated'} .= " <releaseinfo>"; 8.1508 - $self->{options}{'_default_break'} .= " <releaseinfo>"; 8.1509 - 8.1510 - # remark; contains text; Formatted inline or as a displayed block 8.1511 - $self->{options}{'_default_translated'} .= " <remark>"; 8.1512 - $self->{options}{'_default_inline'} .= " <remark>"; 8.1513 - 8.1514 - # replaceable; contains text; Formatted inline 8.1515 - $self->{options}{'_default_translated'} .= " <replaceable>"; 8.1516 - $self->{options}{'_default_inline'} .= " <replaceable>"; 8.1517 - 8.1518 - # returnvalue; contains text; Formatted inline 8.1519 - $self->{options}{'_default_translated'} .= " <returnvalue>"; 8.1520 - $self->{options}{'_default_inline'} .= " <returnvalue>"; 8.1521 - 8.1522 - # revdescription; contains text; Formatted inline or as a displayed block 8.1523 - $self->{options}{'_default_translated'} .= " <revdescription>"; 8.1524 - $self->{options}{'_default_break'} .= " <revdescription>"; 8.1525 - 8.1526 - # revhistory; does not contain text; Formatted as a displayed block 8.1527 - $self->{options}{'_default_untranslated'} .= " <revhistory>"; 8.1528 - $self->{options}{'_default_break'} .= " <revhistory>"; 8.1529 - 8.1530 - # revision; does not contain text; 8.1531 - $self->{options}{'_default_untranslated'} .= " <revision>"; 8.1532 - $self->{options}{'_default_break'} .= " <revision>"; 8.1533 - 8.1534 - # revnumber; contains text; Formatted inline 8.1535 - $self->{options}{'_default_translated'} .= " <revnumber>"; 8.1536 - $self->{options}{'_default_inline'} .= " <revnumber>"; 8.1537 - 8.1538 - # revremark; contains text; Formatted inline or as a displayed block 8.1539 - $self->{options}{'_default_translated'} .= " <revremark>"; 8.1540 - $self->{options}{'_default_break'} .= " <revremark>"; 8.1541 - 8.1542 - # rhs; contains text; Formatted as a displayed block. 8.1543 - # NOTE: it might be better to have the production as verbatim 8.1544 - # Keeping the constrainst inline to have it close to the 8.1545 - # lhs or rhs. 8.1546 - $self->{options}{'_default_translated'} .= " <rhs>"; 8.1547 - $self->{options}{'_default_break'} .= " <rhs>"; 8.1548 - 8.1549 - # row; does not contain text; 8.1550 - $self->{options}{'_default_untranslated'} .= " <row>"; 8.1551 - $self->{options}{'_default_break'} .= " <row>"; 8.1552 - 8.1553 -# SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS 8.1554 - 8.1555 - # sbr; does not contain text; line break 8.1556 - $self->{options}{'_default_untranslated'} .= " <sbr>"; 8.1557 - $self->{options}{'_default_break'} .= " <sbr>"; 8.1558 - 8.1559 - # screen; contains text; verbatim 8.1560 - $self->{options}{'_default_translated'} .= " W<screen>"; 8.1561 - $self->{options}{'_default_placeholder'} .= " <screen>"; 8.1562 - 8.1563 - # screenco; does not contain text; Formatted as a displayed block. 8.1564 - $self->{options}{'_default_untranslated'} .= " <screenco>"; 8.1565 - $self->{options}{'_default_placeholder'} .= " <screenco>"; 8.1566 - 8.1567 - # screeninfo; does not contain text; v4, not in v5 8.1568 - $self->{options}{'_default_untranslated'} .= " <screeninfo>"; 8.1569 - $self->{options}{'_default_placeholder'} .= " <screeninfo>"; 8.1570 - 8.1571 - # screenshot; does not contain text; Formatted as a displayed block. 8.1572 - $self->{options}{'_default_untranslated'} .= " <screenshot>"; 8.1573 - $self->{options}{'_default_placeholder'} .= " <screenshot>"; 8.1574 - 8.1575 - # secondary; contains text; 8.1576 - $self->{options}{'_default_translated'} .= " <secondary>"; 8.1577 - $self->{options}{'_default_break'} .= " <secondary>"; 8.1578 - 8.1579 - # secondaryie; contains text; Formatted as a displayed block. 8.1580 - $self->{options}{'_default_translated'} .= " <secondaryie>"; 8.1581 - $self->{options}{'_default_break'} .= " <secondaryie>"; 8.1582 - 8.1583 - # sect1; does not contain text; Formatted as a displayed block. 8.1584 - $self->{options}{'_default_untranslated'} .= " <sect1>"; 8.1585 - $self->{options}{'_default_break'} .= " <sect1>"; 8.1586 - 8.1587 - # sect1info; does not contain text; v4, not in v5 8.1588 - $self->{options}{'_default_untranslated'} .= " <sect1info>"; 8.1589 - $self->{options}{'_default_placeholder'} .= " <sect1info>"; 8.1590 - 8.1591 - # sect2; does not contain text; Formatted as a displayed block. 8.1592 - $self->{options}{'_default_untranslated'} .= " <sect2>"; 8.1593 - $self->{options}{'_default_break'} .= " <sect2>"; 8.1594 - 8.1595 - # sect2info; does not contain text; v4, not in v5 8.1596 - $self->{options}{'_default_untranslated'} .= " <sect2info>"; 8.1597 - $self->{options}{'_default_placeholder'} .= " <sect2info>"; 8.1598 - 8.1599 - # sect3; does not contain text; Formatted as a displayed block. 8.1600 - $self->{options}{'_default_untranslated'} .= " <sect3>"; 8.1601 - $self->{options}{'_default_break'} .= " <sect3>"; 8.1602 - 8.1603 - # sect3info; does not contain text; v4, not in v5 8.1604 - $self->{options}{'_default_untranslated'} .= " <sect3info>"; 8.1605 - $self->{options}{'_default_placeholder'} .= " <sect3info>"; 8.1606 - 8.1607 - # sect4; does not contain text; Formatted as a displayed block. 8.1608 - $self->{options}{'_default_untranslated'} .= " <sect4>"; 8.1609 - $self->{options}{'_default_break'} .= " <sect4>"; 8.1610 - 8.1611 - # sect4info; does not contain text; v4, not in v5 8.1612 - $self->{options}{'_default_untranslated'} .= " <sect4info>"; 8.1613 - $self->{options}{'_default_placeholder'} .= " <sect4info>"; 8.1614 - 8.1615 - # sect5; does not contain text; Formatted as a displayed block. 8.1616 - $self->{options}{'_default_untranslated'} .= " <sect5>"; 8.1617 - $self->{options}{'_default_break'} .= " <sect5>"; 8.1618 - 8.1619 - # sect5info; does not contain text; v4, not in v5 8.1620 - $self->{options}{'_default_untranslated'} .= " <sect5info>"; 8.1621 - $self->{options}{'_default_placeholder'} .= " <sect5info>"; 8.1622 - 8.1623 - # section; does not contain text; Formatted as a displayed block. 8.1624 - $self->{options}{'_default_untranslated'} .= " <section>"; 8.1625 - $self->{options}{'_default_break'} .= " <section>"; 8.1626 - 8.1627 - # sectioninfo; does not contain text; v3.1 -> v4, not in v5 8.1628 - $self->{options}{'_default_untranslated'} .= " <sectioninfo>"; 8.1629 - $self->{options}{'_default_placeholder'} .= " <sectioninfo>"; 8.1630 - 8.1631 - # see; contains text; 8.1632 - $self->{options}{'_default_translated'} .= " <see>"; 8.1633 - $self->{options}{'_default_break'} .= " <see>"; 8.1634 - 8.1635 - # seealso; contains text; 8.1636 - $self->{options}{'_default_translated'} .= " <seealso>"; 8.1637 - $self->{options}{'_default_break'} .= " <seealso>"; 8.1638 - 8.1639 - # seealsoie; contains text; Formatted as a displayed block. 8.1640 - $self->{options}{'_default_translated'} .= " <seealsoie>"; 8.1641 - $self->{options}{'_default_break'} .= " <seealsoie>"; 8.1642 - 8.1643 - # seeie; contains text; Formatted as a displayed block. 8.1644 - $self->{options}{'_default_translated'} .= " <seeie>"; 8.1645 - $self->{options}{'_default_break'} .= " <seeie>"; 8.1646 - 8.1647 - # seg; contains text; 8.1648 - $self->{options}{'_default_translated'} .= " <seg>"; 8.1649 - $self->{options}{'_default_break'} .= " <seg>"; 8.1650 - 8.1651 - # seglistitem; does not contain text; 8.1652 - $self->{options}{'_default_untranslated'} .= " <seglistitem>"; 8.1653 - $self->{options}{'_default_break'} .= " <seglistitem>"; 8.1654 - 8.1655 - # segmentedlist; does not contain text; 8.1656 - $self->{options}{'_default_untranslated'} .= " <segmentedlist>"; 8.1657 - $self->{options}{'_default_break'} .= " <segmentedlist>"; 8.1658 - 8.1659 - # segtitle; contains text; 8.1660 - $self->{options}{'_default_translated'} .= " <segtitle>"; 8.1661 - $self->{options}{'_default_break'} .= " <segtitle>"; 8.1662 - 8.1663 - # seriesinfo; does not contain text; 8.1664 - # Removed in v4.0 8.1665 - $self->{options}{'_default_untranslated'} .= " <seriesinfo>"; 8.1666 - $self->{options}{'_default_placeholder'} .= " <seriesinfo>"; 8.1667 - 8.1668 - # seriesvolnums; contains text; Formatted inline 8.1669 - # NOTE: could be in the break class 8.1670 - $self->{options}{'_default_translated'} .= " <seriesvolnums>"; 8.1671 - $self->{options}{'_default_inline'} .= " <seriesvolnums>"; 8.1672 - 8.1673 - # set; does not contain text; Formatted as a displayed block. 8.1674 - $self->{options}{'_default_untranslated'} .= " <set>"; 8.1675 - $self->{options}{'_default_break'} .= " <set>"; 8.1676 - 8.1677 - # setindex; does not contain text; Formatted as a displayed block. 8.1678 - $self->{options}{'_default_untranslated'} .= " <setindex>"; 8.1679 - $self->{options}{'_default_break'} .= " <setindex>"; 8.1680 - 8.1681 - # setindexinfo; does not contain text; v4, not in v5 8.1682 - $self->{options}{'_default_untranslated'} .= " <setindexinfo>"; 8.1683 - $self->{options}{'_default_placeholder'} .= " <setindexinfo>"; 8.1684 - 8.1685 - # setinfo; does not contain text; v4, not in v5 8.1686 - $self->{options}{'_default_untranslated'} .= " <setinfo>"; 8.1687 - $self->{options}{'_default_placeholder'} .= " <setinfo>"; 8.1688 - 8.1689 - # sgmltag; contains text; Formatted inline; v4, not in v5 8.1690 - $self->{options}{'_default_translated'} .= " <sgmltag>"; 8.1691 - $self->{options}{'_default_inline'} .= " <sgmltag>"; 8.1692 - 8.1693 - # shortaffil; contains text; Formatted inline or as a 8.1694 - # displayed block depending on context 8.1695 - $self->{options}{'_default_translated'} .= " <shortaffil>"; 8.1696 - $self->{options}{'_default_inline'} .= " <shortaffil>"; 8.1697 - 8.1698 - # shortcut; does not contain text; Formatted inline 8.1699 - $self->{options}{'_default_untranslated'} .= " <shortcut>"; 8.1700 - $self->{options}{'_default_inline'} .= " <shortcut>"; 8.1701 - 8.1702 - # sidebar; does not contain text; Formatted as a displayed block. 8.1703 - $self->{options}{'_default_untranslated'} .= " <sidebar>"; 8.1704 - $self->{options}{'_default_break'} .= " <sidebar>"; 8.1705 - 8.1706 - # sidebarinfo; does not contain text; v4, not in v5 8.1707 - $self->{options}{'_default_untranslated'} .= " <sidebarinfo>"; 8.1708 - $self->{options}{'_default_placeholder'} .= " <sidebarinfo>"; 8.1709 - 8.1710 - # simpara; contains text; Formatted as a displayed block. 8.1711 - $self->{options}{'_default_translated'} .= " <simpara>"; 8.1712 - $self->{options}{'_default_break'} .= " <simpara>"; 8.1713 - 8.1714 - # simplelist; does not contain text; 8.1715 - $self->{options}{'_default_untranslated'} .= " <simplelist>"; 8.1716 - $self->{options}{'_default_inline'} .= " <simplelist>"; 8.1717 - 8.1718 - # simplemsgentry; does not contain text; Formatted as a displayed block. 8.1719 - $self->{options}{'_default_untranslated'} .= " <simplemsgentry>"; 8.1720 - $self->{options}{'_default_break'} .= " <simplemsgentry>"; 8.1721 - 8.1722 - # simplesect; does not contain text; Formatted as a displayed block. 8.1723 - $self->{options}{'_default_untranslated'} .= " <simplesect>"; 8.1724 - $self->{options}{'_default_break'} .= " <simplesect>"; 8.1725 - 8.1726 - # spanspec; does not contain text; Formatted as a displayed block. 8.1727 - $self->{options}{'_default_untranslated'} .= " <spanspec>"; 8.1728 - $self->{options}{'_default_break'} .= " <spanspec>"; 8.1729 - 8.1730 - # state; contains text; Formatted inline 8.1731 - $self->{options}{'_default_translated'} .= " <state>"; 8.1732 - $self->{options}{'_default_inline'} .= " <state>"; 8.1733 - 8.1734 - # step; does not contain text; Formatted as a displayed block. 8.1735 - $self->{options}{'_default_untranslated'} .= " <step>"; 8.1736 - $self->{options}{'_default_break'} .= " <step>"; 8.1737 - 8.1738 - # stepalternatives; does not contain text; Formatted as a displayed block. 8.1739 - $self->{options}{'_default_untranslated'} .= " <stepalternatives>"; 8.1740 - $self->{options}{'_default_break'} .= " <stepalternatives>"; 8.1741 - 8.1742 - # street; contains text; Formatted inline 8.1743 - $self->{options}{'_default_translated'} .= " <street>"; 8.1744 - $self->{options}{'_default_inline'} .= " <street>"; 8.1745 - 8.1746 - # structfield; contains text; Formatted inline; v4, not in v5 8.1747 - $self->{options}{'_default_translated'} .= " <structfield>"; 8.1748 - $self->{options}{'_default_inline'} .= " <structfield>"; 8.1749 - 8.1750 - # structname; contains text; Formatted inline; v4, not in v5 8.1751 - $self->{options}{'_default_translated'} .= " <structname>"; 8.1752 - $self->{options}{'_default_inline'} .= " <structname>"; 8.1753 - 8.1754 - # subject; does not contain text; Formatted inline or as a displayed block 8.1755 - # NOTE: could be in the inline class 8.1756 - $self->{options}{'_default_untranslated'} .= " <subject>"; 8.1757 - $self->{options}{'_default_break'} .= " <subject>"; 8.1758 - 8.1759 - # subjectset; does not contain text; Formatted inline or as a displayed block 8.1760 - # NOTE: could be in the inline class 8.1761 - $self->{options}{'_default_untranslated'} .= " <subjectset>"; 8.1762 - $self->{options}{'_default_break'} .= " <subjectset>"; 8.1763 - 8.1764 - # subjectterm; contains text; Formatted inline or as a displayed block 8.1765 - # NOTE: could be in the inline class 8.1766 - $self->{options}{'_default_translated'} .= " <subjectterm>"; 8.1767 - $self->{options}{'_default_break'} .= " <subjectterm>"; 8.1768 - 8.1769 - # subscript; contains text; Formatted inline 8.1770 - $self->{options}{'_default_translated'} .= " <subscript>"; 8.1771 - $self->{options}{'_default_inline'} .= " <subscript>"; 8.1772 - 8.1773 - # substeps; does not contain text; Formatted as a displayed block. 8.1774 - $self->{options}{'_default_untranslated'} .= " <substeps>"; 8.1775 - $self->{options}{'_default_break'} .= " <substeps>"; 8.1776 - 8.1777 - # subtitle; contains text; Formatted as a displayed block. 8.1778 - $self->{options}{'_default_translated'} .= " <subtitle>"; 8.1779 - $self->{options}{'_default_break'} .= " <subtitle>"; 8.1780 - 8.1781 - # superscript; contains text; Formatted inline 8.1782 - $self->{options}{'_default_translated'} .= " <superscript>"; 8.1783 - $self->{options}{'_default_inline'} .= " <superscript>"; 8.1784 - 8.1785 - # surname; contains text; Formatted inline 8.1786 - $self->{options}{'_default_translated'} .= " <surname>"; 8.1787 - $self->{options}{'_default_inline'} .= " <surname>"; 8.1788 - 8.1789 -#svg:svg 8.1790 - 8.1791 - # symbol; contains text; Formatted inline 8.1792 - $self->{options}{'_default_translated'} .= " <symbol>"; 8.1793 - $self->{options}{'_default_inline'} .= " <symbol>"; 8.1794 - 8.1795 - # synopfragment; does not contain text; Formatted as a displayed block. 8.1796 - $self->{options}{'_default_untranslated'} .= " <synopfragment>"; 8.1797 - $self->{options}{'_default_placeholder'} .= " <synopfragment>"; 8.1798 - 8.1799 - # synopfragmentref; contains text; Formatted inline 8.1800 - $self->{options}{'_default_translated'} .= " <synopfragmentref>"; 8.1801 - $self->{options}{'_default_inline'} .= " <synopfragmentref>"; 8.1802 - 8.1803 - # synopsis; contains text; verbatim 8.1804 - $self->{options}{'_default_translated'} .= " W<synopsis>"; 8.1805 - $self->{options}{'_default_placeholder'} .= " <synopsis>"; 8.1806 - 8.1807 - # systemitem; contains text; Formatted inline 8.1808 - $self->{options}{'_default_translated'} .= " <systemitem>"; 8.1809 - $self->{options}{'_default_inline'} .= " <systemitem>"; 8.1810 - 8.1811 -# TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT 8.1812 - 8.1813 - # table; does not contain text; Formatted as a displayed block. 8.1814 - $self->{options}{'_default_untranslated'} .= " <table>"; 8.1815 - $self->{options}{'_default_placeholder'} .= " <table>"; 8.1816 - 8.1817 - # tag; contains text; Formatted inline 8.1818 - $self->{options}{'_default_translated'} .= " <tag>"; 8.1819 - $self->{options}{'_default_inline'} .= " <tag>"; 8.1820 - 8.1821 - # task; does not contain text; Formatted as a displayed block. 8.1822 - $self->{options}{'_default_untranslated'} .= " <task>"; 8.1823 - $self->{options}{'_default_placeholder'} .= " <task>"; 8.1824 - 8.1825 - # taskprerequisites; does not contain text; Formatted as a displayed block. 8.1826 - $self->{options}{'_default_untranslated'} .= " <taskprerequisites>"; 8.1827 - $self->{options}{'_default_break'} .= " <taskprerequisites>"; 8.1828 - 8.1829 - # taskrelated; does not contain text; Formatted as a displayed block. 8.1830 - $self->{options}{'_default_untranslated'} .= " <taskrelated>"; 8.1831 - $self->{options}{'_default_break'} .= " <taskrelated>"; 8.1832 - 8.1833 - # tasksummary; does not contain text; Formatted as a displayed block. 8.1834 - $self->{options}{'_default_untranslated'} .= " <tasksummary>"; 8.1835 - $self->{options}{'_default_break'} .= " <tasksummary>"; 8.1836 - 8.1837 - # tbody; does not contain text; 8.1838 - $self->{options}{'_default_untranslated'} .= " <tbody>"; 8.1839 - $self->{options}{'_default_break'} .= " <tbody>"; 8.1840 - 8.1841 - # td; contains text; 8.1842 - $self->{options}{'_default_translated'} .= " <td>"; 8.1843 - $self->{options}{'_default_break'} .= " <td>"; 8.1844 - 8.1845 - # term; contains text; Formatted as a displayed block. 8.1846 - $self->{options}{'_default_translated'} .= " <term>"; 8.1847 - $self->{options}{'_default_break'} .= " <term>"; 8.1848 - 8.1849 - # termdef; contains text; Formatted inline 8.1850 - $self->{options}{'_default_translated'} .= " <termdef>"; 8.1851 - $self->{options}{'_default_inline'} .= " <termdef>"; 8.1852 - 8.1853 - # tertiary; contains text; Suppressed 8.1854 - $self->{options}{'_default_translated'} .= " <tertiary>"; 8.1855 - $self->{options}{'_default_placeholder'} .= " <tertiary>"; 8.1856 - 8.1857 - # tertiaryie; contains text; Formatted as a displayed block. 8.1858 - $self->{options}{'_default_translated'} .= " <tertiaryie>"; 8.1859 - $self->{options}{'_default_break'} .= " <tertiaryie>"; 8.1860 - 8.1861 - # textdata; does not contain text; Formatted inline or as a displayed block 8.1862 - # NOTE: could be in the inline class 8.1863 - $self->{options}{'_default_untranslated'} .= " <textdata>"; 8.1864 - $self->{options}{'_default_break'} .= " <textdata>"; 8.1865 - $self->{options}{'_default_attributes'}.=' <textdata>fileref'; 8.1866 - 8.1867 - # textobject; does not contain text; Formatted inline or as a displayed block 8.1868 - # NOTE: could be in the inline class 8.1869 - $self->{options}{'_default_untranslated'} .= " <textobject>"; 8.1870 - $self->{options}{'_default_break'} .= " <textobject>"; 8.1871 - 8.1872 - # tfoot; does not contain text; 8.1873 - $self->{options}{'_default_untranslated'} .= " <tfoot>"; 8.1874 - $self->{options}{'_default_break'} .= " <tfoot>"; 8.1875 - 8.1876 - # tgroup; does not contain text; 8.1877 - $self->{options}{'_default_untranslated'} .= " <tgroup>"; 8.1878 - $self->{options}{'_default_break'} .= " <tgroup>"; 8.1879 - 8.1880 - # th; contains text; 8.1881 - $self->{options}{'_default_translated'} .= " <th>"; 8.1882 - $self->{options}{'_default_break'} .= " <th>"; 8.1883 - 8.1884 - # thead; does not contain text; 8.1885 - $self->{options}{'_default_untranslated'} .= " <thead>"; 8.1886 - $self->{options}{'_default_break'} .= " <thead>"; 8.1887 - 8.1888 - # tip; does not contain text; Formatted as a displayed block. 8.1889 - $self->{options}{'_default_untranslated'} .= " <tip>"; 8.1890 - $self->{options}{'_default_break'} .= " <tip>"; 8.1891 - 8.1892 - # title; contains text; Formatted as a displayed block. 8.1893 - $self->{options}{'_default_translated'} .= " <title>"; 8.1894 - $self->{options}{'_default_break'} .= " <title>"; 8.1895 - 8.1896 - # titleabbrev; contains text; Formatted inline or as a displayed block 8.1897 - # NOTE: could be in the inline class 8.1898 - $self->{options}{'_default_translated'} .= " <titleabbrev>"; 8.1899 - $self->{options}{'_default_break'} .= " <titleabbrev>"; 8.1900 - 8.1901 - # toc; does not contain text; Formatted as a displayed block. 8.1902 - $self->{options}{'_default_untranslated'} .= " <toc>"; 8.1903 - $self->{options}{'_default_break'} .= " <toc>"; 8.1904 - 8.1905 - # tocback; contains text; Formatted as a displayed block. 8.1906 - $self->{options}{'_default_translated'} .= " <tocback>"; 8.1907 - $self->{options}{'_default_break'} .= " <tocback>"; 8.1908 - 8.1909 - # tocchap; does not contain text; Formatted as a displayed block. 8.1910 - $self->{options}{'_default_translated'} .= " <tocchap>"; 8.1911 - $self->{options}{'_default_break'} .= " <tocchap>"; 8.1912 - 8.1913 - # tocdiv; does not contain text; Formatted as a displayed block. 8.1914 - $self->{options}{'_default_untranslated'} .= " <tocdiv>"; 8.1915 - $self->{options}{'_default_break'} .= " <tocdiv>"; 8.1916 - 8.1917 - # tocentry; contains text; Formatted as a displayed block. 8.1918 - $self->{options}{'_default_translated'} .= " <tocentry>"; 8.1919 - $self->{options}{'_default_break'} .= " <tocentry>"; 8.1920 - 8.1921 - # tocfront; does not contain text; Formatted as a displayed block. 8.1922 - $self->{options}{'_default_translated'} .= " <tocfront>"; 8.1923 - $self->{options}{'_default_break'} .= " <tocfront>"; 8.1924 - 8.1925 - # toclevel1; does not contain text; Formatted as a displayed block. 8.1926 - $self->{options}{'_default_untranslated'} .= " <toclevel1>"; 8.1927 - $self->{options}{'_default_break'} .= " <toclevel1>"; 8.1928 - 8.1929 - # toclevel2; does not contain text; Formatted as a displayed block. 8.1930 - $self->{options}{'_default_untranslated'} .= " <toclevel2>"; 8.1931 - $self->{options}{'_default_break'} .= " <toclevel2>"; 8.1932 - 8.1933 - # toclevel3; does not contain text; Formatted as a displayed block. 8.1934 - $self->{options}{'_default_untranslated'} .= " <toclevel3>"; 8.1935 - $self->{options}{'_default_break'} .= " <toclevel3>"; 8.1936 - 8.1937 - # toclevel4; does not contain text; Formatted as a displayed block. 8.1938 - $self->{options}{'_default_untranslated'} .= " <toclevel4>"; 8.1939 - $self->{options}{'_default_break'} .= " <toclevel4>"; 8.1940 - 8.1941 - # toclevel5; does not contain text; Formatted as a displayed block. 8.1942 - $self->{options}{'_default_untranslated'} .= " <toclevel5>"; 8.1943 - $self->{options}{'_default_break'} .= " <toclevel5>"; 8.1944 - 8.1945 - # tocpart; does not contain text; Formatted as a displayed block. 8.1946 - $self->{options}{'_default_untranslated'} .= " <tocpart>"; 8.1947 - $self->{options}{'_default_break'} .= " <tocpart>"; 8.1948 - 8.1949 - # token; contains text; Formatted inline 8.1950 - $self->{options}{'_default_translated'} .= " <token>"; 8.1951 - $self->{options}{'_default_inline'} .= " <token>"; 8.1952 - 8.1953 - # tr; does not contain text; 8.1954 - $self->{options}{'_default_untranslated'} .= " <tr>"; 8.1955 - $self->{options}{'_default_break'} .= " <tr>"; 8.1956 - 8.1957 - # trademark; contains text; Formatted inline 8.1958 - $self->{options}{'_default_translated'} .= " <trademark>"; 8.1959 - $self->{options}{'_default_inline'} .= " <trademark>"; 8.1960 - 8.1961 - # type; contains text; Formatted inline 8.1962 - $self->{options}{'_default_translated'} .= " <type>"; 8.1963 - $self->{options}{'_default_inline'} .= " <type>"; 8.1964 - 8.1965 -# UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU 8.1966 - 8.1967 - # ulink; contains text; Formatted inline; v4, not in v5 8.1968 - $self->{options}{'_default_translated'} .= " <ulink>"; 8.1969 - $self->{options}{'_default_inline'} .= " <ulink>"; 8.1970 - 8.1971 - # uri; contains text; Formatted inline 8.1972 - $self->{options}{'_default_translated'} .= " <uri>"; 8.1973 - $self->{options}{'_default_inline'} .= " <uri>"; 8.1974 - 8.1975 - # userinput; contains text; Formatted inline 8.1976 - $self->{options}{'_default_translated'} .= " <userinput>"; 8.1977 - $self->{options}{'_default_inline'} .= " <userinput>"; 8.1978 - 8.1979 -# VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV 8.1980 - 8.1981 - # varargs; empty element; 8.1982 - $self->{options}{'_default_untranslated'} .= " <varargs>"; 8.1983 - $self->{options}{'_default_inline'} .= " <varargs>"; 8.1984 - 8.1985 - # variablelist; does not contain text; Formatted as a displayed block. 8.1986 - $self->{options}{'_default_untranslated'} .= " <variablelist>"; 8.1987 - $self->{options}{'_default_placeholder'} .= " <variablelist>"; 8.1988 - 8.1989 - # varlistentry; does not contain text; Formatted as a displayed block. 8.1990 - $self->{options}{'_default_untranslated'} .= " <varlistentry>"; 8.1991 - $self->{options}{'_default_break'} .= " <varlistentry>"; 8.1992 - 8.1993 - # varname; contains text; Formatted inline 8.1994 - $self->{options}{'_default_translated'} .= " <varname>"; 8.1995 - $self->{options}{'_default_inline'} .= " <varname>"; 8.1996 - 8.1997 - # videodata; contains text; Formatted inline or as a displayed block 8.1998 - $self->{options}{'_default_untranslated'} .= " <videodata>"; 8.1999 - $self->{options}{'_default_break'} .= " <videodata>"; 8.2000 - $self->{options}{'_default_attributes'}.=' <videodata>fileref'; 8.2001 - 8.2002 - # videoobject; contains text; Formatted inline or as a displayed block 8.2003 - $self->{options}{'_default_untranslated'} .= " <videoobject>"; 8.2004 - $self->{options}{'_default_break'} .= " <videoobject>"; 8.2005 - 8.2006 - # void; empty element; 8.2007 - $self->{options}{'_default_untranslated'} .= " <void>"; 8.2008 - $self->{options}{'_default_inline'} .= " <void>"; 8.2009 - 8.2010 - # volumenum; contains text; Formatted inline 8.2011 - $self->{options}{'_default_translated'} .= " <volumenum>"; 8.2012 - $self->{options}{'_default_inline'} .= " <volumenum>"; 8.2013 - 8.2014 -# WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW 8.2015 - 8.2016 - # warning; does not contain text; Formatted as a displayed block. 8.2017 - $self->{options}{'_default_untranslated'} .= " <warning>"; 8.2018 - $self->{options}{'_default_break'} .= " <warning>"; 8.2019 - 8.2020 - # wordasword; contains text; Formatted inline 8.2021 - $self->{options}{'_default_translated'} .= " <wordasword>"; 8.2022 - $self->{options}{'_default_inline'} .= " <wordasword>"; 8.2023 - 8.2024 -# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 8.2025 - 8.2026 - # xref; empty element; 8.2027 - $self->{options}{'_default_untranslated'} .= " <xref>"; 8.2028 - $self->{options}{'_default_inline'} .= " <xref>"; 8.2029 - 8.2030 -# YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY 8.2031 - 8.2032 - # year; contains text; Formatted inline 8.2033 - $self->{options}{'_default_translated'} .= " <year>"; 8.2034 - $self->{options}{'_default_inline'} .= " <year>"; 8.2035 - 8.2036 -# ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 8.2037 - 8.2038 - $self->{options}{'_default_attributes'}.=' 8.2039 - lang 8.2040 - xml:lang'; 8.2041 - 8.2042 - $self->treat_options; 8.2043 -}
9.1 --- a/tools/po4a/lib/Locale/Po4a/Po.pm Mon Mar 30 17:50:48 2009 +0800 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,1580 +0,0 @@ 9.4 -# Locale::Po4a::Po -- manipulation of po files 9.5 -# $Id: Po.pm,v 1.95 2009-02-28 22:18:39 nekral-guest Exp $ 9.6 -# 9.7 -# This program is free software; you may redistribute it and/or modify it 9.8 -# under the terms of GPL (see COPYING). 9.9 - 9.10 -############################################################################ 9.11 -# Modules and declarations 9.12 -############################################################################ 9.13 - 9.14 -=head1 NAME 9.15 - 9.16 -Locale::Po4a::Po - po file manipulation module 9.17 - 9.18 -=head1 SYNOPSIS 9.19 - 9.20 - use Locale::Po4a::Po; 9.21 - my $pofile=Locale::Po4a::Po->new(); 9.22 - 9.23 - # Read po file 9.24 - $pofile->read('file.po'); 9.25 - 9.26 - # Add an entry 9.27 - $pofile->push('msgid' => 'Hello', 'msgstr' => 'bonjour', 9.28 - 'flags' => "wrap", 'reference'=>'file.c:46'); 9.29 - 9.30 - # Extract a translation 9.31 - $pofile->gettext("Hello"); # returns 'bonjour' 9.32 - 9.33 - # Write back to a file 9.34 - $pofile->write('otherfile.po'); 9.35 - 9.36 -=head1 DESCRIPTION 9.37 - 9.38 -Locale::Po4a::Po is a module that allows you to manipulate message 9.39 -catalogs. You can load and write from/to a file (which extension is often 9.40 -I<po>), you can build new entries on the fly or request for the translation 9.41 -of a string. 9.42 - 9.43 -For a more complete description of message catalogs in the po format and 9.44 -their use, please refer to the documentation of the gettext program. 9.45 - 9.46 -This module is part of the PO4A project, which objective is to use po files 9.47 -(designed at origin to ease the translation of program messages) to 9.48 -translate everything, including documentation (man page, info manual), 9.49 -package description, debconf templates, and everything which may benefit 9.50 -from this. 9.51 - 9.52 -=head1 OPTIONS ACCEPTED BY THIS MODULE 9.53 - 9.54 -=over 4 9.55 - 9.56 -=item porefs 9.57 - 9.58 -This specifies the reference format. It can be one of 'none' to not produce 9.59 -any reference, 'noline' to not specify the line number, and 'full' to 9.60 -include complete references. 9.61 - 9.62 -=back 9.63 - 9.64 -=cut 9.65 - 9.66 -use IO::File; 9.67 - 9.68 - 9.69 -require Exporter; 9.70 - 9.71 -package Locale::Po4a::Po; 9.72 -use DynaLoader; 9.73 - 9.74 -use Locale::Po4a::Common qw(wrap_msg wrap_mod wrap_ref_mod dgettext); 9.75 - 9.76 -use subs qw(makespace); 9.77 -use vars qw(@ISA @EXPORT_OK); 9.78 -@ISA = qw(Exporter DynaLoader); 9.79 -@EXPORT = qw(%debug); 9.80 -@EXPORT_OK = qw(&move_po_if_needed); 9.81 - 9.82 -use Locale::Po4a::TransTractor; 9.83 -# Try to use a C extension if present. 9.84 -eval("bootstrap Locale::Po4a::Po $Locale::Po4a::TransTractor::VERSION"); 9.85 - 9.86 -use 5.006; 9.87 -use strict; 9.88 -use warnings; 9.89 - 9.90 -use Carp qw(croak); 9.91 -use File::Path; # mkdir before write 9.92 -use File::Copy; # move 9.93 -use POSIX qw(strftime floor); 9.94 -use Time::Local; 9.95 - 9.96 -use Encode; 9.97 - 9.98 -my @known_flags=qw(wrap no-wrap c-format fuzzy); 9.99 - 9.100 -our %debug=('canonize' => 0, 9.101 - 'quote' => 0, 9.102 - 'escape' => 0, 9.103 - 'encoding' => 0, 9.104 - 'filter' => 0); 9.105 - 9.106 -=head1 Functions about whole message catalogs 9.107 - 9.108 -=over 4 9.109 - 9.110 -=item new() 9.111 - 9.112 -Creates a new message catalog. If an argument is provided, it's the name of 9.113 -a po file we should load. 9.114 - 9.115 -=cut 9.116 - 9.117 -sub new { 9.118 - my ($this, $options) = (shift, shift); 9.119 - my $class = ref($this) || $this; 9.120 - my $self = {}; 9.121 - bless $self, $class; 9.122 - $self->initialize($options); 9.123 - 9.124 - my $filename = shift; 9.125 - $self->read($filename) if defined($filename) && length($filename); 9.126 - return $self; 9.127 -} 9.128 - 9.129 -# Return the numerical timezone (e.g. +0200) 9.130 -# Neither the %z nor the %s formats of strftime are portable: 9.131 -# '%s' is not supported on Solaris and '%z' indicates 9.132 -# "2006-10-25 19:36E. Europe Standard Time" on MS Windows. 9.133 -sub timezone { 9.134 - my @g = gmtime(); 9.135 - my @l = localtime(); 9.136 - 9.137 - my $diff; 9.138 - $diff = floor(timelocal(@l)/60 +0.5); 9.139 - $diff -= floor(timelocal(@g)/60 +0.5); 9.140 - 9.141 - my $h = floor($diff / 60) + $l[8]; # $l[8] indicates if we are currently 9.142 - # in a daylight saving time zone 9.143 - my $m = $diff%60; 9.144 - 9.145 - return sprintf "%+03d%02d\n", $h, $m; 9.146 -} 9.147 - 9.148 -sub initialize { 9.149 - my ($self, $options) = (shift, shift); 9.150 - my $date = strftime("%Y-%m-%d %H:%M", localtime).timezone(); 9.151 - chomp $date; 9.152 -# $options = ref($options) || $options; 9.153 - 9.154 - $self->{options}{'porefs'}= 'full'; 9.155 - $self->{options}{'msgid-bugs-address'}= undef; 9.156 - $self->{options}{'copyright-holder'}= "Free Software Foundation, Inc."; 9.157 - $self->{options}{'package-name'}= "PACKAGE"; 9.158 - $self->{options}{'package-version'}= "VERSION"; 9.159 - foreach my $opt (keys %$options) { 9.160 - if ($options->{$opt}) { 9.161 - die wrap_mod("po4a::po", 9.162 - dgettext ("po4a", "Unknown option: %s"), $opt) 9.163 - unless exists $self->{options}{$opt}; 9.164 - $self->{options}{$opt} = $options->{$opt}; 9.165 - } 9.166 - } 9.167 - $self->{options}{'porefs'} =~ /^(full|noline|none)$/ || 9.168 - die wrap_mod("po4a::po", 9.169 - dgettext ("po4a", 9.170 - "Invalid value for option 'porefs' ('%s' is ". 9.171 - "not one of 'full', 'noline' or 'none')"), 9.172 - $self->{options}{'porefs'}); 9.173 - 9.174 - $self->{po}=(); 9.175 - $self->{count}=0; # number of msgids in the PO 9.176 - # count_doc: number of strings in the document 9.177 - # (duplicate strings counted multiple times) 9.178 - $self->{count_doc}=0; 9.179 - $self->{header_comment}= 9.180 - " SOME DESCRIPTIVE TITLE\n" 9.181 - ." Copyright (C) YEAR ". 9.182 - $self->{options}{'copyright-holder'}."\n" 9.183 - ." This file is distributed under the same license ". 9.184 - "as the ".$self->{options}{'package-name'}." package.\n" 9.185 - ." FIRST AUTHOR <EMAIL\@ADDRESS>, YEAR.\n" 9.186 - ."\n" 9.187 - .", fuzzy"; 9.188 -# $self->header_tag="fuzzy"; 9.189 - $self->{header}=escape_text("Project-Id-Version: ". 9.190 - $self->{options}{'package-name'}." ". 9.191 - $self->{options}{'package-version'}."\n". 9.192 - ((defined $self->{options}{'msgid-bugs-address'})? 9.193 - "Report-Msgid-Bugs-To: ".$self->{options}{'msgid-bugs-address'}."\n": 9.194 - ""). 9.195 - "POT-Creation-Date: $date\n". 9.196 - "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n". 9.197 - "Last-Translator: FULL NAME <EMAIL\@ADDRESS>\n". 9.198 - "Language-Team: LANGUAGE <LL\@li.org>\n". 9.199 - "MIME-Version: 1.0\n". 9.200 - "Content-Type: text/plain; charset=CHARSET\n". 9.201 - "Content-Transfer-Encoding: ENCODING"); 9.202 - 9.203 - $self->{encoder}=find_encoding("ascii"); 9.204 - 9.205 - # To make stats about gettext hits 9.206 - $self->stats_clear(); 9.207 -} 9.208 - 9.209 -=item read($) 9.210 - 9.211 -Reads a po file (which name is given as argument). Previously existing 9.212 -entries in self are not removed, the new ones are added to the end of the 9.213 -catalog. 9.214 - 9.215 -=cut 9.216 - 9.217 -sub read { 9.218 - my $self=shift; 9.219 - my $filename=shift 9.220 - or croak wrap_mod("po4a::po", 9.221 - dgettext("po4a", 9.222 - "Please provide a non-null filename")); 9.223 - 9.224 - my $fh; 9.225 - if ($filename eq '-') { 9.226 - $fh=*STDIN; 9.227 - } else { 9.228 - open $fh,"<$filename" 9.229 - or croak wrap_mod("po4a::po", 9.230 - dgettext("po4a", "Can't read from %s: %s"), 9.231 - $filename, $!); 9.232 - } 9.233 - 9.234 - ## Read paragraphs line-by-line 9.235 - my $pofile=""; 9.236 - my $textline; 9.237 - while (defined ($textline = <$fh>)) { 9.238 - $pofile .= $textline; 9.239 - } 9.240 -# close INPUT 9.241 -# or croak (sprintf(dgettext("po4a", 9.242 -# "Can't close %s after reading: %s"), 9.243 -# $filename,$!)."\n"); 9.244 - 9.245 - my $linenum=0; 9.246 - 9.247 - foreach my $msg (split (/\n\n/,$pofile)) { 9.248 - my ($msgid,$msgstr,$comment,$automatic,$reference,$flags,$buffer); 9.249 - my ($msgid_plural, $msgstr_plural); 9.250 - foreach my $line (split (/\n/,$msg)) { 9.251 - $linenum++; 9.252 - if ($line =~ /^#\. ?(.*)$/) { # Automatic comment 9.253 - $automatic .= (defined($automatic) ? "\n" : "").$1; 9.254 - 9.255 - } elsif ($line =~ /^#: ?(.*)$/) { # reference 9.256 - $reference .= (defined($reference) ? "\n" : "").$1; 9.257 - 9.258 - } elsif ($line =~ /^#, ?(.*)$/) { # flags 9.259 - $flags .= (defined($flags) ? "\n" : "").$1; 9.260 - 9.261 - } elsif ($line =~ /^#(.*)$/) { # Translator comments 9.262 - $comment .= (defined($comment) ? "\n" : "").($1||""); 9.263 - 9.264 - } elsif ($line =~ /^msgid (".*")$/) { # begin of msgid 9.265 - $buffer = $1; 9.266 - 9.267 - } elsif ($line =~ /^msgid_plural (".*")$/) { 9.268 - # begin of msgid_plural, end of msgid 9.269 - 9.270 - $msgid = $buffer; 9.271 - $buffer = $1; 9.272 - 9.273 - } elsif ($line =~ /^msgstr (".*")$/) { 9.274 - # begin of msgstr, end of msgid 9.275 - 9.276 - $msgid = $buffer; 9.277 - $buffer = "$1"; 9.278 - 9.279 - } elsif ($line =~ /^msgstr\[([0-9]+)\] (".*")$/) { 9.280 - # begin of msgstr[x], end of msgid_plural or msgstr[x-1] 9.281 - 9.282 - # Note: po4a cannot uses plural forms 9.283 - # (no integer to use the plural form) 9.284 - # * drop the msgstr[x] where x >= 2 9.285 - # * use msgstr[0] as the translation of msgid 9.286 - # * use msgstr[1] as the translation of msgid_plural 9.287 - 9.288 - if ($1 eq "0") { 9.289 - $msgid_plural = $buffer; 9.290 - $buffer = "$2"; 9.291 - } elsif ($1 eq "1") { 9.292 - $msgstr = $buffer; 9.293 - $buffer = "$2"; 9.294 - } elsif ($1 eq "2") { 9.295 - $msgstr_plural = $buffer; 9.296 - warn wrap_ref_mod("$filename:$linenum", 9.297 - "po4a::po", 9.298 - dgettext("po4a", "Messages with more than 2 plural forms are not supported.")); 9.299 - } 9.300 - } elsif ($line =~ /^(".*")$/) { 9.301 - # continuation of a line 9.302 - $buffer .= "\n$1"; 9.303 - 9.304 - } else { 9.305 - warn wrap_ref_mod("$filename:$linenum", 9.306 - "po4a::po", 9.307 - dgettext("po4a", "Strange line: -->%s<--"), 9.308 - $line); 9.309 - } 9.310 - } 9.311 - $linenum++; 9.312 - if (defined $msgid_plural) { 9.313 - $msgstr_plural=$buffer; 9.314 - 9.315 - $msgid = unquote_text($msgid) if (defined($msgid)); 9.316 - $msgstr = unquote_text($msgstr) if (defined($msgstr)); 9.317 - 9.318 - $self->push_raw ('msgid' => $msgid, 9.319 - 'msgstr' => $msgstr, 9.320 - 'reference' => $reference, 9.321 - 'flags' => $flags, 9.322 - 'comment' => $comment, 9.323 - 'automatic' => $automatic, 9.324 - 'plural' => 0); 9.325 - 9.326 - $msgid_plural = unquote_text($msgid_plural) 9.327 - if (defined($msgid_plural)); 9.328 - $msgstr_plural = unquote_text($msgstr_plural) 9.329 - if (defined($msgstr_plural)); 9.330 - 9.331 - $self->push_raw ('msgid' => $msgid_plural, 9.332 - 'msgstr' => $msgstr_plural, 9.333 - 'reference' => $reference, 9.334 - 'flags' => $flags, 9.335 - 'comment' => $comment, 9.336 - 'automatic' => $automatic, 9.337 - 'plural' => 1); 9.338 - } else { 9.339 - $msgstr=$buffer; 9.340 - 9.341 - $msgid = unquote_text($msgid) if (defined($msgid)); 9.342 - $msgstr = unquote_text($msgstr) if (defined($msgstr)); 9.343 - 9.344 - $self->push_raw ('msgid' => $msgid, 9.345 - 'msgstr' => $msgstr, 9.346 - 'reference' => $reference, 9.347 - 'flags' => $flags, 9.348 - 'comment' => $comment, 9.349 - 'automatic' => $automatic); 9.350 - } 9.351 - } 9.352 -} 9.353 - 9.354 -=item write($) 9.355 - 9.356 -Writes the current catalog to the given file. 9.357 - 9.358 -=cut 9.359 - 9.360 -sub write{ 9.361 - my $self=shift; 9.362 - my $filename=shift 9.363 - or croak dgettext("po4a","Can't write to a file without filename")."\n"; 9.364 - 9.365 - my $fh; 9.366 - if ($filename eq '-') { 9.367 - $fh=\*STDOUT; 9.368 - } else { 9.369 - # make sure the directory in which we should write the localized 9.370 - # file exists 9.371 - my $dir = $filename; 9.372 - if ($dir =~ m|/|) { 9.373 - $dir =~ s|/[^/]*$||; 9.374 - 9.375 - File::Path::mkpath($dir, 0, 0755) # Croaks on error 9.376 - if (length ($dir) && ! -e $dir); 9.377 - } 9.378 - open $fh,">$filename" 9.379 - or croak wrap_mod("po4a::po", 9.380 - dgettext("po4a", "Can't write to %s: %s"), 9.381 - $filename, $!); 9.382 - } 9.383 - 9.384 - print $fh "".format_comment($self->{header_comment},"") 9.385 - if defined($self->{header_comment}) && length($self->{header_comment}); 9.386 - 9.387 - print $fh "msgid \"\"\n"; 9.388 - print $fh "msgstr ".quote_text($self->{header})."\n\n"; 9.389 - 9.390 - 9.391 - my $buf_msgstr_plural; # USed to keep the first msgstr of plural forms 9.392 - my $first=1; 9.393 - foreach my $msgid ( sort { ($self->{po}{"$a"}{'pos'}) <=> 9.394 - ($self->{po}{"$b"}{'pos'}) 9.395 - } keys %{$self->{po}}) { 9.396 - my $output=""; 9.397 - 9.398 - if ($first) { 9.399 - $first=0; 9.400 - } else { 9.401 - $output .= "\n"; 9.402 - } 9.403 - 9.404 - $output .= format_comment($self->{po}{$msgid}{'comment'},"") 9.405 - if defined($self->{po}{$msgid}{'comment'}) 9.406 - && length ($self->{po}{$msgid}{'comment'}); 9.407 - if ( defined($self->{po}{$msgid}{'automatic'}) 9.408 - && length ($self->{po}{$msgid}{'automatic'})) { 9.409 - foreach my $comment (split(/\\n/,$self->{po}{$msgid}{'automatic'})) 9.410 - { 9.411 - $output .= format_comment($comment, ". ") 9.412 - } 9.413 - } 9.414 - $output .= format_comment($self->{po}{$msgid}{'type'},". type: ") 9.415 - if defined($self->{po}{$msgid}{'type'}) 9.416 - && length ($self->{po}{$msgid}{'type'}); 9.417 - $output .= format_comment($self->{po}{$msgid}{'reference'},": ") 9.418 - if defined($self->{po}{$msgid}{'reference'}) 9.419 - && length ($self->{po}{$msgid}{'reference'}); 9.420 - $output .= "#, ". join(", ", sort split(/\s+/,$self->{po}{$msgid}{'flags'}))."\n" 9.421 - if defined($self->{po}{$msgid}{'flags'}) 9.422 - && length ($self->{po}{$msgid}{'flags'}); 9.423 - 9.424 - if (exists $self->{po}{$msgid}{'plural'}) { 9.425 - if ($self->{po}{$msgid}{'plural'} == 0) { 9.426 - if ($self->get_charset =~ /^utf-8$/i) { 9.427 - my $msgstr = Encode::decode_utf8($self->{po}{$msgid}{'msgstr'}); 9.428 - $msgid = Encode::decode_utf8($msgid); 9.429 - $output .= Encode::encode_utf8("msgid ".quote_text($msgid)."\n"); 9.430 - $buf_msgstr_plural = Encode::encode_utf8("msgstr[0] ".quote_text($msgstr)."\n"); 9.431 - } else { 9.432 - $output = "msgid ".quote_text($msgid)."\n"; 9.433 - $buf_msgstr_plural = "msgstr[0] ".quote_text($self->{po}{$msgid}{'msgstr'})."\n"; 9.434 - } 9.435 - } elsif ($self->{po}{$msgid}{'plural'} == 1) { 9.436 -# TODO: there may be only one plural form 9.437 - if ($self->get_charset =~ /^utf-8$/i) { 9.438 - my $msgstr = Encode::decode_utf8($self->{po}{$msgid}{'msgstr'}); 9.439 - $msgid = Encode::decode_utf8($msgid); 9.440 - $output = Encode::encode_utf8("msgid_plural ".quote_text($msgid)."\n"); 9.441 - $output .= $buf_msgstr_plural; 9.442 - $output .= Encode::encode_utf8("msgstr[1] ".quote_text($msgstr)."\n"); 9.443 - $buf_msgstr_plural = ""; 9.444 - } else { 9.445 - $output = "msgid_plural ".quote_text($msgid)."\n"; 9.446 - $output .= $buf_msgstr_plural; 9.447 - $output .= "msgstr[1] ".quote_text($self->{po}{$msgid}{'msgstr'})."\n"; 9.448 - } 9.449 - } else { 9.450 - die wrap_msg(dgettext("po4a","Can't write PO files with more than two plural forms.")); 9.451 - } 9.452 - } else { 9.453 - if ($self->get_charset =~ /^utf-8$/i) { 9.454 - my $msgstr = Encode::decode_utf8($self->{po}{$msgid}{'msgstr'}); 9.455 - $msgid = Encode::decode_utf8($msgid); 9.456 - $output .= Encode::encode_utf8("msgid ".quote_text($msgid)."\n"); 9.457 - $output .= Encode::encode_utf8("msgstr ".quote_text($msgstr)."\n"); 9.458 - } else { 9.459 - $output .= "msgid ".quote_text($msgid)."\n"; 9.460 - $output .= "msgstr ".quote_text($self->{po}{$msgid}{'msgstr'})."\n"; 9.461 - } 9.462 - } 9.463 - 9.464 - print $fh $output; 9.465 - } 9.466 -# print STDERR "$fh"; 9.467 -# if ($filename ne '-') { 9.468 -# close $fh 9.469 -# or croak (sprintf(dgettext("po4a", 9.470 -# "Can't close %s after writing: %s\n"), 9.471 -# $filename,$!)); 9.472 -# } 9.473 -} 9.474 - 9.475 -=item write_if_needed($$) 9.476 - 9.477 -Like write, but if the PO or POT file already exists, the object will be 9.478 -written in a temporary file which will be compared with the existing file 9.479 -to check that the update is needed (this avoids to change a POT just to 9.480 -update a line reference or the POT-Creation-Date field). 9.481 - 9.482 -=cut 9.483 - 9.484 -sub move_po_if_needed { 9.485 - my ($new_po, $old_po, $backup) = (shift, shift, shift); 9.486 - my $diff; 9.487 - 9.488 - if (-e $old_po) { 9.489 - my $diff_ignore = "-I'^#:' " 9.490 - ."-I'^\"POT-Creation-Date:' " 9.491 - ."-I'^\"PO-Revision-Date:'"; 9.492 - $diff = qx(diff -q $diff_ignore $old_po $new_po); 9.493 - if ( $diff eq "" ) { 9.494 - unlink $new_po 9.495 - or die wrap_msg(dgettext("po4a","Can't unlink %s: %s."), 9.496 - $new_po, $!); 9.497 - # touch the old PO 9.498 - my ($atime, $mtime) = (time,time); 9.499 - utime $atime, $mtime, $old_po; 9.500 - } else { 9.501 - if ($backup) { 9.502 - copy $old_po, $old_po."~" 9.503 - or die wrap_msg(dgettext("po4a","Can't copy %s to %s: %s."), 9.504 - $old_po, $old_po."~", $!); 9.505 - } else { 9.506 - } 9.507 - move $new_po, $old_po 9.508 - or die wrap_msg(dgettext("po4a","Can't move %s to %s: %s."), 9.509 - $new_po, $old_po, $!); 9.510 - } 9.511 - } else { 9.512 - move $new_po, $old_po 9.513 - or die wrap_msg(dgettext("po4a","Can't move %s to %s: %s."), 9.514 - $new_po, $old_po, $!); 9.515 - } 9.516 -} 9.517 - 9.518 -sub write_if_needed { 9.519 - my $self=shift; 9.520 - my $filename=shift 9.521 - or croak dgettext("po4a","Can't write to a file without filename")."\n"; 9.522 - 9.523 - if (-e $filename) { 9.524 - my ($tmp_filename); 9.525 - (undef,$tmp_filename)=File::Temp->tempfile($filename."XXXX", 9.526 - DIR => "/tmp", 9.527 - OPEN => 0, 9.528 - UNLINK => 0); 9.529 - $self->write($tmp_filename); 9.530 - move_po_if_needed($tmp_filename, $filename); 9.531 - } else { 9.532 - $self->write($filename); 9.533 - } 9.534 -} 9.535 - 9.536 -=item gettextize($$) 9.537 - 9.538 -This function produces one translated message catalog from two catalogs, an 9.539 -original and a translation. This process is described in L<po4a(7)|po4a.7>, 9.540 -section I<Gettextization: how does it work?>. 9.541 - 9.542 -=cut 9.543 - 9.544 -sub gettextize { 9.545 - my $this = shift; 9.546 - my $class = ref($this) || $this; 9.547 - my ($poorig,$potrans)=(shift,shift); 9.548 - 9.549 - my $pores=Locale::Po4a::Po->new(); 9.550 - 9.551 - my $please_fail = 0; 9.552 - my $toobad = dgettext("po4a", 9.553 - "\nThe gettextization failed (once again). Don't give up, ". 9.554 - "gettextizing is a subtle art, but this is only needed once ". 9.555 - "to convert a project to the gorgeous luxus offered by po4a ". 9.556 - "to translators.". 9.557 - "\nPlease refer to the po4a(7) documentation, the section ". 9.558 - "\"HOWTO convert a pre-existing translation to po4a?\" ". 9.559 - "contains several hints to help you in your task"); 9.560 - 9.561 - # Don't fail right now when the entry count does not match. Instead, give 9.562 - # it a try so that the user can see where we fail (which is probably where 9.563 - # the problem is). 9.564 - if ($poorig->count_entries_doc() > $potrans->count_entries_doc()) { 9.565 - warn wrap_mod("po4a gettextize", dgettext("po4a", 9.566 - "Original has more strings than the translation (%d>%d). ". 9.567 - "Please fix it by editing the translated version to add ". 9.568 - "some dummy entry."), 9.569 - $poorig->count_entries_doc(), 9.570 - $potrans->count_entries_doc()); 9.571 - $please_fail = 1; 9.572 - } elsif ($poorig->count_entries_doc() < $potrans->count_entries_doc()) { 9.573 - warn wrap_mod("po4a gettextize", dgettext("po4a", 9.574 - "Original has less strings than the translation (%d<%d). ". 9.575 - "Please fix it by removing the extra entry from the ". 9.576 - "translated file. You may need an addendum (cf po4a(7)) ". 9.577 - "to reput the chunk in place after gettextization. A ". 9.578 - "possible cause is that a text duplicated in the original ". 9.579 - "is not translated the same way each time. Remove one of ". 9.580 - "the translations, and you're fine."), 9.581 - $poorig->count_entries_doc(), 9.582 - $potrans->count_entries_doc()); 9.583 - $please_fail = 1; 9.584 - } 9.585 - 9.586 - if ( $poorig->get_charset =~ /^utf-8$/i ) { 9.587 - $potrans->to_utf8; 9.588 - $pores->set_charset("utf-8"); 9.589 - } else { 9.590 - if ($potrans->get_charset eq "CHARSET") { 9.591 - $pores->set_charset("ascii"); 9.592 - } else { 9.593 - $pores->set_charset($potrans->get_charset); 9.594 - } 9.595 - } 9.596 - print "Po character sets:\n". 9.597 - " original=".$poorig->get_charset."\n". 9.598 - " translated=".$potrans->get_charset."\n". 9.599 - " result=".$pores->get_charset."\n" 9.600 - if $debug{'encoding'}; 9.601 - 9.602 - for (my ($o,$t)=(0,0) ; 9.603 - $o<$poorig->count_entries_doc() && $t<$potrans->count_entries_doc(); 9.604 - $o++,$t++) { 9.605 - # 9.606 - # Extract some informations 9.607 - 9.608 - my ($orig,$trans)=($poorig->msgid_doc($o),$potrans->msgid_doc($t)); 9.609 -# print STDERR "Matches [[$orig]]<<$trans>>\n"; 9.610 - 9.611 - my ($reforig,$reftrans)=($poorig->{po}{$orig}{'reference'}, 9.612 - $potrans->{po}{$trans}{'reference'}); 9.613 - my ($typeorig,$typetrans)=($poorig->{po}{$orig}{'type'}, 9.614 - $potrans->{po}{$trans}{'type'}); 9.615 - 9.616 - # 9.617 - # Make sure the type of both string exist 9.618 - # 9.619 - die wrap_mod("po4a gettextize", 9.620 - "Internal error: type of original string number %s ". 9.621 - "isn't provided", $o) 9.622 - if ($typeorig eq ''); 9.623 - 9.624 - die wrap_mod("po4a gettextize", 9.625 - "Internal error: type of translated string number %s ". 9.626 - "isn't provided", $o) 9.627 - if ($typetrans eq ''); 9.628 - 9.629 - # 9.630 - # Make sure both type are the same 9.631 - # 9.632 - if ($typeorig ne $typetrans){ 9.633 - $pores->write("gettextization.failed.po"); 9.634 - die wrap_msg(dgettext("po4a", 9.635 - "po4a gettextization: Structure disparity between ". 9.636 - "original and translated files:\n". 9.637 - "msgid (at %s) is of type '%s' while\n". 9.638 - "msgstr (at %s) is of type '%s'.\n". 9.639 - "Original text: %s\n". 9.640 - "Translated text: %s\n". 9.641 - "(result so far dumped to gettextization.failed.po)"). 9.642 - "%s", 9.643 - $reforig, $typeorig, 9.644 - $reftrans, $typetrans, 9.645 - $orig, 9.646 - $trans, 9.647 - $toobad); 9.648 - } 9.649 - 9.650 - # 9.651 - # Push the entry 9.652 - # 9.653 - my $flags; 9.654 - if (defined $poorig->{po}{$orig}{'flags'}) { 9.655 - $flags = $poorig->{po}{$orig}{'flags'}." fuzzy"; 9.656 - } else { 9.657 - $flags = "fuzzy"; 9.658 - } 9.659 - $pores->push_raw('msgid' => $orig, 9.660 - 'msgstr' => $trans, 9.661 - 'flags' => $flags, 9.662 - 'type' => $typeorig, 9.663 - 'reference' => $reforig, 9.664 - 'conflict' => 1, 9.665 - 'transref' => $potrans->{po}{$trans}{'reference'}) 9.666 - unless (defined($pores->{po}{$orig}) 9.667 - and ($pores->{po}{$orig}{'msgstr'} eq $trans)) 9.668 - # FIXME: maybe we should be smarter about what reference should be 9.669 - # sent to push_raw. 9.670 - } 9.671 - 9.672 - # make sure we return a useful error message when entry count differ 9.673 - die "$toobad\n" if $please_fail; 9.674 - 9.675 - return $pores; 9.676 -} 9.677 - 9.678 -=item filter($) 9.679 - 9.680 -This function extracts a catalog from an existing one. Only the entries having 9.681 -a reference in the given file will be placed in the resulting catalog. 9.682 - 9.683 -This function parses its argument, converts it to a perl function definition, 9.684 -eval this definition and filter the fields for which this function returns 9.685 -true. 9.686 - 9.687 -I love perl sometimes ;) 9.688 - 9.689 -=cut 9.690 - 9.691 -sub filter { 9.692 - my $self=shift; 9.693 - our $filter=shift; 9.694 - 9.695 - my $res; 9.696 - $res = Locale::Po4a::Po->new(); 9.697 - 9.698 - # Parse the filter 9.699 - our $code="sub apply { return "; 9.700 - our $pos=0; 9.701 - our $length = length $filter; 9.702 - 9.703 - # explode chars to parts. How to subscript a string in Perl? 9.704 - our @filter = split(//,$filter); 9.705 - 9.706 - sub gloups { 9.707 - my $fmt=shift; 9.708 - my $space = ""; 9.709 - for (1..$pos){ 9.710 - $space .= ' '; 9.711 - } 9.712 - die wrap_msg("$fmt\n$filter\n$space^ HERE"); 9.713 - } 9.714 - sub showmethecode { 9.715 - return unless $debug{'filter'}; 9.716 - my $fmt=shift; 9.717 - my $space=""; 9.718 - for (1..$pos){ 9.719 - $space .= ' '; 9.720 - } 9.721 - print STDERR "$filter\n$space^ $fmt\n";#"$code\n"; 9.722 - } 9.723 - 9.724 - # I dream of a lex in perl :-/ 9.725 - sub parse_expression { 9.726 - showmethecode("Begin expression") 9.727 - if $debug{'filter'}; 9.728 - 9.729 - gloups("Begin of expression expected, got '%s'",$filter[$pos]) 9.730 - unless ($filter[$pos] eq '('); 9.731 - $pos ++; # pass the '(' 9.732 - if ($filter[$pos] eq '&') { 9.733 - # AND 9.734 - $pos++; 9.735 - showmethecode("Begin of AND") 9.736 - if $debug{'filter'}; 9.737 - $code .= "("; 9.738 - while (1) { 9.739 - gloups ("Unfinished AND statement.") 9.740 - if ($pos == $length); 9.741 - parse_expression(); 9.742 - if ($filter[$pos] eq '(') { 9.743 - $code .= " && "; 9.744 - } elsif ($filter[$pos] eq ')') { 9.745 - last; # do not eat that char 9.746 - } else { 9.747 - gloups("End of AND or begin of sub-expression expected, got '%s'", $filter[$pos]); 9.748 - } 9.749 - } 9.750 - $code .= ")"; 9.751 - } elsif ($filter[$pos] eq '|') { 9.752 - # OR 9.753 - $pos++; 9.754 - $code .= "("; 9.755 - while (1) { 9.756 - gloups("Unfinished OR statement.") 9.757 - if ($pos == $length); 9.758 - parse_expression(); 9.759 - if ($filter[$pos] eq '(') { 9.760 - $code .= " || "; 9.761 - } elsif ($filter[$pos] eq ')') { 9.762 - last; # do not eat that char 9.763 - } else { 9.764 - gloups("End of OR or begin of sub-expression expected, got '%s'",$filter[$pos]); 9.765 - } 9.766 - } 9.767 - $code .= ")"; 9.768 - } elsif ($filter[$pos] eq '!') { 9.769 - # NOT 9.770 - $pos++; 9.771 - $code .= "(!"; 9.772 - gloups("Missing sub-expression in NOT statement.") 9.773 - if ($pos == $length); 9.774 - parse_expression(); 9.775 - $code .= ")"; 9.776 - } else { 9.777 - # must be an equal. Let's get field and argument 9.778 - my ($field,$arg,$done); 9.779 - $field = substr($filter,$pos); 9.780 - gloups("EQ statement contains no '=' or invalid field name") 9.781 - unless ($field =~ /([a-z]*)=/i); 9.782 - $field = lc($1); 9.783 - $pos += (length $field) + 1; 9.784 - 9.785 - # check that we've got a valid field name, 9.786 - # and the number it referes to 9.787 - # DO NOT CHANGE THE ORDER 9.788 - my @names=qw(msgid msgstr reference flags comment automatic); 9.789 - my $fieldpos; 9.790 - for ($fieldpos = 0; 9.791 - $fieldpos < scalar @names && $field ne $names[$fieldpos]; 9.792 - $fieldpos++) {} 9.793 - gloups("Invalid field name: %s",$field) 9.794 - if $fieldpos == scalar @names; # not found 9.795 - 9.796 - # Now, get the argument value. It has to be between quotes, 9.797 - # which can be escaped 9.798 - # We point right on the first char of the argument 9.799 - # (first quote already eaten) 9.800 - my $escaped = 0; 9.801 - my $quoted = 0; 9.802 - if ($filter[$pos] eq '"') { 9.803 - $pos++; 9.804 - $quoted = 1; 9.805 - } 9.806 - showmethecode(($quoted?"Quoted":"Unquoted")." argument of field '$field'") 9.807 - if $debug{'filter'}; 9.808 - 9.809 - while (!$done) { 9.810 - gloups("Unfinished EQ argument.") 9.811 - if ($pos == $length); 9.812 - 9.813 - if ($quoted) { 9.814 - if ($filter[$pos] eq '\\') { 9.815 - if ($escaped) { 9.816 - $arg .= '\\'; 9.817 - $escaped = 0; 9.818 - } else { 9.819 - $escaped = 1; 9.820 - } 9.821 - } elsif ($escaped) { 9.822 - if ($filter[$pos] eq '"') { 9.823 - $arg .= '"'; 9.824 - $escaped = 0; 9.825 - } else { 9.826 - gloups("Invalid escape sequence in argument: '\\%s'",$filter[$pos]); 9.827 - } 9.828 - } else { 9.829 - if ($filter[$pos] eq '"') { 9.830 - $done = 1; 9.831 - } else { 9.832 - $arg .= $filter[$pos]; 9.833 - } 9.834 - } 9.835 - } else { 9.836 - if ($filter[$pos] eq ')') { 9.837 - # counter the next ++ since we don't want to eat 9.838 - # this char 9.839 - $pos--; 9.840 - $done = 1; 9.841 - } else { 9.842 - $arg .= $filter[$pos]; 9.843 - } 9.844 - } 9.845 - $pos++; 9.846 - } 9.847 - # and now, add the code to check this equality 9.848 - $code .= "(\$_[$fieldpos] =~ m/$arg/)"; 9.849 - 9.850 - } 9.851 - showmethecode("End of expression") 9.852 - if $debug{'filter'}; 9.853 - gloups("Unfinished statement.") 9.854 - if ($pos == $length); 9.855 - gloups("End of expression expected, got '%s'",$filter[$pos]) 9.856 - unless ($filter[$pos] eq ')'); 9.857 - $pos++; 9.858 - } 9.859 - # And now, launch the beast, finish the function and use eval 9.860 - # to construct this function. 9.861 - # Ok, the lack of lexer is a fair price for the eval ;) 9.862 - parse_expression(); 9.863 - gloups("Garbage at the end of the expression") 9.864 - if ($pos != $length); 9.865 - $code .= "; }"; 9.866 - print STDERR "CODE = $code\n" 9.867 - if $debug{'filter'}; 9.868 - eval $code; 9.869 - die wrap_mod("po4a::po", dgettext("po4a", "Eval failure: %s"), $@) 9.870 - if $@; 9.871 - 9.872 - for (my $cpt=(0) ; 9.873 - $cpt<$self->count_entries(); 9.874 - $cpt++) { 9.875 - 9.876 - my ($msgid,$ref,$msgstr,$flags,$type,$comment,$automatic); 9.877 - 9.878 - $msgid = $self->msgid($cpt); 9.879 - $ref=$self->{po}{$msgid}{'reference'}; 9.880 - 9.881 - $msgstr= $self->{po}{$msgid}{'msgstr'}; 9.882 - $flags = $self->{po}{$msgid}{'flags'}; 9.883 - $type = $self->{po}{$msgid}{'type'}; 9.884 - $comment = $self->{po}{$msgid}{'comment'}; 9.885 - $automatic = $self->{po}{$msgid}{'automatic'}; 9.886 - 9.887 - # DO NOT CHANGE THE ORDER 9.888 - $res->push_raw('msgid' => $msgid, 9.889 - 'msgstr' => $msgstr, 9.890 - 'flags' => $flags, 9.891 - 'type' => $type, 9.892 - 'reference' => $ref, 9.893 - 'comment' => $comment, 9.894 - 'automatic' => $automatic) 9.895 - if (apply($msgid,$msgstr,$ref,$flags,$comment,$automatic)); 9.896 - } 9.897 - # delete the apply subroutine 9.898 - # otherwise it will be redefined. 9.899 - undef &apply; 9.900 - return $res; 9.901 -} 9.902 - 9.903 -=item to_utf8() 9.904 - 9.905 -Recodes to utf-8 the po's msgstrs. Does nothing if the charset is not 9.906 -specified in the po file ("CHARSET" value), or if it's already utf-8 or 9.907 -ascii. 9.908 - 9.909 -=cut 9.910 - 9.911 -sub to_utf8 { 9.912 - my $this = shift; 9.913 - my $charset = $this->get_charset(); 9.914 - 9.915 - unless ($charset eq "CHARSET" or 9.916 - $charset =~ /^ascii$/i or 9.917 - $charset =~ /^utf-8$/i) { 9.918 - foreach my $msgid ( keys %{$this->{po}} ) { 9.919 - Encode::from_to($this->{po}{$msgid}{'msgstr'}, $charset, "utf-8"); 9.920 - } 9.921 - $this->set_charset("utf-8"); 9.922 - } 9.923 -} 9.924 - 9.925 -=back 9.926 - 9.927 -=head1 Functions to use a message catalog for translations 9.928 - 9.929 -=over 4 9.930 - 9.931 -=item gettext($%) 9.932 - 9.933 -Request the translation of the string given as argument in the current catalog. 9.934 -The function returns the original (untranslated) string if the string was not 9.935 -found. 9.936 - 9.937 -After the string to translate, you can pass a hash of extra 9.938 -arguments. Here are the valid entries: 9.939 - 9.940 -=over 9.941 - 9.942 -=item wrap 9.943 - 9.944 -boolean indicating whether we can consider that whitespaces in string are 9.945 -not important. If yes, the function canonizes the string before looking for 9.946 -a translation, and wraps the result. 9.947 - 9.948 -=item wrapcol 9.949 - 9.950 -The column at which we should wrap (default: 76). 9.951 - 9.952 -=back 9.953 - 9.954 -=cut 9.955 - 9.956 -sub gettext { 9.957 - my $self=shift; 9.958 - my $text=shift; 9.959 - my (%opt)=@_; 9.960 - my $res; 9.961 - 9.962 - return "" unless defined($text) && length($text); # Avoid returning the header. 9.963 - my $validoption="reference wrap wrapcol"; 9.964 - my %validoption; 9.965 - 9.966 - map { $validoption{$_}=1 } (split(/ /,$validoption)); 9.967 - foreach (keys %opt) { 9.968 - Carp::confess "internal error: unknown arg $_.\n". 9.969 - "Here are the valid options: $validoption.\n" 9.970 - unless $validoption{$_}; 9.971 - } 9.972 - 9.973 - $text=canonize($text) 9.974 - if ($opt{'wrap'}); 9.975 - 9.976 - my $esc_text=escape_text($text); 9.977 - 9.978 - $self->{gettextqueries}++; 9.979 - 9.980 - if ( defined $self->{po}{$esc_text} 9.981 - and defined $self->{po}{$esc_text}{'msgstr'} 9.982 - and length $self->{po}{$esc_text}{'msgstr'} 9.983 - and ( not defined $self->{po}{$esc_text}{'flags'} 9.984 - or $self->{po}{$esc_text}{'flags'} !~ /fuzzy/)) { 9.985 - 9.986 - $self->{gettexthits}++; 9.987 - $res = unescape_text($self->{po}{$esc_text}{'msgstr'}); 9.988 - if (defined $self->{po}{$esc_text}{'plural'}) { 9.989 - if ($self->{po}{$esc_text}{'plural'} eq "0") { 9.990 - warn wrap_mod("po4a gettextize", dgettext("po4a", 9.991 - "'%s' is the singular form of a message, ". 9.992 - "po4a will use the msgstr[0] translation (%s)."), 9.993 - $esc_text, $res); 9.994 - } else { 9.995 - warn wrap_mod("po4a gettextize", dgettext("po4a", 9.996 - "'%s' is the plural form of a message, ". 9.997 - "po4a will use the msgstr[1] translation (%s)."), 9.998 - $esc_text, $res); 9.999 - } 9.1000 - } 9.1001 - } else { 9.1002 - $res = $text; 9.1003 - } 9.1004 - 9.1005 - if ($opt{'wrap'}) { 9.1006 - if ($self->get_charset =~ /^utf-8$/i) { 9.1007 - $res=Encode::decode_utf8($res); 9.1008 - $res=wrap ($res, $opt{'wrapcol'} || 76); 9.1009 - $res=Encode::encode_utf8($res); 9.1010 - } else { 9.1011 - $res=wrap ($res, $opt{'wrapcol'} || 76); 9.1012 - } 9.1013 - } 9.1014 -# print STDERR "Gettext >>>$text<<<(escaped=$esc_text)=[[[$res]]]\n\n"; 9.1015 - return $res; 9.1016 -} 9.1017 - 9.1018 -=item stats_get() 9.1019 - 9.1020 -Returns statistics about the hit ratio of gettext since the last time that 9.1021 -stats_clear() was called. Please note that it's not the same 9.1022 -statistics than the one printed by msgfmt --statistic. Here, it's statistics 9.1023 -about recent usage of the po file, while msgfmt reports the status of the 9.1024 -file. Example of use: 9.1025 - 9.1026 - [some use of the po file to translate stuff] 9.1027 - 9.1028 - ($percent,$hit,$queries) = $pofile->stats_get(); 9.1029 - print "So far, we found translations for $percent\% ($hit of $queries) of strings.\n"; 9.1030 - 9.1031 -=cut 9.1032 - 9.1033 -sub stats_get() { 9.1034 - my $self=shift; 9.1035 - my ($h,$q)=($self->{gettexthits},$self->{gettextqueries}); 9.1036 - my $p = ($q == 0 ? 100 : int($h/$q*10000)/100); 9.1037 - 9.1038 -# $p =~ s/\.00//; 9.1039 -# $p =~ s/(\..)0/$1/; 9.1040 - 9.1041 - return ( $p,$h,$q ); 9.1042 -} 9.1043 - 9.1044 -=item stats_clear() 9.1045 - 9.1046 -Clears the statistics about gettext hits. 9.1047 - 9.1048 -=cut 9.1049 - 9.1050 -sub stats_clear { 9.1051 - my $self = shift; 9.1052 - $self->{gettextqueries} = 0; 9.1053 - $self->{gettexthits} = 0; 9.1054 -} 9.1055 - 9.1056 -=back 9.1057 - 9.1058 -=head1 Functions to build a message catalog 9.1059 - 9.1060 -=over 4 9.1061 - 9.1062 -=item push(%) 9.1063 - 9.1064 -Push a new entry at the end of the current catalog. The arguments should 9.1065 -form a hash table. The valid keys are: 9.1066 - 9.1067 -=over 4 9.1068 - 9.1069 -=item msgid 9.1070 - 9.1071 -the string in original language. 9.1072 - 9.1073 -=item msgstr 9.1074 - 9.1075 -the translation. 9.1076 - 9.1077 -=item reference 9.1078 - 9.1079 -an indication of where this string was found. Example: file.c:46 (meaning 9.1080 -in 'file.c' at line 46). It can be a space-separated list in case of 9.1081 -multiple occurrences. 9.1082 - 9.1083 -=item comment 9.1084 - 9.1085 -a comment added here manually (by the translators). The format here is free. 9.1086 - 9.1087 -=item automatic 9.1088 - 9.1089 -a comment which was automatically added by the string extraction 9.1090 -program. See the I<--add-comments> option of the B<xgettext> program for 9.1091 -more information. 9.1092 - 9.1093 -=item flags 9.1094 - 9.1095 -space-separated list of all defined flags for this entry. 9.1096 - 9.1097 -Valid flags are: c-text, python-text, lisp-text, elisp-text, librep-text, 9.1098 -smalltalk-text, java-text, awk-text, object-pascal-text, ycp-text, 9.1099 -tcl-text, wrap, no-wrap and fuzzy. 9.1100 - 9.1101 -See the gettext documentation for their meaning. 9.1102 - 9.1103 -=item type 9.1104 - 9.1105 -This is mostly an internal argument: it is used while gettextizing 9.1106 -documents. The idea here is to parse both the original and the translation 9.1107 -into a po object, and merge them, using one's msgid as msgid and the 9.1108 -other's msgid as msgstr. To make sure that things get ok, each msgid in po 9.1109 -objects are given a type, based on their structure (like "chapt", "sect1", 9.1110 -"p" and so on in docbook). If the types of strings are not the same, that 9.1111 -means that both files do not share the same structure, and the process 9.1112 -reports an error. 9.1113 - 9.1114 -This information is written as automatic comment in the po file since this 9.1115 -gives to translators some context about the strings to translate. 9.1116 - 9.1117 -=item wrap 9.1118 - 9.1119 -boolean indicating whether whitespaces can be mangled in cosmetic 9.1120 -reformattings. If true, the string is canonized before use. 9.1121 - 9.1122 -This information is written to the po file using the 'wrap' or 'no-wrap' flag. 9.1123 - 9.1124 -=item wrapcol 9.1125 - 9.1126 -The column at which we should wrap (default: 76). 9.1127 - 9.1128 -This information is not written to the po file. 9.1129 - 9.1130 -=back 9.1131 - 9.1132 -=cut 9.1133 - 9.1134 -sub push { 9.1135 - my $self=shift; 9.1136 - my %entry=@_; 9.1137 - 9.1138 - my $validoption="wrap wrapcol type msgid msgstr automatic flags reference"; 9.1139 - my %validoption; 9.1140 - 9.1141 - map { $validoption{$_}=1 } (split(/ /,$validoption)); 9.1142 - foreach (keys %entry) { 9.1143 - Carp::confess "internal error: unknown arg $_.\n". 9.1144 - "Here are the valid options: $validoption.\n" 9.1145 - unless $validoption{$_}; 9.1146 - } 9.1147 - 9.1148 - unless ($entry{'wrap'}) { 9.1149 - $entry{'flags'} .= " no-wrap"; 9.1150 - } 9.1151 - if (defined ($entry{'msgid'})) { 9.1152 - $entry{'msgid'} = canonize($entry{'msgid'}) 9.1153 - if ($entry{'wrap'}); 9.1154 - 9.1155 - $entry{'msgid'} = escape_text($entry{'msgid'}); 9.1156 - } 9.1157 - if (defined ($entry{'msgstr'})) { 9.1158 - $entry{'msgstr'} = canonize($entry{'msgstr'}) 9.1159 - if ($entry{'wrap'}); 9.1160 - 9.1161 - $entry{'msgstr'} = escape_text($entry{'msgstr'}); 9.1162 - } 9.1163 - 9.1164 - $self->push_raw(%entry); 9.1165 -} 9.1166 - 9.1167 -# The same as push(), but assuming that msgid and msgstr are already escaped 9.1168 -sub push_raw { 9.1169 - my $self=shift; 9.1170 - my %entry=@_; 9.1171 - my ($msgid,$msgstr,$reference,$comment,$automatic,$flags,$type,$transref)= 9.1172 - ($entry{'msgid'},$entry{'msgstr'}, 9.1173 - $entry{'reference'},$entry{'comment'},$entry{'automatic'}, 9.1174 - $entry{'flags'},$entry{'type'},$entry{'transref'}); 9.1175 - my $keep_conflict = $entry{'conflict'}; 9.1176 - 9.1177 -# print STDERR "Push_raw\n"; 9.1178 -# print STDERR " msgid=>>>$msgid<<<\n" if $msgid; 9.1179 -# print STDERR " msgstr=[[[$msgstr]]]\n" if $msgstr; 9.1180 -# Carp::cluck " flags=$flags\n" if $flags; 9.1181 - 9.1182 - return unless defined($entry{'msgid'}); 9.1183 - 9.1184 - #no msgid => header definition 9.1185 - unless (length($entry{'msgid'})) { 9.1186 -# if (defined($self->{header}) && $self->{header} =~ /\S/) { 9.1187 -# warn dgettext("po4a","Redefinition of the header. ". 9.1188 -# "The old one will be discarded\n"); 9.1189 -# } FIXME: do that iff the header isn't the default one. 9.1190 - $self->{header}=$msgstr; 9.1191 - $self->{header_comment}=$comment; 9.1192 - my $charset = $self->get_charset; 9.1193 - if ($charset ne "CHARSET") { 9.1194 - $self->{encoder}=find_encoding($charset); 9.1195 - } else { 9.1196 - $self->{encoder}=find_encoding("ascii"); 9.1197 - } 9.1198 - return; 9.1199 - } 9.1200 - 9.1201 - if ($self->{options}{'porefs'} eq "none") { 9.1202 - $reference = ""; 9.1203 - } elsif ($self->{options}{'porefs'} eq "noline") { 9.1204 - $reference =~ s/:[0-9]*/:1/g; 9.1205 - } 9.1206 - 9.1207 - if (defined($self->{po}{$msgid})) { 9.1208 - warn wrap_mod("po4a::po", 9.1209 - dgettext("po4a","msgid defined twice: %s"), 9.1210 - $msgid) 9.1211 - if (0); # FIXME: put a verbose stuff 9.1212 - if ( defined $msgstr 9.1213 - and defined $self->{po}{$msgid}{'msgstr'} 9.1214 - and $self->{po}{$msgid}{'msgstr'} ne $msgstr) { 9.1215 - my $txt=quote_text($msgid); 9.1216 - my ($first,$second)= 9.1217 - (format_comment(". ",$self->{po}{$msgid}{'reference'}). 9.1218 - quote_text($self->{po}{$msgid}{'msgstr'}), 9.1219 - 9.1220 - format_comment(". ",$reference). 9.1221 - quote_text($msgstr)); 9.1222 - 9.1223 - if ($keep_conflict) { 9.1224 - if ($self->{po}{$msgid}{'msgstr'} =~ m/^#-#-#-#-# .* #-#-#-#-#\\n/s) { 9.1225 - $msgstr = $self->{po}{$msgid}{'msgstr'}. 9.1226 - "\\n#-#-#-#-# $transref #-#-#-#-#\\n". 9.1227 - $msgstr; 9.1228 - } else { 9.1229 - $msgstr = "#-#-#-#-# ". 9.1230 - $self->{po}{$msgid}{'transref'}. 9.1231 - " #-#-#-#-#\\n". 9.1232 - $self->{po}{$msgid}{'msgstr'}."\\n". 9.1233 - "#-#-#-#-# $transref #-#-#-#-#\\n". 9.1234 - $msgstr; 9.1235 - } 9.1236 - # Every msgid will have the same list of references. 9.1237 - # Only keep the last list. 9.1238 - $self->{po}{$msgid}{'reference'} = ""; 9.1239 - } else { 9.1240 - warn wrap_msg(dgettext("po4a", 9.1241 - "Translations don't match for:\n". 9.1242 - "%s\n". 9.1243 - "-->First translation:\n". 9.1244 - "%s\n". 9.1245 - " Second translation:\n". 9.1246 - "%s\n". 9.1247 - " Old translation discarded."), 9.1248 - $txt,$first,$second); 9.1249 - } 9.1250 - } 9.1251 - } 9.1252 - if (defined $transref) { 9.1253 - $self->{po}{$msgid}{'transref'} = $transref; 9.1254 - } 9.1255 - if (defined $reference) { 9.1256 - if (defined $self->{po}{$msgid}{'reference'}) { 9.1257 - $self->{po}{$msgid}{'reference'} .= " ".$reference; 9.1258 - } else { 9.1259 - $self->{po}{$msgid}{'reference'} = $reference; 9.1260 - } 9.1261 - } 9.1262 - $self->{po}{$msgid}{'msgstr'} = $msgstr; 9.1263 - $self->{po}{$msgid}{'comment'} = $comment; 9.1264 - $self->{po}{$msgid}{'automatic'} = $automatic; 9.1265 - if (defined($self->{po}{$msgid}{'pos_doc'})) { 9.1266 - $self->{po}{$msgid}{'pos_doc'} .= " ".$self->{count_doc}++; 9.1267 - } else { 9.1268 - $self->{po}{$msgid}{'pos_doc'} = $self->{count_doc}++; 9.1269 - } 9.1270 - unless (defined($self->{po}{$msgid}{'pos'})) { 9.1271 - $self->{po}{$msgid}{'pos'} = $self->{count}++; 9.1272 - } 9.1273 - $self->{po}{$msgid}{'type'} = $type; 9.1274 - $self->{po}{$msgid}{'plural'} = $entry{'plural'} 9.1275 - if defined $entry{'plural'}; 9.1276 - 9.1277 - if (defined($flags)) { 9.1278 - $flags = " $flags "; 9.1279 - $flags =~ s/,/ /g; 9.1280 - foreach my $flag (@known_flags) { 9.1281 - if ($flags =~ /\s$flag\s/) { # if flag to be set 9.1282 - unless ( defined($self->{po}{$msgid}{'flags'}) 9.1283 - && $self->{po}{$msgid}{'flags'} =~ /\b$flag\b/) { 9.1284 - # flag not already set 9.1285 - if (defined $self->{po}{$msgid}{'flags'}) { 9.1286 - $self->{po}{$msgid}{'flags'} .= " ".$flag; 9.1287 - } else { 9.1288 - $self->{po}{$msgid}{'flags'} = $flag; 9.1289 - } 9.1290 - } 9.1291 - } 9.1292 - } 9.1293 - } 9.1294 -# print STDERR "stored ((($msgid)))=>(((".$self->{po}{$msgid}{'msgstr'}.")))\n\n"; 9.1295 - 9.1296 -} 9.1297 - 9.1298 -=back 9.1299 - 9.1300 -=head1 Miscellaneous functions 9.1301 - 9.1302 -=over 4 9.1303 - 9.1304 -=item count_entries() 9.1305 - 9.1306 -Returns the number of entries in the catalog (without the header). 9.1307 - 9.1308 -=cut 9.1309 - 9.1310 -sub count_entries($) { 9.1311 - my $self=shift; 9.1312 - return $self->{count}; 9.1313 -} 9.1314 - 9.1315 -=item count_entries_doc() 9.1316 - 9.1317 -Returns the number of entries in document. If a string appears multiple times 9.1318 -in the document, it will be counted multiple times 9.1319 - 9.1320 -=cut 9.1321 - 9.1322 -sub count_entries_doc($) { 9.1323 - my $self=shift; 9.1324 - return $self->{count_doc}; 9.1325 -} 9.1326 - 9.1327 -=item msgid($) 9.1328 - 9.1329 -Returns the msgid of the given number. 9.1330 - 9.1331 -=cut 9.1332 - 9.1333 -sub msgid($$) { 9.1334 - my $self=shift; 9.1335 - my $num=shift; 9.1336 - 9.1337 - foreach my $msgid ( keys %{$self->{po}} ) { 9.1338 - return $msgid if ($self->{po}{$msgid}{'pos'} eq $num); 9.1339 - } 9.1340 - return undef; 9.1341 -} 9.1342 - 9.1343 -=item msgid_doc($) 9.1344 - 9.1345 -Returns the msgid with the given position in the document. 9.1346 - 9.1347 -=cut 9.1348 - 9.1349 -sub msgid_doc($$) { 9.1350 - my $self=shift; 9.1351 - my $num=shift; 9.1352 - 9.1353 - foreach my $msgid ( keys %{$self->{po}} ) { 9.1354 - foreach my $pos (split / /, $self->{po}{$msgid}{'pos_doc'}) { 9.1355 - return $msgid if ($pos eq $num); 9.1356 - } 9.1357 - } 9.1358 - return undef; 9.1359 -} 9.1360 - 9.1361 -=item get_charset() 9.1362 - 9.1363 -Returns the character set specified in the po header. If it hasn't been 9.1364 -set, it will return "CHARSET". 9.1365 - 9.1366 -=cut 9.1367 - 9.1368 -sub get_charset() { 9.1369 - my $self=shift; 9.1370 - 9.1371 - $self->{header} =~ /charset=(.*?)[\s\\]/; 9.1372 - 9.1373 - if (defined $1) { 9.1374 - return $1; 9.1375 - } else { 9.1376 - return "CHARSET"; 9.1377 - } 9.1378 -} 9.1379 - 9.1380 -=item set_charset($) 9.1381 - 9.1382 -This sets the character set of the po header to the value specified in its 9.1383 -first argument. If you never call this function (and no file with a specified 9.1384 -character set is read), the default value is left to "CHARSET". This value 9.1385 -doesn't change the behavior of this module, it's just used to fill that field 9.1386 -in the header, and to return it in get_charset(). 9.1387 - 9.1388 -=cut 9.1389 - 9.1390 -sub set_charset() { 9.1391 - my $self=shift; 9.1392 - 9.1393 - my ($newchar,$oldchar); 9.1394 - $newchar = shift; 9.1395 - $oldchar = $self->get_charset(); 9.1396 - 9.1397 - $self->{header} =~ s/$oldchar/$newchar/; 9.1398 - $self->{encoder}=find_encoding($newchar); 9.1399 -} 9.1400 - 9.1401 -#----[ helper functions ]--------------------------------------------------- 9.1402 - 9.1403 -# transforme the string from its po file representation to the form which 9.1404 -# should be used to print it 9.1405 -sub unescape_text { 9.1406 - my $text = shift; 9.1407 - 9.1408 - print STDERR "\nunescape [$text]====" if $debug{'escape'}; 9.1409 - $text = join("",split(/\n/,$text)); 9.1410 - $text =~ s/\\"/"/g; 9.1411 - # unescape newlines 9.1412 - # NOTE on \G: 9.1413 - # The following regular expression introduce newlines. 9.1414 - # Thus, ^ doesn't match all beginnings of lines. 9.1415 - # \G is a zero-width assertion that matches the position 9.1416 - # of the previous substitution with s///g. As every 9.1417 - # substitution ends by a newline, it always matches a 9.1418 - # position just after a newline. 9.1419 - $text =~ s/( # $1: 9.1420 - (\G|[^\\]) # beginning of the line or any char 9.1421 - # different from '\' 9.1422 - (\\\\)* # followed by any even number of '\' 9.1423 - )\\n # and followed by an escaped newline 9.1424 - /$1\n/sgx; # single string, match globally, allow comments 9.1425 - # unescape tabulations 9.1426 - $text =~ s/( # $1: 9.1427 - (\G|[^\\])# beginning of the line or any char 9.1428 - # different from '\' 9.1429 - (\\\\)* # followed by any even number of '\' 9.1430 - )\\t # and followed by an escaped tabulation 9.1431 - /$1\t/mgx; # multilines string, match globally, allow comments 9.1432 - # and unescape the escape character 9.1433 - $text =~ s/\\\\/\\/g; 9.1434 - print STDERR ">$text<\n" if $debug{'escape'}; 9.1435 - 9.1436 - return $text; 9.1437 -} 9.1438 - 9.1439 -# transform the string to its representation as it should be written in po 9.1440 -# files 9.1441 -sub escape_text { 9.1442 - my $text = shift; 9.1443 - 9.1444 - print STDERR "\nescape [$text]====" if $debug{'escape'}; 9.1445 - $text =~ s/\\/\\\\/g; 9.1446 - $text =~ s/"/\\"/g; 9.1447 - $text =~ s/\n/\\n/g; 9.1448 - $text =~ s/\t/\\t/g; 9.1449 - print STDERR ">$text<\n" if $debug{'escape'}; 9.1450 - 9.1451 - return $text; 9.1452 -} 9.1453 - 9.1454 -# put quotes around the string on each lines (without escaping it) 9.1455 -# It does also normalize the text (ie, make sure its representation is wraped 9.1456 -# on the 80th char, but without changing the meaning of the string) 9.1457 -sub quote_text { 9.1458 - my $string = shift; 9.1459 - 9.1460 - return '""' unless defined($string) && length($string); 9.1461 - 9.1462 - print STDERR "\nquote [$string]====" if $debug{'quote'}; 9.1463 - # break lines on newlines, if any 9.1464 - # see unescape_text for an explanation on \G 9.1465 - $string =~ s/( # $1: 9.1466 - (\G|[^\\]) # beginning of the line or any char 9.1467 - # different from '\' 9.1468 - (\\\\)* # followed by any even number of '\' 9.1469 - \\n) # and followed by an escaped newline 9.1470 - /$1\n/sgx; # single string, match globally, allow comments 9.1471 - $string = wrap($string); 9.1472 - my @string = split(/\n/,$string); 9.1473 - $string = join ("\"\n\"",@string); 9.1474 - $string = "\"$string\""; 9.1475 - if (scalar @string > 1 && $string[0] ne '') { 9.1476 - $string = "\"\"\n".$string; 9.1477 - } 9.1478 - 9.1479 - print STDERR ">$string<\n" if $debug{'quote'}; 9.1480 - return $string; 9.1481 -} 9.1482 - 9.1483 -# undo the work of the quote_text function 9.1484 -sub unquote_text { 9.1485 - my $string = shift; 9.1486 - print STDERR "\nunquote [$string]====" if $debug{'quote'}; 9.1487 - $string =~ s/^""\\n//s; 9.1488 - $string =~ s/^"(.*)"$/$1/s; 9.1489 - $string =~ s/"\n"//gm; 9.1490 - # Note: an even number of '\' could precede \\n, but I could not build a 9.1491 - # document to test this 9.1492 - $string =~ s/([^\\])\\n\n/$1!!DUMMYPOPM!!/gm; 9.1493 - $string =~ s|!!DUMMYPOPM!!|\\n|gm; 9.1494 - print STDERR ">$string<\n" if $debug{'quote'}; 9.1495 - return $string; 9.1496 -} 9.1497 - 9.1498 -# canonize the string: write it on only one line, changing consecutive 9.1499 -# whitespace to only one space. 9.1500 -# Warning, it changes the string and should only be called if the string is 9.1501 -# plain text 9.1502 -sub canonize { 9.1503 - my $text=shift; 9.1504 - print STDERR "\ncanonize [$text]====" if $debug{'canonize'}; 9.1505 - $text =~ s/^ *//s; 9.1506 - $text =~ s/^[ \t]+/ /gm; 9.1507 - # if ($text eq "\n"), it messed up the first string (header) 9.1508 - $text =~ s/\n/ /gm if ($text ne "\n"); 9.1509 - $text =~ s/([.)]) +/$1 /gm; 9.1510 - $text =~ s/([^.)]) */$1 /gm; 9.1511 - $text =~ s/ *$//s; 9.1512 - print STDERR ">$text<\n" if $debug{'canonize'}; 9.1513 - return $text; 9.1514 -} 9.1515 - 9.1516 -# wraps the string. We don't use Text::Wrap since it mangles whitespace at 9.1517 -# the end of splited line 9.1518 -sub wrap { 9.1519 - my $text=shift; 9.1520 - return "0" if ($text eq '0'); 9.1521 - my $col=shift || 76; 9.1522 - my @lines=split(/\n/,"$text"); 9.1523 - my $res=""; 9.1524 - my $first=1; 9.1525 - while (defined(my $line=shift @lines)) { 9.1526 - if ($first && length($line) > $col - 10) { 9.1527 - unshift @lines,$line; 9.1528 - $first=0; 9.1529 - next; 9.1530 - } 9.1531 - if (length($line) > $col) { 9.1532 - my $pos=rindex($line," ",$col); 9.1533 - while (substr($line,$pos-1,1) eq '.' && $pos != -1) { 9.1534 - $pos=rindex($line," ",$pos-1); 9.1535 - } 9.1536 - if ($pos == -1) { 9.1537 - # There are no spaces in the first $col chars, pick-up the 9.1538 - # first space 9.1539 - $pos = index($line," "); 9.1540 - } 9.1541 - if ($pos != -1) { 9.1542 - my $end=substr($line,$pos+1); 9.1543 - $line=substr($line,0,$pos+1); 9.1544 - if ($end =~ s/^( +)//) { 9.1545 - $line .= $1; 9.1546 - } 9.1547 - unshift @lines,$end; 9.1548 - } 9.1549 - } 9.1550 - $first=0; 9.1551 - $res.="$line\n"; 9.1552 - } 9.1553 - # Restore the original trailing spaces 9.1554 - $res =~ s/\s+$//s; 9.1555 - if ($text =~ m/(\s+)$/s) { 9.1556 - $res .= $1; 9.1557 - } 9.1558 - return $res; 9.1559 -} 9.1560 - 9.1561 -# outputs properly a '# ... ' line to be put in the po file 9.1562 -sub format_comment { 9.1563 - my $comment=shift; 9.1564 - my $char=shift; 9.1565 - my $result = "#". $char . $comment; 9.1566 - $result =~ s/\n/\n#$char/gs; 9.1567 - $result =~ s/^#$char$/#/gm; 9.1568 - $result .= "\n"; 9.1569 - return $result; 9.1570 -} 9.1571 - 9.1572 - 9.1573 -1; 9.1574 -__END__ 9.1575 - 9.1576 -=back 9.1577 - 9.1578 -=head1 AUTHORS 9.1579 - 9.1580 - Denis Barbier <barbier@linuxfr.org> 9.1581 - Martin Quinson (mquinson#debian.org) 9.1582 - 9.1583 -=cut
10.1 --- a/tools/po4a/lib/Locale/Po4a/TransTractor.pm Mon Mar 30 17:50:48 2009 +0800 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,1100 +0,0 @@ 10.4 -#!/usr/bin/perl -w 10.5 - 10.6 -require Exporter; 10.7 - 10.8 -package Locale::Po4a::TransTractor; 10.9 -use DynaLoader; 10.10 - 10.11 -use 5.006; 10.12 -use strict; 10.13 -use warnings; 10.14 - 10.15 -use subs qw(makespace); 10.16 -use vars qw($VERSION @ISA @EXPORT); 10.17 -$VERSION="0.36"; 10.18 -@ISA = qw(DynaLoader); 10.19 -@EXPORT = qw(new process translate 10.20 - read write readpo writepo 10.21 - getpoout setpoout); 10.22 - 10.23 -# Try to use a C extension if present. 10.24 -eval("bootstrap Locale::Po4a::TransTractor $VERSION"); 10.25 - 10.26 -use Carp qw(croak); 10.27 -use Locale::Po4a::Po; 10.28 -use Locale::Po4a::Common; 10.29 - 10.30 -use File::Path; # mkdir before write 10.31 - 10.32 -use Encode; 10.33 -use Encode::Guess; 10.34 - 10.35 -=head1 NAME 10.36 - 10.37 -Locale::Po4a::TransTractor - Generic trans(lator ex)tractor. 10.38 - 10.39 -=head1 DESCRIPTION 10.40 - 10.41 -The po4a (po for anything) project goal is to ease translations (and more 10.42 -interestingly, the maintenance of translations) using gettext tools on 10.43 -areas where they were not expected like documentation. 10.44 - 10.45 -This class is the ancestor of every po4a parsers used to parse a document to 10.46 -search translatable strings, extract them to a po file and replace them by 10.47 -their translation in the output document. 10.48 - 10.49 -More formally, it takes the following arguments as input: 10.50 - 10.51 -=over 2 10.52 - 10.53 -=item - 10.54 - 10.55 -a document to translate ; 10.56 - 10.57 -=item - 10.58 - 10.59 -a po file containing the translations to use. 10.60 - 10.61 -=back 10.62 - 10.63 -As output, it produces: 10.64 - 10.65 -=over 2 10.66 - 10.67 -=item - 10.68 - 10.69 -another po file, resulting of the extraction of translatable strings from 10.70 -the input document ; 10.71 - 10.72 -=item - 10.73 - 10.74 -a translated document, with the same structure than the one in input, but 10.75 -with all translatable strings replaced with the translations found in the 10.76 -po file provided in input. 10.77 - 10.78 -=back 10.79 - 10.80 -Here is a graphical representation of this: 10.81 - 10.82 - Input document --\ /---> Output document 10.83 - \ / (translated) 10.84 - +-> parse() function -----+ 10.85 - / \ 10.86 - Input po --------/ \---> Output po 10.87 - (extracted) 10.88 - 10.89 -=head1 FUNCTIONS YOUR PARSER SHOULD OVERRIDE 10.90 - 10.91 -=over 4 10.92 - 10.93 -=item parse() 10.94 - 10.95 -This is where all the work takes place: the parsing of input documents, the 10.96 -generation of output, and the extraction of the translatable strings. This 10.97 -is pretty simple using the provided functions presented in the section 10.98 -"INTERNAL FUNCTIONS" below. See also the synopsis, which present an 10.99 -example. 10.100 - 10.101 -This function is called by the process() function bellow, but if you choose 10.102 -to use the new() function, and to add content manually to your document, 10.103 -you will have to call this function yourself. 10.104 - 10.105 -=item docheader() 10.106 - 10.107 -This function returns the header we should add to the produced document, 10.108 -quoted properly to be a comment in the target language. See the section 10.109 -"Educating developers about translations", from L<po4a(7)|po4a.7>, for what 10.110 -it is good for. 10.111 - 10.112 -=back 10.113 - 10.114 -=cut 10.115 - 10.116 -sub docheader {} 10.117 - 10.118 -sub parse {} 10.119 - 10.120 -=head1 SYNOPSIS 10.121 - 10.122 -The following example parses a list of paragraphs beginning with "<p>". For the sake 10.123 -of simplicity, we assume that the document is well formatted, i.e. that '<p>' 10.124 -tags are the only tags present, and that this tag is at the very beginning 10.125 -of each paragraph. 10.126 - 10.127 - sub parse { 10.128 - my $self = shift; 10.129 - 10.130 - PARAGRAPH: while (1) { 10.131 - my ($paragraph,$pararef)=("",""); 10.132 - my $first=1; 10.133 - my ($line,$lref)=$self->shiftline(); 10.134 - while (defined($line)) { 10.135 - if ($line =~ m/<p>/ && !$first--; ) { 10.136 - # Not the first time we see <p>. 10.137 - # Reput the current line in input, 10.138 - # and put the built paragraph to output 10.139 - $self->unshiftline($line,$lref); 10.140 - 10.141 - # Now that the document is formed, translate it: 10.142 - # - Remove the leading tag 10.143 - $paragraph =~ s/^<p>//s; 10.144 - 10.145 - # - push to output the leading tag (untranslated) and the 10.146 - # rest of the paragraph (translated) 10.147 - $self->pushline( "<p>" 10.148 - . $document->translate($paragraph,$pararef) 10.149 - ); 10.150 - 10.151 - next PARAGRAPH; 10.152 - } else { 10.153 - # Append to the paragraph 10.154 - $paragraph .= $line; 10.155 - $pararef = $lref unless(length($pararef)); 10.156 - } 10.157 - 10.158 - # Reinit the loop 10.159 - ($line,$lref)=$self->shiftline(); 10.160 - } 10.161 - # Did not get a defined line? End of input file. 10.162 - return; 10.163 - } 10.164 - } 10.165 - 10.166 -Once you've implemented the parse function, you can use your document 10.167 -class, using the public interface presented in the next section. 10.168 - 10.169 -=head1 PUBLIC INTERFACE for scripts using your parser 10.170 - 10.171 -=head2 Constructor 10.172 - 10.173 -=over 4 10.174 - 10.175 -=item process(%) 10.176 - 10.177 -This function can do all you need to do with a po4a document in one 10.178 -invocation. Its arguments must be packed as a hash. ACTIONS: 10.179 - 10.180 -=over 3 10.181 - 10.182 -=item a. 10.183 - 10.184 -Reads all the po files specified in po_in_name 10.185 - 10.186 -=item b. 10.187 - 10.188 -Reads all original documents specified in file_in_name 10.189 - 10.190 -=item c. 10.191 - 10.192 -Parses the document 10.193 - 10.194 -=item d. 10.195 - 10.196 -Reads and applies all the addenda specified 10.197 - 10.198 -=item e. 10.199 - 10.200 -Writes the translated document to file_out_name (if given) 10.201 - 10.202 -=item f. 10.203 - 10.204 -Writes the extracted po file to po_out_name (if given) 10.205 - 10.206 -=back 10.207 - 10.208 -ARGUMENTS, beside the ones accepted by new() (with expected type): 10.209 - 10.210 -=over 4 10.211 - 10.212 -=item file_in_name (@) 10.213 - 10.214 -List of filenames where we should read the input document. 10.215 - 10.216 -=item file_in_charset ($) 10.217 - 10.218 -Charset used in the input document (if it isn't specified, it will try 10.219 -to detect it from the input document). 10.220 - 10.221 -=item file_out_name ($) 10.222 - 10.223 -Filename where we should write the output document. 10.224 - 10.225 -=item file_out_charset ($) 10.226 - 10.227 -Charset used in the output document (if it isn't specified, it will use 10.228 -the po file charset). 10.229 - 10.230 -=item po_in_name (@) 10.231 - 10.232 -List of filenames where we should read the input po files from, containing 10.233 -the translation which will be used to translate the document. 10.234 - 10.235 -=item po_out_name ($) 10.236 - 10.237 -Filename where we should write the output po file, containing the strings 10.238 -extracted from the input document. 10.239 - 10.240 -=item addendum (@) 10.241 - 10.242 -List of filenames where we should read the addenda from. 10.243 - 10.244 -=item addendum_charset ($) 10.245 - 10.246 -Charset for the addenda. 10.247 - 10.248 -=back 10.249 - 10.250 -=item new(%) 10.251 - 10.252 -Create a new Po4a document. Accepted options (but be in a hash): 10.253 - 10.254 -=over 4 10.255 - 10.256 -=item verbose ($) 10.257 - 10.258 -Sets the verbosity. 10.259 - 10.260 -=item debug ($) 10.261 - 10.262 -Sets the debugging. 10.263 - 10.264 -=back 10.265 - 10.266 -=cut 10.267 - 10.268 -sub process { 10.269 - ## Determine if we were called via an object-ref or a classname 10.270 - my $self = shift; 10.271 - 10.272 - ## Any remaining arguments are treated as initial values for the 10.273 - ## hash that is used to represent this object. 10.274 - my %params = @_; 10.275 - 10.276 - # Build the args for new() 10.277 - my %newparams = (); 10.278 - foreach (keys %params) { 10.279 - next if ($_ eq 'po_in_name' || 10.280 - $_ eq 'po_out_name' || 10.281 - $_ eq 'file_in_name' || 10.282 - $_ eq 'file_in_charset' || 10.283 - $_ eq 'file_out_name' || 10.284 - $_ eq 'file_out_charset' || 10.285 - $_ eq 'addendum' || 10.286 - $_ eq 'addendum_charset'); 10.287 - $newparams{$_}=$params{$_}; 10.288 - } 10.289 - 10.290 - $self->detected_charset($params{'file_in_charset'}); 10.291 - $self->{TT}{'file_out_charset'}=$params{'file_out_charset'}; 10.292 - if (defined($self->{TT}{'file_out_charset'}) and 10.293 - length($self->{TT}{'file_out_charset'})) { 10.294 - $self->{TT}{'file_out_encoder'} = find_encoding($self->{TT}{'file_out_charset'}); 10.295 - } 10.296 - $self->{TT}{'addendum_charset'}=$params{'addendum_charset'}; 10.297 - 10.298 - foreach my $file (@{$params{'po_in_name'}}) { 10.299 - print STDERR "readpo($file)... " if $self->debug(); 10.300 - $self->readpo($file); 10.301 - print STDERR "done.\n" if $self->debug() 10.302 - } 10.303 - foreach my $file (@{$params{'file_in_name'}}) { 10.304 - print STDERR "read($file)..." if $self->debug(); 10.305 - $self->read($file); 10.306 - print STDERR "done.\n" if $self->debug(); 10.307 - } 10.308 - print STDERR "parse..." if $self->debug(); 10.309 - $self->parse(); 10.310 - print STDERR "done.\n" if $self->debug(); 10.311 - foreach my $file (@{$params{'addendum'}}) { 10.312 - print STDERR "addendum($file)..." if $self->debug(); 10.313 - $self->addendum($file) || die "An addendum failed\n"; 10.314 - print STDERR "done.\n" if $self->debug(); 10.315 - } 10.316 - if (defined $params{'file_out_name'}) { 10.317 - print STDERR "write(".$params{'file_out_name'}.")... " 10.318 - if $self->debug(); 10.319 - $self->write($params{'file_out_name'}); 10.320 - print STDERR "done.\n" if $self->debug(); 10.321 - } 10.322 - if (defined $params{'po_out_name'}) { 10.323 - print STDERR "writepo(".$params{'po_out_name'}.")... " 10.324 - if $self->debug(); 10.325 - $self->writepo($params{'po_out_name'}); 10.326 - print STDERR "done.\n" if $self->debug(); 10.327 - } 10.328 - return $self; 10.329 -} 10.330 - 10.331 -sub new { 10.332 - ## Determine if we were called via an object-ref or a classname 10.333 - my $this = shift; 10.334 - my $class = ref($this) || $this; 10.335 - my $self = { }; 10.336 - my %options=@_; 10.337 - ## Bless ourselves into the desired class and perform any initialization 10.338 - bless $self, $class; 10.339 - 10.340 - ## initialize the plugin 10.341 - # prevent the plugin from croaking on the options intended for Po.pm 10.342 - $self->{options}{'porefs'} = ''; 10.343 - # let the plugin parse the options and such 10.344 - $self->initialize(%options); 10.345 - 10.346 - ## Create our private data 10.347 - my %po_options; 10.348 - $po_options{'porefs'} = $self->{options}{'porefs'}; 10.349 - 10.350 - # private data 10.351 - $self->{TT}=(); 10.352 - $self->{TT}{po_in}=Locale::Po4a::Po->new(); 10.353 - $self->{TT}{po_out}=Locale::Po4a::Po->new(\%po_options); 10.354 - # Warning, this is an array of array: 10.355 - # The document is splited on lines, and for each 10.356 - # [0] is the line content, [1] is the reference [2] the type 10.357 - $self->{TT}{doc_in}=(); 10.358 - $self->{TT}{doc_out}=(); 10.359 - if (defined $options{'verbose'}) { 10.360 - $self->{TT}{verbose} = $options{'verbose'}; 10.361 - } 10.362 - if (defined $options{'debug'}) { 10.363 - $self->{TT}{debug} = $options{'debug'}; 10.364 - } 10.365 - # Input document is in ascii until we prove the opposite (in read()) 10.366 - $self->{TT}{ascii_input}=1; 10.367 - # We try not to use utf unless it's forced from the outside (in case the 10.368 - # document isn't in ascii) 10.369 - $self->{TT}{utf_mode}=0; 10.370 - 10.371 - 10.372 - return $self; 10.373 -} 10.374 - 10.375 -=back 10.376 - 10.377 -=head2 Manipulating document files 10.378 - 10.379 -=over 4 10.380 - 10.381 -=item read($) 10.382 - 10.383 -Add another input document at the end of the existing one. The argument is 10.384 -the filename to read. 10.385 - 10.386 -Please note that it does not parse anything. You should use the parse() 10.387 -function when you're done with packing input files into the document. 10.388 - 10.389 -=cut 10.390 - 10.391 -#' 10.392 -sub read() { 10.393 - my $self=shift; 10.394 - my $filename=shift 10.395 - or croak wrap_msg(dgettext("po4a", "Can't read from file without having a filename")); 10.396 - my $linenum=0; 10.397 - 10.398 - open INPUT,"<$filename" 10.399 - or croak wrap_msg(dgettext("po4a", "Can't read from %s: %s"), $filename, $!); 10.400 - while (defined (my $textline = <INPUT>)) { 10.401 - $linenum++; 10.402 - my $ref="$filename:$linenum"; 10.403 - my @entry=($textline,$ref); 10.404 - push @{$self->{TT}{doc_in}}, @entry; 10.405 - 10.406 - if (!defined($self->{TT}{'file_in_charset'})) { 10.407 - # Detect if this file has non-ascii characters 10.408 - if($self->{TT}{ascii_input}) { 10.409 - my $decoder = guess_encoding($textline); 10.410 - if (!ref($decoder) or $decoder !~ /Encode::XS=/) { 10.411 - # We have detected a non-ascii line 10.412 - $self->{TT}{ascii_input} = 0; 10.413 - # Save the reference for future error message 10.414 - $self->{TT}{non_ascii_ref} ||= $ref; 10.415 - } 10.416 - } 10.417 - } 10.418 - } 10.419 - close INPUT 10.420 - or croak wrap_msg(dgettext("po4a", "Can't close %s after reading: %s"), $filename, $!); 10.421 - 10.422 -} 10.423 - 10.424 -=item write($) 10.425 - 10.426 -Write the translated document to the given filename. 10.427 - 10.428 -=cut 10.429 - 10.430 -sub write { 10.431 - my $self=shift; 10.432 - my $filename=shift 10.433 - or croak wrap_msg(dgettext("po4a", "Can't write to a file without filename")); 10.434 - 10.435 - my $fh; 10.436 - if ($filename eq '-') { 10.437 - $fh=\*STDOUT; 10.438 - } else { 10.439 - # make sure the directory in which we should write the localized file exists 10.440 - my $dir = $filename; 10.441 - if ($dir =~ m|/|) { 10.442 - $dir =~ s|/[^/]*$||; 10.443 - 10.444 - File::Path::mkpath($dir, 0, 0755) # Croaks on error 10.445 - if (length ($dir) && ! -e $dir); 10.446 - } 10.447 - open $fh,">$filename" 10.448 - or croak wrap_msg(dgettext("po4a", "Can't write to %s: %s"), $filename, $!); 10.449 - } 10.450 - 10.451 - map { print $fh $_ } $self->docheader(); 10.452 - map { print $fh $_ } @{$self->{TT}{doc_out}}; 10.453 - 10.454 - if ($filename ne '-') { 10.455 - close $fh or croak wrap_msg(dgettext("po4a", "Can't close %s after writing: %s"), $filename, $!); 10.456 - } 10.457 - 10.458 -} 10.459 - 10.460 -=back 10.461 - 10.462 -=head2 Manipulating po files 10.463 - 10.464 -=over 4 10.465 - 10.466 -=item readpo($) 10.467 - 10.468 -Add the content of a file (which name is passed in argument) to the 10.469 -existing input po. The old content is not discarded. 10.470 - 10.471 -=item writepo($) 10.472 - 10.473 -Write the extracted po file to the given filename. 10.474 - 10.475 -=item stats() 10.476 - 10.477 -Returns some statistics about the translation done so far. Please note that 10.478 -it's not the same statistics than the one printed by msgfmt 10.479 ---statistic. Here, it's stats about recent usage of the po file, while 10.480 -msgfmt reports the status of the file. It is a wrapper to the 10.481 -Locale::Po4a::Po::stats_get function applied to the input po file. Example 10.482 -of use: 10.483 - 10.484 - [normal use of the po4a document...] 10.485 - 10.486 - ($percent,$hit,$queries) = $document->stats(); 10.487 - print "We found translations for $percent\% ($hit from $queries) of strings.\n"; 10.488 - 10.489 -=back 10.490 - 10.491 -=cut 10.492 - 10.493 -sub getpoout { 10.494 - return $_[0]->{TT}{po_out}; 10.495 -} 10.496 -sub setpoout { 10.497 - $_[0]->{TT}{po_out} = $_[1]; 10.498 -} 10.499 -sub readpo { 10.500 - $_[0]->{TT}{po_in}->read($_[1]); 10.501 -} 10.502 -sub writepo { 10.503 - $_[0]->{TT}{po_out}->write( $_[1] ); 10.504 -} 10.505 -sub stats { 10.506 - return $_[0]->{TT}{po_in}->stats_get(); 10.507 -} 10.508 - 10.509 -=head2 Manipulating addenda 10.510 - 10.511 -=over 4 10.512 - 10.513 -=item addendum($) 10.514 - 10.515 -Please refer to L<po4a(7)|po4a.7> for more information on what addenda are, 10.516 -and how translators should write them. To apply an addendum to the translated 10.517 -document, simply pass its filename to this function and you are done ;) 10.518 - 10.519 -This function returns a non-null integer on error. 10.520 - 10.521 -=cut 10.522 - 10.523 -# Internal function to read the header. 10.524 -sub addendum_parse { 10.525 - my ($filename,$header)=shift; 10.526 - 10.527 - my ($errcode,$mode,$position,$boundary,$bmode,$content)= 10.528 - (1,"","","","",""); 10.529 - 10.530 - unless (open (INS, "<$filename")) { 10.531 - warn wrap_msg(dgettext("po4a", "Can't read from %s: %s"), $filename, $!); 10.532 - goto END_PARSE_ADDFILE; 10.533 - } 10.534 - 10.535 - unless (defined ($header=<INS>) && $header) { 10.536 - warn wrap_msg(dgettext("po4a", "Can't read Po4a header from %s."), $filename); 10.537 - goto END_PARSE_ADDFILE; 10.538 - } 10.539 - 10.540 - unless ($header =~ s/PO4A-HEADER://i) { 10.541 - warn wrap_msg(dgettext("po4a", "First line of %s does not look like a Po4a header."), $filename); 10.542 - goto END_PARSE_ADDFILE; 10.543 - } 10.544 - foreach my $part (split(/;/,$header)) { 10.545 - unless ($part =~ m/^\s*([^=]*)=(.*)$/) { 10.546 - warn wrap_msg(dgettext("po4a", "Syntax error in Po4a header of %s, near \"%s\""), $filename, $part); 10.547 - goto END_PARSE_ADDFILE; 10.548 - } 10.549 - my ($key,$value)=($1,$2); 10.550 - $key=lc($key); 10.551 - if ($key eq 'mode') { $mode=lc($value); 10.552 - } elsif ($key eq 'position') { $position=$value; 10.553 - } elsif ($key eq 'endboundary') { 10.554 - $boundary=$value; 10.555 - $bmode='after'; 10.556 - } elsif ($key eq 'beginboundary') { 10.557 - $boundary=$value; 10.558 - $bmode='before'; 10.559 - } else { 10.560 - warn wrap_msg(dgettext("po4a", "Invalid argument in the Po4a header of %s: %s"), $filename, $key); 10.561 - goto END_PARSE_ADDFILE; 10.562 - } 10.563 - } 10.564 - 10.565 - unless (length($mode)) { 10.566 - warn wrap_msg(dgettext("po4a", "The Po4a header of %s does not define the mode."), $filename); 10.567 - goto END_PARSE_ADDFILE; 10.568 - } 10.569 - unless ($mode eq "before" || $mode eq "after") { 10.570 - warn wrap_msg(dgettext("po4a", "Mode invalid in the Po4a header of %s: should be 'before' or 'after' not %s."), $filename, $mode); 10.571 - goto END_PARSE_ADDFILE; 10.572 - } 10.573 - 10.574 - unless (length($position)) { 10.575 - warn wrap_msg(dgettext("po4a", "The Po4a header of %s does not define the position."), $filename); 10.576 - goto END_PARSE_ADDFILE; 10.577 - } 10.578 - unless ($mode eq "before" || length($boundary)) { 10.579 - warn wrap_msg(dgettext("po4a", "No ending boundary given in the Po4a header, but mode=after.")); 10.580 - goto END_PARSE_ADDFILE; 10.581 - } 10.582 - 10.583 - while (defined(my $line = <INS>)) { 10.584 - $content .= $line; 10.585 - } 10.586 - close INS; 10.587 - 10.588 - $errcode=0; 10.589 - END_PARSE_ADDFILE: 10.590 - return ($errcode,$mode,$position,$boundary,$bmode,$content); 10.591 -} 10.592 - 10.593 -sub mychomp { 10.594 - my ($str) = shift; 10.595 - chomp($str); 10.596 - return $str; 10.597 -} 10.598 - 10.599 -sub addendum { 10.600 - my ($self,$filename) = @_; 10.601 - 10.602 - print STDERR "Apply addendum $filename..." if $self->debug(); 10.603 - unless ($filename) { 10.604 - warn wrap_msg(dgettext("po4a", 10.605 - "Can't apply addendum when not given the filename")); 10.606 - return 0; 10.607 - } 10.608 - die wrap_msg(dgettext("po4a", "Addendum %s does not exist."), $filename) 10.609 - unless -e $filename; 10.610 - 10.611 - my ($errcode,$mode,$position,$boundary,$bmode,$content)= 10.612 - addendum_parse($filename); 10.613 - return 0 if ($errcode); 10.614 - 10.615 - print STDERR "mode=$mode;pos=$position;bound=$boundary;bmode=$bmode;ctn=$content\n" 10.616 - if $self->debug(); 10.617 - 10.618 - # We only recode the addendum if an origin charset is specified, else we 10.619 - # suppose it's already in the output document's charset 10.620 - if (defined($self->{TT}{'addendum_charset'}) && 10.621 - length($self->{TT}{'addendum_charset'})) { 10.622 - Encode::from_to($content,$self->{TT}{'addendum_charset'}, 10.623 - $self->get_out_charset); 10.624 - } 10.625 - 10.626 - my $found = scalar grep { /$position/ } @{$self->{TT}{doc_out}}; 10.627 - if ($found == 0) { 10.628 - warn wrap_msg(dgettext("po4a", 10.629 - "No candidate position for the addendum %s."), $filename); 10.630 - return 0; 10.631 - } 10.632 - if ($found > 1) { 10.633 - warn wrap_msg(dgettext("po4a", 10.634 - "More than one candidate position found for the addendum %s."), $filename); 10.635 - return 0; 10.636 - } 10.637 - 10.638 - if ($mode eq "before") { 10.639 - if ($self->verbose() > 1 || $self->debug() ) { 10.640 - map { print STDERR wrap_msg(dgettext("po4a", "Addendum '%s' applied before this line: %s"), $filename, $_) if (/$position/); 10.641 - } @{$self->{TT}{doc_out}}; 10.642 - } 10.643 - @{$self->{TT}{doc_out}} = map { /$position/ ? ($content,$_) : $_ 10.644 - } @{$self->{TT}{doc_out}}; 10.645 - } else { 10.646 - my @newres=(); 10.647 - 10.648 - do { 10.649 - # make sure it doesnt whine on empty document 10.650 - my $line = scalar @{$self->{TT}{doc_out}} ? shift @{$self->{TT}{doc_out}} : ""; 10.651 - push @newres,$line; 10.652 - my $outline=mychomp($line); 10.653 - $outline =~ s/^[ \t]*//; 10.654 - 10.655 - if ($line =~ m/$position/) { 10.656 - while ($line=shift @{$self->{TT}{doc_out}}) { 10.657 - last if ($line=~/$boundary/); 10.658 - push @newres,$line; 10.659 - } 10.660 - if (defined $line) { 10.661 - if ($bmode eq 'before') { 10.662 - print wrap_msg(dgettext("po4a", 10.663 - "Addendum '%s' applied before this line: %s"), 10.664 - $filename, $outline) 10.665 - if ($self->verbose() > 1 || $self->debug()); 10.666 - push @newres,$content; 10.667 - push @newres,$line; 10.668 - } else { 10.669 - print wrap_msg(dgettext("po4a", 10.670 - "Addendum '%s' applied after the line: %s."), 10.671 - $filename, $outline) 10.672 - if ($self->verbose() > 1 || $self->debug()); 10.673 - push @newres,$line; 10.674 - push @newres,$content; 10.675 - } 10.676 - } else { 10.677 - print wrap_msg(dgettext("po4a", "Addendum '%s' applied at the end of the file."), $filename) 10.678 - if ($self->verbose() > 1 || $self->debug()); 10.679 - push @newres,$content; 10.680 - } 10.681 - } 10.682 - } while (scalar @{$self->{TT}{doc_out}}); 10.683 - @{$self->{TT}{doc_out}} = @newres; 10.684 - } 10.685 - print STDERR "done.\n" if $self->debug(); 10.686 - return 1; 10.687 -} 10.688 - 10.689 -=back 10.690 - 10.691 -=head1 INTERNAL FUNCTIONS used to write derivated parsers 10.692 - 10.693 -=head2 Getting input, providing output 10.694 - 10.695 -Four functions are provided to get input and return output. They are very 10.696 -similar to shift/unshift and push/pop. The first pair is about input, while 10.697 -the second is about output. Mnemonic: in input, you are interested in the 10.698 -first line, what shift gives, and in output you want to add your result at 10.699 -the end, like push does. 10.700 - 10.701 -=over 4 10.702 - 10.703 -=item shiftline() 10.704 - 10.705 -This function returns the next line of the doc_in to be parsed and its 10.706 -reference (packed as an array). 10.707 - 10.708 -=item unshiftline($$) 10.709 - 10.710 -Unshifts a line of the input document and its reference. 10.711 - 10.712 -=item pushline($) 10.713 - 10.714 -Push a new line to the doc_out. 10.715 - 10.716 -=item popline() 10.717 - 10.718 -Pop the last pushed line from the doc_out. 10.719 - 10.720 -=back 10.721 - 10.722 -=cut 10.723 - 10.724 -sub shiftline { 10.725 - my ($line,$ref)=(shift @{$_[0]->{TT}{doc_in}}, 10.726 - shift @{$_[0]->{TT}{doc_in}}); 10.727 - return ($line,$ref); 10.728 -} 10.729 -sub unshiftline { 10.730 - my $self = shift; 10.731 - unshift @{$self->{TT}{doc_in}},@_; 10.732 -} 10.733 - 10.734 -sub pushline { push @{$_[0]->{TT}{doc_out}}, $_[1] if defined $_[1]; } 10.735 -sub popline { return pop @{$_[0]->{TT}{doc_out}}; } 10.736 - 10.737 -=head2 Marking strings as translatable 10.738 - 10.739 -One function is provided to handle the text which should be translated. 10.740 - 10.741 -=over 4 10.742 - 10.743 -=item translate($$$) 10.744 - 10.745 -Mandatory arguments: 10.746 - 10.747 -=over 2 10.748 - 10.749 -=item - 10.750 - 10.751 -A string to translate 10.752 - 10.753 -=item - 10.754 - 10.755 -The reference of this string (ie, position in inputfile) 10.756 - 10.757 -=item - 10.758 - 10.759 -The type of this string (ie, the textual description of its structural role 10.760 -; used in Locale::Po4a::Po::gettextization() ; see also L<po4a(7)|po4a.7>, 10.761 -section I<Gettextization: how does it work?>) 10.762 - 10.763 -=back 10.764 - 10.765 -This function can also take some extra arguments. They must be organized as 10.766 -a hash. For example: 10.767 - 10.768 - $self->translate("string","ref","type", 10.769 - 'wrap' => 1); 10.770 - 10.771 -=over 10.772 - 10.773 -=item wrap 10.774 - 10.775 -boolean indicating whether we can consider that whitespaces in string are 10.776 -not important. If yes, the function canonizes the string before looking for 10.777 -a translation or extracting it, and wraps the translation. 10.778 - 10.779 -=item wrapcol 10.780 - 10.781 -The column at which we should wrap (default: 76). 10.782 - 10.783 -=item comment 10.784 - 10.785 -An extra comment to add to the entry. 10.786 - 10.787 -=back 10.788 - 10.789 -Actions: 10.790 - 10.791 -=over 2 10.792 - 10.793 -=item - 10.794 - 10.795 -Pushes the string, reference and type to po_out. 10.796 - 10.797 -=item - 10.798 - 10.799 -Returns the translation of the string (as found in po_in) so that the 10.800 -parser can build the doc_out. 10.801 - 10.802 -=item - 10.803 - 10.804 -Handles the charsets to recode the strings before sending them to 10.805 -po_out and before returning the translations. 10.806 - 10.807 -=back 10.808 - 10.809 -=back 10.810 - 10.811 -=cut 10.812 - 10.813 -sub translate { 10.814 - my $self=shift; 10.815 - my ($string,$ref,$type)=(shift,shift,shift); 10.816 - my (%options)=@_; 10.817 - 10.818 - # my $validoption="wrap wrapcol"; 10.819 - # my %validoption; 10.820 - 10.821 - return "" unless defined($string) && length($string); 10.822 - 10.823 - # map { $validoption{$_}=1 } (split(/ /,$validoption)); 10.824 - # foreach (keys %options) { 10.825 - # Carp::confess "internal error: translate() called with unknown arg $_. Valid options: $validoption" 10.826 - # unless $validoption{$_}; 10.827 - # } 10.828 - 10.829 - my $in_charset; 10.830 - if ($self->{TT}{ascii_input}) { 10.831 - $in_charset = "ascii"; 10.832 - } else { 10.833 - if (defined($self->{TT}{'file_in_charset'}) and 10.834 - length($self->{TT}{'file_in_charset'}) and 10.835 - $self->{TT}{'file_in_charset'} !~ m/ascii/i) { 10.836 - $in_charset=$self->{TT}{'file_in_charset'}; 10.837 - } else { 10.838 - # FYI, the document charset have to be determined *before* we see the first 10.839 - # string to recode. 10.840 - die wrap_mod("po4a", dgettext("po4a", "Couldn't determine the input document's charset. Please specify it on the command line. (non-ascii char at %s)"), $self->{TT}{non_ascii_ref}) 10.841 - } 10.842 - } 10.843 - 10.844 - if ($self->{TT}{po_in}->get_charset ne "CHARSET") { 10.845 - $string = encode_from_to($string, 10.846 - $self->{TT}{'file_in_encoder'}, 10.847 - $self->{TT}{po_in}{encoder}); 10.848 - } 10.849 - 10.850 - if (defined $options{'wrapcol'} && $options{'wrapcol'} < 0) { 10.851 -# FIXME: should be the parameter given with --width 10.852 - $options{'wrapcol'} = 76 + $options{'wrapcol'}; 10.853 - } 10.854 - my $transstring = $self->{TT}{po_in}->gettext($string, 10.855 - 'wrap' => $options{'wrap'}||0, 10.856 - 'wrapcol' => $options{'wrapcol'}); 10.857 - 10.858 - if ($self->{TT}{po_in}->get_charset ne "CHARSET") { 10.859 - my $out_encoder = $self->{TT}{'file_out_encoder'}; 10.860 - unless (defined $out_encoder) { 10.861 - $out_encoder = find_encoding($self->get_out_charset) 10.862 - } 10.863 - $transstring = encode_from_to($transstring, 10.864 - $self->{TT}{po_in}{encoder}, 10.865 - $out_encoder); 10.866 - } 10.867 - 10.868 - # If the input document isn't completely in ascii, we should see what to 10.869 - # do with the current string 10.870 - unless ($self->{TT}{ascii_input}) { 10.871 - my $out_charset = $self->{TT}{po_out}->get_charset; 10.872 - # We set the output po charset 10.873 - if ($out_charset eq "CHARSET") { 10.874 - if ($self->{TT}{utf_mode}) { 10.875 - $out_charset="utf-8"; 10.876 - } else { 10.877 - $out_charset=$in_charset; 10.878 - } 10.879 - $self->{TT}{po_out}->set_charset($out_charset); 10.880 - } 10.881 - if ( $in_charset !~ /^$out_charset$/i ) { 10.882 - Encode::from_to($string,$in_charset,$out_charset); 10.883 - if (defined($options{'comment'}) and length($options{'comment'})) { 10.884 - Encode::from_to($options{'comment'},$in_charset,$out_charset); 10.885 - } 10.886 - } 10.887 - } 10.888 - 10.889 - # the comments provided by the modules are automatic comments from the PO point of view 10.890 - $self->{TT}{po_out}->push('msgid' => $string, 10.891 - 'reference' => $ref, 10.892 - 'type' => $type, 10.893 - 'automatic' => $options{'comment'}, 10.894 - 'wrap' => $options{'wrap'}||0, 10.895 - 'wrapcol' => $options{'wrapcol'}); 10.896 - 10.897 -# if ($self->{TT}{po_in}->get_charset ne "CHARSET") { 10.898 -# Encode::from_to($transstring,$self->{TT}{po_in}->get_charset, 10.899 -# $self->get_out_charset); 10.900 -# } 10.901 - 10.902 - if ($options{'wrap'}||0) { 10.903 - $transstring =~ s/( *)$//s; 10.904 - my $trailing_spaces = $1||""; 10.905 - $transstring =~ s/ *$//gm; 10.906 - $transstring .= $trailing_spaces; 10.907 - } 10.908 - 10.909 - return $transstring; 10.910 -} 10.911 - 10.912 -=head2 Misc functions 10.913 - 10.914 -=over 4 10.915 - 10.916 -=item verbose() 10.917 - 10.918 -Returns if the verbose option was passed during the creation of the 10.919 -TransTractor. 10.920 - 10.921 -=cut 10.922 - 10.923 -sub verbose { 10.924 - if (defined $_[1]) { 10.925 - $_[0]->{TT}{verbose} = $_[1]; 10.926 - } else { 10.927 - return $_[0]->{TT}{verbose} || 0; # undef and 0 have the same meaning, but one generates warnings 10.928 - } 10.929 -} 10.930 - 10.931 -=item debug() 10.932 - 10.933 -Returns if the debug option was passed during the creation of the 10.934 -TransTractor. 10.935 - 10.936 -=cut 10.937 - 10.938 -sub debug { 10.939 - return $_[0]->{TT}{debug}; 10.940 -} 10.941 - 10.942 -=item detected_charset($) 10.943 - 10.944 -This tells TransTractor that a new charset (the first argument) has been 10.945 -detected from the input document. It can usually be read from the document 10.946 -header. Only the first charset will remain, coming either from the 10.947 -process() arguments or detected from the document. 10.948 - 10.949 -=cut 10.950 - 10.951 -sub detected_charset { 10.952 - my ($self,$charset)=(shift,shift); 10.953 - unless (defined($self->{TT}{'file_in_charset'}) and 10.954 - length($self->{TT}{'file_in_charset'}) ) { 10.955 - $self->{TT}{'file_in_charset'}=$charset; 10.956 - if (defined $charset) { 10.957 - $self->{TT}{'file_in_encoder'}=find_encoding($charset); 10.958 - } 10.959 - } 10.960 - 10.961 - if (defined $self->{TT}{'file_in_charset'} and 10.962 - length $self->{TT}{'file_in_charset'} and 10.963 - $self->{TT}{'file_in_charset'} !~ m/ascii/i) { 10.964 - $self->{TT}{ascii_input}=0; 10.965 - } 10.966 -} 10.967 - 10.968 -=item get_out_charset() 10.969 - 10.970 -This function will return the charset that should be used in the output 10.971 -document (usually useful to substitute the input document's detected charset 10.972 -where it has been found). 10.973 - 10.974 -It will use the output charset specified in the command line. If it wasn't 10.975 -specified, it will use the input po's charset, and if the input po has the 10.976 -default "CHARSET", it will return the input document's charset, so that no 10.977 -encoding is performed. 10.978 - 10.979 -=cut 10.980 - 10.981 -sub get_out_charset { 10.982 - my $self=shift; 10.983 - my $charset; 10.984 - 10.985 - # Use the value specified at the command line 10.986 - if (defined($self->{TT}{'file_out_charset'}) and 10.987 - length($self->{TT}{'file_out_charset'})) { 10.988 - $charset=$self->{TT}{'file_out_charset'}; 10.989 - } else { 10.990 - if ($self->{TT}{utf_mode} && $self->{TT}{ascii_input}) { 10.991 - $charset="utf-8"; 10.992 - } else { 10.993 - $charset=$self->{TT}{po_in}->get_charset; 10.994 - $charset=$self->{TT}{'file_in_charset'} 10.995 - if $charset eq "CHARSET" and 10.996 - defined($self->{TT}{'file_in_charset'}) and 10.997 - length($self->{TT}{'file_in_charset'}); 10.998 - $charset="ascii" 10.999 - if $charset eq "CHARSET"; 10.1000 - } 10.1001 - } 10.1002 - return $charset; 10.1003 -} 10.1004 - 10.1005 -=item recode_skipped_text($) 10.1006 - 10.1007 -This function returns the recoded text passed as argument, from the input 10.1008 -document's charset to the output document's one. This isn't needed when 10.1009 -translating a string (translate() recodes everything itself), but it is when 10.1010 -you skip a string from the input document and you want the output document to 10.1011 -be consistent with the global encoding. 10.1012 - 10.1013 -=cut 10.1014 - 10.1015 -sub recode_skipped_text { 10.1016 - my ($self,$text)=(shift,shift); 10.1017 - unless ($self->{TT}{'ascii_input'}) { 10.1018 - if(defined($self->{TT}{'file_in_charset'}) and 10.1019 - length($self->{TT}{'file_in_charset'}) ) { 10.1020 - $text = encode_from_to($text, 10.1021 - $self->{TT}{'file_in_encoder'}, 10.1022 - find_encoding($self->get_out_charset)); 10.1023 - } else { 10.1024 - die wrap_mod("po4a", dgettext("po4a", "Couldn't determine the input document's charset. Please specify it on the command line. (non-ascii char at %s)"), $self->{TT}{non_ascii_ref}) 10.1025 - } 10.1026 - } 10.1027 - return $text; 10.1028 -} 10.1029 - 10.1030 - 10.1031 -# encode_from_to($,$,$) 10.1032 -# 10.1033 -# Encode the given text from one encoding to another one. 10.1034 -# It differs from Encode::from_to because it does not take the name of the 10.1035 -# encoding in argument, but the encoders (as returned by the 10.1036 -# Encode::find_encoding(<name>) method). Thus it permits to save a bunch 10.1037 -# of call to find_encoding. 10.1038 -# 10.1039 -# If the "from" encoding is undefined, it is considered as UTF-8 (or 10.1040 -# ascii). 10.1041 -# If the "to" encoding is undefined, it is considered as UTF-8. 10.1042 -# 10.1043 -sub encode_from_to { 10.1044 - my ($text,$from,$to) = (shift,shift,shift); 10.1045 - 10.1046 - if (not defined $from) { 10.1047 - # for ascii and UTF-8, no conversion needed to get an utf-8 10.1048 - # string. 10.1049 - } else { 10.1050 - $text = $from->decode($text, 0); 10.1051 - } 10.1052 - 10.1053 - if (not defined $to) { 10.1054 - # Already in UTF-8, no conversion needed 10.1055 - } else { 10.1056 - $text = $to->encode($text, 0); 10.1057 - } 10.1058 - 10.1059 - return $text; 10.1060 -} 10.1061 - 10.1062 -=back 10.1063 - 10.1064 -=head1 FUTURE DIRECTIONS 10.1065 - 10.1066 -One shortcoming of the current TransTractor is that it can't handle 10.1067 -translated document containing all languages, like debconf templates, or 10.1068 -.desktop files. 10.1069 - 10.1070 -To address this problem, the only interface changes needed are: 10.1071 - 10.1072 -=over 2 10.1073 - 10.1074 -=item - 10.1075 - 10.1076 -take a hash as po_in_name (a list per language) 10.1077 - 10.1078 -=item - 10.1079 - 10.1080 -add an argument to translate to indicate the target language 10.1081 - 10.1082 -=item - 10.1083 - 10.1084 -make a pushline_all function, which would make pushline of its content for 10.1085 -all language, using a map-like syntax: 10.1086 - 10.1087 - $self->pushline_all({ "Description[".$langcode."]=". 10.1088 - $self->translate($line,$ref,$langcode) 10.1089 - }); 10.1090 - 10.1091 -=back 10.1092 - 10.1093 -Will see if it's enough ;) 10.1094 - 10.1095 -=head1 AUTHORS 10.1096 - 10.1097 - Denis Barbier <barbier@linuxfr.org> 10.1098 - Martin Quinson (mquinson#debian.org) 10.1099 - Jordi Vilalta <jvprat@gmail.com> 10.1100 - 10.1101 -=cut 10.1102 - 10.1103 -1;
11.1 --- a/tools/po4a/lib/Locale/Po4a/Xml.pm Mon Mar 30 17:50:48 2009 +0800 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,1973 +0,0 @@ 11.4 -#!/usr/bin/perl 11.5 - 11.6 -# Po4a::Xml.pm 11.7 -# 11.8 -# extract and translate translatable strings from XML documents. 11.9 -# 11.10 -# This code extracts plain text from tags and attributes from generic 11.11 -# XML documents, and it can be used as a base to build modules for 11.12 -# XML-based documents. 11.13 -# 11.14 -# Copyright (c) 2004 by Jordi Vilalta <jvprat@gmail.com> 11.15 -# Copyright (c) 2008-2009 by Nicolas François <nicolas.francois@centraliens.net> 11.16 -# 11.17 -# This program is free software; you can redistribute it and/or modify 11.18 -# it under the terms of the GNU General Public License as published by 11.19 -# the Free Software Foundation; either version 2 of the License, or 11.20 -# (at your option) any later version. 11.21 -# 11.22 -# This program is distributed in the hope that it will be useful, 11.23 -# but WITHOUT ANY WARRANTY; without even the implied warranty of 11.24 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.25 -# GNU General Public License for more details. 11.26 -# 11.27 -# You should have received a copy of the GNU General Public License 11.28 -# along with this program; if not, write to the Free Software 11.29 -# Foundation, Inc., 11.30 -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 11.31 -# 11.32 -######################################################################## 11.33 - 11.34 -=head1 NAME 11.35 - 11.36 -Locale::Po4a::Xml - Convert XML documents and derivates from/to PO files 11.37 - 11.38 -=head1 DESCRIPTION 11.39 - 11.40 -The po4a (po for anything) project goal is to ease translations (and more 11.41 -interestingly, the maintenance of translations) using gettext tools on 11.42 -areas where they were not expected like documentation. 11.43 - 11.44 -Locale::Po4a::Xml is a module to help the translation of XML documents into 11.45 -other [human] languages. It can also be used as a base to build modules for 11.46 -XML-based documents. 11.47 - 11.48 -=cut 11.49 - 11.50 -package Locale::Po4a::Xml; 11.51 - 11.52 -use 5.006; 11.53 -use strict; 11.54 -use warnings; 11.55 - 11.56 -require Exporter; 11.57 -use vars qw(@ISA @EXPORT); 11.58 -@ISA = qw(Locale::Po4a::TransTractor); 11.59 -@EXPORT = qw(new initialize @tag_types); 11.60 - 11.61 -use Locale::Po4a::TransTractor; 11.62 -use Locale::Po4a::Common; 11.63 -use Carp qw(croak); 11.64 -use File::Basename; 11.65 -use File::Spec; 11.66 - 11.67 -#It will mantain the path from the root tag to the current one 11.68 -my @path; 11.69 - 11.70 -#It will contain a list of external entities and their attached paths 11.71 -my %entities; 11.72 - 11.73 -my @comments; 11.74 - 11.75 -sub shiftline { 11.76 - my $self = shift; 11.77 - # call Transtractor's shiftline 11.78 - my ($line,$ref) = $self->SUPER::shiftline(); 11.79 - return ($line,$ref) if (not defined $line); 11.80 - 11.81 - for my $k (keys %entities) { 11.82 - if ($line =~ m/^(.*?)&$k;(.*)$/s) { 11.83 - my ($before, $after) = ($1, $2); 11.84 - my $linenum=0; 11.85 - my @textentries; 11.86 - 11.87 - open (my $in, $entities{$k}) 11.88 - or croak wrap_mod("po4a::xml", 11.89 - dgettext("po4a", "Can't read from %s: %s"), 11.90 - $entities{$k}, $!); 11.91 - while (defined (my $textline = <$in>)) { 11.92 - $linenum++; 11.93 - my $textref=$entities{$k}.":$linenum"; 11.94 - push @textentries, ($textline,$textref); 11.95 - } 11.96 - close $in 11.97 - or croak wrap_mod("po4a::xml", 11.98 - dgettext("po4a", "Can't close %s after reading: %s"), 11.99 - $entities{$k}, $!); 11.100 - 11.101 - push @textentries, ($after, $ref); 11.102 - $line = $before.(shift @textentries); 11.103 - $ref .= " ".(shift @textentries); 11.104 - $self->unshiftline(@textentries); 11.105 - } 11.106 - } 11.107 - 11.108 - return ($line,$ref); 11.109 -} 11.110 - 11.111 -sub read { 11.112 - my ($self,$filename)=@_; 11.113 - push @{$self->{DOCPOD}{infile}}, $filename; 11.114 - $self->Locale::Po4a::TransTractor::read($filename); 11.115 -} 11.116 - 11.117 -sub parse { 11.118 - my $self=shift; 11.119 - map {$self->parse_file($_)} @{$self->{DOCPOD}{infile}}; 11.120 -} 11.121 - 11.122 -# @save_holders is a stack of references to ('paragraph', 'translation', 11.123 -# 'sub_translations', 'open', 'close', 'folded_attributes') hashes, where: 11.124 -# paragraph is a reference to an array (see paragraph in the 11.125 -# treat_content() subroutine) of strings followed by 11.126 -# references. It contains the @paragraph array as it was 11.127 -# before the processing was interrupted by a tag instroducing 11.128 -# a placeholder. 11.129 -# translation is the translation of this level up to now 11.130 -# sub_translations is a reference to an array of strings containing the 11.131 -# translations which must replace the placeholders. 11.132 -# open is the tag which opened the placeholder. 11.133 -# close is the tag which closed the placeholder. 11.134 -# folded_attributes is an hash of tags with their attributes (<tag attrs=...> 11.135 -# strings), referenced by the folded tag id, which should 11.136 -# replace the <tag po4a-id=id> strings in the current 11.137 -# translation. 11.138 -# 11.139 -# If @save_holders only has 1 holder, then we are not processing the 11.140 -# content of an holder, we are translating the document. 11.141 -my @save_holders; 11.142 - 11.143 - 11.144 -# If we are at the bottom of the stack and there is no <placeholder ...> in 11.145 -# the current translation, we can push the translation in the translated 11.146 -# document. 11.147 -# Otherwise, we keep the translation in the current holder. 11.148 -sub pushline { 11.149 - my ($self, $line) = (shift, shift); 11.150 - 11.151 - my $holder = $save_holders[$#save_holders]; 11.152 - my $translation = $holder->{'translation'}; 11.153 - $translation .= $line; 11.154 - 11.155 - while ( %{$holder->{folded_attributes}} 11.156 - and $translation =~ m/^(.*)<([^>]+?)\s+po4a-id=([0-9]+)>(.*)$/s) { 11.157 - my $begin = $1; 11.158 - my $tag = $2; 11.159 - my $id = $3; 11.160 - my $end = $4; 11.161 - if (defined $holder->{folded_attributes}->{$id}) { 11.162 - # TODO: check if the tag is the same 11.163 - $translation = $begin.$holder->{folded_attributes}->{$id}.$end; 11.164 - delete $holder->{folded_attributes}->{$id}; 11.165 - } else { 11.166 - # TODO: It will be hard to identify the location. 11.167 - # => find a way to retrieve the reference. 11.168 - die wrap_mod("po4a::xml", dgettext("po4a", "'po4a-id=%d' in the translation does not exist in the original string (or 'po4a-id=%d' used twice in the translation)."), $id, $id); 11.169 - } 11.170 - } 11.171 -# TODO: check that %folded_attributes is empty at some time 11.172 -# => in translate_paragraph? 11.173 - 11.174 - if ( ($#save_holders > 0) 11.175 - or ($translation =~ m/<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>/s)) { 11.176 - $holder->{'translation'} = $translation; 11.177 - } else { 11.178 - $self->SUPER::pushline($translation); 11.179 - $holder->{'translation'} = ''; 11.180 - } 11.181 -} 11.182 - 11.183 -=head1 TRANSLATING WITH PO4A::XML 11.184 - 11.185 -This module can be used directly to handle generic XML documents. This will 11.186 -extract all tag's content, and no attributes, since it's where the text is 11.187 -written in most XML based documents. 11.188 - 11.189 -There are some options (described in the next section) that can customize 11.190 -this behavior. If this doesn't fit to your document format you're encouraged 11.191 -to write your own module derived from this, to describe your format's details. 11.192 -See the section "Writing derivate modules" below, for the process description. 11.193 - 11.194 -=cut 11.195 - 11.196 -# 11.197 -# Parse file and translate it 11.198 -# 11.199 -sub parse_file { 11.200 - my ($self,$filename) = @_; 11.201 - my $eof = 0; 11.202 - 11.203 - while (!$eof) { 11.204 - # We get all the text until the next breaking tag (not 11.205 - # inline) and translate it 11.206 - $eof = $self->treat_content; 11.207 - if (!$eof) { 11.208 - # And then we treat the following breaking tag 11.209 - $eof = $self->treat_tag; 11.210 - } 11.211 - } 11.212 -} 11.213 - 11.214 -=head1 OPTIONS ACCEPTED BY THIS MODULE 11.215 - 11.216 -The global debug option causes this module to show the excluded strings, in 11.217 -order to see if it skips something important. 11.218 - 11.219 -These are this module's particular options: 11.220 - 11.221 -=over 4 11.222 - 11.223 -=item B<nostrip> 11.224 - 11.225 -Prevents it to strip the spaces around the extracted strings. 11.226 - 11.227 -=item B<wrap> 11.228 - 11.229 -Canonizes the string to translate, considering that whitespaces are not 11.230 -important, and wraps the translated document. This option can be overridden 11.231 -by custom tag options. See the "tags" option below. 11.232 - 11.233 -=item B<caseinsensitive> 11.234 - 11.235 -It makes the tags and attributes searching to work in a case insensitive 11.236 -way. If it's defined, it will treat E<lt>BooKE<gt>laNG and E<lt>BOOKE<gt>Lang as E<lt>bookE<gt>lang. 11.237 - 11.238 -=item B<includeexternal> 11.239 - 11.240 -When defined, external entities are included in the generated (translated) 11.241 -document, and for the extraction of strings. If it's not defined, you 11.242 -will have to translate external entities separately as independent 11.243 -documents. 11.244 - 11.245 -=item B<ontagerror> 11.246 - 11.247 -This option defines the behavior of the module when it encounter a invalid 11.248 -Xml syntax (a closing tag which does not match the last opening tag, or a 11.249 -tag's attribute without value). 11.250 -It can take the following values: 11.251 - 11.252 -=over 11.253 - 11.254 -=item I<fail> 11.255 - 11.256 -This is the default value. 11.257 -The module will exit with an error. 11.258 - 11.259 -=item I<warn> 11.260 - 11.261 -The module will continue, and will issue a warning. 11.262 - 11.263 -=item I<silent> 11.264 - 11.265 -The module will continue without any warnings. 11.266 - 11.267 -=back 11.268 - 11.269 -Be careful when using this option. 11.270 -It is generally recommended to fix the input file. 11.271 - 11.272 -=item B<tagsonly> 11.273 - 11.274 -Extracts only the specified tags in the "tags" option. Otherwise, it 11.275 -will extract all the tags except the ones specified. 11.276 - 11.277 -Note: This option is deprecated. 11.278 - 11.279 -=item B<doctype> 11.280 - 11.281 -String that will try to match with the first line of the document's doctype 11.282 -(if defined). If it doesn't, a warning will indicate that the document 11.283 -might be of a bad type. 11.284 - 11.285 -=item B<tags> 11.286 - 11.287 -Space-separated list of tags you want to translate or skip. By default, 11.288 -the specified tags will be excluded, but if you use the "tagsonly" option, 11.289 -the specified tags will be the only ones included. The tags must be in the 11.290 -form E<lt>aaaE<gt>, but you can join some (E<lt>bbbE<gt>E<lt>aaaE<gt>) to say that the content of 11.291 -the tag E<lt>aaaE<gt> will only be translated when it's into a E<lt>bbbE<gt> tag. 11.292 - 11.293 -You can also specify some tag options putting some characters in front of 11.294 -the tag hierarchy. For example, you can put 'w' (wrap) or 'W' (don't wrap) 11.295 -to override the default behavior specified by the global "wrap" option. 11.296 - 11.297 -Example: WE<lt>chapterE<gt>E<lt>titleE<gt> 11.298 - 11.299 -Note: This option is deprecated. 11.300 -You should use the B<translated> and B<untranslated> options instead. 11.301 - 11.302 -=item B<attributes> 11.303 - 11.304 -Space-separated list of tag's attributes you want to translate. You can 11.305 -specify the attributes by their name (for example, "lang"), but you can 11.306 -prefix it with a tag hierarchy, to specify that this attribute will only be 11.307 -translated when it's into the specified tag. For example: E<lt>bbbE<gt>E<lt>aaaE<gt>lang 11.308 -specifies that the lang attribute will only be translated if it's into an 11.309 -E<lt>aaaE<gt> tag, and it's into a E<lt>bbbE<gt> tag. 11.310 - 11.311 -=item B<foldattributes> 11.312 - 11.313 -Do not translate attributes in inline tags. 11.314 -Instead, replace all attributes of a tag by po4a-id=<id>. 11.315 - 11.316 -This is useful when attributes shall not be translated, as this simplifies the 11.317 -strings for translators, and avoids typos. 11.318 - 11.319 -=item B<break> 11.320 - 11.321 -Space-separated list of tags which should break the sequence. 11.322 -By default, all tags break the sequence. 11.323 - 11.324 -The tags must be in the form <aaa>, but you can join some 11.325 -(<bbb><aaa>), if a tag (<aaa>) should only be considered 11.326 -when it's into another tag (<bbb>). 11.327 - 11.328 -=item B<inline> 11.329 - 11.330 -Space-separated list of tags which should be treated as inline. 11.331 -By default, all tags break the sequence. 11.332 - 11.333 -The tags must be in the form <aaa>, but you can join some 11.334 -(<bbb><aaa>), if a tag (<aaa>) should only be considered 11.335 -when it's into another tag (<bbb>). 11.336 - 11.337 -=item B<placeholder> 11.338 - 11.339 -Space-separated list of tags which should be treated as placeholders. 11.340 -Placeholders do not break the sequence, but the content of placeholders is 11.341 -translated separately. 11.342 - 11.343 -The location of the placeholder in its blocks will be marked with a string 11.344 -similar to: 11.345 - 11.346 - <placeholder type=\"footnote\" id=\"0\"/> 11.347 - 11.348 -The tags must be in the form <aaa>, but you can join some 11.349 -(<bbb><aaa>), if a tag (<aaa>) should only be considered 11.350 -when it's into another tag (<bbb>). 11.351 - 11.352 -=item B<nodefault> 11.353 - 11.354 -Space separated list of tags that the module should not try to set by 11.355 -default in any category. 11.356 - 11.357 -=item B<cpp> 11.358 - 11.359 -Support C preprocessor directives. 11.360 -When this option is set, po4a will consider preprocessor directives as 11.361 -paragraph separators. 11.362 -This is important if the XML file must be preprocessed because otherwise 11.363 -the directives may be inserted in the middle of lines if po4a consider it 11.364 -belong to the current paragraph, and they won't be recognized by the 11.365 -preprocessor. 11.366 -Note: the preprocessor directives must only appear between tags 11.367 -(they must not break a tag). 11.368 - 11.369 -=item B<translated> 11.370 - 11.371 -Space-separated list of tags you want to translate. 11.372 - 11.373 -The tags must be in the form <aaa>, but you can join some 11.374 -(<bbb><aaa>), if a tag (<aaa>) should only be considered 11.375 -when it's into another tag (<bbb>). 11.376 - 11.377 -You can also specify some tag options putting some characters in front of 11.378 -the tag hierarchy. For example, you can put 'w' (wrap) or 'W' (don't wrap) 11.379 -to overide the default behavior specified by the global "wrap" option. 11.380 - 11.381 -Example: WE<lt>chapterE<gt>E<lt>titleE<gt> 11.382 - 11.383 -=item B<untranslated> 11.384 - 11.385 -Space-separated list of tags you do not want to translate. 11.386 - 11.387 -The tags must be in the form <aaa>, but you can join some 11.388 -(<bbb><aaa>), if a tag (<aaa>) should only be considered 11.389 -when it's into another tag (<bbb>). 11.390 - 11.391 -=item B<defaulttranslateoption> 11.392 - 11.393 -The default categories for tags that are not in any of the translated, 11.394 -untranslated, break, inline, or placeholder. 11.395 - 11.396 -This is a set of letters: 11.397 - 11.398 -=over 11.399 - 11.400 -=item I<w> 11.401 - 11.402 -Tags should be translated and content can be re-wrapped. 11.403 - 11.404 -=item I<W> 11.405 - 11.406 -Tags should be translated and content should not be re-wrapped. 11.407 - 11.408 -=item I<i> 11.409 - 11.410 -Tags should be translated inline. 11.411 - 11.412 -=item I<p> 11.413 - 11.414 -Tags should be translated as placeholders. 11.415 - 11.416 -=back 11.417 - 11.418 -=back 11.419 - 11.420 -=cut 11.421 -# TODO: defaulttranslateoption 11.422 -# w => indicate that it is only valid for translatable tags and do not 11.423 -# care about inline/break/placeholder? 11.424 -# ... 11.425 - 11.426 -sub initialize { 11.427 - my $self = shift; 11.428 - my %options = @_; 11.429 - 11.430 - # Reset the path 11.431 - @path = (); 11.432 - 11.433 - # Initialize the stack of holders 11.434 - my @paragraph = (); 11.435 - my @sub_translations = (); 11.436 - my %folded_attributes; 11.437 - my %holder = ('paragraph' => \@paragraph, 11.438 - 'translation' => "", 11.439 - 'sub_translations' => \@sub_translations, 11.440 - 'folded_attributes' => \%folded_attributes); 11.441 - @save_holders = (\%holder); 11.442 - 11.443 - $self->{options}{'nostrip'}=0; 11.444 - $self->{options}{'wrap'}=0; 11.445 - $self->{options}{'caseinsensitive'}=0; 11.446 - $self->{options}{'tagsonly'}=0; 11.447 - $self->{options}{'tags'}=''; 11.448 - $self->{options}{'break'}=''; 11.449 - $self->{options}{'translated'}=''; 11.450 - $self->{options}{'untranslated'}=''; 11.451 - $self->{options}{'defaulttranslateoption'}=''; 11.452 - $self->{options}{'attributes'}=''; 11.453 - $self->{options}{'foldattributes'}=0; 11.454 - $self->{options}{'inline'}=''; 11.455 - $self->{options}{'placeholder'}=''; 11.456 - $self->{options}{'doctype'}=''; 11.457 - $self->{options}{'nodefault'}=''; 11.458 - $self->{options}{'includeexternal'}=0; 11.459 - $self->{options}{'ontagerror'}="fail"; 11.460 - $self->{options}{'cpp'}=0; 11.461 - 11.462 - $self->{options}{'verbose'}=''; 11.463 - $self->{options}{'debug'}=''; 11.464 - 11.465 - foreach my $opt (keys %options) { 11.466 - if ($options{$opt}) { 11.467 - die wrap_mod("po4a::xml", 11.468 - dgettext("po4a", "Unknown option: %s"), $opt) 11.469 - unless exists $self->{options}{$opt}; 11.470 - $self->{options}{$opt} = $options{$opt}; 11.471 - } 11.472 - } 11.473 - # Default options set by modules. Forbidden for users. 11.474 - $self->{options}{'_default_translated'}=''; 11.475 - $self->{options}{'_default_untranslated'}=''; 11.476 - $self->{options}{'_default_break'}=''; 11.477 - $self->{options}{'_default_inline'}=''; 11.478 - $self->{options}{'_default_placeholder'}=''; 11.479 - $self->{options}{'_default_attributes'}=''; 11.480 - 11.481 - #It will maintain the list of the translatable tags 11.482 - $self->{tags}=(); 11.483 - $self->{translated}=(); 11.484 - $self->{untranslated}=(); 11.485 - #It will maintain the list of the translatable attributes 11.486 - $self->{attributes}=(); 11.487 - #It will maintain the list of the breaking tags 11.488 - $self->{break}=(); 11.489 - #It will maintain the list of the inline tags 11.490 - $self->{inline}=(); 11.491 - #It will maintain the list of the placeholder tags 11.492 - $self->{placeholder}=(); 11.493 - #list of the tags that must not be set in the tags or inline category 11.494 - #by this module or sub-module (unless specified in an option) 11.495 - $self->{nodefault}=(); 11.496 - 11.497 - $self->treat_options; 11.498 -} 11.499 - 11.500 -=head1 WRITING DERIVATE MODULES 11.501 - 11.502 -=head2 DEFINE WHAT TAGS AND ATTRIBUTES TO TRANSLATE 11.503 - 11.504 -The simplest customization is to define which tags and attributes you want 11.505 -the parser to translate. This should be done in the initialize function. 11.506 -First you should call the main initialize, to get the command-line options, 11.507 -and then, append your custom definitions to the options hash. If you want 11.508 -to treat some new options from command line, you should define them before 11.509 -calling the main initialize: 11.510 - 11.511 - $self->{options}{'new_option'}=''; 11.512 - $self->SUPER::initialize(%options); 11.513 - $self->{options}{'_default_translated'}.=' <p> <head><title>'; 11.514 - $self->{options}{'attributes'}.=' <p>lang id'; 11.515 - $self->{options}{'_default_inline'}.=' <br>'; 11.516 - $self->treat_options; 11.517 - 11.518 -You should use the B<_default_inline>, B<_default_break>, 11.519 -B<_default_placeholder>, B<_default_translated>, B<_default_untranslated>, 11.520 -and B<_default_attributes> options in derivated modules. This allow users 11.521 -to override the default behavior defined in your module with command line 11.522 -options. 11.523 - 11.524 -=head2 OVERRIDING THE found_string FUNCTION 11.525 - 11.526 -Another simple step is to override the function "found_string", which 11.527 -receives the extracted strings from the parser, in order to translate them. 11.528 -There you can control which strings you want to translate, and perform 11.529 -transformations to them before or after the translation itself. 11.530 - 11.531 -It receives the extracted text, the reference on where it was, and a hash 11.532 -that contains extra information to control what strings to translate, how 11.533 -to translate them and to generate the comment. 11.534 - 11.535 -The content of these options depends on the kind of string it is (specified in an 11.536 -entry of this hash): 11.537 - 11.538 -=over 11.539 - 11.540 -=item type="tag" 11.541 - 11.542 -The found string is the content of a translatable tag. The entry "tag_options" 11.543 -contains the option characters in front of the tag hierarchy in the module 11.544 -"tags" option. 11.545 - 11.546 -=item type="attribute" 11.547 - 11.548 -Means that the found string is the value of a translatable attribute. The 11.549 -entry "attribute" has the name of the attribute. 11.550 - 11.551 -=back 11.552 - 11.553 -It must return the text that will replace the original in the translated 11.554 -document. Here's a basic example of this function: 11.555 - 11.556 - sub found_string { 11.557 - my ($self,$text,$ref,$options)=@_; 11.558 - $text = $self->translate($text,$ref,"type ".$options->{'type'}, 11.559 - 'wrap'=>$self->{options}{'wrap'}); 11.560 - return $text; 11.561 - } 11.562 - 11.563 -There's another simple example in the new Dia module, which only filters 11.564 -some strings. 11.565 - 11.566 -=cut 11.567 - 11.568 -sub found_string { 11.569 - my ($self,$text,$ref,$options)=@_; 11.570 - 11.571 - if ($text =~ m/^\s*$/s) { 11.572 - return $text; 11.573 - } 11.574 - 11.575 - my $comment; 11.576 - my $wrap = $self->{options}{'wrap'}; 11.577 - 11.578 - if ($options->{'type'} eq "tag") { 11.579 - $comment = "Content of: ".$self->get_path; 11.580 - 11.581 - if($options->{'tag_options'} =~ /w/) { 11.582 - $wrap = 1; 11.583 - } 11.584 - if($options->{'tag_options'} =~ /W/) { 11.585 - $wrap = 0; 11.586 - } 11.587 - } elsif ($options->{'type'} eq "attribute") { 11.588 - $comment = "Attribute '".$options->{'attribute'}."' of: ".$self->get_path; 11.589 - } elsif ($options->{'type'} eq "CDATA") { 11.590 - $comment = "CDATA"; 11.591 - $wrap = 0; 11.592 - } else { 11.593 - die wrap_ref_mod($ref, "po4a::xml", dgettext("po4a", "Internal error: unknown type identifier '%s'."), $options->{'type'}); 11.594 - } 11.595 - $text = $self->translate($text,$ref,$comment,'wrap'=>$wrap, comment => $options->{'comments'}); 11.596 - return $text; 11.597 -} 11.598 - 11.599 -=head2 MODIFYING TAG TYPES (TODO) 11.600 - 11.601 -This is a more complex one, but it enables a (almost) total customization. 11.602 -It's based in a list of hashes, each one defining a tag type's behavior. The 11.603 -list should be sorted so that the most general tags are after the most 11.604 -concrete ones (sorted first by the beginning and then by the end keys). To 11.605 -define a tag type you'll have to make a hash with the following keys: 11.606 - 11.607 -=over 4 11.608 - 11.609 -=item beginning 11.610 - 11.611 -Specifies the beginning of the tag, after the "E<lt>". 11.612 - 11.613 -=item end 11.614 - 11.615 -Specifies the end of the tag, before the "E<gt>". 11.616 - 11.617 -=item breaking 11.618 - 11.619 -It says if this is a breaking tag class. A non-breaking (inline) tag is one 11.620 -that can be taken as part of the content of another tag. It can take the 11.621 -values false (0), true (1) or undefined. If you leave this undefined, you'll 11.622 -have to define the f_breaking function that will say whether a concrete tag of 11.623 -this class is a breaking tag or not. 11.624 - 11.625 -=item f_breaking 11.626 - 11.627 -It's a function that will tell if the next tag is a breaking one or not. It 11.628 -should be defined if the "breaking" option is not. 11.629 - 11.630 -=item f_extract 11.631 - 11.632 -If you leave this key undefined, the generic extraction function will have to 11.633 -extract the tag itself. It's useful for tags that can have other tags or 11.634 -special structures in them, so that the main parser doesn't get mad. This 11.635 -function receives a boolean that says if the tag should be removed from the 11.636 -input stream or not. 11.637 - 11.638 -=item f_translate 11.639 - 11.640 -This function receives the tag (in the get_string_until() format) and returns 11.641 -the translated tag (translated attributes or all needed transformations) as a 11.642 -single string. 11.643 - 11.644 -=back 11.645 - 11.646 -=cut 11.647 - 11.648 -##### Generic XML tag types #####' 11.649 - 11.650 -our @tag_types = ( 11.651 - { beginning => "!--#", 11.652 - end => "--", 11.653 - breaking => 0, 11.654 - f_extract => \&tag_extract_comment, 11.655 - f_translate => \&tag_trans_comment}, 11.656 - { beginning => "!--", 11.657 - end => "--", 11.658 - breaking => 0, 11.659 - f_extract => \&tag_extract_comment, 11.660 - f_translate => \&tag_trans_comment}, 11.661 - { beginning => "?xml", 11.662 - end => "?", 11.663 - breaking => 1, 11.664 - f_translate => \&tag_trans_xmlhead}, 11.665 - { beginning => "?", 11.666 - end => "?", 11.667 - breaking => 1, 11.668 - f_translate => \&tag_trans_procins}, 11.669 - { beginning => "!DOCTYPE", 11.670 - end => "", 11.671 - breaking => 1, 11.672 - f_extract => \&tag_extract_doctype, 11.673 - f_translate => \&tag_trans_doctype}, 11.674 - { beginning => "![CDATA[", 11.675 - end => "", 11.676 - breaking => 1, 11.677 - f_extract => \&CDATA_extract, 11.678 - f_translate => \&CDATA_trans}, 11.679 - { beginning => "/", 11.680 - end => "", 11.681 - f_breaking => \&tag_break_close, 11.682 - f_translate => \&tag_trans_close}, 11.683 - { beginning => "", 11.684 - end => "/", 11.685 - f_breaking => \&tag_break_alone, 11.686 - f_translate => \&tag_trans_alone}, 11.687 - { beginning => "", 11.688 - end => "", 11.689 - f_breaking => \&tag_break_open, 11.690 - f_translate => \&tag_trans_open} 11.691 -); 11.692 - 11.693 -sub tag_extract_comment { 11.694 - my ($self,$remove)=(shift,shift); 11.695 - my ($eof,@tag)=$self->get_string_until('-->',{include=>1,remove=>$remove}); 11.696 - return ($eof,@tag); 11.697 -} 11.698 - 11.699 -sub tag_trans_comment { 11.700 - my ($self,@tag)=@_; 11.701 - return $self->join_lines(@tag); 11.702 -} 11.703 - 11.704 -sub tag_trans_xmlhead { 11.705 - my ($self,@tag)=@_; 11.706 - 11.707 - # We don't have to translate anything from here: throw away references 11.708 - my $tag = $self->join_lines(@tag); 11.709 - $tag =~ /encoding=(("|')|)(.*?)(\s|\2)/s; 11.710 - my $in_charset=$3; 11.711 - $self->detected_charset($in_charset); 11.712 - my $out_charset=$self->get_out_charset; 11.713 - 11.714 - if (defined $in_charset) { 11.715 - $tag =~ s/$in_charset/$out_charset/; 11.716 - } else { 11.717 - if ($tag =~ m/standalone/) { 11.718 - $tag =~ s/(standalone)/encoding="$out_charset" $1/; 11.719 - } else { 11.720 - $tag.= " encoding=\"$out_charset\""; 11.721 - } 11.722 - } 11.723 - 11.724 - return $tag; 11.725 -} 11.726 - 11.727 -sub tag_trans_procins { 11.728 - my ($self,@tag)=@_; 11.729 - return $self->join_lines(@tag); 11.730 -} 11.731 - 11.732 -sub tag_extract_doctype { 11.733 - my ($self,$remove)=(shift,shift); 11.734 - 11.735 - # Check if there is an internal subset (between []). 11.736 - my ($eof,@tag)=$self->get_string_until('>',{include=>1,unquoted=>1}); 11.737 - my $parity = 0; 11.738 - my $paragraph = ""; 11.739 - map { $parity = 1 - $parity; $paragraph.= $parity?$_:""; } @tag; 11.740 - my $found = 0; 11.741 - if ($paragraph =~ m/<.*\[.*</s) { 11.742 - $found = 1 11.743 - } 11.744 - 11.745 - if (not $found) { 11.746 - ($eof,@tag)=$self->get_string_until('>',{include=>1,remove=>$remove,unquoted=>1}); 11.747 - } else { 11.748 - ($eof,@tag)=$self->get_string_until(']\s*>',{include=>1,remove=>$remove,unquoted=>1,regex=>1}); 11.749 - } 11.750 - return ($eof,@tag); 11.751 -} 11.752 - 11.753 -sub tag_trans_doctype { 11.754 -# This check is not really reliable. There are system and public 11.755 -# identifiers. Only the public one could be checked reliably. 11.756 - my ($self,@tag)=@_; 11.757 - if (defined $self->{options}{'doctype'} ) { 11.758 - my $doctype = $self->{options}{'doctype'}; 11.759 - if ( $tag[0] !~ /\Q$doctype\E/i ) { 11.760 - warn wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Bad document type. '%s' expected. You can fix this warning with a -o doctype option, or ignore this check with -o doctype=\"\"."), $doctype); 11.761 - } 11.762 - } 11.763 - my $i = 0; 11.764 - my $basedir = $tag[1]; 11.765 - $basedir =~ s/:[0-9]+$//; 11.766 - $basedir = dirname($basedir); 11.767 - 11.768 - while ( $i < $#tag ) { 11.769 - my $t = $tag[$i]; 11.770 - my $ref = $tag[$i+1]; 11.771 - if ( $t =~ /^(\s*<!ENTITY\s+)(.*)$/is ) { 11.772 - my $part1 = $1; 11.773 - my $part2 = $2; 11.774 - my $includenow = 0; 11.775 - my $file = 0; 11.776 - my $name = ""; 11.777 - if ($part2 =~ /^(%\s+)(.*)$/s ) { 11.778 - $part1.= $1; 11.779 - $part2 = $2; 11.780 - $includenow = 1; 11.781 - } 11.782 - $part2 =~ /^(\S+)(\s+)(.*)$/s; 11.783 - $name = $1; 11.784 - $part1.= $1.$2; 11.785 - $part2 = $3; 11.786 - if ( $part2 =~ /^(SYSTEM\s+)(.*)$/is ) { 11.787 - $part1.= $1; 11.788 - $part2 = $2; 11.789 - $file = 1; 11.790 - if ($self->{options}{'includeexternal'}) { 11.791 - $entities{$name} = $part2; 11.792 - $entities{$name} =~ s/^"?(.*?)".*$/$1/s; 11.793 - $entities{$name} = File::Spec->catfile($basedir, $entities{$name}); 11.794 - } 11.795 - } 11.796 - if ((not $file) and (not $includenow)) { 11.797 - if ($part2 =~ m/^\s*(["'])(.*)\1(\s*>.*)$/s) { 11.798 - my $comment = "Content of the $name entity"; 11.799 - my $quote = $1; 11.800 - my $text = $2; 11.801 - $part2 = $3; 11.802 - $text = $self->translate($text, 11.803 - $ref, 11.804 - $comment, 11.805 - 'wrap'=>1); 11.806 - $t = $part1."$quote$text$quote$part2"; 11.807 - } 11.808 - } 11.809 -# print $part1."\n"; 11.810 -# print $name."\n"; 11.811 -# print $part2."\n"; 11.812 - } 11.813 - $tag[$i] = $t; 11.814 - $i += 2; 11.815 - } 11.816 - return $self->join_lines(@tag); 11.817 -} 11.818 - 11.819 -sub tag_break_close { 11.820 - my ($self,@tag)=@_; 11.821 - my $struct = $self->get_path; 11.822 - my $options = $self->get_translate_options($struct); 11.823 - if ($options =~ m/[ip]/) { 11.824 - return 0; 11.825 - } else { 11.826 - return 1; 11.827 - } 11.828 -} 11.829 - 11.830 -sub tag_trans_close { 11.831 - my ($self,@tag)=@_; 11.832 - my $name = $self->get_tag_name(@tag); 11.833 - 11.834 - my $test = pop @path; 11.835 - if (!defined($test) || $test ne $name ) { 11.836 - my $ontagerror = $self->{options}{'ontagerror'}; 11.837 - if ($ontagerror eq "warn") { 11.838 - warn wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong. Continuing..."), $name); 11.839 - } elsif ($ontagerror ne "silent") { 11.840 - die wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong."), $name); 11.841 - } 11.842 - } 11.843 - return $self->join_lines(@tag); 11.844 -} 11.845 - 11.846 -sub CDATA_extract { 11.847 - my ($self,$remove)=(shift,shift); 11.848 - my ($eof, @tag) = $self->get_string_until(']]>',{include=>1,unquoted=>0,remove=>$remove}); 11.849 - 11.850 - return ($eof, @tag); 11.851 -} 11.852 - 11.853 -sub CDATA_trans { 11.854 - my ($self,@tag)=@_; 11.855 - return $self->found_string($self->join_lines(@tag), 11.856 - $tag[1], 11.857 - {'type' => "CDATA"}); 11.858 -} 11.859 - 11.860 -sub tag_break_alone { 11.861 - my ($self,@tag)=@_; 11.862 - my $struct = $self->get_path($self->get_tag_name(@tag)); 11.863 - if ($self->get_translate_options($struct) =~ m/i/) { 11.864 - return 0; 11.865 - } else { 11.866 - return 1; 11.867 - } 11.868 -} 11.869 - 11.870 -sub tag_trans_alone { 11.871 - my ($self,@tag)=@_; 11.872 - my $name = $self->get_tag_name(@tag); 11.873 - push @path, $name; 11.874 - 11.875 - $name = $self->treat_attributes(@tag); 11.876 - 11.877 - pop @path; 11.878 - return $name; 11.879 -} 11.880 - 11.881 -sub tag_break_open { 11.882 - my ($self,@tag)=@_; 11.883 - my $struct = $self->get_path($self->get_tag_name(@tag)); 11.884 - my $options = $self->get_translate_options($struct); 11.885 - if ($options =~ m/[ip]/) { 11.886 - return 0; 11.887 - } else { 11.888 - return 1; 11.889 - } 11.890 -} 11.891 - 11.892 -sub tag_trans_open { 11.893 - my ($self,@tag)=@_; 11.894 - my $name = $self->get_tag_name(@tag); 11.895 - push @path, $name; 11.896 - 11.897 - $name = $self->treat_attributes(@tag); 11.898 - 11.899 - return $name; 11.900 -} 11.901 - 11.902 -##### END of Generic XML tag types ##### 11.903 - 11.904 -=head1 INTERNAL FUNCTIONS used to write derivated parsers 11.905 - 11.906 -=head2 WORKING WITH TAGS 11.907 - 11.908 -=over 4 11.909 - 11.910 -=item get_path() 11.911 - 11.912 -This function returns the path to the current tag from the document's root, 11.913 -in the form E<lt>htmlE<gt>E<lt>bodyE<gt>E<lt>pE<gt>. 11.914 - 11.915 -An additional array of tags (without brackets) can be passed in argument. 11.916 -These path elements are added to the end of the current path. 11.917 - 11.918 -=cut 11.919 - 11.920 -sub get_path { 11.921 - my $self = shift; 11.922 - my @add = @_; 11.923 - if ( @path > 0 or @add > 0 ) { 11.924 - return "<".join("><",@path,@add).">"; 11.925 - } else { 11.926 - return "outside any tag (error?)"; 11.927 - } 11.928 -} 11.929 - 11.930 -=item tag_type() 11.931 - 11.932 -This function returns the index from the tag_types list that fits to the next 11.933 -tag in the input stream, or -1 if it's at the end of the input file. 11.934 - 11.935 -=cut 11.936 - 11.937 -sub tag_type { 11.938 - my $self = shift; 11.939 - my ($line,$ref) = $self->shiftline(); 11.940 - my ($match1,$match2); 11.941 - my $found = 0; 11.942 - my $i = 0; 11.943 - 11.944 - if (!defined($line)) { return -1; } 11.945 - 11.946 - $self->unshiftline($line,$ref); 11.947 - my ($eof,@lines) = $self->get_string_until(">",{include=>1,unquoted=>1}); 11.948 - my $line2 = $self->join_lines(@lines); 11.949 - while (!$found && $i < @tag_types) { 11.950 - ($match1,$match2) = ($tag_types[$i]->{beginning},$tag_types[$i]->{end}); 11.951 - if ($line =~ /^<\Q$match1\E/) { 11.952 - if (!defined($tag_types[$i]->{f_extract})) { 11.953 -#print substr($line2,length($line2)-1-length($match2),1+length($match2))."\n"; 11.954 - if (defined($line2) and $line2 =~ /\Q$match2\E>$/) { 11.955 - $found = 1; 11.956 -#print "YES: <".$match1." ".$match2.">\n"; 11.957 - } else { 11.958 -#print "NO: <".$match1." ".$match2.">\n"; 11.959 - $i++; 11.960 - } 11.961 - } else { 11.962 - $found = 1; 11.963 - } 11.964 - } else { 11.965 - $i++; 11.966 - } 11.967 - } 11.968 - if (!$found) { 11.969 - #It should never enter here, unless you undefine the most 11.970 - #general tags (as <...>) 11.971 - die "po4a::xml: Unknown tag type: ".$line."\n"; 11.972 - } else { 11.973 - return $i; 11.974 - } 11.975 -} 11.976 - 11.977 -=item extract_tag($$) 11.978 - 11.979 -This function returns the next tag from the input stream without the beginning 11.980 -and end, in an array form, to maintain the references from the input file. It 11.981 -has two parameters: the type of the tag (as returned by tag_type) and a 11.982 -boolean, that indicates if it should be removed from the input stream. 11.983 - 11.984 -=cut 11.985 - 11.986 -sub extract_tag { 11.987 - my ($self,$type,$remove) = (shift,shift,shift); 11.988 - my ($match1,$match2) = ($tag_types[$type]->{beginning},$tag_types[$type]->{end}); 11.989 - my ($eof,@tag); 11.990 - if (defined($tag_types[$type]->{f_extract})) { 11.991 - ($eof,@tag) = &{$tag_types[$type]->{f_extract}}($self,$remove); 11.992 - } else { 11.993 - ($eof,@tag) = $self->get_string_until($match2.">",{include=>1,remove=>$remove,unquoted=>1}); 11.994 - } 11.995 - $tag[0] =~ /^<\Q$match1\E(.*)$/s; 11.996 - $tag[0] = $1; 11.997 - $tag[$#tag-1] =~ /^(.*)\Q$match2\E>$/s; 11.998 - $tag[$#tag-1] = $1; 11.999 - return ($eof,@tag); 11.1000 -} 11.1001 - 11.1002 -=item get_tag_name(@) 11.1003 - 11.1004 -This function returns the name of the tag passed as an argument, in the array 11.1005 -form returned by extract_tag. 11.1006 - 11.1007 -=cut 11.1008 - 11.1009 -sub get_tag_name { 11.1010 - my ($self,@tag)=@_; 11.1011 - $tag[0] =~ /^(\S*)/; 11.1012 - return $1; 11.1013 -} 11.1014 - 11.1015 -=item breaking_tag() 11.1016 - 11.1017 -This function returns a boolean that says if the next tag in the input stream 11.1018 -is a breaking tag or not (inline tag). It leaves the input stream intact. 11.1019 - 11.1020 -=cut 11.1021 - 11.1022 -sub breaking_tag { 11.1023 - my $self = shift; 11.1024 - my $break; 11.1025 - 11.1026 - my $type = $self->tag_type; 11.1027 - if ($type == -1) { return 0; } 11.1028 - 11.1029 -#print "TAG TYPE = ".$type."\n"; 11.1030 - $break = $tag_types[$type]->{breaking}; 11.1031 - if (!defined($break)) { 11.1032 - # This tag's breaking depends on its content 11.1033 - my ($eof,@lines) = $self->extract_tag($type,0); 11.1034 - $break = &{$tag_types[$type]->{f_breaking}}($self,@lines); 11.1035 - } 11.1036 -#print "break = ".$break."\n"; 11.1037 - return $break; 11.1038 -} 11.1039 - 11.1040 -=item treat_tag() 11.1041 - 11.1042 -This function translates the next tag from the input stream. Using each 11.1043 -tag type's custom translation functions. 11.1044 - 11.1045 -=cut 11.1046 - 11.1047 -sub treat_tag { 11.1048 - my $self = shift; 11.1049 - my $type = $self->tag_type; 11.1050 - 11.1051 - my ($match1,$match2) = ($tag_types[$type]->{beginning},$tag_types[$type]->{end}); 11.1052 - my ($eof,@lines) = $self->extract_tag($type,1); 11.1053 - 11.1054 - $lines[0] =~ /^(\s*)(.*)$/s; 11.1055 - my $space1 = $1; 11.1056 - $lines[0] = $2; 11.1057 - $lines[$#lines-1] =~ /^(.*?)(\s*)$/s; 11.1058 - my $space2 = $2; 11.1059 - $lines[$#lines-1] = $1; 11.1060 - 11.1061 - # Calling this tag type's specific handling (translation of 11.1062 - # attributes...) 11.1063 - my $line = &{$tag_types[$type]->{f_translate}}($self,@lines); 11.1064 - $self->pushline("<".$match1.$space1.$line.$space2.$match2.">"); 11.1065 - return $eof; 11.1066 -} 11.1067 - 11.1068 -=item tag_in_list($@) 11.1069 - 11.1070 -This function returns a string value that says if the first argument (a tag 11.1071 -hierarchy) matches any of the tags from the second argument (a list of tags 11.1072 -or tag hierarchies). If it doesn't match, it returns 0. Else, it returns the 11.1073 -matched tag's options (the characters in front of the tag) or 1 (if that tag 11.1074 -doesn't have options). 11.1075 - 11.1076 -=back 11.1077 - 11.1078 -=cut 11.1079 -sub tag_in_list ($$$) { 11.1080 - my ($self,$path,$list) = @_; 11.1081 - if ($self->{options}{'caseinsensitive'}) { 11.1082 - $path = lc $path; 11.1083 - } 11.1084 - 11.1085 - while (1) { 11.1086 - if (defined $list->{$path}) { 11.1087 - if (length $list->{$path}) { 11.1088 - return $list->{$path}; 11.1089 - } else { 11.1090 - return 1; 11.1091 - } 11.1092 - } 11.1093 - last unless ($path =~ m/</); 11.1094 - $path =~ s/^<.*?>//; 11.1095 - } 11.1096 - 11.1097 - return 0; 11.1098 -} 11.1099 - 11.1100 -=head2 WORKING WITH ATTRIBUTES 11.1101 - 11.1102 -=over 4 11.1103 - 11.1104 -=item treat_attributes(@) 11.1105 - 11.1106 -This function handles the translation of the tags' attributes. It receives the tag 11.1107 -without the beginning / end marks, and then it finds the attributes, and it 11.1108 -translates the translatable ones (specified by the module option "attributes"). 11.1109 -This returns a plain string with the translated tag. 11.1110 - 11.1111 -=back 11.1112 - 11.1113 -=cut 11.1114 - 11.1115 -sub treat_attributes { 11.1116 - my ($self,@tag)=@_; 11.1117 - 11.1118 - $tag[0] =~ /^(\S*)(.*)/s; 11.1119 - my $text = $1; 11.1120 - $tag[0] = $2; 11.1121 - 11.1122 - while (@tag) { 11.1123 - my $complete = 1; 11.1124 - 11.1125 - $text .= $self->skip_spaces(\@tag); 11.1126 - if (@tag) { 11.1127 - # Get the attribute's name 11.1128 - $complete = 0; 11.1129 - 11.1130 - $tag[0] =~ /^([^\s=]+)(.*)/s; 11.1131 - my $name = $1; 11.1132 - my $ref = $tag[1]; 11.1133 - $tag[0] = $2; 11.1134 - $text .= $name; 11.1135 - $text .= $self->skip_spaces(\@tag); 11.1136 - if (@tag) { 11.1137 - # Get the '=' 11.1138 - if ($tag[0] =~ /^=(.*)/s) { 11.1139 - $tag[0] = $1; 11.1140 - $text .= "="; 11.1141 - $text .= $self->skip_spaces(\@tag); 11.1142 - if (@tag) { 11.1143 - # Get the value 11.1144 - my $value=""; 11.1145 - $ref=$tag[1]; 11.1146 - my $quot=substr($tag[0],0,1); 11.1147 - if ($quot ne "\"" and $quot ne "'") { 11.1148 - # Unquoted value 11.1149 - $quot=""; 11.1150 - $tag[0] =~ /^(\S+)(.*)/s; 11.1151 - $value = $1; 11.1152 - $tag[0] = $2; 11.1153 - } else { 11.1154 - # Quoted value 11.1155 - $text .= $quot; 11.1156 - $tag[0] =~ /^\Q$quot\E(.*)/s; 11.1157 - $tag[0] = $1; 11.1158 - while ($tag[0] !~ /\Q$quot\E/) { 11.1159 - $value .= $tag[0]; 11.1160 - shift @tag; 11.1161 - shift @tag; 11.1162 - } 11.1163 - $tag[0] =~ /^(.*?)\Q$quot\E(.*)/s; 11.1164 - $value .= $1; 11.1165 - $tag[0] = $2; 11.1166 - } 11.1167 - $complete = 1; 11.1168 - if ($self->tag_in_list($self->get_path.$name,$self->{attributes})) { 11.1169 - $text .= $self->found_string($value, $ref, { type=>"attribute", attribute=>$name }); 11.1170 - } else { 11.1171 - print wrap_ref_mod($ref, "po4a::xml", dgettext("po4a", "Content of attribute %s excluded: %s"), $self->get_path.$name, $value) 11.1172 - if $self->debug(); 11.1173 - $text .= $self->recode_skipped_text($value); 11.1174 - } 11.1175 - $text .= $quot; 11.1176 - } 11.1177 - } 11.1178 - } 11.1179 - 11.1180 - unless ($complete) { 11.1181 - my $ontagerror = $self->{options}{'ontagerror'}; 11.1182 - if ($ontagerror eq "warn") { 11.1183 - warn wrap_ref_mod($ref, "po4a::xml", dgettext ("po4a", "Bad attribute syntax. Continuing...")); 11.1184 - } elsif ($ontagerror ne "silent") { 11.1185 - die wrap_ref_mod($ref, "po4a::xml", dgettext ("po4a", "Bad attribute syntax")); 11.1186 - } 11.1187 - } 11.1188 - } 11.1189 - } 11.1190 - return $text; 11.1191 -} 11.1192 - 11.1193 -# Returns an empty string if the content in the $path should not be 11.1194 -# translated. 11.1195 -# 11.1196 -# Otherwise, returns the set of options for translation: 11.1197 -# w: the content shall be re-wrapped 11.1198 -# W: the content shall not be re-wrapped 11.1199 -# i: the tag shall be inlined 11.1200 -# p: a placeholder shall replace the tag (and its content) 11.1201 -# 11.1202 -# A translatable inline tag in an untranslated tag is treated as a translatable breaking tag. 11.1203 -my %translate_options_cache; 11.1204 -sub get_translate_options { 11.1205 - my $self = shift; 11.1206 - my $path = shift; 11.1207 - 11.1208 - if (defined $translate_options_cache{$path}) { 11.1209 - return $translate_options_cache{$path}; 11.1210 - } 11.1211 - 11.1212 - my $options = ""; 11.1213 - my $translate = 0; 11.1214 - my $usedefault = 1; 11.1215 - 11.1216 - my $inlist = 0; 11.1217 - my $tag = $self->get_tag_from_list($path, $self->{tags}); 11.1218 - if (defined $tag) { 11.1219 - $inlist = 1; 11.1220 - } 11.1221 - if ($self->{options}{'tagsonly'} eq $inlist) { 11.1222 - $usedefault = 0; 11.1223 - if (defined $tag) { 11.1224 - $options = $tag; 11.1225 - $options =~ s/<.*$//; 11.1226 - } else { 11.1227 - if ($self->{options}{'wrap'}) { 11.1228 - $options = "w"; 11.1229 - } else { 11.1230 - $options = "W"; 11.1231 - } 11.1232 - } 11.1233 - $translate = 1; 11.1234 - } 11.1235 - 11.1236 -# TODO: a less precise set of tags should not override a more precise one 11.1237 - # The tags and tagsonly options are deprecated. 11.1238 - # The translated and untranslated options have an higher priority. 11.1239 - $tag = $self->get_tag_from_list($path, $self->{translated}); 11.1240 - if (defined $tag) { 11.1241 - $usedefault = 0; 11.1242 - $options = $tag; 11.1243 - $options =~ s/<.*$//; 11.1244 - $translate = 1; 11.1245 - } 11.1246 - 11.1247 - if ($translate and $options !~ m/w/i) { 11.1248 - $options .= ($self->{options}{'wrap'})?"w":"W"; 11.1249 - } 11.1250 - 11.1251 - if (not defined $tag) { 11.1252 - $tag = $self->get_tag_from_list($path, $self->{untranslated}); 11.1253 - if (defined $tag) { 11.1254 - $usedefault = 0; 11.1255 - $options = ""; 11.1256 - $translate = 0; 11.1257 - } 11.1258 - } 11.1259 - 11.1260 - $tag = $self->get_tag_from_list($path, $self->{inline}); 11.1261 - if (defined $tag) { 11.1262 - $usedefault = 0; 11.1263 - $options .= "i"; 11.1264 - } else { 11.1265 - $tag = $self->get_tag_from_list($path, $self->{placeholder}); 11.1266 - if (defined $tag) { 11.1267 - $usedefault = 0; 11.1268 - $options .= "p"; 11.1269 - } 11.1270 - } 11.1271 - 11.1272 - if ($usedefault) { 11.1273 - $options = $self->{options}{'defaulttranslateoption'}; 11.1274 - } 11.1275 - 11.1276 - # A translatable inline tag in an untranslated tag is treated as a 11.1277 - # translatable breaking tag. 11.1278 - if ($options =~ m/i/) { 11.1279 - my $ppath = $path; 11.1280 - $ppath =~ s/<[^>]*>$//; 11.1281 - my $poptions = $self->get_translate_options ($ppath); 11.1282 - if ($poptions eq "") { 11.1283 - $options =~ s/i//; 11.1284 - } 11.1285 - } 11.1286 - 11.1287 - if ($options =~ m/i/ and $self->{options}{'foldattributes'}) { 11.1288 - $options .= "f"; 11.1289 - } 11.1290 - 11.1291 - $translate_options_cache{$path} = $options; 11.1292 - return $options; 11.1293 -} 11.1294 - 11.1295 - 11.1296 -# Return the tag (or biggest set of tags) of a list which matches with the 11.1297 -# given path. 11.1298 -# 11.1299 -# The tag (or set of tags) is returned with its options. 11.1300 -# 11.1301 -# If no tags could match the path, undef is returned. 11.1302 -sub get_tag_from_list ($$$) { 11.1303 - my ($self,$path,$list) = @_; 11.1304 - if ($self->{options}{'caseinsensitive'}) { 11.1305 - $path = lc $path; 11.1306 - } 11.1307 - 11.1308 - while (1) { 11.1309 - if (defined $list->{$path}) { 11.1310 - return $list->{$path}.$path; 11.1311 - } 11.1312 - last unless ($path =~ m/</); 11.1313 - $path =~ s/^<.*?>//; 11.1314 - } 11.1315 - 11.1316 - return undef; 11.1317 -} 11.1318 - 11.1319 - 11.1320 - 11.1321 -sub treat_content { 11.1322 - my $self = shift; 11.1323 - my $blank=""; 11.1324 - # Indicates if the paragraph will have to be translated 11.1325 - my $translate = ""; 11.1326 - 11.1327 - my ($eof,@paragraph)=$self->get_string_until('<',{remove=>1}); 11.1328 - 11.1329 - while (!$eof and !$self->breaking_tag) { 11.1330 - NEXT_TAG: 11.1331 - my @text; 11.1332 - my $type = $self->tag_type; 11.1333 - my $f_extract = $tag_types[$type]->{'f_extract'}; 11.1334 - if ( defined($f_extract) 11.1335 - and $f_extract eq \&tag_extract_comment) { 11.1336 - # Remove the content of the comments 11.1337 - ($eof, @text) = $self->extract_tag($type,1); 11.1338 - $text[$#text-1] .= "\0"; 11.1339 - if ($tag_types[$type]->{'beginning'} eq "!--#") { 11.1340 - $text[0] = "#".$text[0]; 11.1341 - } 11.1342 - push @comments, @text; 11.1343 - } else { 11.1344 - my ($tmpeof, @tag) = $self->extract_tag($type,0); 11.1345 - # Append the found inline tag 11.1346 - ($eof,@text)=$self->get_string_until('>', 11.1347 - {include=>1, 11.1348 - remove=>1, 11.1349 - unquoted=>1}); 11.1350 - # Append or remove the opening/closing tag from 11.1351 - # the tag path 11.1352 - if ($tag_types[$type]->{'end'} eq "") { 11.1353 - if ($tag_types[$type]->{'beginning'} eq "") { 11.1354 - # Opening inline tag 11.1355 - my $cur_tag_name = $self->get_tag_name(@tag); 11.1356 - my $t_opts = $self->get_translate_options($self->get_path($cur_tag_name)); 11.1357 - if ($t_opts =~ m/p/) { 11.1358 - # We enter a new holder. 11.1359 - # Append a <placeholder ...> tag to the current 11.1360 - # paragraph, and save the @paragraph in the 11.1361 - # current holder. 11.1362 - my $last_holder = $save_holders[$#save_holders]; 11.1363 - my $placeholder_str = "<placeholder type=\"".$cur_tag_name."\" id=\"".($#{$last_holder->{'sub_translations'}}+1)."\"/>"; 11.1364 - push @paragraph, ($placeholder_str, $text[1]); 11.1365 - my @saved_paragraph = @paragraph; 11.1366 - 11.1367 - $last_holder->{'paragraph'} = \@saved_paragraph; 11.1368 - 11.1369 - # Then we must push a new holder 11.1370 - my @new_paragraph = (); 11.1371 - my @sub_translations = (); 11.1372 - my %folded_attributes; 11.1373 - my %new_holder = ('paragraph' => \@new_paragraph, 11.1374 - 'open' => $text[0], 11.1375 - 'translation' => "", 11.1376 - 'close' => undef, 11.1377 - 'sub_translations' => \@sub_translations, 11.1378 - 'folded_attributes' => \%folded_attributes); 11.1379 - push @save_holders, \%new_holder; 11.1380 - @text = (); 11.1381 - 11.1382 - # The current @paragraph 11.1383 - # (for the current holder) 11.1384 - # is empty. 11.1385 - @paragraph = (); 11.1386 - } elsif ($t_opts =~ m/f/) { 11.1387 - my $tag_full = $self->join_lines(@text); 11.1388 - my $tag_ref = $text[1]; 11.1389 - if ($tag_full =~ m/^<\s*\S+\s+\S.*>$/s) { 11.1390 - my $holder = $save_holders[$#save_holders]; 11.1391 - my $id = 0; 11.1392 - foreach (keys %{$holder->{folded_attributes}}) { 11.1393 - $id = $_ + 1 if ($_ >= $id); 11.1394 - } 11.1395 - $holder->{folded_attributes}->{$id} = $tag_full; 11.1396 - 11.1397 - @text = ("<$cur_tag_name po4a-id=$id>", $tag_ref); 11.1398 - } 11.1399 - } 11.1400 - push @path, $cur_tag_name; 11.1401 - } elsif ($tag_types[$type]->{'beginning'} eq "/") { 11.1402 - # Closing inline tag 11.1403 - 11.1404 - # Check if this is closing the 11.1405 - # last opening tag we detected. 11.1406 - my $test = pop @path; 11.1407 - my $name = $self->get_tag_name(@tag); 11.1408 - if (!defined($test) || 11.1409 - $test ne $name ) { 11.1410 - my $ontagerror = $self->{options}{'ontagerror'}; 11.1411 - if ($ontagerror eq "warn") { 11.1412 - warn wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong. Continuing..."), $name); 11.1413 - } elsif ($ontagerror ne "silent") { 11.1414 - die wrap_ref_mod($tag[1], "po4a::xml", dgettext("po4a", "Unexpected closing tag </%s> found. The main document may be wrong."), $name); 11.1415 - } 11.1416 - } 11.1417 - 11.1418 - if ($self->get_translate_options($self->get_path($self->get_tag_name(@tag))) =~ m/p/) { 11.1419 - # This closes the current holder. 11.1420 - 11.1421 - push @path, $self->get_tag_name(@tag); 11.1422 - # Now translate this paragraph if needed. 11.1423 - # This will call pushline and append the 11.1424 - # translation to the current holder's translation. 11.1425 - $self->translate_paragraph(@paragraph); 11.1426 - pop @path; 11.1427 - 11.1428 - # Now that this holder is closed, we can remove 11.1429 - # the holder from the stack. 11.1430 - my $holder = pop @save_holders; 11.1431 - # We need to keep the translation of this holder 11.1432 - my $translation = $holder->{'open'}.$holder->{'translation'}.$text[0]; 11.1433 - # FIXME: @text could be multilines. 11.1434 - 11.1435 - @text = (); 11.1436 - 11.1437 - # Then we store the translation in the previous 11.1438 - # holder's sub_translations array 11.1439 - my $previous_holder = $save_holders[$#save_holders]; 11.1440 - push @{$previous_holder->{'sub_translations'}}, $translation; 11.1441 - # We also need to restore the @paragraph array, as 11.1442 - # it was before we encountered the holder. 11.1443 - @paragraph = @{$previous_holder->{'paragraph'}}; 11.1444 - } 11.1445 - } 11.1446 - } 11.1447 - push @paragraph, @text; 11.1448 - } 11.1449 - 11.1450 - # Next tag 11.1451 - ($eof,@text)=$self->get_string_until('<',{remove=>1}); 11.1452 - if ($#text > 0) { 11.1453 - # Check if text (extracted after the inline tag) 11.1454 - # has to be translated 11.1455 - push @paragraph, @text; 11.1456 - } 11.1457 - } 11.1458 - 11.1459 - # This strips the extracted strings 11.1460 - # (only if you don't specify the 'nostrip' option, and if the 11.1461 - # paragraph can be re-wrapped) 11.1462 - $translate = $self->get_translate_options($self->get_path); 11.1463 - if (!$self->{options}{'nostrip'} and $translate !~ m/W/) { 11.1464 - my $clean = 0; 11.1465 - # Clean the beginning 11.1466 - while (!$clean and $#paragraph > 0) { 11.1467 - $paragraph[0] =~ /^(\s*)(.*)/s; 11.1468 - my $match = $1; 11.1469 - if ($paragraph[0] eq $match) { 11.1470 - if ($match ne "") { 11.1471 - $self->pushline($match); 11.1472 - } 11.1473 - shift @paragraph; 11.1474 - shift @paragraph; 11.1475 - } else { 11.1476 - $paragraph[0] = $2; 11.1477 - if ($match ne "") { 11.1478 - $self->pushline($match); 11.1479 - } 11.1480 - $clean = 1; 11.1481 - } 11.1482 - } 11.1483 - $clean = 0; 11.1484 - # Clean the end 11.1485 - while (!$clean and $#paragraph > 0) { 11.1486 - $paragraph[$#paragraph-1] =~ /^(.*?)(\s*)$/s; 11.1487 - my $match = $2; 11.1488 - if ($paragraph[$#paragraph-1] eq $match) { 11.1489 - if ($match ne "") { 11.1490 - $blank = $match.$blank; 11.1491 - } 11.1492 - pop @paragraph; 11.1493 - pop @paragraph; 11.1494 - } else { 11.1495 - $paragraph[$#paragraph-1] = $1; 11.1496 - if ($match ne "") { 11.1497 - $blank = $match.$blank; 11.1498 - } 11.1499 - $clean = 1; 11.1500 - } 11.1501 - } 11.1502 - } 11.1503 - 11.1504 - # Translate the string when needed 11.1505 - # This will either push the translation in the translated document or 11.1506 - # in the current holder translation. 11.1507 - $self->translate_paragraph(@paragraph); 11.1508 - 11.1509 - # Push the trailing blanks 11.1510 - if ($blank ne "") { 11.1511 - $self->pushline($blank); 11.1512 - } 11.1513 - return $eof; 11.1514 -} 11.1515 - 11.1516 -# Translate a @paragraph array of (string, reference). 11.1517 -# The $translate argument indicates if the strings must be translated or 11.1518 -# just pushed 11.1519 -sub translate_paragraph { 11.1520 - my $self = shift; 11.1521 - my @paragraph = @_; 11.1522 - my $translate = $self->get_translate_options($self->get_path); 11.1523 - 11.1524 - while ( (scalar @paragraph) 11.1525 - and ($paragraph[0] =~ m/^\s*\n/s)) { 11.1526 - $self->pushline($paragraph[0]); 11.1527 - shift @paragraph; 11.1528 - shift @paragraph; 11.1529 - } 11.1530 - 11.1531 - my $comments; 11.1532 - while (@comments) { 11.1533 - my ($comment,$eoc); 11.1534 - do { 11.1535 - my ($t,$l) = (shift @comments, shift @comments); 11.1536 - $t =~ s/\n?(\0)?$//; 11.1537 - $eoc = $1; 11.1538 - $comment .= "\n" if defined $comment; 11.1539 - $comment .= $t; 11.1540 - } until ($eoc); 11.1541 - $comments .= "\n" if defined $comments; 11.1542 - $comments .= $comment; 11.1543 - $self->pushline("<!--".$comment."-->\n") if defined $comment; 11.1544 - } 11.1545 - @comments = (); 11.1546 - 11.1547 - if ($self->{options}{'cpp'}) { 11.1548 - my @tmp = @paragraph; 11.1549 - @paragraph = (); 11.1550 - while (@tmp) { 11.1551 - my ($t,$l) = (shift @tmp, shift @tmp); 11.1552 - # #include can be followed by a filename between 11.1553 - # <> brackets. In that case, the argument won't be 11.1554 - # handled in the same call to translate_paragraph. 11.1555 - # Thus do not try to match "include ". 11.1556 - if ($t =~ m/^#[ \t]*(if |endif|undef |include|else|ifdef |ifndef |define )/si) { 11.1557 - if (@paragraph) { 11.1558 - $self->translate_paragraph(@paragraph); 11.1559 - @paragraph = (); 11.1560 - $self->pushline("\n"); 11.1561 - } 11.1562 - $self->pushline($t); 11.1563 - } else { 11.1564 - push @paragraph, ($t,$l); 11.1565 - } 11.1566 - } 11.1567 - } 11.1568 - 11.1569 - my $para = $self->join_lines(@paragraph); 11.1570 - if ( length($para) > 0 ) { 11.1571 - if ($translate ne "") { 11.1572 - # This tag should be translated 11.1573 - $self->pushline($self->found_string( 11.1574 - $para, 11.1575 - $paragraph[1], { 11.1576 - type=>"tag", 11.1577 - tag_options=>$translate, 11.1578 - comments=>$comments 11.1579 - })); 11.1580 - } else { 11.1581 - # Inform that this tag isn't translated in debug mode 11.1582 - print wrap_ref_mod($paragraph[1], "po4a::xml", dgettext ("po4a", "Content of tag %s excluded: %s"), $self->get_path, $para) 11.1583 - if $self->debug(); 11.1584 - $self->pushline($self->recode_skipped_text($para)); 11.1585 - } 11.1586 - } 11.1587 - # Now the paragraph is fully translated. 11.1588 - # If we have all the holders' translation, we can replace the 11.1589 - # placeholders by their translations. 11.1590 - # We must wait to have all the translations because the holders are 11.1591 - # numbered. 11.1592 - { 11.1593 - my $holder = $save_holders[$#save_holders]; 11.1594 - my $translation = $holder->{'translation'}; 11.1595 - 11.1596 - # Count the number of <placeholder ...> in $translation 11.1597 - my $count = 0; 11.1598 - my $str = $translation; 11.1599 - while ( (defined $str) 11.1600 - and ($str =~ m/^.*?<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>(.*)$/s)) { 11.1601 - $count += 1; 11.1602 - $str = $2; 11.1603 - if ($holder->{'sub_translations'}->[$1] =~ m/<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>/s) { 11.1604 - $count = -1; 11.1605 - last; 11.1606 - } 11.1607 - } 11.1608 - 11.1609 - if ( (defined $translation) 11.1610 - and (scalar(@{$holder->{'sub_translations'}}) == $count)) { 11.1611 - # OK, all the holders of the current paragraph are 11.1612 - # closed (and translated). 11.1613 - # Replace them by their translation. 11.1614 - while ($translation =~ m/^(.*?)<placeholder\s+type="[^"]+"\s+id="(\d+)"\s*\/>(.*)$/s) { 11.1615 - # FIXME: we could also check that 11.1616 - # * the holder exists 11.1617 - # * all the holders are used 11.1618 - $translation = $1.$holder->{'sub_translations'}->[$2].$3; 11.1619 - } 11.1620 - # We have our translation 11.1621 - $holder->{'translation'} = $translation; 11.1622 - # And there is no need for any holder in it. 11.1623 - my @sub_translations = (); 11.1624 - $holder->{'sub_translations'} = \@sub_translations; 11.1625 - } 11.1626 - } 11.1627 - 11.1628 -} 11.1629 - 11.1630 - 11.1631 - 11.1632 -=head2 WORKING WITH THE MODULE OPTIONS 11.1633 - 11.1634 -=over 4 11.1635 - 11.1636 -=item treat_options() 11.1637 - 11.1638 -This function fills the internal structures that contain the tags, attributes 11.1639 -and inline data with the options of the module (specified in the command-line 11.1640 -or in the initialize function). 11.1641 - 11.1642 -=back 11.1643 - 11.1644 -=cut 11.1645 - 11.1646 -sub treat_options { 11.1647 - my $self = shift; 11.1648 - 11.1649 - if ($self->{options}{'caseinsensitive'}) { 11.1650 - $self->{options}{'nodefault'} = lc $self->{options}{'nodefault'}; 11.1651 - $self->{options}{'tags'} = lc $self->{options}{'tags'}; 11.1652 - $self->{options}{'break'} = lc $self->{options}{'break'}; 11.1653 - $self->{options}{'_default_break'} = lc $self->{options}{'_default_break'}; 11.1654 - $self->{options}{'translated'} = lc $self->{options}{'translated'}; 11.1655 - $self->{options}{'_default_translated'} = lc $self->{options}{'_default_translated'}; 11.1656 - $self->{options}{'untranslated'} = lc $self->{options}{'untranslated'}; 11.1657 - $self->{options}{'_default_untranslated'} = lc $self->{options}{'_default_untranslated'}; 11.1658 - $self->{options}{'attributes'} = lc $self->{options}{'attributes'}; 11.1659 - $self->{options}{'_default_attributes'} = lc $self->{options}{'_default_attributes'}; 11.1660 - $self->{options}{'inline'} = lc $self->{options}{'inline'}; 11.1661 - $self->{options}{'_default_inline'} = lc $self->{options}{'_default_inline'}; 11.1662 - $self->{options}{'placeholder'} = lc $self->{options}{'placeholder'}; 11.1663 - $self->{options}{'_default_placeholder'} = lc $self->{options}{'_default_placeholder'}; 11.1664 - } 11.1665 - 11.1666 - $self->{options}{'nodefault'} =~ /^\s*(.*)\s*$/s; 11.1667 - my %list_nodefault; 11.1668 - foreach (split(/\s+/s,$1)) { 11.1669 - $list_nodefault{$_} = 1; 11.1670 - } 11.1671 - $self->{nodefault} = \%list_nodefault; 11.1672 - 11.1673 - $self->{options}{'tags'} =~ /^\s*(.*)\s*$/s; 11.1674 - if (length $self->{options}{'tags'}) { 11.1675 - warn wrap_mod("po4a::xml", 11.1676 - dgettext("po4a", 11.1677 - "The '%s' option is deprecated. Please use the translated/untranslated and/or break/inline/placeholder categories."), "tags"); 11.1678 - } 11.1679 - foreach (split(/\s+/s,$1)) { 11.1680 - $_ =~ m/^(.*?)(<.*)$/; 11.1681 - $self->{tags}->{$2} = $1 || ""; 11.1682 - } 11.1683 - 11.1684 - if ($self->{options}{'tagsonly'}) { 11.1685 - warn wrap_mod("po4a::xml", 11.1686 - dgettext("po4a", 11.1687 - "The '%s' option is deprecated. Please use the translated/untranslated and/or break/inline/placeholder categories."), "tagsonly"); 11.1688 - } 11.1689 - 11.1690 - $self->{options}{'break'} =~ /^\s*(.*)\s*$/s; 11.1691 - foreach my $tag (split(/\s+/s,$1)) { 11.1692 - $tag =~ m/^(.*?)(<.*)$/; 11.1693 - $self->{break}->{$2} = $1 || ""; 11.1694 - } 11.1695 - $self->{options}{'_default_break'} =~ /^\s*(.*)\s*$/s; 11.1696 - foreach my $tag (split(/\s+/s,$1)) { 11.1697 - $tag =~ m/^(.*?)(<.*)$/; 11.1698 - $self->{break}->{$2} = $1 || "" 11.1699 - unless $list_nodefault{$2} 11.1700 - or defined $self->{break}->{$2}; 11.1701 - } 11.1702 - 11.1703 - $self->{options}{'translated'} =~ /^\s*(.*)\s*$/s; 11.1704 - foreach my $tag (split(/\s+/s,$1)) { 11.1705 - $tag =~ m/^(.*?)(<.*)$/; 11.1706 - $self->{translated}->{$2} = $1 || ""; 11.1707 - } 11.1708 - $self->{options}{'_default_translated'} =~ /^\s*(.*)\s*$/s; 11.1709 - foreach my $tag (split(/\s+/s,$1)) { 11.1710 - $tag =~ m/^(.*?)(<.*)$/; 11.1711 - $self->{translated}->{$2} = $1 || "" 11.1712 - unless $list_nodefault{$2} 11.1713 - or defined $self->{translated}->{$2}; 11.1714 - } 11.1715 - 11.1716 - $self->{options}{'untranslated'} =~ /^\s*(.*)\s*$/s; 11.1717 - foreach my $tag (split(/\s+/s,$1)) { 11.1718 - $tag =~ m/^(.*?)(<.*)$/; 11.1719 - $self->{untranslated}->{$2} = $1 || ""; 11.1720 - } 11.1721 - $self->{options}{'_default_untranslated'} =~ /^\s*(.*)\s*$/s; 11.1722 - foreach my $tag (split(/\s+/s,$1)) { 11.1723 - $tag =~ m/^(.*?)(<.*)$/; 11.1724 - $self->{untranslated}->{$2} = $1 || "" 11.1725 - unless $list_nodefault{$2} 11.1726 - or defined $self->{untranslated}->{$2}; 11.1727 - } 11.1728 - 11.1729 - $self->{options}{'attributes'} =~ /^\s*(.*)\s*$/s; 11.1730 - foreach my $tag (split(/\s+/s,$1)) { 11.1731 - if ($tag =~ m/^(.*?)(<.*)$/) { 11.1732 - $self->{attributes}->{$2} = $1 || ""; 11.1733 - } else { 11.1734 - $self->{attributes}->{$tag} = ""; 11.1735 - } 11.1736 - } 11.1737 - $self->{options}{'_default_attributes'} =~ /^\s*(.*)\s*$/s; 11.1738 - foreach my $tag (split(/\s+/s,$1)) { 11.1739 - if ($tag =~ m/^(.*?)(<.*)$/) { 11.1740 - $self->{attributes}->{$2} = $1 || "" 11.1741 - unless $list_nodefault{$2} 11.1742 - or defined $self->{attributes}->{$2}; 11.1743 - } else { 11.1744 - $self->{attributes}->{$tag} = "" 11.1745 - unless $list_nodefault{$tag} 11.1746 - or defined $self->{attributes}->{$tag}; 11.1747 - } 11.1748 - } 11.1749 - 11.1750 - my @list_inline; 11.1751 - $self->{options}{'inline'} =~ /^\s*(.*)\s*$/s; 11.1752 - foreach my $tag (split(/\s+/s,$1)) { 11.1753 - $tag =~ m/^(.*?)(<.*)$/; 11.1754 - $self->{inline}->{$2} = $1 || ""; 11.1755 - } 11.1756 - $self->{options}{'_default_inline'} =~ /^\s*(.*)\s*$/s; 11.1757 - foreach my $tag (split(/\s+/s,$1)) { 11.1758 - $tag =~ m/^(.*?)(<.*)$/; 11.1759 - $self->{inline}->{$2} = $1 || "" 11.1760 - unless $list_nodefault{$2} 11.1761 - or defined $self->{inline}->{$2}; 11.1762 - } 11.1763 - 11.1764 - $self->{options}{'placeholder'} =~ /^\s*(.*)\s*$/s; 11.1765 - foreach my $tag (split(/\s+/s,$1)) { 11.1766 - $tag =~ m/^(.*?)(<.*)$/; 11.1767 - $self->{placeholder}->{$2} = $1 || ""; 11.1768 - } 11.1769 - $self->{options}{'_default_placeholder'} =~ /^\s*(.*)\s*$/s; 11.1770 - foreach my $tag (split(/\s+/s,$1)) { 11.1771 - $tag =~ m/^(.*?)(<.*)$/; 11.1772 - $self->{placeholder}->{$2} = $1 || "" 11.1773 - unless $list_nodefault{$2} 11.1774 - or defined $self->{placeholder}->{$2}; 11.1775 - } 11.1776 - 11.1777 - # There should be no translated and untranslated tags 11.1778 - foreach my $tag (keys %{$self->{translated}}) { 11.1779 - die wrap_mod("po4a::xml", 11.1780 - dgettext("po4a", 11.1781 - "Tag '%s' both in the %s and %s categories."), $tag, "translated", "untranslated") 11.1782 - if defined $self->{untranslated}->{$tag}; 11.1783 - } 11.1784 - # There should be no inline, break, and placeholder tags 11.1785 - foreach my $tag (keys %{$self->{inline}}) { 11.1786 - die wrap_mod("po4a::xml", 11.1787 - dgettext("po4a", 11.1788 - "Tag '%s' both in the %s and %s categories."), $tag, "inline", "break") 11.1789 - if defined $self->{break}->{$tag}; 11.1790 - die wrap_mod("po4a::xml", 11.1791 - dgettext("po4a", 11.1792 - "Tag '%s' both in the %s and %s categories."), $tag, "inline", "placeholder") 11.1793 - if defined $self->{placeholder}->{$tag}; 11.1794 - } 11.1795 - foreach my $tag (keys %{$self->{break}}) { 11.1796 - die wrap_mod("po4a::xml", 11.1797 - dgettext("po4a", 11.1798 - "Tag '%s' both in the %s and %s categories."), $tag, "break", "placeholder") 11.1799 - if defined $self->{placeholder}->{$tag}; 11.1800 - } 11.1801 -} 11.1802 - 11.1803 -=head2 GETTING TEXT FROM THE INPUT DOCUMENT 11.1804 - 11.1805 -=over 11.1806 - 11.1807 -=item get_string_until($%) 11.1808 - 11.1809 -This function returns an array with the lines (and references) from the input 11.1810 -document until it finds the first argument. The second argument is an options 11.1811 -hash. Value 0 means disabled (the default) and 1, enabled. 11.1812 - 11.1813 -The valid options are: 11.1814 - 11.1815 -=over 4 11.1816 - 11.1817 -=item include 11.1818 - 11.1819 -This makes the returned array to contain the searched text 11.1820 - 11.1821 -=item remove 11.1822 - 11.1823 -This removes the returned stream from the input 11.1824 - 11.1825 -=item unquoted 11.1826 - 11.1827 -This ensures that the searched text is outside any quotes 11.1828 - 11.1829 -=back 11.1830 - 11.1831 -=cut 11.1832 - 11.1833 -sub get_string_until { 11.1834 - my ($self,$search) = (shift,shift); 11.1835 - my $options = shift; 11.1836 - my ($include,$remove,$unquoted, $regex) = (0,0,0,0); 11.1837 - 11.1838 - if (defined($options->{include})) { $include = $options->{include}; } 11.1839 - if (defined($options->{remove})) { $remove = $options->{remove}; } 11.1840 - if (defined($options->{unquoted})) { $unquoted = $options->{unquoted}; } 11.1841 - if (defined($options->{regex})) { $regex = $options->{regex}; } 11.1842 - 11.1843 - my ($line,$ref) = $self->shiftline(); 11.1844 - my (@text,$paragraph); 11.1845 - my ($eof,$found) = (0,0); 11.1846 - 11.1847 - $search = "\Q$search\E" unless $regex; 11.1848 - while (defined($line) and !$found) { 11.1849 - push @text, ($line,$ref); 11.1850 - $paragraph .= $line; 11.1851 - if ($unquoted) { 11.1852 - if ( $paragraph =~ /^((\".*?\")|(\'.*?\')|[^\"\'])*$search/s ) { 11.1853 - $found = 1; 11.1854 - } 11.1855 - } else { 11.1856 - if ( $paragraph =~ /$search/s ) { 11.1857 - $found = 1; 11.1858 - } 11.1859 - } 11.1860 - if (!$found) { 11.1861 - ($line,$ref)=$self->shiftline(); 11.1862 - } 11.1863 - } 11.1864 - 11.1865 - if (!defined($line)) { $eof = 1; } 11.1866 - 11.1867 - if ( $found ) { 11.1868 - $line = ""; 11.1869 - if($unquoted) { 11.1870 - $paragraph =~ /^(?:(?:\".*?\")|(?:\'.*?\')|[^\"\'])*?$search(.*)$/s; 11.1871 - $line = $1; 11.1872 - $text[$#text-1] =~ s/\Q$line\E$//s; 11.1873 - } else { 11.1874 - $paragraph =~ /$search(.*)$/s; 11.1875 - $line = $1; 11.1876 - $text[$#text-1] =~ s/\Q$line\E$//s; 11.1877 - } 11.1878 - if(!$include) { 11.1879 - $text[$#text-1] =~ /^(.*)($search.*)$/s; 11.1880 - $text[$#text-1] = $1; 11.1881 - $line = $2.$line; 11.1882 - } 11.1883 - if (defined($line) and ($line ne "")) { 11.1884 - $self->unshiftline ($line,$text[$#text]); 11.1885 - } 11.1886 - } 11.1887 - if (!$remove) { 11.1888 - $self->unshiftline (@text); 11.1889 - } 11.1890 - 11.1891 - #If we get to the end of the file, we return the whole paragraph 11.1892 - return ($eof,@text); 11.1893 -} 11.1894 - 11.1895 -=item skip_spaces(\@) 11.1896 - 11.1897 -This function receives as argument the reference to a paragraph (in the format 11.1898 -returned by get_string_until), skips his heading spaces and returns them as 11.1899 -a simple string. 11.1900 - 11.1901 -=cut 11.1902 - 11.1903 -sub skip_spaces { 11.1904 - my ($self,$pstring)=@_; 11.1905 - my $space=""; 11.1906 - 11.1907 - while (@$pstring and (@$pstring[0] =~ /^(\s+)(.*)$/s or @$pstring[0] eq "")) { 11.1908 - if (@$pstring[0] ne "") { 11.1909 - $space .= $1; 11.1910 - @$pstring[0] = $2; 11.1911 - } 11.1912 - 11.1913 - if (@$pstring[0] eq "") { 11.1914 - shift @$pstring; 11.1915 - shift @$pstring; 11.1916 - } 11.1917 - } 11.1918 - return $space; 11.1919 -} 11.1920 - 11.1921 -=item join_lines(@) 11.1922 - 11.1923 -This function returns a simple string with the text from the argument array 11.1924 -(discarding the references). 11.1925 - 11.1926 -=cut 11.1927 - 11.1928 -sub join_lines { 11.1929 - my ($self,@lines)=@_; 11.1930 - my ($line,$ref); 11.1931 - my $text = ""; 11.1932 - while ($#lines > 0) { 11.1933 - ($line,$ref) = (shift @lines,shift @lines); 11.1934 - $text .= $line; 11.1935 - } 11.1936 - return $text; 11.1937 -} 11.1938 - 11.1939 -=back 11.1940 - 11.1941 -=head1 STATUS OF THIS MODULE 11.1942 - 11.1943 -This module can translate tags and attributes. 11.1944 - 11.1945 -=head1 TODO LIST 11.1946 - 11.1947 -DOCTYPE (ENTITIES) 11.1948 - 11.1949 -There is a minimal support for the translation of entities. They are 11.1950 -translated as a whole, and tags are not taken into account. Multilines 11.1951 -entities are not supported and entities are always rewrapped during the 11.1952 -translation. 11.1953 - 11.1954 -MODIFY TAG TYPES FROM INHERITED MODULES 11.1955 -(move the tag_types structure inside the $self hash?) 11.1956 - 11.1957 -=head1 SEE ALSO 11.1958 - 11.1959 -L<po4a(7)|po4a.7>, L<Locale::Po4a::TransTractor(3pm)|Locale::Po4a::TransTractor>. 11.1960 - 11.1961 -=head1 AUTHORS 11.1962 - 11.1963 - Jordi Vilalta <jvprat@gmail.com> 11.1964 - Nicolas François <nicolas.francois@centraliens.net> 11.1965 - 11.1966 -=head1 COPYRIGHT AND LICENSE 11.1967 - 11.1968 - Copyright (c) 2004 by Jordi Vilalta <jvprat@gmail.com> 11.1969 - Copyright (c) 2008-2009 by Nicolas François <nicolas.francois@centraliens.net> 11.1970 - 11.1971 -This program is free software; you may redistribute it and/or modify it 11.1972 -under the terms of GPL (see the COPYING file). 11.1973 - 11.1974 -=cut 11.1975 - 11.1976 -1;
12.1 --- a/tools/po4a/po4a-translate Mon Mar 30 17:50:48 2009 +0800 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,257 +0,0 @@ 12.4 -#! /usr/bin/env perl 12.5 -eval 'exec perl -S $0 ${1+"$@"}' 12.6 - if $running_under_some_shell; 12.7 - 12.8 -# po4a-translate -- translate doc files using a message catalog(ie, po file) 12.9 -# $Id: po4a-translate,v 1.41 2009-03-07 12:33:10 nekral-guest Exp $ 12.10 -# 12.11 -# Copyright 2002, 2003, 2004 by Martin Quinson (mquinson#debian.org) 12.12 -# 12.13 -# This program is free software; you can redistribute it and/or modify it 12.14 -# under the terms of GPL (see COPYING). 12.15 - 12.16 -=head1 NAME 12.17 - 12.18 -po4a-translate - convert a po file back to documentation format 12.19 - 12.20 -=head1 SYNOPSIS 12.21 - 12.22 -po4a-translate -f E<lt>fmtE<gt> -m E<lt>master.docE<gt> -p E<lt>XX.poE<gt> -l E<lt>XX.docE<gt> 12.23 - 12.24 -(XX.doc is the output, all others are inputs) 12.25 - 12.26 -=head1 DESCRIPTION 12.27 - 12.28 -The po4a (po for anything) project goal is to ease translations (and more 12.29 -interestingly, the maintenance of translations) using gettext tools on 12.30 -areas where they were not expected like documentation. 12.31 - 12.32 -The C<po4a-translate> script is in charge of converting the translation 12.33 -(which was done in a po file) under the documentation format back. The 12.34 -provided C<po> file should be the translation of the C<pot> file which were 12.35 -produced by po4a-gettextize(1). 12.36 - 12.37 -=head1 OPTIONS 12.38 - 12.39 -=over 4 12.40 - 12.41 -=item -f, --format 12.42 - 12.43 -Format of the documentation you want to handle. Use the --help-format 12.44 -option to see the list of available formats. 12.45 - 12.46 -=item -a, --addendum 12.47 - 12.48 -Add a file to the resulting file (to put translator's name or a section 12.49 -"About this translation", for example). The first line of the file to insert 12.50 -should be a PO4A header indicating where it should be added (see section 12.51 -I<HOWTO add extra text to translations> in po4a(7)). 12.52 - 12.53 -=item -A, --addendum-charset 12.54 - 12.55 -Charset of the addenda. Note that all the addenda should be in the same 12.56 -charset. 12.57 - 12.58 -=item -m, --master 12.59 - 12.60 -File containing the master document to translate. 12.61 - 12.62 -=item -M, --master-charset 12.63 - 12.64 -Charset of the file containing the document to translate. 12.65 - 12.66 -=item -l, --localized 12.67 - 12.68 -File where the localized (translated) document should be written. 12.69 - 12.70 -=item -L, --localized-charset 12.71 - 12.72 -Charset of the file containing the localized document. 12.73 - 12.74 -=item -p, --po 12.75 - 12.76 -File from which the message catalog should be read. 12.77 - 12.78 -=item -o, --option 12.79 - 12.80 -Extra option(s) to pass to the format plugin. Specify each option in the 12.81 -'name=value' format. See the documentation of each plugin for more 12.82 -information about the valid options and their meanings. 12.83 - 12.84 -=item -k, --keep 12.85 - 12.86 -Minimal threshold for translation percentage to keep (ie, write) the 12.87 -resulting file (default: 80). Ie, by default, files have to be translated 12.88 -at at least 80% to get written. 12.89 - 12.90 -=item -w, --width 12.91 - 12.92 -Column at which we should wrap the resulting file. 12.93 - 12.94 -=item -h, --help 12.95 - 12.96 -Show a short help message. 12.97 - 12.98 -=item --help-format 12.99 - 12.100 -List the documentation format understood by po4a. 12.101 - 12.102 -=item -V, --version 12.103 - 12.104 -Display the version of the script and exit. 12.105 - 12.106 -=item -v, --verbose 12.107 - 12.108 -Increase the verbosity of the program. 12.109 - 12.110 -=item -d, --debug 12.111 - 12.112 -Output some debugging information. 12.113 - 12.114 -=back 12.115 - 12.116 -=head1 Adding content (beside translations) to generated files 12.117 - 12.118 -To add some extra content to the generated document beside what you 12.119 -translated (like the name of the translator, or a "about this translation" 12.120 -section), you should use the C<--addendum> option. 12.121 - 12.122 -The first line of the addendum must be a header indicating where to put 12.123 -it in the document (it can be before or after a given part of the 12.124 -document). The rest of the file will be added verbatim to the resulting 12.125 -file without further processing. 12.126 - 12.127 -Note that if po4a-translate fails to add one of the given files, it discards 12.128 -the whole translation (because the missing file could be the one indicating 12.129 -the author, what would prevent the users to contact him to report bugs in 12.130 -the translation). 12.131 - 12.132 -The header has a pretty rigid syntax. For more information on how to use 12.133 -this feature and how it works, please refer to the po4a(7) man page. 12.134 - 12.135 -=head1 SEE ALSO 12.136 - 12.137 -L<po4a(7)>, L<po4a-gettextize(1)>, L<po4a-updatepo(1)>, L<po4a-normalize(1)>. 12.138 - 12.139 - 12.140 -=head1 AUTHORS 12.141 - 12.142 - Denis Barbier <barbier@linuxfr.org> 12.143 - Martin Quinson (mquinson#debian.org) 12.144 - 12.145 -=head1 COPYRIGHT AND LICENSE 12.146 - 12.147 -Copyright 2002, 2003, 2004 by SPI, inc. 12.148 - 12.149 -This program is free software; you may redistribute it and/or modify it 12.150 -under the terms of GPL (see the COPYING file). 12.151 - 12.152 -=cut 12.153 - 12.154 -use 5.006; 12.155 -use strict; 12.156 -use warnings; 12.157 - 12.158 -use Locale::Po4a::Chooser; 12.159 -use Locale::Po4a::TransTractor; 12.160 -use Locale::Po4a::Common; 12.161 - 12.162 -use Pod::Usage qw(pod2usage); 12.163 -use Getopt::Long qw(GetOptions); 12.164 - 12.165 -Locale::Po4a::Common::textdomain("po4a"); 12.166 - 12.167 -sub show_version { 12.168 - Locale::Po4a::Common::show_version("po4a-translate"); 12.169 - exit 0; 12.170 -} 12.171 - 12.172 - 12.173 -Getopt::Long::Configure('no_auto_abbrev','no_ignore_case'); 12.174 -my ($outfile,$width,$threshold)=('-',80,80); 12.175 -my ($help,$help_fmt,@verbose,$debug,@addfiles,$format,@options); 12.176 -my ($master_filename,$po_filename); 12.177 -my ($mastchar,$locchar,$addchar); 12.178 -GetOptions( 12.179 - 'help|h' => \$help, 12.180 - 'help-format' => \$help_fmt, 12.181 - 12.182 - 'master|m=s' => \$master_filename, 12.183 - 'localized|l=s' => \$outfile, 12.184 - 'po|p=s' => \$po_filename, 12.185 - 'addendum|a=s' => \@addfiles, 12.186 - 'format|f=s' => \$format, 12.187 - 12.188 - 'master-charset|M=s' => \$mastchar, 12.189 - 'localized-charset|L=s' => \$locchar, 12.190 - 'addendum-charset|A=s' => \$addchar, 12.191 - 12.192 - 'option|o=s' => \@options, 12.193 - 12.194 - 'width|w=s' => \$width, 12.195 - 'verbose|v' => \@verbose, 12.196 - 'debug|d' => \$debug, 12.197 - 'keep|k=s' => \$threshold, 12.198 - 12.199 - 'version|V' => \&show_version 12.200 -) or pod2usage(); 12.201 - 12.202 -$help && pod2usage(-verbose => 1, -exitval => 0); 12.203 -$help_fmt && Locale::Po4a::Chooser::list(0); 12.204 - 12.205 -(defined($master_filename) && length($master_filename))||pod2usage(); 12.206 -(defined($po_filename) && length($po_filename)) ||pod2usage(); 12.207 --e $master_filename || die wrap_msg(gettext("File %s does not exist."), $master_filename); 12.208 --e $po_filename || die wrap_msg(gettext("File %s does not exist."), $po_filename); 12.209 - 12.210 -my (@pos,@masters); 12.211 -push @pos,$po_filename; 12.212 -push @masters,$master_filename; 12.213 - 12.214 -my %options = ( 12.215 - "verbose" => scalar @verbose, 12.216 - "debug" => $debug); 12.217 - 12.218 -foreach (@options) { 12.219 - if (m/^([^=]*)=(.*)$/) { 12.220 - $options{$1}="$2"; 12.221 - } else { 12.222 - $options{$_}=1; 12.223 - } 12.224 -} 12.225 -# parser 12.226 -my $doc=Locale::Po4a::Chooser::new($format,%options); 12.227 - 12.228 - 12.229 -# Prepare the document to be used as translator, but not parser 12.230 -$doc->process('po_in_name' => \@pos, 12.231 - 'file_in_name' => \@masters, 12.232 - 'file_in_charset' => $mastchar, 12.233 - 'file_out_charset' => $locchar, 12.234 - 'addendum_charset' => $addchar); 12.235 - 12.236 -my ($percent,$hit,$queries) = $doc->stats(); 12.237 -my $error=0; 12.238 - 12.239 -print STDERR wrap_msg(gettext("%s is %s%% translated (%s of %s strings)."), 12.240 - $master_filename, $percent, $hit, $queries) 12.241 - if (scalar @verbose) && ($percent>=$threshold); 12.242 - 12.243 - 12.244 -if ($percent<$threshold) { 12.245 - print STDERR wrap_msg(gettext("Discard the translation of %s (only %s%% translated; need %s%%)."), 12.246 - $master_filename, $percent, $threshold); 12.247 - unlink($outfile) if (-e $outfile); 12.248 -} else { 12.249 - foreach my $add (@addfiles) { 12.250 - unless ($doc->addendum($add)) { 12.251 - unlink($outfile) if (-e $outfile); 12.252 - die wrap_msg(gettext("Discard the translation of %s (addendum %s does not apply)."), 12.253 - $master_filename, $add); 12.254 - } 12.255 - } 12.256 - $doc->write($outfile); 12.257 -} 12.258 - 12.259 -1; 12.260 -
13.1 --- a/tools/po4a/po4a-updatepo Mon Mar 30 17:50:48 2009 +0800 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,235 +0,0 @@ 13.4 -#! /usr/bin/env perl 13.5 -eval 'exec perl -S $0 ${1+"$@"}' 13.6 - if $running_under_some_shell; 13.7 - 13.8 -# pod-updatepo -- Update the po translation of POD data. 13.9 -# $Id: po4a-updatepo,v 1.44 2009-03-07 12:33:10 nekral-guest Exp $ 13.10 -# 13.11 -# Copyright 2002, 2003, 2004 by Martin Quinson (mquinson#debian.org) 13.12 -# 13.13 -# This program is free software; you can redistribute it and/or modify it 13.14 -# under the terms of GPL (see COPYING). 13.15 - 13.16 -=head1 NAME 13.17 - 13.18 -po4a-updatepo - update the translation (in po format) of documentation 13.19 - 13.20 -=head1 SYNOPSIS 13.21 - 13.22 -po4a-updatepo -f E<lt>fmtE<gt> (-m E<lt>master.docE<gt>)+ (-p E<lt>XX.poE<gt>)+ 13.23 - 13.24 -(XX.po are the outputs, all others are inputs) 13.25 - 13.26 -=head1 DESCRIPTION 13.27 - 13.28 -The po4a (po for anything) project goal is to ease translations (and more 13.29 -interestingly, the maintenance of translations) using gettext tools on 13.30 -areas where they were not expected like documentation. 13.31 - 13.32 -The C<po4a-updatepo> script is in charge of updating po files to make 13.33 -them reflect the changes made to the original documentation file. For that, 13.34 -it converts the documentation file to a pot file, and call L<msgmerge(1)> 13.35 -on this new pot and on the provided po files. 13.36 - 13.37 -It is possible to give more than one po file (if you want to update several 13.38 -languages at once), and several documentation files (if you want to store 13.39 -the translations of several documents in the same po file). 13.40 - 13.41 -If the master document has non-ascii characters, it will convert the po files 13.42 -to utf-8 (if they weren't already), in order to allow non-standard characters 13.43 -in a culture independent way. 13.44 - 13.45 -=head1 COMMAND-LINE OPTIONS 13.46 - 13.47 -=over 4 13.48 - 13.49 -=item -f, --format 13.50 - 13.51 -Format of the documentation you want to handle. Use the --help-format 13.52 -option to see the list of available formats. 13.53 - 13.54 -=item -m, --master 13.55 - 13.56 -File(s) containing the master document to translate. 13.57 - 13.58 -=item -M, --master-charset 13.59 - 13.60 -Charset of the files containing the document to translate. Note that all 13.61 -files must have the same charset. 13.62 - 13.63 -=item -p, --po 13.64 - 13.65 -Po file(s) to update. If these files do not exist, they are created by 13.66 -C<po4a-updatepo>. 13.67 - 13.68 -=item -o, --option 13.69 - 13.70 -Extra option(s) to pass to the format plugin and other po4a internal module. 13.71 -Specify each option in the 'name=value' format. See the documentation of 13.72 -each plugin for more information about the valid options and their meanings. 13.73 - 13.74 -=item --previous 13.75 - 13.76 -This option adds '--previous' to the options passed to msgmerge. 13.77 -It requires gettext 0.16 or later. 13.78 - 13.79 -=item --msgmerge-opt options 13.80 - 13.81 -Extra options for msgmerge. 13.82 - 13.83 -=item -h, --help 13.84 - 13.85 -Show a short help message. 13.86 - 13.87 -=item --help-format 13.88 - 13.89 -List the documentation format handled by po4a. 13.90 - 13.91 -=item -V, --version 13.92 - 13.93 -Display the version of the script and exit. 13.94 - 13.95 -=item -v, --verbose 13.96 - 13.97 -Increase the verbosity of the program. 13.98 - 13.99 -=item -d, --debug 13.100 - 13.101 -Output some debugging information. 13.102 - 13.103 -=back 13.104 - 13.105 -=head1 SEE ALSO 13.106 - 13.107 -L<po4a(7)>, L<po4a-gettextize(1)>, L<po4a-translate(1)>, L<po4a-normalize(1)>. 13.108 - 13.109 -=head1 AUTHORS 13.110 - 13.111 - Denis Barbier <barbier@linuxfr.org> 13.112 - Martin Quinson (mquinson#debian.org) 13.113 - 13.114 -=head1 COPYRIGHT AND LICENSE 13.115 - 13.116 -Copyright 2002, 2003, 2004, 2005 by SPI, inc. 13.117 - 13.118 -This program is free software; you may redistribute it and/or modify it 13.119 -under the terms of GPL (see the COPYING file). 13.120 - 13.121 -=cut 13.122 - 13.123 -use 5.006; 13.124 -use strict; 13.125 -use warnings; 13.126 - 13.127 -use Getopt::Long qw(GetOptions); 13.128 -use Locale::Po4a::Po; 13.129 - 13.130 -use Locale::Po4a::Chooser; 13.131 -use Locale::Po4a::TransTractor; 13.132 -use Locale::Po4a::Common; 13.133 - 13.134 -use Pod::Usage qw(pod2usage); 13.135 - 13.136 -use File::Temp; 13.137 - 13.138 -Locale::Po4a::Common::textdomain('po4a'); 13.139 - 13.140 -sub show_version { 13.141 - Locale::Po4a::Common::show_version("po4a-updatepo"); 13.142 - exit 0; 13.143 -} 13.144 - 13.145 - 13.146 -# init commandline parser 13.147 -Getopt::Long::config('bundling', 'no_getopt_compat', 'no_auto_abbrev'); 13.148 - 13.149 -# Parse our options 13.150 -my (@masterfiles,@pofiles); 13.151 -my ($help,$help_fmt,$verbose,$debug,$format,@options); 13.152 -my $mastchar; 13.153 -my $previous; 13.154 -my $msgmerge_opt = ""; 13.155 -GetOptions('help|h' => \$help, 13.156 - 'help-format' => \$help_fmt, 13.157 - 13.158 - 'master|m=s' => \@masterfiles, 13.159 - 'po|p=s' => \@pofiles, 13.160 - 'format|f=s' => \$format, 13.161 - 13.162 - 'master-charset|M=s' => \$mastchar, 13.163 - 13.164 - 'option|o=s' => \@options, 13.165 - 13.166 - 'previous' => \$previous, 13.167 - 'msgmerge-opt=s' => \$msgmerge_opt, 13.168 - 13.169 - 'verbose|v' => \$verbose, 13.170 - 'debug|d' => \$debug, 13.171 - 'version|V' => \&show_version) 13.172 - or pod2usage(); 13.173 - 13.174 -$help && pod2usage (-verbose => 1, -exitval => 0); 13.175 -$help_fmt && Locale::Po4a::Chooser::list(0); 13.176 -pod2usage () if scalar @masterfiles < 1 || scalar @pofiles < 1; 13.177 - 13.178 -$msgmerge_opt .= " --previous" if $previous; 13.179 - 13.180 -my %options = ( 13.181 - "verbose" => $verbose, 13.182 - "debug" => $debug); 13.183 - 13.184 -foreach (@options) { 13.185 - if (m/^([^=]*)=(.*)$/) { 13.186 - $options{$1}="$2"; 13.187 - } else { 13.188 - $options{$_}=1; 13.189 - } 13.190 -} 13.191 - 13.192 -# parser 13.193 -my ($doc)=Locale::Po4a::Chooser::new($format,%options); 13.194 - 13.195 -map { -e $_ || die wrap_msg(gettext("File %s does not exist."), $_) } @masterfiles; 13.196 -map { die wrap_msg(gettext("po4a-updatepo can't take the input po from stdin.")) 13.197 - if $_ eq '-' && !-e '-'} @pofiles; 13.198 - 13.199 -my ($pot_filename); 13.200 -(undef,$pot_filename)=File::Temp->tempfile("po4a-updatepoXXXX", 13.201 - DIR => "/tmp", 13.202 - SUFFIX => ".pot", 13.203 - OPEN => 0, 13.204 - UNLINK => 0) 13.205 - or die wrap_msg(gettext("Can't create a temporary pot file: %s"), $!); 13.206 - 13.207 - 13.208 -print STDERR wrap_msg(gettext("Parse input files... ")) if $verbose; 13.209 - 13.210 -$doc->{TT}{utf_mode} = 1; 13.211 - 13.212 -$doc->process('file_in_name' => \@masterfiles, 13.213 - 'file_in_charset' => $mastchar, 13.214 - 'po_out_name' => $pot_filename, 13.215 - 'debug' => $debug, 13.216 - 'verbose' => $verbose); 13.217 - 13.218 -print STDERR wrap_msg(gettext("done.")) if $verbose; 13.219 - 13.220 - 13.221 -while (my $po_filename=shift @pofiles) { 13.222 - if (-e $po_filename) { 13.223 - print STDERR wrap_msg(gettext("Updating %s:"), $po_filename) 13.224 - if $verbose; 13.225 - my $cmd = "msgmerge $msgmerge_opt -U $po_filename $pot_filename"; 13.226 - system ($cmd) == 0 13.227 - or die wrap_msg(gettext("Error while running msgmerge: %s"), $!); 13.228 - system "msgfmt --statistics -v -o /dev/null $po_filename" 13.229 - if $verbose; 13.230 - } else { 13.231 - print STDERR wrap_msg(gettext("Creating %s:"), $po_filename) 13.232 - if $verbose; 13.233 - system ("cp",$pot_filename,$po_filename) == 0 13.234 - or die wrap_msg(gettext("Error while copying the po file: %s"), $!); 13.235 - } 13.236 -} 13.237 - 13.238 -unlink($pot_filename);