]> git.lyx.org Git - features.git/blob - development/autotests/useSystemFonts.pl
Ctests perl scripts: Added use of prototypes
[features.git] / development / autotests / useSystemFonts.pl
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 #
4 # file useSystemFonts.pl
5 # 1.) Copies lyx-files to another location
6 # 2.) While copying,
7 #   2a.) searches for relative references to files and
8 #        replaces them with absolute ones
9 #   2b.) In order to be able to compile with luatex or xetex
10 #        changes default fonts to use non-tex-fonts instead
11 #
12 # Syntax: perl useSystemFonts.pl sourceFile destFile format
13 # Each param represents a path to a file
14 # sourceFile: full path to a lyx file
15 # destFile: destination path
16 #   Each subdocument will be copied into a subdirectory of dirname(destFile)
17 # format: any string of the form '[a-zA-Z0-9]+', e.g. pdf5
18 #
19 # This file is free software; you can redistribute it and/or
20 # modify it under the terms of the GNU General Public
21 # License as published by the Free Software Foundation; either
22 # version 2 of the License, or (at your option) any later version.
23 #
24 # This software is distributed in the hope that it will be useful,
25 # but WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27 # General Public License for more details.
28 #
29 # You should have received a copy of the GNU General Public
30 # License along with this software; if not, write to the Free Software
31 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
32 #
33 # Copyright (c) 2013 Kornel Benko <kornel@lyx.org>
34 #           (c) 2013 Scott Kostyshak <skotysh@lyx.org>
35
36 use strict;
37
38 BEGIN {
39   use File::Spec;
40   my $p = File::Spec->rel2abs( __FILE__ );
41   $p =~ s/[\/\\]?[^\/\\]+$//;
42   unshift(@INC, "$p");
43 }
44 use File::Basename;
45 use File::Path;
46 use File::Copy "cp";
47 use File::Temp qw/ :POSIX /;
48 use lyxStatus;
49
50 # Prototypes
51 sub printCopiedDocuments($);
52 sub interpretedCopy($$$$);
53 sub copyFoundSubdocuments($);
54 sub copyJob($$);
55 sub isrelativeFix($$$);
56 sub isrelative($$$);
57 sub createTemporaryFileName($$);
58 sub copyJobPending($$);
59 sub addNewJob($$$$$);
60 sub addFileCopyJob($$$$);
61 sub getNewNameOf($$);
62
63 # convert lyx file to be compilable with xetex
64
65 my ($source, $dest, $format, $fontT, $rest) = @ARGV;
66
67 diestack("Too many arguments") if (defined($rest));
68 diestack("Sourcefilename not defined") if (! defined($source));
69 diestack("Destfilename not defined") if (! defined($dest));
70 diestack("Format (e.g. pdf4) not defined") if (! defined($format));
71 diestack("Font type (e.g. texF) not defined") if (! defined($fontT));
72
73 $source = File::Spec->rel2abs($source);
74 $dest = File::Spec->rel2abs($dest);
75
76 my %font = ();
77 my $lang = "main";
78 if ($source =~ /\/([a-z][a-z](_[A-Z][A-Z])?)\//) {
79   $lang = $1;
80 }
81 if ($fontT eq "systemF") {
82   if ($lang =~ /^(he|el|ru|uk|main)$/) {
83     $font{roman} = "FreeSans";
84     $font{sans} = "FreeSans";
85     $font{typewriter} = "FreeSans";
86   }
87   elsif ($lang eq "fa") {
88     $font{roman} = "FreeFarsi";
89     $font{sans} = "FreeFarsi";
90     $font{typewriter} = "FreeFarsi Monospace";
91   }
92   elsif ($lang eq "zh_CN") {
93     $font{roman} = "WenQuanYi Micro Hei";
94     $font{sans} = "WenQuanYi Micro Hei";
95     $font{typewriter} = "WenQuanYi Micro Hei";
96   }
97   else {
98     # default system fonts
99     $font{roman} = "FreeSans";
100     $font{sans} = "FreeSans";
101     $font{typewriter} = "FreeSans";
102   }
103 }
104 else {
105   # use tex font here
106 }
107
108 my $sourcedir = dirname($source);
109 my $destdir = dirname($dest);
110 if (! -d $destdir) {
111   diestack("could not make dir \"$destdir\"") if (! mkdir $destdir);
112 }
113
114 my $destdirOfSubdocuments;
115 {
116   my ($name, $pat, $suffix) = fileparse($source, qr/\.[^.]*/);
117   my $ext = $format . "_$lang";
118   $destdirOfSubdocuments = "$destdir/tmp_$ext" . "_$name"; # Global var, something TODO here
119 }
120
121 if(-d $destdirOfSubdocuments) {
122   rmtree($destdirOfSubdocuments);
123 }
124 mkdir($destdirOfSubdocuments);  #  for possibly included files
125
126 my %IncludedFiles = ();
127 my %type2hash = (
128   "copy_only" => "copyonly",
129   "interpret" => "interpret");
130
131 addNewJob($source, $dest, "interpret", {}, \%IncludedFiles);
132
133 copyFoundSubdocuments(\%IncludedFiles);
134
135 #printCopiedDocuments(\%IncludedFiles);
136
137 exit(0);
138 ###########################################################
139
140 sub printCopiedDocuments($)
141 {
142   my ($rFiles) = @_;
143   for my $k (keys %{$rFiles}) {
144     my $rJob = $rFiles->{$k};
145     for my $j ( values %type2hash) {
146       if (defined($rJob->{$j})) {
147         print "$j: $k->$rJob->{$j}, " . $rJob->{$j . "copied"} . "\n";
148       }
149     }
150   }
151 }
152
153 sub interpretedCopy($$$$)
154 {
155   my ($source, $dest, $destdirOfSubdocuments, $rFiles) = @_;
156   my $sourcedir = dirname($source);
157   my $res = 0;
158
159   diestack("could not read \"$source\"") if (!open(FI, $source));
160   diestack("could not write \"$dest\"") if (! open(FO, '>', $dest));
161
162   initLyxStack(\%font, $fontT);
163
164   while (my $l = <FI>) {
165     chomp($l);
166     my $rStatus = checkLyxLine($l);
167     if ($rStatus->{found}) {
168       my $rF = $rStatus->{result};
169       if ($rStatus->{"filetype"} eq "replace_only") {
170         # e.g. if no files involved (font chage etc)
171         $l = join('', @{$rF});
172       }
173       else {
174         my $filelist = $rStatus->{filelist};
175         my $fidx = $rStatus->{fileidx};
176         my $separator = $rStatus->{"separator"};
177         my $foundrelative = 0;
178         for my $f (@{$filelist}) {
179           my @isrel = isrelative($f,
180                                   $sourcedir,
181                                   $rStatus->{ext});
182           if ($isrel[0]) {
183             $foundrelative = 1;
184             my $ext = $isrel[1];
185             if ($rStatus->{"filetype"} eq "prefix_only") {
186               $f = getNewNameOf("$sourcedir/$f", $rFiles);
187             }
188             else {
189               my ($newname, $res1);
190               ($newname, $res1) = addFileCopyJob("$sourcedir/$f$ext",
191                                                   "$destdirOfSubdocuments",
192                                                   $rStatus->{"filetype"},
193                                                   $rFiles);
194               print "Added ($res1) file \"$sourcedir/$f$ext\" to be copied to \"$newname\"\n";
195               if ($ext ne "") {
196                 $newname =~ s/$ext$//;
197               }
198               $f = $newname;
199               $res += $res1;
200             }
201           }
202         }
203         if ($foundrelative) {
204           $rF->[$fidx] = join($separator, @{$filelist});
205           $l = join('', @{$rF});
206         }
207       }
208     }
209     print FO "$l\n";
210   }
211   close(FI);
212   close(FO);
213
214   closeLyxStack();
215   return($res);
216 }
217
218 sub copyFoundSubdocuments($)
219 {
220   my ($rFiles) = @_;
221   my $res = 0;
222   do {
223     $res = 0;
224     my %copylist = ();
225
226     for my $filename (keys  %{$rFiles}) {
227       next if (! copyJobPending($filename, $rFiles));
228       $copylist{$filename} = 1;
229     }
230     for my $f (keys %copylist) {
231       # Second loop needed, because here $rFiles may change
232       my ($res1, @destfiles) = copyJob($f, $rFiles);
233       $res += $res1;
234       for my $destfile (@destfiles) {
235         print "res1 = $res1 for \"$f\" to be copied to $destfile\n";
236       }
237     }
238   } while($res > 0);            #  loop, while $rFiles changed
239 }
240
241 sub copyJob($$)
242 {
243   my ($source, $rFiles) = @_;
244   my $sourcedir = dirname($source);
245   my $res = 0;
246   my @dest = ();
247
248   for my $k (values %type2hash) {
249     if ($rFiles->{$source}->{$k}) {
250       if (! $rFiles->{$source}->{$k . "copied"}) {
251         $rFiles->{$source}->{$k . "copied"} = 1;
252         my $dest = $rFiles->{$source}->{$k};
253         push(@dest, $dest);
254         if ($k eq "copyonly") {
255           diestack("Could not copy \"$source\" to \"$dest\"") if (! cp($source, $dest));
256         }
257         else {
258           interpretedCopy($source, $dest, $destdirOfSubdocuments, $rFiles);
259         }
260         $res += 1;
261       }
262     }
263   }
264   return($res, @dest);
265 }
266
267 # Trivial check
268 sub isrelativeFix($$$)
269 {
270   my ($f, $sourcedir, $ext) = @_;
271
272   return(1, $ext) if  (-e "$sourcedir/$f$ext");
273   return(0,0);
274 }
275
276 sub isrelative($$$)
277 {
278   my ($f, $sourcedir, $ext) = @_;
279
280   if (ref($ext) eq "ARRAY") {
281     for my $ext2 (@{$ext}) {
282       my @res = isrelativeFix($f, $sourcedir, $ext2);
283       if ($res[0]) {
284         return(@res);
285       }
286     }
287     return(0,0);
288   }
289   else {
290     return(isrelativeFix($f, $sourcedir, $ext));
291   }
292 }
293
294 sub createTemporaryFileName($$)
295 {
296   my ($source, $destdir) = @_;
297
298   # get the basename to be used for the template
299   my ($name, $path, $suffix) = fileparse($source, qr/\.[^.]*/);
300   #print "source = $source, name = $name, path = $path, suffix = $suffix\n";
301   my $template = "xx_$name" . "_";
302   my $fname = File::Temp::tempnam($destdir, $template);
303
304   # Append extension from source
305   if ($suffix ne "") {
306     $fname .= "$suffix";
307   }
308   return($fname);
309 }
310
311 # Check, if file not copied yet
312 sub copyJobPending($$)
313 {
314   my ($f, $rFiles) = @_;
315   for my $t (values %type2hash) {
316     if (defined($rFiles->{$f}->{$t})) {
317       return 1 if (! $rFiles->{$f}->{$t . "copied"});
318     }
319   }
320   return 0;
321 }
322
323 sub addNewJob($$$$$)
324 {
325   my ($source, $newname, $hashname, $rJob, $rFiles) = @_;
326
327   $rJob->{$hashname} = $newname;
328   $rJob->{$hashname . "copied"} = 0;
329   $rFiles->{$source} = $rJob;
330 }
331
332 sub addFileCopyJob($$$$)
333 {
334   my ($source, $destdirOfSubdocuments, $filetype, $rFiles) = @_;
335   my ($res, $newname) = (0, undef);
336   my $rJob = $rFiles->{$source};
337
338   my $hashname = $type2hash{$filetype};
339   if (! defined($hashname)) {
340     diestack("unknown filetype \"$filetype\"");
341   }
342   if (!defined($rJob->{$hashname})) {
343     addNewJob($source,
344                createTemporaryFileName($source, $destdirOfSubdocuments),
345                "$hashname", $rJob, $rFiles);
346     $res = 1;
347   }
348   $newname = $rJob->{$hashname};
349   return($newname, $res);
350 }
351
352 sub getNewNameOf($$)
353 {
354   my ($f, $rFiles) = @_;
355   my $resultf = $f;
356
357   if (defined($rFiles->{$f})) {
358     for my $t (values %type2hash) {
359       if (defined($rFiles->{$f}->{$t})) {
360         $resultf = $rFiles->{$f}->{$t};
361         last;
362       }
363     }
364   }
365   return($resultf);
366 }