diff options
author | wl <wl> | 2013-08-11 08:30:04 +0000 |
---|---|---|
committer | wl <wl> | 2013-08-11 08:30:04 +0000 |
commit | 0d475003833d6e09eeadbd81b35c8525437b6c16 (patch) | |
tree | 9b266499d38678e5188002323a0032c1d91b20b2 /contrib/glilypond/subs.pl | |
parent | dd226e578e7a8a0a13826c0039318e6ce7869141 (diff) | |
download | groff-0d475003833d6e09eeadbd81b35c8525437b6c16.tar.gz |
Revert accidental removal of previous files.
Diffstat (limited to 'contrib/glilypond/subs.pl')
-rw-r--r-- | contrib/glilypond/subs.pl | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/contrib/glilypond/subs.pl b/contrib/glilypond/subs.pl new file mode 100644 index 00000000..fa713d14 --- /dev/null +++ b/contrib/glilypond/subs.pl @@ -0,0 +1,469 @@ +my $License = q* +######################################################################## +# Legalese +######################################################################## + +Subroutines for `glilypond'. + +Source file position: `<groff-source>/contrib/glilypond/subs.pl' +Installed position: `<prefix>/lib/groff/glilypond/subs.pl' + +Copyright (C) 2013 Free Software Foundation, Inc. + Written by Bernd Warken <groff-bernd.warken-72@web.de> + + Last update: 10 May 2013 + +This file is part of `glilypond', which is part of `GNU groff'. + + `GNU groff' is free software: you can redistribute it and/or modify it +under the terms of the `GNU General Public License' as published by the +`Free Software Foundation', either version 3 of the License, or (at your +option) any later version. + + `GNU groff' is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the `GNU +General Public License' for more details. + + You should have received a copy of the 'GNU General Public License` +along with `groff', see the files `COPYING' and `LICENSE' in the top +directory of the `groff' source package. If not, see +<http://www.gnu.org/licenses/>. +*; + +##### end legalese + + +# use strict; +# use warnings; +# use diagnostics; + +use integer; +use utf8; +use feature 'state'; + + +######################################################################## +# subs for using several times +######################################################################## + +sub create_ly2eps { # `--ly2eps' default + our ( $out, $Read, $Temp ); + + my $prefix = $Read->{'file_numbered'}; # with dir change to temp dir + + # `$ lilypond --ps -dbackend=eps -dgs-load-fonts \ + # output=file_without_extension file.ly' + # extensions are added automatically + my $opts = '--ps -dbackend=eps -dinclude-eps-fonts -dgs-load-fonts ' . + "--output=$prefix $prefix"; + &run_lilypond("$opts"); + + Cwd::chdir $Temp->{'cwd'} or + die "Could not change to former directory `" . + $Temp->{'cwd'} . "': $!"; + + my $eps_dir = $Temp->{'eps_dir'}; + my $dir = $Temp->{'temp_dir'}; + opendir( my $dh, $dir ) or + die "could not open temporary directory `$dir': $!"; + + my $re = qr< + ^ + $prefix + - + .* + \.eps + $ + >x; + my $file; + while ( readdir( $dh ) ) { + chomp; + $file = $_; + if ( /$re/ ) { + my $file_path = File::Spec->catfile($dir, $file); + if ( $eps_dir ) { + my $could_copy = FALSE; + File::Copy::copy($file_path, $eps_dir) + and $could_copy = TRUE; + if ( $could_copy ) { + unlink $file_path; + $file_path = File::Spec->catfile($eps_dir, $_); + } + } + $out->print( '.PSPIC ' . $file_path ); + } + } # end while readdir + closedir( $dh ); +} # end sub create_ly2eps() + + +sub create_pdf2eps { # `--pdf2eps' + our ( $v, $stdout, $stderr, $out, $Read, $Temp ); + + my $prefix = $Read->{'file_numbered'}; # with dir change to temp dir + + &run_lilypond("--pdf --output=$prefix $prefix"); + + my $file_pdf = $prefix . '.pdf'; + my $file_ps = $prefix . '.ps'; + + # pdf2ps in temp dir + my $temp_file = &next_temp_file; + $v->print( "\n##### run of `pdf2ps'" ); + # `$ pdf2ps file.pdf file.ps' + my $output = `pdf2ps $file_pdf $file_ps 2> $temp_file`; + die 'Program pdf2ps does not work.' if ( $? ); + &shell_handling($output, $temp_file); + $v->print( "##### end run of `pdf2ps'\n" ); + + # ps2eps in temp dir + $temp_file = &next_temp_file; + $v->print( "\n##### run of `ps2eps'" ); + # `$ ps2eps file.ps' + $output = `ps2eps $file_ps 2> $temp_file`; + die 'Program ps2eps does not work.' if ( $? ); + &shell_handling($output, $temp_file); + $v->print( "##### end run of `ps2eps'\n" ); + + # change back to former dir + Cwd::chdir $Temp->{'cwd'} or + die "Could not change to former directory `" . + $Temp->{'cwd'} . "': $!"; + + # handling of .eps file + my $file_eps = $prefix . '.eps'; + my $eps_path = File::Spec->catfile($Temp->{'temp_dir'}, $file_eps); + if ( $Temp->{'eps_dir'} ) { + my $has_copied = FALSE; + File::Copy::copy( $eps_path, $Temp->{'eps_dir'} ) + and $has_copied = TRUE; + if ( $has_copied ) { + unlink $eps_path; + $eps_path = File::Spec->catfile( $Temp->{'eps_dir'}, $file_eps ); + } else { + $stderr->print( "Could not use EPS-directory." ); + } # end Temp->{'eps_dir'} + } + # print into groff output + $out->print( '.PSPIC ' . $eps_path ); +} # end sub create_pdf2eps() + + +sub is_subdir { # arg1 is subdir of arg2 (is longer) + my ( $dir1, $dir2 ) = @_; + $dir1 = &path2abs( $dir1 );; + $dir2 = &path2abs( $dir2 );; + my @split1 = File::Spec->splitdir($dir1); + my @split2 = File::Spec->splitdir($dir2); + for ( @split2 ) { + next if ( $_ eq shift @split1 ); + return FALSE; + } + return TRUE; +} + + +sub license { + our ( $Legalese, $stdout ); + &version; + $stdout->print( $Legalese->{'license'} ); +} # end sub license() + + +sub make_dir { # make directory or check if it exists + our ( $v, $Args ); + + my $dir_arg = shift; + chomp $dir_arg; + $dir_arg =~ s/^\s*(.*)\s*$/$1/; + + unless ( $dir_arg ) { + $v->print( "make_dir(): empty argument" ); + return FALSE; + } + + unless ( File::Spec->file_name_is_absolute($dir_arg) ) { + my $res = Cwd::realpath($dir_arg); + $res = File::Spec->canonpath($dir_arg) unless ( $res ); + $dir_arg = $res if ( $res ); + } + + return $dir_arg if ( -d $dir_arg && -w $dir_arg ); + + + # search thru the dir parts + my @dir_parts = File::Spec->splitdir($dir_arg); + my @dir_grow; + my $dir_grow; + my $can_create = FALSE; # dir could be created if TRUE + + DIRPARTS: for ( @dir_parts ) { + push @dir_grow, $_; + next DIRPARTS unless ( $_ ); # empty string for root directory + + # from array to path dir string + $dir_grow = File::Spec->catdir(@dir_grow); + + next DIRPARTS if ( -d $dir_grow ); + + if ( -e $dir_grow ) { # exists, but not a dir, so must be removed + die "Couldn't create dir `$dir_arg', it is blocked by `$dir_grow'." + unless ( -w $dir_grow ); + + # now it's writable, but not a dir, so it can be removed + unlink ( $dir_grow ) or + die "Couldn't remove `$dir_grow', " . + "so I cannot create dir `$dir_arg': $!"; + } + + # $dir_grow does no longer exist, so the former dir must be writable + # in order to create the directory + pop @dir_grow; + $dir_grow = File::Spec->catdir(@dir_grow); + + die "`$dir_grow' is not writable, " . + "so directory `$dir_arg' can't be createdd." + unless ( -w $dir_grow ); + + # former directory is writable, so `$dir_arg' can be created + + File::Path::make_path( $dir_arg, + { + mask => oct('0700'), + verbose => $Args->{'verbose'}, + } + ) # `mkdir -P' + or die "Could not create directory `$dir_arg': $!"; + + last DIRPARTS; + } + + die "`$dir_arg' is not a writable directory" + unless ( -d $dir_arg && -w $dir_arg ); + + return $dir_arg; + +} # end sub make_dir() + + +my $number = 0; +sub next_temp_file { + our ( $Temp, $v, $Args ); + ++$number; + my $temp_basename = $Args->{'prefix'} . '_temp_' . $number; + my $temp_file = File::Spec->catfile( $Temp->{'temp_dir'} , + $temp_basename ); + $v->print( "next temporary file: `$temp_file'" ); + return $temp_file; +} # end sub next_temp_file() + + +sub path2abs { + our ( $Temp, $Args ); + + my $path = shift; + $path =~ s/ + ^ + \s* + ( + .* + ) + \s* + $ + /$1/x; + + die "path2abs(): argument is empty." unless ( $path ); + + # Perl does not support shell `~' for home dir + if ( $path =~ / + ^ + ~ + /x ) { + if ( $path eq '~' ) { # only own home + $path = File::HomeDir->my_home; + } elsif ( $path =~ m< + ^ + ~ / + ( + .* + ) + $ + >x ) { # subdir of own home + $path = File::Spec->catdir( $Temp->{'cwd'}, $1 ); + } elsif ( $path =~ m< + ^ + ~ + ( + [^/]+ + ) + $ + >x ) { # home of other user + $path = File::HomeDir->users_home($1); + } elsif ( $path =~ m< + ^ + ~ + ( + [^/]+ + ) + /+ + ( + .* + ) + $ + >x ) { # subdir of other home + $path = File::Spec-> + catdir( File::HomeDir->users_home($1), $2 ); + } + } + + $path = File::Spec->rel2abs($path); + + # now $path is absolute + return $path; +} # end sub path2abs() + + +sub run_lilypond { + # arg is the options collection for `lilypond' to run + # either from ly or pdf + + our ( $Temp, $v ); + + my $opts = shift; + chomp $opts; + + my $temp_file = &next_temp_file; + my $output = EMPTYSTRING; + + # change to temp dir + Cwd::chdir $Temp->{'temp_dir'} or + die "Could not change to temporary directory `" . + $Temp->{'temp_dir'} . "': $!"; + + $v->print( "\n##### run of `lilypond " . $opts . "'" ); + $output = `lilypond $opts 2>$temp_file`; + die "Program lilypond does not work, see `$temp_file': $?" + if ( $? ); + chomp $output; + &shell_handling($output, $temp_file); + $v->print( "##### end run of `lilypond'\n" ); + + # stay in temp dir +} # end sub run_lilypond() + + +sub shell_handling { + # Handle ``-shell-command output in a string (arg1). + # stderr goes to temporary file $TempFile. + + our ( $out, $v, $Args ); + + my $out_string = shift; + my $temp_file = shift; + + my $a = &string2array($out_string); # array ref + for ( @$a ) { + $out->print( $_ ); + } + + $temp_file && -f $temp_file && -r $temp_file || + die "shell_handling(): $temp_file is not a readable file."; + my $temp = new FH_READ_FILE($temp_file); + my $res = $temp->read_all(); + for ( @$res ) { + chomp; + $v->print($_); + } + + unlink $temp_file unless ( $Args->{'keep_all'} ); +} # end sub shell_handling() + + +sub string2array { + my $s = shift; + my @a = (); + for ( split "\n", $s ) { + chomp; + push @a, $_; + } + return \@a; +} # end string2array() + + +sub usage { # for `--help' + our ( $Globals, $Args ); + + my $p = $Globals->{'prog'}; + my $usage = EMPTYSTRING; + $usage = '###### usage:' . "\n" if ( $Args->{'verbose'} ); + $usage .= qq*Options for $p: +Read a `roff' file or standard input and transform `lilypond' parts +(everything between `.lilypond start' and `.lilypond end') into +`EPS'-files that can be read by groff using `.PSPIC'. + +There is also a command `.lilypond include <file_name>' that can +include a complete `lilypond' file into the `groff' document. + + +# Breaking options: +$p -?|-h|--help|--usage # usage +$p --version # version information +$p --license # the license is GPL >= 3 + + +# Normal options: +$p [options] [--] [filename ...] + +There are 2 options for influencing the way how the `EPS' files for the +`roff' display are generated: +--ly2eps `lilypond' generates `EPS' files directly (default) +--pdf2eps `lilypond' generates a `PDF' file that is transformed + +-k|--keep_all do not delete any temporary files +-v|--verbose print much information to STDERR + +Options with an argument: +-e|--eps_dir=... use a directory for the EPS files +-o|--output=... sent output in the groff language into file ... +-p|--prefix=... start for the names of temporary files +-t|--temp_dir=... provide the directory for temporary files. + +The directories set are created when they do not exist. +*; + + # old options: + # --keep_files -k: do not delete any temporary files + # --file_prefix=... -p: start for the names of temporary files + + $main::stdout->print( $usage ); +} # end sub usage() + + +sub version { # for `--version' + our ( $Globals, $Legalese, $stdout, $Args ); + my $end; + if ( $Globals->{'groff_version'} ) { + $end = " version $Globals->{'groff_version'}"; + } else { + $end = '.'; + } + + my $output = EMPTYSTRING; + $output = "###### version:\n" if ( $Args->{'verbose'} ); + $output .= "`" . $Globals->{'prog'} . "' version `" . + $Legalese->{'version'} . "' of `" . + $Legalese->{'last_update'} . "' is part of `GNU groff'" . $end; + + $stdout->print($output); +} # end sub version() + + +# end of subs + +1; +######################################################################## +### Emacs settings +# Local Variables: +# mode: CPerl +# End: |