parse-wormedit: convert pbm format to monochrome pnm
[wormy.git] / parse-wormedit
index 0c94994a5ae79a122d603d924af658354a898a56..cf1798d6a25e6cb787b9836577add8782ec93aed 100755 (executable)
@@ -1,7 +1,8 @@
 #!/usr/bin/env perl
+use 5.010;
 use strict;
 use warnings;
-use 5.010;
+use experimental 'switch';
 use lib 'lib';  # make runnable for simple cases
 
 use Data::Dumper;
@@ -9,14 +10,17 @@ use Getopt::Long 2.33 qw(HelpMessage :config bundling);
 use Games::Wormy::TICalcLevels;
 use Games::Wormy::WormEdit;
 
-our $VERSION = '1.06';
+our $VERSION = '1.07';
 
 GetOptions(\my %opt,
-       'raw|r',  # full output
+       'format|f=s', # output type
+       'raw|r!',  # compatibility for yaml format
        'version=i',  # force version
-       'render:i',  # image of level(s)
+       'levels|render:i',  # image of level(s)
        'output|o=s',  # output file
 ) or HelpMessage(-exitval => 2);
+$opt{format} //= 'yaml' if $opt{raw};
+$opt{format} //= 'pnm'  if defined $opt{levels};
 
 my @OBJTYPE = ('none', 'line', 'fat line', 'bar', 'circle');
 my @ENDTYPE = ('none', 'message', 'small message');
@@ -50,12 +54,12 @@ else {
 
 if ($opt{output}) {{
        # derive format from file extension
-       if ($opt{output} =~ /\.yaml$/) {
-               $opt{raw} = 1;
+       if ($opt{output} =~ /\.(yaml|txt)$/) {
+               $opt{format} //= $1
        }
-       elsif ($opt{output} !~ /\.txt$/) {
-               $opt{render} ||= 0;
-               last;  # images are written directly to file
+       else {
+               # images are written directly to file
+               last;
        }
 
        # redirect standard output to given file
@@ -65,27 +69,8 @@ if ($opt{output}) {{
 }}
 
 # output with user-preferred formatting
-if (defined $opt{render}) {
-       require Games::Wormy::Render;
-
-       my @request;
-       if ($opt{render}) {
-               # find all numeric values in argument
-               @request = $opt{render} =~ /(\d+)/g;
-       }
-       else {
-               # default to all singleplayer levels
-               @request = 0 .. $data->{levelcount}->{single} - 1;
-       }
-
-       my $img = Games::Wormy::Render->composite(
-               map { $data->{levels}->[$_] } @request
-       );
-       $img->write(
-               $opt{output} ? (file => $opt{output}) : (fh => \*STDOUT, type => 'pnm')
-       ) or die $img->errstr;
-}
-elsif ($opt{raw}) {
+given ($opt{format}) {
+when ('yaml') {
        # full data in yaml (human-readable) formatting
        require YAML;
        local $YAML::CompressSeries;
@@ -107,7 +92,7 @@ elsif ($opt{raw}) {
 
        print $yml;
 }
-else {
+when ('txt') {
        print $data->{name};
        print " ($data->{description})" if defined $data->{description};
        print "\n";
@@ -160,6 +145,33 @@ else {
        }
        print "\n";
 }
+default {
+       require Games::Wormy::Render;
+
+       my @request;
+       if ($opt{levels}) {
+               # find all numeric values in argument
+               @request = $opt{levels} =~ /(\d+)/g;
+       }
+       else {
+               # default to all singleplayer levels
+               @request = 0 .. $data->{levelcount}->{single} - 1;
+       }
+       @request or die "no levels found or specified\n";
+
+       my $img = Games::Wormy::Render->composite(
+               map { $data->{levels}->[$_] } @request
+       ) or die "empty result for levels\n";
+       if ($opt{format} ~~ 'pbm') {
+               $img = $img->to_paletted({make_colors => 'mono'});
+               $opt{format} = 'pnm';
+       }
+       $img->write(
+               $opt{output} ? (file => $opt{output}) : (fh => \*STDOUT),
+               type => $opt{format} // 'pnm',
+       ) or die $img->errstr;
+}
+}
 
 __END__
 
@@ -169,14 +181,32 @@ parse-wormedit - Wormy level data parser
 
 =head1 SYNOPSIS
 
- parse-wormedit [--raw|--render] [--output <file.ext>] <input.lvl>
+ parse-wormedit [--format=<type>] [--levels=<number>] [--output=<file.ext>] <input.lvl>
 
 =head1 DESCRIPTION
 
 Reads Wormy levels (either original WormEdit source or compiled TI-86 string)
-from STDIN or given file, and prints summarised contents to STDOUT.
+from STDIN or given file, and prints parsed data to STDOUT.
+
+If an I<output> file name is given, its extension determines the format,
+otherwise explicitly given by the I<format> option:
+
+=over 6
+
+=item txt
+
+Plain text summary of levelpack contents.
+
+=item yaml
+
+All parsed data in YAML syntax.
+
+=item pnm, png, bmp, ...
+
+Image drawing of rendered levels.
+Unrecognised values are interpreted as file type and converted by Imager.
 
-If an I<output> file name is given, its extension determines the format.
+=back
 
 =head1 AUTHOR