#!/usr/bin/perl
# The Missing Textutils, Ondrej Bojar, obo@cuni.cz
# http://www.cuni.cz/~obo/textutils
#
# 'circumvent_blank_lines' removes blank lines from stdin, saving their
# linenumbers to the given auxiliary file.
# Later, use --reinsert=auxfile to reinsert the blank lines at appropriate
# places.
#
# $Id: circumvent_blank_lines,v 1.1 2012-03-26 08:31:38 bojar Exp $
#

use Getopt::Long;
use File::Path;
use File::Basename;
use strict;

binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");

my $reinsert = undef;
my $help = 0;
GetOptions(
  "reinsert=s" => \$reinsert,
  "help" => \$help,
) or exit(1);

my $auxfn = shift;

if (!defined $auxfn && !defined $reinsert && !$help) {
  print STDERR "usage: $0 where-to-store-line-numbers < input  > output
   or: $0 --reinsert=where-to-store-line-numbers < input  > output
";
  exit 1;
}

if (defined $reinsert) {
  # load empty linenos
  my @skip_at = ();
  my $hdl = my_open($reinsert);
  while (<$hdl>) {
    chomp;
    push @skip_at, $_;
  }
  close $hdl;

  my $cnt = 0;
  my $skipped = 0;
  while(<>) {
    $cnt++;
    while (defined $skip_at[0] && $skip_at[0] == $cnt) {
      # print STDERR "Printing blank line for the skipped one at $cnt\n";
      $skipped++;
      $cnt++;
      shift @skip_at;
      print "\n";
    }
    print $_; # print the original line
  }
  $cnt++; # skip_at counts at +1
  while (defined $skip_at[0] && $skip_at[0] == $cnt) {
    # print STDERR "Printing blank line for skipped sent $cnt\n";
    $skipped++;
    $cnt++;
    shift @skip_at;
    print "\n"; # add extra line for the skipped trailing ones
  }
  print STDERR "Reinserted $skipped blank lines.\n";
} else {
  # skip blank lines, storing their linenos
  my $hdl = my_save($auxfn);

  my $cnt = 0;
  my $skipped = 0;
  while (<>) {
    $cnt++;
    if (/^\s*$/) {
      # skip empty lines
      print $hdl $cnt, "\n";
      $skipped++;
      next;
    }
    print $_;
  }

  close $hdl;
  print STDERR "Skipped $skipped lines, line numbers stored here: $auxfn\n";
}


sub my_open {
  my $f = shift;
  if ($f eq "-") {
    binmode(STDIN, ":utf8");
    return *STDIN;
  }

  die "Not found: $f" if ! -e $f;
  my $opn;
  my $hdl;
  my $ft = `file '$f'`;
  # file might not recognize some files!
  if ($f =~ /\.gz$/ || $ft =~ /gzip compressed data/) {
    $opn = "zcat '$f' |";
  } elsif ($f =~ /\.bz2$/ || $ft =~ /bzip2 compressed data/) {
    $opn = "bzcat '$f' |";
  } else {
    $opn = "$f";
  }
  open $hdl, $opn or die "Can't open '$opn': $!";
  binmode $hdl, ":utf8";
  return $hdl;
}

sub my_save {
  my $f = shift;
  if ($f eq "-") {
    binmode(STDOUT, ":utf8");
    return *STDOUT;
  }

  my $opn;
  my $hdl;
  # file might not recognize some files!
  if ($f =~ /\.gz$/) {
    $opn = "| gzip -c > '$f'";
  } elsif ($f =~ /\.bz2$/) {
    $opn = "| bzip2 > '$f'";
  } else {
    $opn = ">$f";
  }
  mkpath( dirname($f) );
  open $hdl, $opn or die "Can't write to '$opn': $!";
  binmode $hdl, ":utf8";
  return $hdl;
}
