App-Music-ChordPro

 view release on metacpan or  search on metacpan

lib/ChordPro/Delegate/Program.pm  view on Meta::CPAN

	// whose name is prepended to the command arguments.
	// Alternatively, the name of one of the predefined temporary
	// files (%{tmpfile1} and %{tmpfile2}) can be used. Do not
	// forget to add this name to the command arguments.
	input   : argfile

	// Get the resultant output from a (temporary) file.
	// Use value "stdout" to collect results from standard output.
	// Note that lilypond will append "cropped.svg", so we pass
	// the base of the file names.
	result  : "%{tmpbase}.cropped.svg"

	// Command argumenta.
	args    : [ -dno-point-and-click --svg --silent
		    // Output to...
		    --output "%{tmpbase}"
		    // Input from... (appended, see "argfile" above)
		  ]

        // Preprocessing. "first" and "last" are applied to the whole
        // data at once. "lines" is applied line by line, after "first"
        // and before "last".
        preprocess {
            first : [ {...} ]
            lines : [ {...} ]
            last  : [ {...} ]
        }

	// (Optional) Input lines to prepend to the user data.
	preamble : [
	    '\\version "2.21.0"'
	    "#(ly:set-option 'crop #t)",
	    "\\header { tagline = ##f }"
	]

	// (Optional) Input lines to apppend to the user data.
	postamble : []

	// Default alignment is center, but ly delegate wants left.
	align     : left

    }
  }

Example of usage:

  {start_of_ly}
  \relative c''{ c d e f }
  {end_of_ly}

Notes:

  * No attribute options in the input.

=cut

use ChordPro::Files;
use ChordPro::Utils qw(dimension maybe make_preprocessor);
use ChordPro::Output::Common qw(fmt_subst);
use IPC::Run3 qw(run3);
use Ref::Util qw( is_arrayref );
use ChordPro::Utils qw(detect_image_format);

sub DEBUG() { $::config->{debug}->{x1} }

sub cmd2image( $song, %args ) {
    my $elt = $args{elt};
    my $ctl = { %{ $::config->{delegates}->{$elt->{context}} } };
    _cmd2image( $song, $ctl, %args );
}

sub _cmd2image( $song, $ctl, %args ) {
    my $elt = $args{elt};
    my $kv = { %{$elt->{opts}} };
    my $context = $elt->{context};

    # Default alignment.
    $kv->{align} //= $ctl->{align};

    if ( DEBUG > 1 ) {
	use DDP; p %args, as => "args";
	use DDP; p $elt,  as => "elt";
	use DDP; p $kv,   as => "opts";
	use DDP; p $ctl,  as => "ctl";
    }

    # Predefined temporary (file) names.
    state $imgcnt++;
    state $td = File::Temp::tempdir( CLEANUP => !DEBUG );
    my $tmpbase   = fn_catfile( $td, "tmp${imgcnt}" );
    my $tmpfile1  = fn_catfile( $td, "tmp${imgcnt}a.tmp" );
    my $tmpfile2  = fn_catfile( $td, "tmp${imgcnt}b.tmp" );

    # Prepare meta for substitutions.
    my $ss = { meta => { %{$song->{meta}},
			 tmpdir   => $td,
			 tmpbase  => $tmpbase,
			 tmpfile1 => $tmpfile1,
			 tmpfile2 => $tmpfile2,
			 %$kv } };
    my $subst = sub($t) { defined($t) ? fmt_subst( $ss, $t ) : "" };

    # Transfer command arguments.
    my @cmd;
    for ( @{$ctl->{args}} ) {
	push( @cmd, $subst->($_) );
    }

    #### Input handling ####

    my $input  = $subst->($ctl->{input})  || "stdin";
    my @data = @{$elt->{data}};

    # Preprocessor.
    my $prep = make_preprocessor( $ctl->{preprocess} );

    my $data;
    if ( $prep->{first} ) {
	$data = join( "\n", @data );
	$::config->{debug}->{pp} && warn("PRE[first]: ---\n", $data, "\n---\n");
	$prep->{first}->($data);



( run in 0.992 second using v1.01-cache-2.11-cpan-ceb78f64989 )