xref: /AOO41X/main/helpcontent2/helpers/update_tree.pl (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir:
2*cdf0e10cSrcweireval 'exec perl -wS $0 ${1+"$@"}'
3*cdf0e10cSrcweir    if 0;
4*cdf0e10cSrcweir#*************************************************************************
5*cdf0e10cSrcweir#
6*cdf0e10cSrcweir# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7*cdf0e10cSrcweir#
8*cdf0e10cSrcweir# Copyright 2000, 2010 Oracle and/or its affiliates.
9*cdf0e10cSrcweir#
10*cdf0e10cSrcweir# OpenOffice.org - a multi-platform office productivity suite
11*cdf0e10cSrcweir#
12*cdf0e10cSrcweir# This file is part of OpenOffice.org.
13*cdf0e10cSrcweir#
14*cdf0e10cSrcweir# OpenOffice.org is free software: you can redistribute it and/or modify
15*cdf0e10cSrcweir# it under the terms of the GNU Lesser General Public License version 3
16*cdf0e10cSrcweir# only, as published by the Free Software Foundation.
17*cdf0e10cSrcweir#
18*cdf0e10cSrcweir# OpenOffice.org is distributed in the hope that it will be useful,
19*cdf0e10cSrcweir# but WITHOUT ANY WARRANTY; without even the implied warranty of
20*cdf0e10cSrcweir# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21*cdf0e10cSrcweir# GNU Lesser General Public License version 3 for more details
22*cdf0e10cSrcweir# (a copy is included in the LICENSE file that accompanied this code).
23*cdf0e10cSrcweir#
24*cdf0e10cSrcweir# You should have received a copy of the GNU Lesser General Public License
25*cdf0e10cSrcweir# version 3 along with OpenOffice.org.  If not, see
26*cdf0e10cSrcweir# <http://www.openoffice.org/license.html>
27*cdf0e10cSrcweir# for a copy of the LGPLv3 License.
28*cdf0e10cSrcweir#
29*cdf0e10cSrcweir#*************************************************************************
30*cdf0e10cSrcweir
31*cdf0e10cSrcweiruse Cwd 'abs_path';
32*cdf0e10cSrcweiruse File::Find;
33*cdf0e10cSrcweiruse File::Copy qw/cp mv/;
34*cdf0e10cSrcweiruse File::Basename;
35*cdf0e10cSrcweiruse Benchmark;
36*cdf0e10cSrcweir
37*cdf0e10cSrcweir$t0 = new Benchmark;
38*cdf0e10cSrcweir# update the tree files in <platform>/misc/*
39*cdf0e10cSrcweir
40*cdf0e10cSrcweir$| = 1;
41*cdf0e10cSrcweir
42*cdf0e10cSrcweirmy $prj = $ENV{ENVPRJ};
43*cdf0e10cSrcweir
44*cdf0e10cSrcweirmy $inpath = $ENV{INPATH};
45*cdf0e10cSrcweirterminate() if ( ! defined $inpath );
46*cdf0e10cSrcweir
47*cdf0e10cSrcweirmy $destpath = $inpath;
48*cdf0e10cSrcweirmy $with_lang = $ENV{WITH_LANG};
49*cdf0e10cSrcweir
50*cdf0e10cSrcweir
51*cdf0e10cSrcweir# Always use / directory separators
52*cdf0e10cSrcweir$prj =~ s/\\/\//g if defined($prj);
53*cdf0e10cSrcweir$inpath =~ s/\\/\//g;
54*cdf0e10cSrcweir$destpath =~ s/\\/\//g;
55*cdf0e10cSrcweir
56*cdf0e10cSrcweir
57*cdf0e10cSrcweirif ( ! defined $prj ) {
58*cdf0e10cSrcweir# do someting that works for manual call
59*cdf0e10cSrcweir    ($scriptname = `pwd`) =~ s/\n/\/$0/;
60*cdf0e10cSrcweir    ($tree_src = $scriptname) =~ s/\/update_tree.pl/\/..\/source\/auxiliary/;
61*cdf0e10cSrcweir    ($tree_dest = $scriptname) =~ s/\/update_tree.pl/\/..\/$destpath\/misc/;
62*cdf0e10cSrcweir    ($source_dir = $scriptname) =~ s/\/update_tree.pl/\/..\/source/;
63*cdf0e10cSrcweir    ($source_dir_xhp = $scriptname) =~ s/\/update_tree.pl/\/..\/source/;
64*cdf0e10cSrcweir
65*cdf0e10cSrcweir    if ( defined $ENV{TRYSDF} || defined $ENV{LOCALIZESDF} )
66*cdf0e10cSrcweir    {
67*cdf0e10cSrcweir        if( defined $ENV{LOCALIZATION_FOUND} && $ENV{LOCALIZATION_FOUND} eq "YES" )
68*cdf0e10cSrcweir        {
69*cdf0e10cSrcweir            $source_dir = $ENV{TRYSDF};
70*cdf0e10cSrcweir        }
71*cdf0e10cSrcweir        else
72*cdf0e10cSrcweir        {
73*cdf0e10cSrcweir            $source_dir = $ENV{LOCALIZESDF};
74*cdf0e10cSrcweir        }
75*cdf0e10cSrcweir        $source_dir =~ s/\/auxiliary\/localize.sdf$// ;
76*cdf0e10cSrcweir    }
77*cdf0e10cSrcweir    #else {die "ERROR: The env variables TRYSDF LOCALIZATION_FOUND LOCALIZESDF not found ... something is wrong!\n";}
78*cdf0e10cSrcweir
79*cdf0e10cSrcweir
80*cdf0e10cSrcweir    $treestrings = "$source_dir/text/shared/tree_strings.xhp";
81*cdf0e10cSrcweir} else {
82*cdf0e10cSrcweir    $tree_src = "$prj\/source\/auxiliary";
83*cdf0e10cSrcweir    $tree_dest = "$prj\/$destpath\/misc";
84*cdf0e10cSrcweir    $source_dir = "$prj\/source";
85*cdf0e10cSrcweir    $source_dir_xhp = "$prj\/source";
86*cdf0e10cSrcweir    $treestrings = "$source_dir/text/shared/tree_strings.xhp";
87*cdf0e10cSrcweir
88*cdf0e10cSrcweir    if( defined $ENV{LOCALIZATION_FOUND} && $ENV{LOCALIZATION_FOUND} eq "YES" )
89*cdf0e10cSrcweir    {
90*cdf0e10cSrcweir        $source_dir = $ENV{TRYSDF};
91*cdf0e10cSrcweir    }
92*cdf0e10cSrcweir    else
93*cdf0e10cSrcweir    {
94*cdf0e10cSrcweir        $source_dir = $ENV{LOCALIZESDF};
95*cdf0e10cSrcweir    }
96*cdf0e10cSrcweir    $source_dir =~ s/\/auxiliary\/localize.sdf$// ;
97*cdf0e10cSrcweir    #else {die "ERROR: The env variables TRYSDF LOCALIZATION_FOUND LOCALIZESDF not found ... something is wrong!\n";}
98*cdf0e10cSrcweir
99*cdf0e10cSrcweir}
100*cdf0e10cSrcweir
101*cdf0e10cSrcweir# Get the English tree files as master
102*cdf0e10cSrcweir#-------------------------------
103*cdf0e10cSrcweir# Update English from xhp
104*cdf0e10cSrcweir#-------------------------------
105*cdf0e10cSrcweir&do_english;
106*cdf0e10cSrcweir#-------------------------------
107*cdf0e10cSrcweir# Update localizations from sdf
108*cdf0e10cSrcweir#-------------------------------
109*cdf0e10cSrcweir
110*cdf0e10cSrcweir@langs = split /\s+/, $with_lang;
111*cdf0e10cSrcweir&read_loc;
112*cdf0e10cSrcweirprint "################\nUpdating the treefiles for @langs \n";
113*cdf0e10cSrcweirfor $l(@langs) {
114*cdf0e10cSrcweir    if ($l ne "en-US") {
115*cdf0e10cSrcweir        &do_lang($l);
116*cdf0e10cSrcweir    }
117*cdf0e10cSrcweir}
118*cdf0e10cSrcweir
119*cdf0e10cSrcweir#-------------------------------
120*cdf0e10cSrcweir#
121*cdf0e10cSrcweir$t1 = new Benchmark;
122*cdf0e10cSrcweir$td = timediff($t1, $t0);
123*cdf0e10cSrcweirprint timestr($td),"\n";
124*cdf0e10cSrcweir
125*cdf0e10cSrcweir####################
126*cdf0e10cSrcweir# SUBS
127*cdf0e10cSrcweir####################
128*cdf0e10cSrcweirsub terminate {
129*cdf0e10cSrcweir    $err = shift;
130*cdf0e10cSrcweir    print "$err\n\n";
131*cdf0e10cSrcweir    $msg = <<"MSG";
132*cdf0e10cSrcweir
133*cdf0e10cSrcweirupdate_tree.pl
134*cdf0e10cSrcweir   all languages in WITH_LANG are processed. WITH_LANG=ALL is
135*cdf0e10cSrcweir   not supported in manual calls.
136*cdf0e10cSrcweir
137*cdf0e10cSrcweir   Updates the *.tree files.
138*cdf0e10cSrcweir   At first, the English file is updated based on the English
139*cdf0e10cSrcweir   help topic titles as read from the help files. Then, the
140*cdf0e10cSrcweir   localized tree files are written based on the English tree
141*cdf0e10cSrcweir   file and the localized help topic titles.
142*cdf0e10cSrcweir
143*cdf0e10cSrcweir   Requires a valid SO/OOo environment.
144*cdf0e10cSrcweirMSG
145*cdf0e10cSrcweir   print "$msg\n";
146*cdf0e10cSrcweir   exit( -1 );
147*cdf0e10cSrcweir   # die "$msg\n";
148*cdf0e10cSrcweir}
149*cdf0e10cSrcweir
150*cdf0e10cSrcweir#---------------------------------------------------
151*cdf0e10cSrcweir
152*cdf0e10cSrcweirsub do_english {
153*cdf0e10cSrcweir    print "Processing en-US\n";
154*cdf0e10cSrcweir    undef %helpsection; undef %node;
155*cdf0e10cSrcweir    &readtreestrings;
156*cdf0e10cSrcweir    &gettreefiles;
157*cdf0e10cSrcweir    &processtreefiles('en-US');
158*cdf0e10cSrcweir}
159*cdf0e10cSrcweir
160*cdf0e10cSrcweir#---------------------------------------------------
161*cdf0e10cSrcweirsub do_lang {
162*cdf0e10cSrcweir    $lng = shift;
163*cdf0e10cSrcweir    print "\n---------------------------------------------------\nProcessing $lng\n";
164*cdf0e10cSrcweir    &processtreefiles($lng);
165*cdf0e10cSrcweir    print "\n";
166*cdf0e10cSrcweir}
167*cdf0e10cSrcweir
168*cdf0e10cSrcweir#---------------------------------------------------
169*cdf0e10cSrcweirsub readtreestrings {
170*cdf0e10cSrcweir    print "Reading tree strings for en-US...";
171*cdf0e10cSrcweir    if (open TREE, $treestrings) {
172*cdf0e10cSrcweir        while (<TREE>) {
173*cdf0e10cSrcweir            chomp;
174*cdf0e10cSrcweir            s/<\/*help:productname>//gis;
175*cdf0e10cSrcweir            if (/help_section/) {
176*cdf0e10cSrcweir                s/^\s*<.*help_section//;
177*cdf0e10cSrcweir                s/<\/.*$//;
178*cdf0e10cSrcweir                ($id = $_) =~ s/^.*id=&quot;(\d+)&quot;.*$/$1/;
179*cdf0e10cSrcweir                ($title = $_) =~ s/^.*title=&quot;(.*)&quot;.*$/$1/;
180*cdf0e10cSrcweir                $helpsection{$id} = $title;
181*cdf0e10cSrcweir            }
182*cdf0e10cSrcweir
183*cdf0e10cSrcweir            if (/node id=/) {
184*cdf0e10cSrcweir                s/^\s*<.*node //;
185*cdf0e10cSrcweir                s/<\/.*$//;
186*cdf0e10cSrcweir                ($id = $_) =~ s/^.*id=&quot;(\d+)&quot;.*$/$1/;
187*cdf0e10cSrcweir                ($title = $_) =~ s/^.*title=&quot;(.*)&quot;.*$/$1/;
188*cdf0e10cSrcweir                $node{$id} = $title;
189*cdf0e10cSrcweir            }
190*cdf0e10cSrcweir        }
191*cdf0e10cSrcweir        close TREE;
192*cdf0e10cSrcweir    } else {
193*cdf0e10cSrcweir	    &terminate("Error opening $treestrings");
194*cdf0e10cSrcweir    }
195*cdf0e10cSrcweir    print "done\n";
196*cdf0e10cSrcweir}
197*cdf0e10cSrcweir
198*cdf0e10cSrcweir#------------------------------------
199*cdf0e10cSrcweirsub gettreefiles {
200*cdf0e10cSrcweir    # Read the tree files from the directory
201*cdf0e10cSrcweir    # this list is also used for all foreign languages
202*cdf0e10cSrcweir    print "Reading tree files...";
203*cdf0e10cSrcweir    if (opendir ENUS, "$tree_src") {
204*cdf0e10cSrcweir        @treeviews = grep /\.tree/, readdir ENUS;
205*cdf0e10cSrcweir        closedir ENUS;
206*cdf0e10cSrcweir    } else {
207*cdf0e10cSrcweir        &terminate("Cannot open directory $tree_src");
208*cdf0e10cSrcweir    }
209*cdf0e10cSrcweir    print "done\n";
210*cdf0e10cSrcweir}
211*cdf0e10cSrcweir
212*cdf0e10cSrcweir#------------------------------------
213*cdf0e10cSrcweirsub processtreefiles {
214*cdf0e10cSrcweir    $lng = shift;
215*cdf0e10cSrcweir	use File::Temp qw/ tempfile /;
216*cdf0e10cSrcweir	use File::Spec;
217*cdf0e10cSrcweir
218*cdf0e10cSrcweir	for $tv(@treeviews) {
219*cdf0e10cSrcweir        print "\nProcessing $tv\n";
220*cdf0e10cSrcweir        @lines = &readtv("$tree_src/$tv");
221*cdf0e10cSrcweir        print "Read ".scalar @lines." lines\n";
222*cdf0e10cSrcweir        for $l(@lines) {
223*cdf0e10cSrcweir            if ($l =~ /topic/) {
224*cdf0e10cSrcweir                ($id = $l) =~ s/^.*id="([^"]*)".*$/$1/gis;
225*cdf0e10cSrcweir                ($module = $id) =~ s/^([^\/]*).*$/$1/;
226*cdf0e10cSrcweir                $id =~ s/^.*?\///;
227*cdf0e10cSrcweir                $file = "$source_dir_xhp/$id";
228*cdf0e10cSrcweir
229*cdf0e10cSrcweir                if ($lng eq 'en-US') { # english comes from the file
230*cdf0e10cSrcweir                    if (open F,$file) {
231*cdf0e10cSrcweir                        print ".";
232*cdf0e10cSrcweir                        undef $/; $cnt = <F>; close F;
233*cdf0e10cSrcweir                        $cnt =~ s/^.*<title[^>]+id="tit"[^>]*>([^<]*)<\/title>.*$/$1/gis;
234*cdf0e10cSrcweir                        $cnt =~ s/&apos;/\'/gis; $cnt =~ s/&amp;/+/gis;
235*cdf0e10cSrcweir                        $cnt =~ s/&quot;/\'/gis; $cnt =~ s/&/+/gis;
236*cdf0e10cSrcweir                        $l = "<topic id=\"$module/$id\">$cnt</topic>\n";
237*cdf0e10cSrcweir                    } else {
238*cdf0e10cSrcweir                        print "!";
239*cdf0e10cSrcweir                        $l = "<!-- removed $module/$id -->\n";
240*cdf0e10cSrcweir                    }
241*cdf0e10cSrcweir                } else { # localized comes from the localize sdf
242*cdf0e10cSrcweir                    #print "\nid: $id";
243*cdf0e10cSrcweir                    if (defined($loc_title{$lng}->{$id})) {
244*cdf0e10cSrcweir                        print ".";
245*cdf0e10cSrcweir                        $l = "<topic id=\"$module/$id\">$loc_title{$lng}->{$id}</topic>\n";
246*cdf0e10cSrcweir                    } else {
247*cdf0e10cSrcweir                        print "!";
248*cdf0e10cSrcweir                    }
249*cdf0e10cSrcweir                }
250*cdf0e10cSrcweir            }
251*cdf0e10cSrcweir
252*cdf0e10cSrcweir            if ($l =~/<node/) {
253*cdf0e10cSrcweir                ($id = $l) =~ s/^.*id="(\d+)".*$/$1/gis;
254*cdf0e10cSrcweir                if ($lng eq 'en-US') {
255*cdf0e10cSrcweir                    if (defined($node{$id})) {
256*cdf0e10cSrcweir                        $l =~ s/title="(.*)"/title="$node{$id}"/;
257*cdf0e10cSrcweir                    } else {
258*cdf0e10cSrcweir                        $l =~ s/title="(.*)"/title="NOTFOUND:$id"/;
259*cdf0e10cSrcweir                    }
260*cdf0e10cSrcweir                } else {
261*cdf0e10cSrcweir                    if (defined($node{$lng}->{$id})) {
262*cdf0e10cSrcweir                        $l =~ s/title="(.*)"/title="$node{$lng}->{$id}"/;
263*cdf0e10cSrcweir                    }
264*cdf0e10cSrcweir                }
265*cdf0e10cSrcweir            }
266*cdf0e10cSrcweir
267*cdf0e10cSrcweir            if ($l =~/<help_section/) {
268*cdf0e10cSrcweir                ($id = $l) =~ s/^.*id="(\d+)".*$/$1/gis;
269*cdf0e10cSrcweir                if ($lng eq 'en-US') {
270*cdf0e10cSrcweir                    if (defined($helpsection{$id})) {
271*cdf0e10cSrcweir                        $l =~ s/title="(.*)"/title="$helpsection{$id}"/;
272*cdf0e10cSrcweir                    } else {
273*cdf0e10cSrcweir                        print "#";
274*cdf0e10cSrcweir                        $l =~ s/title="(.*)"/title="NOTFOUND:$id"/;
275*cdf0e10cSrcweir                    }
276*cdf0e10cSrcweir                } else {
277*cdf0e10cSrcweir                    if (defined($helpsection{$lng}->{$id})) {
278*cdf0e10cSrcweir                        $l =~ s/title="(.*)"/title="$helpsection{$lng}->{$id}"/;
279*cdf0e10cSrcweir                    }
280*cdf0e10cSrcweir                }
281*cdf0e10cSrcweir            }
282*cdf0e10cSrcweir        }
283*cdf0e10cSrcweir 		if ( ! -d "$tree_dest/$lng" ) {
284*cdf0e10cSrcweir	        mkdir "$tree_dest/$lng" or die "\nCouldn't create directory \"$tree_dest/$lng\"";
285*cdf0e10cSrcweir		}
286*cdf0e10cSrcweir		my $treeoutdir = "$tree_dest/$lng";
287*cdf0e10cSrcweir		my $tmpname_template=$tv."_XXXXX";
288*cdf0e10cSrcweir		my ( $treetmpfilehandle, $treetmpfile ) = tempfile($tmpname_template , DIR => File::Spec->tmpdir() );
289*cdf0e10cSrcweir		close $treetmpfilehandle ;
290*cdf0e10cSrcweir        if (open TV, ">$treetmpfile") {
291*cdf0e10cSrcweir            for $line(@lines) {
292*cdf0e10cSrcweir                $line =~ s/\$\[officename\]/%PRODUCTNAME/g;
293*cdf0e10cSrcweir                $line =~ s/\$\[officeversion\]/%PRODUCTVERSION/g;
294*cdf0e10cSrcweir                print TV $line;
295*cdf0e10cSrcweir            }
296*cdf0e10cSrcweir            close TV;
297*cdf0e10cSrcweir			chmod 0664, $treetmpfile or &terminate("Cannot change rights on $treetmpfile");
298*cdf0e10cSrcweir			if( $^O eq 'MSWin32' )
299*cdf0e10cSrcweir			{
300*cdf0e10cSrcweir				$tree_dest =~ s/\//\\/g ;
301*cdf0e10cSrcweir				unlink "$tree_dest\\$lng\\$tv" ;
302*cdf0e10cSrcweir                mv $treetmpfile , "$tree_dest\\$lng\\$tv" or &terminate("Cannot mv $treetmpfile to $tree_dest\\$lng\\$tv" );
303*cdf0e10cSrcweir			}
304*cdf0e10cSrcweir			else
305*cdf0e10cSrcweir			{
306*cdf0e10cSrcweir				unlink "$tree_dest/$lng/$tv" ;
307*cdf0e10cSrcweir                my $ret=mv $treetmpfile , "$tree_dest/$lng/$tv$inpath" or &terminate("Cannot write to $tree_dest/$lng/$tv$inpath - Error $!");
308*cdf0e10cSrcweir                my $ret=mv "$tree_dest/$lng/$tv$inpath" , "$tree_dest/$lng/$tv" or &terminate("Cannot write to $tree_dest/$lng/$tv - Error $!");
309*cdf0e10cSrcweir			}
310*cdf0e10cSrcweir      } else {
311*cdf0e10cSrcweir            &terminate("Cannot write to $tvout");
312*cdf0e10cSrcweir        }
313*cdf0e10cSrcweir    }
314*cdf0e10cSrcweir}
315*cdf0e10cSrcweir
316*cdf0e10cSrcweir#------------------------------------
317*cdf0e10cSrcweirsub readtv {
318*cdf0e10cSrcweir    my $f = shift;
319*cdf0e10cSrcweir    if (open TV, $f) {
320*cdf0e10cSrcweir        $/ = "\n";
321*cdf0e10cSrcweir        my @l = <TV>;
322*cdf0e10cSrcweir        close TV;
323*cdf0e10cSrcweir        return @l;
324*cdf0e10cSrcweir    } else {
325*cdf0e10cSrcweir        &terminate("Error opening $f");
326*cdf0e10cSrcweir    }
327*cdf0e10cSrcweir}
328*cdf0e10cSrcweir
329*cdf0e10cSrcweir#------------------------------------
330*cdf0e10cSrcweir# read entries form localize.sdf files
331*cdf0e10cSrcweir#------------------------------------
332*cdf0e10cSrcweirsub read_loc {
333*cdf0e10cSrcweir    print "\n\nReading localized titles...";
334*cdf0e10cSrcweir    $/ = "\n";
335*cdf0e10cSrcweir    my $path = "$source_dir/text";
336*cdf0e10cSrcweir    print " in $source_dir/text\n";
337*cdf0e10cSrcweir    @files = `find $source_dir/text -name localize.sdf`;
338*cdf0e10cSrcweir    for my $fname (@files) {
339*cdf0e10cSrcweir        $FS = '\t';
340*cdf0e10cSrcweir        print ".";
341*cdf0e10cSrcweir        open(LOCALIZE_SDF, $fname) || die 'Cannot open "localize.sdf".'."$fname";
342*cdf0e10cSrcweir        while (<LOCALIZE_SDF>) {
343*cdf0e10cSrcweir            my $sdf_line = $_;
344*cdf0e10cSrcweir	    my ($Fld1,$file,$Fld3,$Fld4,$id,$Fld6,$Fld7,$Fld8,$Fld9,$lang,$text) = split($FS, $sdf_line , 12);
345*cdf0e10cSrcweir            next if ( $Fld1 =~ /^#/);
346*cdf0e10cSrcweir	    if ($id eq 'tit') {
347*cdf0e10cSrcweir                #strip filename
348*cdf0e10cSrcweir                $file =~ s/.*text\\/text\\/g;
349*cdf0e10cSrcweir                #convert \ to / in filename
350*cdf0e10cSrcweir                $file =~ s/\\/\//g;
351*cdf0e10cSrcweir                #fpe: i46823 - need to encode &s, added encoding
352*cdf0e10cSrcweir                $text =~ s/&(?!amp;)/&amp;/g;
353*cdf0e10cSrcweir                # add entry to the hash
354*cdf0e10cSrcweir                $loc_title{$lang}->{$file} = $text;
355*cdf0e10cSrcweir            }
356*cdf0e10cSrcweir            if ($file =~ /tree_strings.xhp/) {
357*cdf0e10cSrcweir                #strip filename
358*cdf0e10cSrcweir                $file =~ s/.*text/text/g;
359*cdf0e10cSrcweir                #convert \ to / in filename
360*cdf0e10cSrcweir                $file =~ s/\\/\//g;
361*cdf0e10cSrcweir                if ($text =~ /^<help_section/) {
362*cdf0e10cSrcweir                    #example: <help_section application="scalc" id="08" title="表計算ドキュメント">
363*cdf0e10cSrcweir                    my ($fld1,$app,$fld3,$id,$fld5,$sec_title) = split('"', $text, 7);
364*cdf0e10cSrcweir                    #fpe: i46823 - need to encode &s, added encoding
365*cdf0e10cSrcweir                    if( defined $sec_title )
366*cdf0e10cSrcweir		            {
367*cdf0e10cSrcweir		    	        $sec_title =~ s/&(?!amp;)/&amp;/g;
368*cdf0e10cSrcweir		    	        #unquot \<item ... /\>
369*cdf0e10cSrcweir			            terminate( "\n\nERROR: Bad string in file '$fname' will cause invalid xml tree file \n---\n'$sdf_line'\n---\nPlease remove or replace < = '&lt;' and  > = '&gt;' within the title attribute '$sec_title'\n") , if( $sec_title =~ /[\<\>]/ );
370*cdf0e10cSrcweir		    	        $helpsection{$lang}->{$id} = $sec_title;
371*cdf0e10cSrcweir		            }
372*cdf0e10cSrcweir                } elsif ($text =~/<node id=/) {
373*cdf0e10cSrcweir                    # example: <node id="0205" title="Tabelas em documentos de texto">
374*cdf0e10cSrcweir                    # BEWARE: title may contain escaped '"' so only match " not preceded by \
375*cdf0e10cSrcweir                    # using a zero‐width negative look‐behind assertion.
376*cdf0e10cSrcweir                    my ($fld1,$id,$fld3,$node_title,$Fld5) = split(/(?<!\\)"/, $text, 5);
377*cdf0e10cSrcweir                    #fpe: i46823 - need to encode &s, added encoding
378*cdf0e10cSrcweir		            if( defined $node_title )
379*cdf0e10cSrcweir		            {
380*cdf0e10cSrcweir			            $node_title =~ s/&(?!amp;)/&amp;/g;
381*cdf0e10cSrcweir		   	            terminate( "\n\nERROR: Bad string in '$fname' will cause invalid xml tree file \n---\n'$sdf_line'\n---\nPlease remove or replace < = '&lt;' and  > = '&gt;' within the title attribute '$node_title'\n") , if( $node_title =~ /[\<\>]/ );
382*cdf0e10cSrcweir		            }
383*cdf0e10cSrcweir		            $node{$lang}->{$id} = $node_title;
384*cdf0e10cSrcweir                }
385*cdf0e10cSrcweir            }
386*cdf0e10cSrcweir        }
387*cdf0e10cSrcweir        close LOCALIZE_SDF;
388*cdf0e10cSrcweir    }
389*cdf0e10cSrcweir    # statistics
390*cdf0e10cSrcweir    $total_elements=0;
391*cdf0e10cSrcweir    foreach $lang (keys %loc_title) {
392*cdf0e10cSrcweir        $no_elements = scalar(keys(%{$loc_title{$lang}}));
393*cdf0e10cSrcweir        push(@langstat, "$lang:\t ".$no_elements." matches\n");
394*cdf0e10cSrcweir        $total_elements += $no_elements;
395*cdf0e10cSrcweir    }
396*cdf0e10cSrcweir    print "\ndone reading a total of ".$total_elements." localized titles for ".scalar(keys(%loc_title))." languages from ".scalar @files ." files\n";
397*cdf0e10cSrcweir    print sort(@langstat);
398*cdf0e10cSrcweir}
399*cdf0e10cSrcweir
400