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