]> git.lyx.org Git - features.git/blob - development/autotests/useSystemFonts.pl
Cmake export tests: Try to use language dependent inputencoding.
[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 sub getlangs($$);
63 sub getLangEntry();
64
65 # convert lyx file to be compilable with xetex
66
67 my ($source, $dest, $format, $fontT, $languageFile, $rest) = @ARGV;
68 my %encodings = ();      # Encoding with TeX fonts, depending on language tag
69
70 diestack("Too many arguments") if (defined($rest));
71 diestack("Sourcefilename not defined") if (! defined($source));
72 diestack("Destfilename not defined") if (! defined($dest));
73 diestack("Format (e.g. pdf4) not defined") if (! defined($format));
74 diestack("Font type (e.g. texF) not defined") if (! defined($fontT));
75
76 $source = File::Spec->rel2abs($source);
77 $dest = File::Spec->rel2abs($dest);
78
79 my %font = ();
80 my $lang = "main";
81 if ($source =~ /\/([a-z][a-z](_[A-Z][A-Z])?)[\/_]/) {
82   $lang = $1;
83 }
84
85 if (defined($languageFile)) {
86 }
87 my $inputEncoding = undef;
88 if ($fontT eq "systemF") {
89   if ($lang =~ /^(ru|uk|sk)$/) {
90     $font{roman} = "DejaVu Serif";
91     $font{sans} = "DejaVu Sans";
92     $font{typewriter} = "DejaVu Sans Mono";
93   }
94   elsif ($lang =~ /^(he|el|main)$/) {
95     $font{roman} = "FreeSans";
96     $font{sans} = "FreeSans";
97     $font{typewriter} = "FreeSans";
98   }
99   elsif ($lang eq "fa") {
100     $font{roman} = "FreeFarsi";
101     $font{sans} = "FreeFarsi";
102     $font{typewriter} = "FreeFarsi Monospace";
103   }
104   elsif ($lang eq "zh_CN") {
105     $font{roman} = "WenQuanYi Micro Hei";
106     $font{sans} = "WenQuanYi Micro Hei";
107     $font{typewriter} = "WenQuanYi Micro Hei";
108   }
109   elsif ($lang eq "ko" ) {
110     $font{roman} = "NanumGothic"; # NanumMyeongjo, NanumGothic Eco, NanumGothicCoding
111     $font{sans} = "NanumGothic";
112     $font{typewriter} = "NanumGothic";
113   }
114   elsif ($lang eq "ar" ) {
115     # available in 'fonts-sil-scheherazade' package
116     $font{roman} = "Scheherazade";
117     $font{sans} = "Scheherazade";
118     $font{typewriter} = "Scheherazade";
119   }
120   else {
121     # default system fonts
122     $font{roman} = "FreeSans";
123     $font{sans} = "FreeSans";
124     $font{typewriter} = "FreeSans";
125   }
126 }
127 else {
128   # use tex font here
129   my %encoding = ();
130   if (defined($languageFile)) {
131     &getlangs($languageFile, \%encoding);
132   }
133   if ($format =~ /^(pdf4)$/) { # xelatex
134     # set input encoding to 'ascii' always
135     $inputEncoding = {
136       "search" => '.*', # this will be substituted from '\inputencoding'-line
137       "out" => "ascii",
138     };
139   }
140   elsif ($format =~ /^(dvi3|pdf5)$/) { # (dvi)?lualatex
141     # when to set input encoding to 'ascii'?
142     if (defined($encoding{$lang})) {
143       $inputEncoding = {
144         "search" => 'auto|default', # this will be substituted from '\inputencoding'-line
145         "out" => $encoding{$lang},
146       };
147     }
148   }
149 }
150
151 my $sourcedir = dirname($source);
152 my $destdir = dirname($dest);
153 if (! -d $destdir) {
154   diestack("could not make dir \"$destdir\"") if (! mkdir $destdir);
155 }
156
157 my $destdirOfSubdocuments;
158 {
159   my ($name, $pat, $suffix) = fileparse($source, qr/\.[^.]*/);
160   my $ext = $format . "_$lang";
161   $destdirOfSubdocuments = "$destdir/tmp_$ext" . "_$name"; # Global var, something TODO here
162 }
163
164 if(-d $destdirOfSubdocuments) {
165   rmtree($destdirOfSubdocuments);
166 }
167 mkdir($destdirOfSubdocuments);  #  for possibly included files
168
169 my %IncludedFiles = ();
170 my %type2hash = (
171   "copy_only" => "copyonly",
172   "interpret" => "interpret");
173
174 addNewJob($source, $dest, "interpret", {}, \%IncludedFiles);
175
176 copyFoundSubdocuments(\%IncludedFiles);
177
178 #printCopiedDocuments(\%IncludedFiles);
179
180 exit(0);
181 ###########################################################
182
183 sub printCopiedDocuments($)
184 {
185   my ($rFiles) = @_;
186   for my $k (keys %{$rFiles}) {
187     my $rJob = $rFiles->{$k};
188     for my $j ( values %type2hash) {
189       if (defined($rJob->{$j})) {
190         print "$j: $k->$rJob->{$j}, " . $rJob->{$j . "copied"} . "\n";
191       }
192     }
193   }
194 }
195
196 sub interpretedCopy($$$$)
197 {
198   my ($source, $dest, $destdirOfSubdocuments, $rFiles) = @_;
199   my $sourcedir = dirname($source);
200   my $res = 0;
201
202   diestack("could not read \"$source\"") if (!open(FI, $source));
203   diestack("could not write \"$dest\"") if (! open(FO, '>', $dest));
204
205   initLyxStack(\%font, $fontT, $inputEncoding);
206
207   while (my $l = <FI>) {
208     chomp($l);
209     my $rStatus = checkLyxLine($l);
210     if ($rStatus->{found}) {
211       my $rF = $rStatus->{result};
212       if ($rStatus->{"filetype"} eq "replace_only") {
213         # e.g. if no files involved (font chage etc)
214         $l = join('', @{$rF});
215       }
216       else {
217         my $filelist = $rStatus->{filelist};
218         my $fidx = $rStatus->{fileidx};
219         my $separator = $rStatus->{"separator"};
220         my $foundrelative = 0;
221         for my $f (@{$filelist}) {
222           my @isrel = isrelative($f,
223                                   $sourcedir,
224                                   $rStatus->{ext});
225           if ($isrel[0]) {
226             $foundrelative = 1;
227             my $ext = $isrel[1];
228             if ($rStatus->{"filetype"} eq "prefix_only") {
229               $f = getNewNameOf("$sourcedir/$f", $rFiles);
230             }
231             else {
232               my ($newname, $res1);
233               ($newname, $res1) = addFileCopyJob("$sourcedir/$f$ext",
234                                                   "$destdirOfSubdocuments",
235                                                   $rStatus->{"filetype"},
236                                                   $rFiles);
237               print "Added ($res1) file \"$sourcedir/$f$ext\" to be copied to \"$newname\"\n";
238               if ($ext ne "") {
239                 $newname =~ s/$ext$//;
240               }
241               $f = $newname;
242               $res += $res1;
243             }
244           }
245         }
246         if ($foundrelative) {
247           $rF->[$fidx] = join($separator, @{$filelist});
248           $l = join('', @{$rF});
249         }
250       }
251     }
252     print FO "$l\n";
253   }
254   close(FI);
255   close(FO);
256
257   closeLyxStack();
258   return($res);
259 }
260
261 sub copyFoundSubdocuments($)
262 {
263   my ($rFiles) = @_;
264   my $res = 0;
265   do {
266     $res = 0;
267     my %copylist = ();
268
269     for my $filename (keys  %{$rFiles}) {
270       next if (! copyJobPending($filename, $rFiles));
271       $copylist{$filename} = 1;
272     }
273     for my $f (keys %copylist) {
274       # Second loop needed, because here $rFiles may change
275       my ($res1, @destfiles) = copyJob($f, $rFiles);
276       $res += $res1;
277       for my $destfile (@destfiles) {
278         print "res1 = $res1 for \"$f\" to be copied to $destfile\n";
279       }
280     }
281   } while($res > 0);            #  loop, while $rFiles changed
282 }
283
284 sub copyJob($$)
285 {
286   my ($source, $rFiles) = @_;
287   my $sourcedir = dirname($source);
288   my $res = 0;
289   my @dest = ();
290
291   for my $k (values %type2hash) {
292     if ($rFiles->{$source}->{$k}) {
293       if (! $rFiles->{$source}->{$k . "copied"}) {
294         $rFiles->{$source}->{$k . "copied"} = 1;
295         my $dest = $rFiles->{$source}->{$k};
296         push(@dest, $dest);
297         if ($k eq "copyonly") {
298           diestack("Could not copy \"$source\" to \"$dest\"") if (! cp($source, $dest));
299         }
300         else {
301           interpretedCopy($source, $dest, $destdirOfSubdocuments, $rFiles);
302         }
303         $res += 1;
304       }
305     }
306   }
307   return($res, @dest);
308 }
309
310 # Trivial check
311 sub isrelativeFix($$$)
312 {
313   my ($f, $sourcedir, $ext) = @_;
314
315   return(1, $ext) if  (-e "$sourcedir/$f$ext");
316   return(0,0);
317 }
318
319 sub isrelative($$$)
320 {
321   my ($f, $sourcedir, $ext) = @_;
322
323   if (ref($ext) eq "ARRAY") {
324     for my $ext2 (@{$ext}) {
325       my @res = isrelativeFix($f, $sourcedir, $ext2);
326       if ($res[0]) {
327         return(@res);
328       }
329     }
330     return(0,0);
331   }
332   else {
333     return(isrelativeFix($f, $sourcedir, $ext));
334   }
335 }
336
337 sub createTemporaryFileName($$)
338 {
339   my ($source, $destdir) = @_;
340
341   # get the basename to be used for the template
342   my ($name, $path, $suffix) = fileparse($source, qr/\.[^.]*/);
343   #print "source = $source, name = $name, path = $path, suffix = $suffix\n";
344   my $template = "xx_$name" . "_";
345   my $fname = File::Temp::tempnam($destdir, $template);
346
347   # Append extension from source
348   if ($suffix ne "") {
349     $fname .= "$suffix";
350   }
351   return($fname);
352 }
353
354 # Check, if file not copied yet
355 sub copyJobPending($$)
356 {
357   my ($f, $rFiles) = @_;
358   for my $t (values %type2hash) {
359     if (defined($rFiles->{$f}->{$t})) {
360       return 1 if (! $rFiles->{$f}->{$t . "copied"});
361     }
362   }
363   return 0;
364 }
365
366 sub addNewJob($$$$$)
367 {
368   my ($source, $newname, $hashname, $rJob, $rFiles) = @_;
369
370   $rJob->{$hashname} = $newname;
371   $rJob->{$hashname . "copied"} = 0;
372   $rFiles->{$source} = $rJob;
373 }
374
375 sub addFileCopyJob($$$$)
376 {
377   my ($source, $destdirOfSubdocuments, $filetype, $rFiles) = @_;
378   my ($res, $newname) = (0, undef);
379   my $rJob = $rFiles->{$source};
380
381   my $hashname = $type2hash{$filetype};
382   if (! defined($hashname)) {
383     diestack("unknown filetype \"$filetype\"");
384   }
385   if (!defined($rJob->{$hashname})) {
386     addNewJob($source,
387                createTemporaryFileName($source, $destdirOfSubdocuments),
388                "$hashname", $rJob, $rFiles);
389     $res = 1;
390   }
391   $newname = $rJob->{$hashname};
392   return($newname, $res);
393 }
394
395 sub getNewNameOf($$)
396 {
397   my ($f, $rFiles) = @_;
398   my $resultf = $f;
399
400   if (defined($rFiles->{$f})) {
401     for my $t (values %type2hash) {
402       if (defined($rFiles->{$f}->{$t})) {
403         $resultf = $rFiles->{$f}->{$t};
404         last;
405       }
406     }
407   }
408   return($resultf);
409 }
410
411 sub getlangs($$)
412 {
413   my ($languagefile, $rencoding) = @_;
414
415   if (open(FI, $languagefile)) {
416     while (my $l = <FI>) {
417       if ($l =~ /^Language/) {
418         my ($lng, $enc) = &getLangEntry();
419         if (defined($lng)) {
420           my @tag = split('_', $lng);
421           if ($tag[0] eq lc($tag[1])) {
422             $lng = $tag[0];
423           }
424           if (! defined($rencoding->{$lng})) {
425             $rencoding->{$lng} = $enc;
426           }
427         }
428       }
429     }
430     close(FI);
431   }
432 }
433
434 sub getLangEntry()
435 {
436   my ($lng, $enc) = (undef, undef);
437   while (my $l = <FI>) {
438     chomp($l);
439     if ($l =~ /^\s*Encoding\s+([^ ]+)\s*$/) {
440       $enc = $1;
441     }
442     elsif ($l =~ /^\s*LangCode\s+([^ ]+)\s*$/) {
443       $lng = $1;
444     }
445     elsif ($l =~ /^\s*End\s*$/) {
446       last;
447     }
448   }
449   if (defined($lng) && defined($enc)) {
450     return($lng, $enc);
451   }
452   else {
453     return(undef, undef);
454   }
455 }