2 ########################################################################
4 ########################################################################
6 Subroutines for `glilypond'.
8 Source file position: `<groff-source>/contrib/glilypond/subs.pl'
9 Installed position: `<prefix>/lib/groff/glilypond/subs.pl'
11 Copyright (C) 2013-2014 Free Software Foundation, Inc.
12 Written by Bernd Warken <groff-bernd.warken-72@web.de>
14 This file is part of `glilypond', which is part of `GNU groff'.
16 `GNU groff' is free software: you can redistribute it and/or modify it
17 under the terms of the `GNU General Public License' as published by the
18 `Free Software Foundation', either version 3 of the License, or (at your
19 option) any later version.
21 `GNU groff' is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the `GNU
24 General Public License' for more details.
26 You should have received a copy of the 'GNU General Public License`
27 along with `groff', see the files `COPYING' and `LICENSE' in the top
28 directory of the `groff' source package. If not, see
29 <http://www.gnu.org/licenses/>.
44 ########################################################################
45 # subs for using several times
46 ########################################################################
48 sub create_ly2eps { # `--ly2eps' default
49 our ( $out, $Read, $Temp );
51 my $prefix = $Read->{'file_numbered'}; # with dir change to temp dir
53 # `$ lilypond --ps -dbackend=eps -dgs-load-fonts \
54 # output=file_without_extension file.ly'
55 # extensions are added automatically
56 my $opts = '--ps -dbackend=eps -dinclude-eps-fonts -dgs-load-fonts ' .
57 "--output=$prefix $prefix";
58 &run_lilypond("$opts");
60 Cwd::chdir $Temp->{'cwd'} or
61 die "Could not change to former directory `" .
62 $Temp->{'cwd'} . "': $!";
64 my $eps_dir = $Temp->{'eps_dir'};
65 my $dir = $Temp->{'temp_dir'};
66 opendir( my $dh, $dir ) or
67 die "could not open temporary directory `$dir': $!";
78 while ( readdir( $dh ) ) {
82 my $file_path = File::Spec->catfile($dir, $file);
84 my $could_copy = FALSE;
85 File::Copy::copy($file_path, $eps_dir)
86 and $could_copy = TRUE;
89 $file_path = File::Spec->catfile($eps_dir, $_);
92 $out->print( '.PSPIC ' . $file_path );
96 } # end sub create_ly2eps()
99 sub create_pdf2eps { # `--pdf2eps'
100 our ( $v, $stdout, $stderr, $out, $Read, $Temp );
102 my $prefix = $Read->{'file_numbered'}; # with dir change to temp dir
104 &run_lilypond("--pdf --output=$prefix $prefix");
106 my $file_pdf = $prefix . '.pdf';
107 my $file_ps = $prefix . '.ps';
110 my $temp_file = &next_temp_file;
111 $v->print( "\n##### run of `pdf2ps'" );
112 # `$ pdf2ps file.pdf file.ps'
113 my $output = `pdf2ps $file_pdf $file_ps 2> $temp_file`;
114 die 'Program pdf2ps does not work.' if ( $? );
115 &shell_handling($output, $temp_file);
116 $v->print( "##### end run of `pdf2ps'\n" );
119 $temp_file = &next_temp_file;
120 $v->print( "\n##### run of `ps2eps'" );
122 $output = `ps2eps $file_ps 2> $temp_file`;
123 die 'Program ps2eps does not work.' if ( $? );
124 &shell_handling($output, $temp_file);
125 $v->print( "##### end run of `ps2eps'\n" );
127 # change back to former dir
128 Cwd::chdir $Temp->{'cwd'} or
129 die "Could not change to former directory `" .
130 $Temp->{'cwd'} . "': $!";
132 # handling of .eps file
133 my $file_eps = $prefix . '.eps';
134 my $eps_path = File::Spec->catfile($Temp->{'temp_dir'}, $file_eps);
135 if ( $Temp->{'eps_dir'} ) {
136 my $has_copied = FALSE;
137 File::Copy::copy( $eps_path, $Temp->{'eps_dir'} )
138 and $has_copied = TRUE;
141 $eps_path = File::Spec->catfile( $Temp->{'eps_dir'}, $file_eps );
143 $stderr->print( "Could not use EPS-directory." );
144 } # end Temp->{'eps_dir'}
146 # print into groff output
147 $out->print( '.PSPIC ' . $eps_path );
148 } # end sub create_pdf2eps()
151 sub is_subdir { # arg1 is subdir of arg2 (is longer)
152 my ( $dir1, $dir2 ) = @_;
153 $dir1 = &path2abs( $dir1 );;
154 $dir2 = &path2abs( $dir2 );;
155 my @split1 = File::Spec->splitdir($dir1);
156 my @split2 = File::Spec->splitdir($dir2);
158 next if ( $_ eq shift @split1 );
166 our ( $Legalese, $stdout );
168 $stdout->print( $Legalese->{'license'} );
169 } # end sub license()
172 sub make_dir { # make directory or check if it exists
177 $dir_arg =~ s/^\s*(.*)\s*$/$1/;
179 unless ( $dir_arg ) {
180 $v->print( "make_dir(): empty argument" );
184 unless ( File::Spec->file_name_is_absolute($dir_arg) ) {
185 my $res = Cwd::realpath($dir_arg);
186 $res = File::Spec->canonpath($dir_arg) unless ( $res );
187 $dir_arg = $res if ( $res );
190 return $dir_arg if ( -d $dir_arg && -w $dir_arg );
193 # search thru the dir parts
194 my @dir_parts = File::Spec->splitdir($dir_arg);
197 my $can_create = FALSE; # dir could be created if TRUE
199 DIRPARTS: for ( @dir_parts ) {
201 next DIRPARTS unless ( $_ ); # empty string for root directory
203 # from array to path dir string
204 $dir_grow = File::Spec->catdir(@dir_grow);
206 next DIRPARTS if ( -d $dir_grow );
208 if ( -e $dir_grow ) { # exists, but not a dir, so must be removed
209 die "Couldn't create dir `$dir_arg', it is blocked by `$dir_grow'."
210 unless ( -w $dir_grow );
212 # now it's writable, but not a dir, so it can be removed
213 unlink ( $dir_grow ) or
214 die "Couldn't remove `$dir_grow', " .
215 "so I cannot create dir `$dir_arg': $!";
218 # $dir_grow does no longer exist, so the former dir must be writable
219 # in order to create the directory
221 $dir_grow = File::Spec->catdir(@dir_grow);
223 die "`$dir_grow' is not writable, " .
224 "so directory `$dir_arg' can't be createdd."
225 unless ( -w $dir_grow );
227 # former directory is writable, so `$dir_arg' can be created
229 File::Path::make_path( $dir_arg,
232 verbose => $Args->{'verbose'},
235 or die "Could not create directory `$dir_arg': $!";
240 die "`$dir_arg' is not a writable directory"
241 unless ( -d $dir_arg && -w $dir_arg );
245 } # end sub make_dir()
250 our ( $Temp, $v, $Args );
252 my $temp_basename = $Args->{'prefix'} . '_temp_' . $number;
253 my $temp_file = File::Spec->catfile( $Temp->{'temp_dir'} ,
255 $v->print( "next temporary file: `$temp_file'" );
257 } # end sub next_temp_file()
261 our ( $Temp, $Args );
274 die "path2abs(): argument is empty." unless ( $path );
276 # Perl does not support shell `~' for home dir
281 if ( $path eq '~' ) { # only own home
282 $path = File::HomeDir->my_home;
283 } elsif ( $path =~ m<
290 >x ) { # subdir of own home
291 $path = File::Spec->catdir( $Temp->{'cwd'}, $1 );
292 } elsif ( $path =~ m<
299 >x ) { # home of other user
300 $path = File::HomeDir->users_home($1);
301 } elsif ( $path =~ m<
312 >x ) { # subdir of other home
314 catdir( File::HomeDir->users_home($1), $2 );
318 $path = File::Spec->rel2abs($path);
320 # now $path is absolute
322 } # end sub path2abs()
326 # arg is the options collection for `lilypond' to run
327 # either from ly or pdf
334 my $temp_file = &next_temp_file;
335 my $output = EMPTYSTRING;
338 Cwd::chdir $Temp->{'temp_dir'} or
339 die "Could not change to temporary directory `" .
340 $Temp->{'temp_dir'} . "': $!";
342 $v->print( "\n##### run of `lilypond " . $opts . "'" );
343 $output = `lilypond $opts 2>$temp_file`;
344 die "Program lilypond does not work, see `$temp_file': $?"
347 &shell_handling($output, $temp_file);
348 $v->print( "##### end run of `lilypond'\n" );
351 } # end sub run_lilypond()
355 # Handle ``-shell-command output in a string (arg1).
356 # stderr goes to temporary file $TempFile.
358 our ( $out, $v, $Args );
360 my $out_string = shift;
361 my $temp_file = shift;
363 my $a = &string2array($out_string); # array ref
368 $temp_file && -f $temp_file && -r $temp_file ||
369 die "shell_handling(): $temp_file is not a readable file.";
370 my $temp = new FH_READ_FILE($temp_file);
371 my $res = $temp->read_all();
377 unlink $temp_file unless ( $Args->{'keep_all'} );
378 } # end sub shell_handling()
384 for ( split "\n", $s ) {
389 } # end string2array()
392 sub usage { # for `--help'
393 our ( $Globals, $Args );
395 my $p = $Globals->{'prog'};
396 my $usage = EMPTYSTRING;
397 $usage = '###### usage:' . "\n" if ( $Args->{'verbose'} );
398 $usage .= qq*Options for $p:
399 Read a `roff' file or standard input and transform `lilypond' parts
400 (everything between `.lilypond start' and `.lilypond end') into
401 `EPS'-files that can be read by groff using `.PSPIC'.
403 There is also a command `.lilypond include <file_name>' that can
404 include a complete `lilypond' file into the `groff' document.
408 $p -?|-h|--help|--usage # usage
409 $p --version # version information
410 $p --license # the license is GPL >= 3
414 $p [options] [--] [filename ...]
416 There are 2 options for influencing the way how the `EPS' files for the
417 `roff' display are generated:
418 --ly2eps `lilypond' generates `EPS' files directly (default)
419 --pdf2eps `lilypond' generates a `PDF' file that is transformed
421 -k|--keep_all do not delete any temporary files
422 -v|--verbose print much information to STDERR
424 Options with an argument:
425 -e|--eps_dir=... use a directory for the EPS files
426 -o|--output=... sent output in the groff language into file ...
427 -p|--prefix=... start for the names of temporary files
428 -t|--temp_dir=... provide the directory for temporary files.
430 The directories set are created when they do not exist.
434 # --keep_files -k: do not delete any temporary files
435 # --file_prefix=... -p: start for the names of temporary files
437 $main::stdout->print( $usage );
441 sub version { # for `--version'
442 our ( $Globals, $Legalese, $stdout, $Args );
444 if ( $Globals->{'groff_version'} ) {
445 $end = " version $Globals->{'groff_version'}";
450 my $output = EMPTYSTRING;
451 $output = "###### version:\n" if ( $Args->{'verbose'} );
452 $output .= "`" . $Globals->{'prog'} . "' version `" .
453 $Legalese->{'version'} . "' is part of `GNU groff'" . $end;
455 $stdout->print($output);
456 } # end sub version()
462 ########################################################################