#!/usr/bin/perl -w
# generates a latex source for beamer from a simple file

use warnings;

use strict;

my $file = $ARGV[0] or die "perl instantbeamer filename (without extension)";
my $first;
my $second;
my $data;
my $row = 0;
my $oldrow = 0;
my %rows;
my $block = 0;
my @array;
my @lists;
my $flag = 0;
my $frameflag = -1;
my $slidestop = 0;
my $curlist;


open(INSTANT,"${file}.ibs") or die "cannot open ${file}.ibs";
open(LATEX,">${file}.tex") or die "cannot open ${file}.tex";
open(X,">${file}.x") or die "cannot open ${file}.tex";


while (<INSTANT>) {
    $row += 1;
    if ($_ !~ /^\s*$/) {
	if ($_ =~ /^\s*slidestop\s*/ and $flag == 0) {
	    $slidestop = 1;
	}
	$data = $data.$_;
	chomp $data;
	$flag =1;
    } else {
	if ($data) {
	    print X "$data\n";
	    $data = "";
	    $block += 1;
	    $rows{$block} = "$oldrow--$row";
	    $oldrow = $row;
	}
    }
}

close (INSTANT);
close (X);


if ($slidestop == 1) {
    print LATEX "\\documentclass\[slidestop\]\{beamer\}\n";
} else {
print LATEX "\\documentclass\{beamer\}\n";
}



open(X,"${file}.x") or die "cannot open ${file}.x";


$block = 1;

while (<X>) {
    if ($_ =~ m/^\s*$/ or $_ =~ m/^!/) {
	$data = $_;
	$data =~ s/^!(.*)/$1/;
	print LATEX "$data";
    } elsif ($_ =~ /^\s*pckg:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*pckg:(.*)$/$1/;
	if ($data =~ /\|/) {
	    if ($data =~ /\|.*\|/) {
		die "more than two parameters in pckg in rows $rows{$block}\n";
	    } else {
		$first = $data;
		$second = $data;
		$first =~ s/^([^\|]*)\|(.*)/$1/;
		$second =~ s/^([^\|]*)\|(.*)/$2/;
		print LATEX "\\usepackage\[$second\]\{$first\}\n";
	    }
	} else {
	print LATEX "\\usepackage\{$data\}\n";
    }
    } elsif ($_ =~ /^\s*theme:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*theme:(.*)$/$1/;
	if ($data =~ /\|/) {
	    if ($data =~ /\|.*\|/) {
		die "more than two parameters in theme in rows $rows{$block}\n";
	    } else {
		$first = $data;
		$second = $data;
		$first =~ s/^([^\|]*)\|(.*)/$1/;
		$second =~ s/^([^\|]*)\|(.*)/$2/;
		print LATEX "\\mode<presentation>\n{\n\\usetheme\{$first\}\n\\usecolortheme\{$second\}\n\}\n\\usepackage\{hyperref\}\n";}
	} else {
	    print LATEX "\\mode<presentation>\n{\n\\usetheme\{$data\}\n\}\n";
	}
    } elsif ($_ =~ /^\s*begin-document/){
	print LATEX "\\begin\{document\}\n\n";
	include ("lista-szlista.tex");
    } elsif ($_ =~ /^\s*author:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*author:(.*)$/$1/;
	print LATEX "\\author";
	if ($data =~ /\|\*/) {
	    $first = $data;
	    $second = $data;
	    $first =~ s/^(([^\|]\|?\|?)+[^\|])\|\*(.*)/$3/;
	    $second =~ s/^(([^\|]\|?\|?)+[^\|])\|\*(.*)/$1/;
	    print LATEX "\[$first\]";
	    $data = $second;
	}
	if ($data =~ /\|\|/) {
	    @array = split /\|\|/, $data;
	} else {
	    push @array, $data;
	}
	print LATEX "\{";
	$flag = 0;
	while ($data = shift(@array)) {
	    if ($flag == 1) {
		print LATEX " -- ";
	    } else {
		$flag =1;
	    }
	    if ($data =~ /\|/) {
		$first = $data;
		$second = $data;
		$first =~ s/^([^\|]*)\|(.*)$/$1/;
		$second =~ s/^([^\|]*)\|(.*)$/$2/;
		print LATEX "$first \\inst\{$second\}";
	    } else {
	    print LATEX "$data";
	}
	}
	print LATEX "\}\n";
    } elsif ($_ =~ /^\s*inst:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*inst:(.*)$/$1/;
	print LATEX "\\institute";
	if ($data =~ /\|\*/) {
	    $first = $data;
	    $second = $data;
	    $first =~ s/^(([^\|]\|?)+[^\|]+)\|\*(.*)/$3/;
	    $second =~ s/^(([^\|]\|?)+[^\|]+)\|\*(.*)/$1/;
	    print LATEX "\[$first\]";
	    $data = $second;
	} if ($data =~ /\|/) {
	    @array = split /\|/, $data;
	    $flag = 1;
	    print LATEX "\{\n";
	    	while ($data = shift(@array)) {
		    if ($flag > 1) {
			print LATEX "\\and\n";
		    }
		    print LATEX "\\inst{$flag}\n$data\n";
		    $flag += 1;
		}
	    print LATEX "\}\n";
	} else {
	    print LATEX "\{$data\}\n";
	}
    } elsif ($_ =~ /^\s*title:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*title:(.*)$/$1/;
	print LATEX "\\title";
	if ($data =~ /\|/) {
	    $first = $data;
	    $second = $data;
	    $first =~ s/^([^\|]*)\|(.*)/$2/;
	    $second =~ s/^([^\|]*)\|(.*)/$1/;
	    print LATEX "\[$first\]";
	    $data = $second;
	} 
	print LATEX "\{$data\}\n";
    } elsif ($_ =~ /^\s*date:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*date:(.*)$/$1/;
	print LATEX "\\date";
	if ($data =~ /\|/) {
	    $first = $data;
	    $second = $data;
	    $first =~ s/^([^\|]*)\|(.*)/$2/;
	    $second =~ s/^([^\|]*)\|(.*)/$1/;
	    print LATEX "\[$first\]";
	    $data = $second;
	} 
	print LATEX "\{$data\}\n";
    } elsif ($_ =~ /^\s*subject:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*$//;
	$data =~ s/^\s*subject:(.*)$/$1/;
	print LATEX "\\subject\{$data\}\n";
    } elsif ($_ =~ /^\s*sectionlayout:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*sectionlayout:(.*)\s*$/$1/;
	if ($frameflag == -1) {
	    print LATEX "\\begin\{frame\}\\titlepage\n\\end\{frame\}\n\n\\begin\{frame\}\\tableofcontents\n\\end\{frame\}";
	    $frameflag = 0;
	}
	print LATEX "\\AtBeginSection\[\]\n\{\n\\begin\{frame\}\n\\frametitle\{$data\}\n\\tableofcontents\[currentsection,currentsubsection\]\n\\end\{frame\}\n\}\n\n";
    } elsif ($_ =~ /^\s*subsectionlayout:/) {
	if ($frameflag == -1) {
	    print LATEX "\\begin\{frame\}\\titlepage\n\\end\{frame\}\n\n\\begin\{frame\}\\tableofcontents\n\\end\{frame\}";
	    $frameflag = 0;
	}
	$data = $_;
	chomp $data;
	$data =~ s/\s*subsectionlayout:(.*)\s*$/$1/;
	print LATEX "\\AtBeginSubsection\[\]\n\{\n\\begin\{frame\}\n\\frametitle\{$data\}\n\\tableofcontents\[currentsection,currentsubsection\]\n\\end\{frame\}\n\}\n\n";
    } elsif ($_ =~ /^\s*frame:?/) {
	if ($frameflag == -1) {
	    print LATEX "\\begin\{frame\}\\titlepage\n\\end\{frame\}\n\n\\begin\{frame\}\\tableofcontents\n\\end\{frame\}";
	    $frameflag = 0;
	}
	$data = $_;
	chomp $data;
	$data =~ s/\s*frame:?(.*)\s*$/$1/;
	if ($frameflag == 1) {
	    endframe();
    }
	print LATEX "\\begin\{frame\}\n";
	if ($data) {
	    print LATEX "\\frametitle\{$data\}\n\n";
	} 
	$frameflag = 1;
    } elsif ($_ =~ /^\s*section:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*section:(.*)\s*$/$1/;
	if ($frameflag == 1) {
	    endframe();
	}
	print LATEX "\\section\{$data\}\n\n";
    } elsif ($_ =~ /^\s*subsection:/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*subsection:(.*)\s*$/$1/;
	if ($frameflag == 1) {
	    endframe();
	}
	print LATEX "\\subsection\{$data\}\n\n";
    } elsif ($_ =~ /^\s*\+/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*\+(.*)\s*$/$1/;
	$data =~ s/\+\+/\}\\uncover<\+->\{/g;
	print LATEX "\\uncover<+->\{$data\}\n\n";
    } elsif ($_ =~ /^\s*>/) {
	$data = $_;
	chomp $data;
	$data =~ s/\s*>(.*\S)\s*$/$1/;
	die "Unknown list type in rows $row: $data\n" if ($data !~ /^[lLnN]$/);
	print LATEX "\\begin";
	$data = "{list}{\$\\bullet\$\\hfill}{}" if $data eq "l";
	$data = "{lista}" if $data eq "L";
	$data = "{enumerate}" if $data eq "n";
	$data = "{szlista}" if $data eq "N";
	print LATEX "$data\n\n";
	if ($data =~ /\{list\}/) {
	    $data = "{list}";
	}
	push @lists, $data;
	$curlist = $data;
    } elsif ($_ =~ /^\s*</) {
	$data = pop(@lists) or die "More lists closed than opened (in rows $rows{$block}).\n";	    
	print LATEX "\\end$data\n\n";
	$curlist = pop(@lists) or $curlist = "";
	push @lists, $curlist if ($curlist);
    } elsif ($_ =~ /^\s*\./) {
	die "Item outside a list (in rows $rows{$block}).\n" if ($curlist eq "");
	$data = $_;
	chomp $data;
	$data =~ s/\s*\.(.*)\s*$/$1/;
	if ($data =~ /^\+/) {
	    $first ="<+->";
	    $data =~ s/^\+(.*)/$1/;
	} else {
	    $first = "";
	}
	if ($data =~ /^\[/) {
	    $second = $data;
	    $second =~ s/^\[([^\]]*)\].*/$1/  or die "Ill formed item in rows $rows{$block}";
	    $second = "\[$second\]";
	    $data =~ s/^\[([^\]]*)\](.*)/$2/;
	} else {
	    $second = "";
	}
	if ($curlist eq "{szlista}") {
	    print LATEX "\\szitem$first$second $data\n\n";
	} else {
	    print LATEX "\\item$first$second $data\n\n";
	}
    } elsif ($_ =~ /^\s*=+\s*$/) {
	$data = $_;
	$data =~ s/===/\n\\bigskip\n/g;
	$data =~ s/==/\n\\medskip\n/g;
	$data =~ s/=/\n\\smallskip\n/g;
       	print LATEX "$data\n";
    }


    $block += 1;
    $row = $rows{$block};
}

if ($frameflag == 1) {
    endframe();
}


print LATEX "\\end\{document\}\n\n";


close (X);
close (LATEX);

system "pdflatex ${file}.tex";




sub include {
    my $file = shift;
    open (INCLUDE,$file) or die "cannot open $file";
    while (<INCLUDE>) {
	print LATEX "$_";
    }
    close (INCLUDE);
}
    
sub endframe{
    while (my $data = pop(@lists)) {
	print LATEX "\\end$data\n";
    }
    print LATEX "\\end\{frame\}\n\n";
    $frameflag = 0;
}  
