4 # file useSystemFonts.pl
5 # 1.) Copies lyx-files to another location
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
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
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.
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.
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
33 # Copyright (c) 2013 Kornel Benko <kornel@lyx.org>
34 # (c) 2013 Scott Kostyshak <skotysh@lyx.org>
40 my $p = File::Spec->rel2abs( __FILE__ );
41 $p =~ s/[\/\\]?[^\/\\]+$//;
47 use File::Temp qw/ :POSIX /;
50 # convert lyx file to be compilable with xetex
52 my ($source, $dest, $format, $fontT, $rest) = @ARGV;
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));
60 $source = File::Spec->rel2abs($source);
61 $dest = File::Spec->rel2abs($dest);
65 if ($source =~ /\/([a-z][a-z](_[A-Z][A-Z])?)\//) {
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";
74 elsif ($lang eq "fa") {
75 $font{roman} = "FreeFarsi";
76 $font{sans} = "FreeFarsi";
77 $font{typewriter} = "FreeFarsi Monospace";
79 elsif ($lang eq "zh_CN") {
80 $font{roman} = "WenQuanYi Micro Hei";
81 $font{sans} = "WenQuanYi Micro Hei";
82 $font{typewriter} = "WenQuanYi Micro Hei";
85 # default system fonts
86 $font{roman} = "FreeSans";
87 $font{sans} = "FreeSans";
88 $font{typewriter} = "FreeSans";
95 my $sourcedir = dirname($source);
96 my $destdir = dirname($dest);
98 &diestack("could not make dir \"$destdir\"") if (! mkdir $destdir);
101 my $destdirOfSubdocuments;
103 my ($name, $pat, $suffix) = fileparse($source, qr/\.[^.]*/);
104 my $ext = $format . "_$lang";
105 $destdirOfSubdocuments = "$destdir/tmp_$ext" . "_$name"; # Global var, something TODO here
108 if(-d $destdirOfSubdocuments) {
109 rmtree($destdirOfSubdocuments);
111 mkdir($destdirOfSubdocuments); # for possibly included files
113 my %IncludedFiles = ();
115 "copy_only" => "copyonly",
116 "interpret" => "interpret");
118 &addNewJob($source, $dest, "interpret", {}, \%IncludedFiles);
120 ©FoundSubdocuments(\%IncludedFiles);
122 #&printCopiedDocuments(\%IncludedFiles);
125 ###########################################################
127 sub printCopiedDocuments($)
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";
140 sub interpretedCopy($$$$)
142 my ($source, $dest, $destdirOfSubdocuments, $rFiles) = @_;
143 my $sourcedir = dirname($source);
146 &diestack("could not read \"$source\"") if (!open(FI, $source));
147 &diestack("could not write \"$dest\"") if (! open(FO, '>', $dest));
149 &initLyxStack(\%font, $fontT);
151 while (my $l = <FI>) {
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});
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,
172 if ($rStatus->{"filetype"} eq "prefix_only") {
173 $f = &getNewNameOf("$sourcedir/$f", $rFiles);
176 my ($newname, $res1);
177 ($newname, $res1) = &addFileCopyJob("$sourcedir/$f$ext",
178 "$destdirOfSubdocuments",
179 $rStatus->{"filetype"},
181 print "Added ($res1) file \"$sourcedir/$f$ext\" to be copied to \"$newname\"\n";
183 $newname =~ s/$ext$//;
190 if ($foundrelative) {
191 $rF->[$fidx] = join($separator, @{$filelist});
192 $l = join('', @{$rF});
205 sub copyFoundSubdocuments($)
213 for my $filename (keys %{$rFiles}) {
214 next if (! ©JobPending($filename, $rFiles));
215 $copylist{$filename} = 1;
217 for my $f (keys %copylist) {
218 # Second loop needed, because here $rFiles may change
219 my ($res1, @destfiles) = ©Job($f, $rFiles);
221 for my $destfile (@destfiles) {
222 print "res1 = $res1 for \"$f\" to be copied to $destfile\n";
225 } while($res > 0); # loop, while $rFiles changed
230 my ($source, $rFiles) = @_;
231 my $sourcedir = dirname($source);
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};
241 if ($k eq "copyonly") {
242 &diestack("Could not copy \"$source\" to \"$dest\"") if (! cp($source, $dest));
245 &interpretedCopy($source, $dest, $destdirOfSubdocuments, $rFiles);
255 sub isrelativeFix($$$)
257 my ($f, $sourcedir, $ext) = @_;
259 return(1, $ext) if (-e "$sourcedir/$f$ext");
265 my ($f, $sourcedir, $ext) = @_;
267 if (ref($ext) eq "ARRAY") {
268 for my $ext2 (@{$ext}) {
269 my @res = &isrelativeFix($f, $sourcedir, $ext2);
277 return(&isrelativeFix($f, $sourcedir, $ext));
281 sub createTemporaryFileName($$)
283 my ($source, $destdir) = @_;
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);
291 # Append extension from source
298 # Check, if file not copied yet
299 sub copyJobPending($$)
301 my ($f, $rFiles) = @_;
302 for my $t (values %type2hash) {
303 if (defined($rFiles->{$f}->{$t})) {
304 return 1 if (! $rFiles->{$f}->{$t . "copied"});
312 my ($source, $newname, $hashname, $rJob, $rFiles) = @_;
314 $rJob->{$hashname} = $newname;
315 $rJob->{$hashname . "copied"} = 0;
316 $rFiles->{$source} = $rJob;
319 sub addFileCopyJob($$$$)
321 my ($source, $destdirOfSubdocuments, $filetype, $rFiles) = @_;
322 my ($res, $newname) = (0, undef);
323 my $rJob = $rFiles->{$source};
325 my $hashname = $type2hash{$filetype};
326 if (! defined($hashname)) {
327 &diestack("unknown filetype \"$filetype\"");
329 if (!defined($rJob->{$hashname})) {
331 &createTemporaryFileName($source, $destdirOfSubdocuments),
332 "$hashname", $rJob, $rFiles);
335 $newname = $rJob->{$hashname};
336 return($newname, $res);
341 my ($f, $rFiles) = @_;
344 if (defined($rFiles->{$f})) {
345 for my $t (values %type2hash) {
346 if (defined($rFiles->{$f}->{$t})) {
347 $resultf = $rFiles->{$f}->{$t};