]> git.lyx.org Git - lyx.git/blob - development/autotests/useSystemFonts.pl
55f520aef9b34ef95ba454038709c6fffc2cad89
[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 # convert lyx file to be compilable with xetex
51
52 my ($source, $dest, $format, $fontT, $rest) = @ARGV;
53
54 &diestack("Too many arguments") if (defined($rest));
55 &diestack("Sourcefilename not defined") if (! defined($source));
56 &diestack("Destfilename not defined") if (! defined($dest));
57 &diestack("Format (e.g. pdf4) not defined") if (! defined($format));
58 &diestack("Font type (e.g. texF) not defined") if (! defined($fontT));
59
60 $source = File::Spec->rel2abs($source);
61 $dest = File::Spec->rel2abs($dest);
62
63 my %font = ();
64 my $lang = "main";
65 if ($source =~ /\/([a-z][a-z](_[A-Z][A-Z])?)\//) {
66   $lang = $1;
67 }
68 if ($fontT eq "systemF") {
69   if ($lang =~ /^(he|el|ru|uk|main)$/) {
70     $font{roman} = "FreeSans";
71     $font{sans} = "FreeSans";
72     $font{typewriter} = "FreeSans";
73   }
74   elsif ($lang eq "fa") {
75     $font{roman} = "FreeFarsi";
76     $font{sans} = "FreeFarsi";
77     $font{typewriter} = "FreeFarsi Monospace";
78   }
79   elsif ($lang eq "zh_CN") {
80     $font{roman} = "WenQuanYi Micro Hei";
81     $font{sans} = "WenQuanYi Micro Hei";
82     $font{typewriter} = "WenQuanYi Micro Hei";
83   }
84   else {
85     # default system fonts
86     $font{roman} = "FreeSans";
87     $font{sans} = "FreeSans";
88     $font{typewriter} = "FreeSans";
89   }
90 }
91 else {
92   # use tex font here
93 }
94
95 my $sourcedir = dirname($source);
96 my $destdir = dirname($dest);
97 if (! -d $destdir) {
98   &diestack("could not make dir \"$destdir\"") if (! mkdir $destdir);
99 }
100
101 my $destdirOfSubdocuments;
102 {
103   my ($name, $pat, $suffix) = fileparse($source, qr/\.[^.]*/);
104   my $ext = $format . "_$lang";
105   $destdirOfSubdocuments = "$destdir/tmp_$ext" . "_$name"; # Global var, something TODO here
106 }
107
108 if(-d $destdirOfSubdocuments) {
109   rmtree($destdirOfSubdocuments);
110 }
111 mkdir($destdirOfSubdocuments);  #  for possibly included files
112
113 my %IncludedFiles = ();
114 my %type2hash = (
115   "copy_only" => "copyonly",
116   "interpret" => "interpret");
117
118 &addNewJob($source, $dest, "interpret", {}, \%IncludedFiles);
119
120 &copyFoundSubdocuments(\%IncludedFiles);
121
122 #&printCopiedDocuments(\%IncludedFiles);
123
124 exit(0);
125 ###########################################################
126
127 sub printCopiedDocuments($)
128 {
129   my ($rFiles) = @_;
130   for my $k (keys %{$rFiles}) {
131     my $rJob = $rFiles->{$k};
132     for my $j ( values %type2hash) {
133       if (defined($rJob->{$j})) {
134         print "$j: $k->$rJob->{$j}, " . $rJob->{$j . "copied"} . "\n";
135       }
136     }
137   }
138 }
139
140 sub interpretedCopy($$$$)
141 {
142   my ($source, $dest, $destdirOfSubdocuments, $rFiles) = @_;
143   my $sourcedir = dirname($source);
144   my $res = 0;
145
146   &diestack("could not read \"$source\"") if (!open(FI, $source));
147   &diestack("could not write \"$dest\"") if (! open(FO, '>', $dest));
148
149   &initLyxStack(\%font, $fontT);
150
151   while (my $l = <FI>) {
152     chomp($l);
153     my $rStatus = &checkLyxLine($l);
154     if ($rStatus->{found}) {
155       my $rF = $rStatus->{result};
156       if ($rStatus->{"filetype"} eq "replace_only") {
157         # e.g. if no files involved (font chage etc)
158         $l = join('', @{$rF});
159       }
160       else {
161         my $filelist = $rStatus->{filelist};
162         my $fidx = $rStatus->{fileidx};
163         my $separator = $rStatus->{"separator"};
164         my $foundrelative = 0;
165         for my $f (@{$filelist}) {
166           my @isrel = &isrelative($f,
167                                   $sourcedir,
168                                   $rStatus->{ext});
169           if ($isrel[0]) {
170             $foundrelative = 1;
171             my $ext = $isrel[1];
172             if ($rStatus->{"filetype"} eq "prefix_only") {
173               $f = &getNewNameOf("$sourcedir/$f", $rFiles);
174             }
175             else {
176               my ($newname, $res1);
177               ($newname, $res1) = &addFileCopyJob("$sourcedir/$f$ext",
178                                                   "$destdirOfSubdocuments",
179                                                   $rStatus->{"filetype"},
180                                                   $rFiles);
181               print "Added ($res1) file \"$sourcedir/$f$ext\" to be copied to \"$newname\"\n";
182               if ($ext ne "") {
183                 $newname =~ s/$ext$//;
184               }
185               $f = $newname;
186               $res += $res1;
187             }
188           }
189         }
190         if ($foundrelative) {
191           $rF->[$fidx] = join($separator, @{$filelist});
192           $l = join('', @{$rF});
193         }
194       }
195     }
196     print FO "$l\n";
197   }
198   close(FI);
199   close(FO);
200
201   &closeLyxStack();
202   return($res);
203 }
204
205 sub copyFoundSubdocuments($)
206 {
207   my ($rFiles) = @_;
208   my $res = 0;
209   do {
210     $res = 0;
211     my %copylist = ();
212
213     for my $filename (keys  %{$rFiles}) {
214       next if (! &copyJobPending($filename, $rFiles));
215       $copylist{$filename} = 1;
216     }
217     for my $f (keys %copylist) {
218       # Second loop needed, because here $rFiles may change
219       my ($res1, @destfiles) = &copyJob($f, $rFiles);
220       $res += $res1;
221       for my $destfile (@destfiles) {
222         print "res1 = $res1 for \"$f\" to be copied to $destfile\n";
223       }
224     }
225   } while($res > 0);            #  loop, while $rFiles changed
226 }
227
228 sub copyJob($$)
229 {
230   my ($source, $rFiles) = @_;
231   my $sourcedir = dirname($source);
232   my $res = 0;
233   my @dest = ();
234
235   for my $k (values %type2hash) {
236     if ($rFiles->{$source}->{$k}) {
237       if (! $rFiles->{$source}->{$k . "copied"}) {
238         $rFiles->{$source}->{$k . "copied"} = 1;
239         my $dest = $rFiles->{$source}->{$k};
240         push(@dest, $dest);
241         if ($k eq "copyonly") {
242           &diestack("Could not copy \"$source\" to \"$dest\"") if (! cp($source, $dest));
243         }
244         else {
245           &interpretedCopy($source, $dest, $destdirOfSubdocuments, $rFiles);
246         }
247         $res += 1;
248       }
249     }
250   }
251   return($res, @dest);
252 }
253
254 # Trivial check
255 sub isrelativeFix($$$)
256 {
257   my ($f, $sourcedir, $ext) = @_;
258
259   return(1, $ext) if  (-e "$sourcedir/$f$ext");
260   return(0,0);
261 }
262
263 sub isrelative($$$)
264 {
265   my ($f, $sourcedir, $ext) = @_;
266
267   if (ref($ext) eq "ARRAY") {
268     for my $ext2 (@{$ext}) {
269       my @res = &isrelativeFix($f, $sourcedir, $ext2);
270       if ($res[0]) {
271         return(@res);
272       }
273     }
274     return(0,0);
275   }
276   else {
277     return(&isrelativeFix($f, $sourcedir, $ext));
278   }
279 }
280
281 sub createTemporaryFileName($$)
282 {
283   my ($source, $destdir) = @_;
284
285   # get the basename to be used for the template
286   my ($name, $path, $suffix) = fileparse($source, qr/\.[^.]*/);
287   #print "source = $source, name = $name, path = $path, suffix = $suffix\n";
288   my $template = "xx_$name" . "_";
289   my $fname = File::Temp::tempnam($destdir, $template);
290
291   # Append extension from source
292   if ($suffix ne "") {
293     $fname .= "$suffix";
294   }
295   return($fname);
296 }
297
298 # Check, if file not copied yet
299 sub copyJobPending($$)
300 {
301   my ($f, $rFiles) = @_;
302   for my $t (values %type2hash) {
303     if (defined($rFiles->{$f}->{$t})) {
304       return 1 if (! $rFiles->{$f}->{$t . "copied"});
305     }
306   }
307   return 0;
308 }
309
310 sub addNewJob($$$)
311 {
312   my ($source, $newname, $hashname, $rJob, $rFiles) = @_;
313
314   $rJob->{$hashname} = $newname;
315   $rJob->{$hashname . "copied"} = 0;
316   $rFiles->{$source} = $rJob;
317 }
318
319 sub addFileCopyJob($$$$)
320 {
321   my ($source, $destdirOfSubdocuments, $filetype, $rFiles) = @_;
322   my ($res, $newname) = (0, undef);
323   my $rJob = $rFiles->{$source};
324
325   my $hashname = $type2hash{$filetype};
326   if (! defined($hashname)) {
327     &diestack("unknown filetype \"$filetype\"");
328   }
329   if (!defined($rJob->{$hashname})) {
330     &addNewJob($source,
331                &createTemporaryFileName($source, $destdirOfSubdocuments),
332                "$hashname", $rJob, $rFiles);
333     $res = 1;
334   }
335   $newname = $rJob->{$hashname};
336   return($newname, $res);
337 }
338
339 sub getNewNameOf($$)
340 {
341   my ($f, $rFiles) = @_;
342   my $resultf = $f;
343
344   if (defined($rFiles->{$f})) {
345     for my $t (values %type2hash) {
346       if (defined($rFiles->{$f}->{$t})) {
347         $resultf = $rFiles->{$f}->{$t};
348         last;
349       }
350     }
351   }
352   return($resultf);
353 }