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