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