package lyra;

require 5.005_62;
use strict;
use warnings;
use chord;
use Data::Dumper;
use CGI qw(:all);
use File::Basename;
use File::stat;
use utf8::all;
use lib ("/home/jj/lib/perl5");

require Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw( );
our $VERSION = '0.01';

our $init;

my @t;
my $hoje;
my $arc;
my $outputdir;
my $baseurl;
my $indexfile;

sub mkdata{ sprintf('%4d/%02d/%02d',1900+$_[5],$_[4]+1,$_[3]); }
sub setoutputdir{ $outputdir = shift; }
sub setbaseurl{ $baseurl = shift; }
sub setindexfile{ $indexfile = shift; }

BEGIN{
   @t= gmtime(time);
   $hoje= mkdata(@t);
   $arc = do("lyr.dumper")  || {} ; ### warn "erro... $!$@\n";
   setoutputdir("");
   #setbaseurl("http://natura.di.uminho.pt/~jj/musica");
   setbaseurl("");
   setindexfile("indice_autores.html#");
}

sub whatishew{
   newFiles(@_);
   savelyrmeta();
}

sub newFiles {
  for my $a (@_){
    my $st = stat($a) or die "No $a: $!";
    my $data = mkdata(localtime($st->mtime));
    if($arc->{$a}){ print "<li> alterações $a</li>\n" } 
    else          { print "<li> acrescentado ao arquivo $a ($hoje)</li>\n" ;
                    $arc->{$a}{data} = "$hoje"; } 
  }
}

sub savelyrmeta{ 
  open(F,">lyr.dumper") or die;
  print F Dumper($arc);
  close F;
}

sub init{
  for(<../*.lyr>){ 
    my $st = stat($_) or die "No $_: $!";
    my $data = mkdata(localtime($st->mtime));
    if($arc->{$_}){ } 
    else          { $arc->{$_}{data} = "$data"; } } 
}

sub ahtml { my $a = shift;
   my %hea = %$a;
   my $ti=($hea{singer}||$hea{author}||$hea{music}||$hea{lyrics}
        || $hea{file}).": $hea{title}";
   a({href=>"$hea{file}"},$ti);
}

sub read_head {
   my $name = shift;
   my ($st, $hea)=(0,{});
   open(F, "< $name") or die "can't find '$name' :-(((" ;
   if($name =~ m/(.*)\.lyr$/) {
      $hea = {file=>$name};

      while(<F>){
         if($st==0){
            if (/^ *$/)                    {$st=1; }
            if (/\s*(\w+)\s*:\s*(.*?)\s*$/){$hea->{lc($1)}=$2;}
          }
         elsif($st==1){ if (/<abc>|\{soabc\}/i)      {$hea->{abc} = 1};
         }
      }
   }
   else {return ({});}
   close(F);
   $hea;
}

=head1 comments

#options
our ( $tit, $aut, $html, $nostart, $nomaketitle, $nocolor,
      $pageformat, $index, $noindex, $abc2col, $column, $nonewpage);

$index ||=0;


$l = 1 unless $d || $html;

my $opt = {
    tit=> $tit || "Letras de música\\\\Vol I -- popular",
    ($column      ? (column     => $column )     : ()),
    ($abc2col     ? (column => 2 , abc => 2)     : ()),
    ($nocolor     ? (color      => 0)            : ()),
    ($nonewpage   ? (newpage => '\pagebreak[2]') : ()),
    ($nomaketitle ? (maketitle  => 0)            : ()),
    ($pageformat  ? (pageformat => $pageformat)  : ()),
    aut => $aut || "Arquivo de música de língua portuguesa"};

=cut

sub mksongbook{ # options: column => 2, abc=>2, color=>Bool,
                #      newpage =>'\pagebreak[2]', maketitle  => Bool, 
                #      pageformat => "a4" , aut => "...", tit=> "..."
                #      outputfile => "f", minipage => 1,

  my %opt =( tit=> "Música em português",
             column => 2,  
             color=> 0, 
             maketitle  => 1, 
             nostart => 0,
             index => 1,
             pageformat=>'a4',
             minipage => 1,
             aut =>"Arquivo de música de língua portuguesa" );
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  if($opt{outputfile}){open(F,">$opt{outputfile}") 
                       or die("cant create $opt{outputfile}\n");}
  else { *F = *STDOUT }
  unless($opt{nostart}){print F beginlatex( \%opt );}
  for my $a (@_)       {
     if($a =~ /\\/){ print F $a; }
     else          { print F latex3(\%opt, getmusic(\%opt,$a))}
  };
  unless($opt{nostart}){print F endlatex(\%opt);}
  if($opt{outputfile}){close(F)}
}

sub mkdumper{
  my %opt =();
  if(ref($_[0]) eq "HASH") {%opt = (%opt , %{shift(@_)}) } ;
  if($opt{outputfile}){open(F,">$opt{outputfile}") 
                       or die("cant create $opt{outputfile}\n");}
  else { *F = *STDOUT }
  for my $a (@_){ print F Dumper(getmusic(\%opt,$a));}
  if($opt{outputfile}){close(F)}
}

sub mkhtml{
   my %opt =( tit=> "Música em português",
             column => 2,
             color=> 0,
             maketitle  => 1,
             indexfile  => $indexfile,
             nostart => 0,
             index => 1,
             pageformat=>'a4',
             aut =>"Arquivo de música de língua portuguesa" );
   if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }

   if($opt{outputdir}){ mkdir($opt{outputdir});}
   for my $a (@_){
      my $htmlout = html3( \%opt,
                        getmusic(\%opt,$a),
                        sub{my $b=shift;
                            my $c = $b;
                            $c =~ s/\s*\(.*?\)\s*//g;
                            a({href=>"$opt{indexfile}$c"},$b)}) ;
      if($opt{outputdir}){
        if($a =~ m!(.*/)?(.*)\.lyr! ) {
           open(F,">$opt{outputdir}/$2.html") 
           or die("cant open $opt{outputdir}/$2.html\n");
           print F $htmlout;
           close F; }
        else { print  $htmlout }}
      else { print  $htmlout }
   }
}

=head1 main

unless($nostart || $html ){ print beginlatex( $opt );}

for (@ARGV){ 
   my $name = $_;
   my $a=getmusic(\%opt,$_);
   if ($d)    { print Dumper( $a) };
   if ($l)    { print latex3( $opt, $a) };
   if ($html) { 
      my $htmlout = html3( $a, 
                        sub{my $b=shift; 
                            my $c = $b;
                            $c =~ s/\s*\(.*?\)\s*//g;
                            a({href=>"$indexfile$c"},$b)}) ;
      if($outputdir){ 
        if($name =~ m!(.*/)?(.*)\.lyr! ) {
          open(F,">$outputdir/$2.html") or die("cantopen $outputdir/$2.html\n");
          print F $htmlout;
          close F; }
        else { print  $htmlout }}
      else { print  $htmlout }
   }
}

unless($nostart || $html ){ print endlatex({($noindex ? (index => 0): ()),});}

=cut

sub beginlatex {
  my %opt =( tit=>"Música em português" ,
             date => '\today',
             maketitle => 1,
        	 column => 2,
        	 color => 1,
             ls  => "11pt",
             pageformat => "b5",
             aut=>"Arquivo de letras de música");
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }

  my $pageformat = $opt{pageformat} ? "\\usepackage{$opt{pageformat}}" : "";
  if ($opt{pageformat} eq "b5"){
     $pageformat = "\\RequirePackage[b5paper,mag=1193,top=2cm,left=1.5cm,right=1.5cm,bottom=1.5cm,nohead,nofoot]{geometry}";}

  if ($opt{pageformat} eq "a4"){
     $pageformat = "\\RequirePackage[a4paper,top=2cm,left=2.5cm,right=2cm,bottom=1.5cm,nohead,nofoot]{geometry}";}

  my $colsty = $opt{color}       ? "\\usepackage{color}" : "";
  my $col    = $opt{color}       ? "\\color{red}" : "";
  my $colum  = ($opt{column}==2) ? "\\twocolumn" : "";
  my $letsize = $opt{ls} ? ",$opt{ls}" : "";

  my $r = qq{ 
\\documentclass[portuges,a4paper$letsize]{extarticle} 
\\usepackage{babel} 
$pageformat
\\usepackage[utf8]{inputenc} 
\\usepackage{t1enc} 
%\\usepackage{aeguill}
\\usepackage{makeidx} 
\\usepackage{fancyvrb} 
\\usepackage{graphicx} 
$colsty
\\makeindex
\\begin{document} 
\\VerbatimFootnotes
\\columnsep .3in
\\newenvironment{myverse}
               { \\advance\\leftmargin -3.0em
                 \\advance\\rightmargin -3.0em
                 %%\\begin{verse}
               }%
               { %%\\end{verse}
               }
\\newcommand{\\chordjj}[2]{\\begin{tabular}[b]{\@{}l\@{}}{\\footnotesize\\sf$col
#1}\\mbox{ }\\\\[-1mm]#2\\\\\\end{tabular}}
\\newcommand{\\chord}[1]{\\raisebox{-0.8ex}{\\makebox[0pt][l]{\\vbox{\\vss\\hbox{\\scriptsize\\bf#1}\\vss\\hbox{\\vbox{\\rule{0pt}{0.5ex}}}}}}}
};

  $r .= qq{
\\title{$opt{tit}} 
\\author{$opt{aut}} 
\\date{$opt{date}} 
\\maketitle 
\\vfill
$colum
\\parindent 0pt
\\tableofcontents\\newpage
} if $opt{maketitle};

  $r .= qq{
$colum
\\parskip 1.8em
\\parindent 0pt
};
  $r;
}

sub endlatex{
  my %opt = ( index => 1);
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  ($opt{index}?"\\printindex":"")."\\end{document}\n";
}

sub __{
  my $r = shift;
  $r =~ s{"(.*?)"}{``$1''}g;
  $r =~ s{([^\\])\&}{$1\\\&}g;
  $r =~ s{([^\\])\%}{$1\\\%}g;
  $r =~ s{([^\\])\#}{$1\\\#}g;
  $r =~ s{([^\\])_}{$1\\_}g;
  ### $r =~ s{\\\\(\n\\mbox\{\}\\\\)+}{\n}g ; # if $v1;
  $r;
}

sub latex2{ my $a=shift; 
  sprintf("\\newpage\\subsection*{\%s}\n\\addcontentsline{toc}{subsection}{\%s}",
          $a,$a)
}

my $column=2;

sub latex3{ 
  my %opt = ( column => 2, abc=> 1, newpage => "\\newpage " );
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  my $a=shift; 
  my $_back = '\mbox{}\hspace{-10pt}';
  my $r="";
  $a->{subti} //= "";
  $r.= '\begin{minipage}{\textwidth}'   if ($opt{minipage} and $opt{column}==1);
  $r.= '\begin{minipage}{\columnwidth}' if ($opt{minipage} and $opt{column}==2);
  if($a->{abc}){ 
   if($opt{column} ==2 && $opt{abc}==1) { $r.="\\twocolumn[\\protect{ "; 
                                          $column=1; }
   else { $r .= $opt{newpage} . '% $opt{column}'. $opt{column}.
                                '$opt{abc}' . $opt{abc} ."\n" ;}

   $r .= sprintf("\\subsection*{\%s}\n\\addcontentsline{toc}{subsection}{\%s}\n", 
           $a->{title}, $a->{title});
   $r .= ($a->{subti} ? "\\textit{$a->{subti}}" : "") .
         ($a->{in} ?  _processaInLatex($a->{in}) : "") .
         ($a->{inbook} ? _processaInLatex($a->{inbook}) : "") .
          "\n\n";
   if($opt{column} ==2 && $opt{abc}==2){
        $r .= "$_back\\includegraphics[width=0.53\\textwidth]{$a->{abcpsmall}}\n\n";}
   elsif($opt{pageformat} eq "agenda"){
          $r .= "$_back\\includegraphics[width=1.06\\textwidth]{$a->{abcpsmall}}\n\n";}
   else { $r .= "$_back\\includegraphics[width=1.06\\textwidth]{$a->{abcp}}\n\n";}

   if($opt{column} == 2 && $opt{abc}==1) { $r .= "\\vspace{0.5cm}}]\n\n";}
  }
  else {
   if($column == 1 && $opt{column} ==2 ){$r.='\twocolumn '; $column=2;}
   else            {$r.= $opt{newpage}}
   $r .= sprintf("\\subsection*{\%s}\n\\addcontentsline{toc}{subsection}{\%s}\n", 
           $a->{title}, $a->{title});
   $r .= ($a->{subti} ? "\\textit{$a->{subti}}" : "") .
         ($a->{in} ? _processaInLatex($a->{in}) : "") .
         ($a->{inbook} ? _processaInLatex($a->{inbook}) : "") .
          "\n\n";
  }
  $r .= _geraIndexEntry($a);
  $r .= _processaBodyLatex($a->{body});
  $r .= "\n\n{\\footnotesize\\textit{". __($a->{agrad})."}}\n\n" if $a->{agrad};
  if($a->{acordes}){ 
    my %x = (dir=>"chordsEPS",relpath=>"chordsEPS");
    %x=(%x ,local_chords=>local_chords($a->{learn_chords})) if $a->{learn_chords} ;
    %x=(%x ,chordsize => "1.3cm")            if $opt{pageformat} eq "a4" ; 
    %x=(%x ,chordsize => "1.3cm")            if $opt{pageformat} eq "agenda" ; 
    $r .= "\n\n".latexchords( (%x ? {%x} : ()), @{$a->{acordes}}); 
  }
  $r .= "\n\n";
  $r .= _processaNotaLatex($a->{notetitle},$a->{nota},$a->{notetype}) if $a->{nota};
  $r.= '\end{minipage}

' if ($opt{minipage} );
$r;
}


sub html3{ 
  my %opt = (outputdir => $outputdir);
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  my $a=shift; 
  my $refaut=shift || sub{shift} ;
  my $r=hr;
  my $htmlsubtit = $a->{subti};
  $htmlsubtit =~ s/([:,]\s*)([^;,)]+)/"$1". &{$refaut}($2)/ge;
  $htmlsubtit =~ s/;\s*$//;
  $htmlsubtit =~ s/;/<br>/g;
  $r .= h2($a->{title})."\n" 
     . ($a->{abc}? strong(a({href=>$a->{abcmidurl}},"Midi")).br : "")
     . ($a->{head}{mp3}? strong(a({href=>$a->{head}{mp3}},"Mp3")).br :"")
     . strong($htmlsubtit). br."\n" 
     . ($a->{in}? $a->{in}:"")
     . hr; 
  if($a->{abc}){ $r .= img({src => $a->{abcrasterurl}})."\n\n"; }
  $r .= "\n\n". blockquote( _processaBodyHtml($a->{body})). "\n\n";
  $r .= p(small($a->{agrad})).hr;
  if($a->{acordes}){ 
    my %x = (dir=>"chordsPNG",relpath=>"chordsPNG");
    %x=(local_chords=>local_chords($a->{learn_chords})) if $a->{learn_chords} ;
    %x=(%x,dir=>"$opt{outputdir}/chordsPNG",relpath=>"chordsPNG") if $opt{outputdir} ; 
    $r .= "\n\n".htmlchords( (%x ? {%x} : ()), (sort @{$a->{acordes}})); 
  }
  $r .= _processaNotaHtml($a->{notetitle},$a->{nota},$a->{notetype}) if $a->{nota};
$r;
}

sub _processaInLatex{ my $a=shift;
   $a = __($a); 
   "\\footnotetext{$a}";
}

sub _processaNotaHtml{
  my ($notetitle,$nota,$t) = @_;
  $notetitle =~ s/"(.*?)"/``$1''/gs;
  $nota =~ s/"(.*?)"/``$1''/gs;
  h4($notetitle). p( $nota)."\n";
}

sub _processaBodyHtml{
  my $b=shift;
  my $r="";
  my (@a,@b);
  for(split(/\n/,$b)){
    if (/<chr>/) { 
       @a = ( m!<chr>(.*?)</chr>!g); 
       @b = ( (m!^([^<]*)!) , (m!</chr>(.*?)<chr>!g), (m!>([^<]*)$!)) ;
       if($b[0] =~ /^\s*$/){shift(@b)} 
       else {unshift(@a,"")}
       $r.= table({cellspacing=>0, cellpadding=>0, border=>0},
         ### Tr(td([(map{font({face=>"helvetica,arial",color=>"red"},)})]))
         Tr(td([(map{$_ ? font({color=>"red"}, i($_)."__SPA__"):"" } @a)])),
         Tr(td([map{ s/ $/__SPA__/; s/^ /__SPA__/;$_} @b]))); }
    else{ $r.= "$_\n" ;}
  }
  $b=$r;
  $b =~ s/<corus>\n?/<blockquote>/g;  
  $b =~ s/\n?<\/corus>/<\/blockquote>/g;  
  $b =~ s/\n\n+/__SEP__/g;  
  $b =~ s/\n/<br>/g;  
  $b =~ s!__SEP__!\n</p>\n<p>!g;  
  $b =~ s{"}{'}g;
  $b =~ s{\&}{\&amp;}g;
  $b =~ s!__SPA__!\&nbsp;!g;  
  $b
}

sub _processaNotaLatex{
  my ($notetitle,$nota,$t) = @_;
  if($t eq "html"){
    for ($notetitle,$nota){
      s{\&}{\\\&}g;
      s/"(.*?)"/``$1''/gs;
      s/<br>/\\mbox{}\\\\/ig; 
      s/<\/?(p|br)>/\n\n/ig; 
      s/<pre>/\\begin{Verbatim}/g; 
      s/<\/pre>/\\end{Verbatim}\n/g; 
      s/\s+$//;
      s/Verbatim\}/Verbatim}\n/g; 
    } }
  else {
    for ($notetitle,$nota){
      s{\&}{\\\&}g;
      s/"(.*?)"/``$1''/gs;
      s/\n\n+/__SEP__/g;  
#      s/\n/\\mbox{}\\\\/g;  
      s/<br>/\\mbox{}\\\\/ig; 
      s!__SEP__!\n\n!g;  
      s/\s+$//;
    }
  }
  __("\n{\\small\\textbf{$notetitle} - $nota}\n\n");
}

sub _processaBodyLatex{
  my $b=shift;
  $b =~ s!<chr>(.*?)</chr>([ 	]*\[[^<\n\\]*)!\\chordjj{$1}{~$2}!g;  
  $b =~ s!<chr>(.*?)</chr>([^<\n\\]*?)( *)(?=[<\n\\]|$)!\\chordjj{$1}{$2}$3!g;  
  #### $b =~ s!<chr>(.*?)</chr>([^<\n\\]*)!\\chordjj{$1}{$2}!g;  
  $b =~ s/\n*<corus>\n?/\\begin{quote}/g;  
  $b =~ s/\n?<\/corus>\n*/\\end{quote}/g;  
  $b =~ s!\n( *\[.*?\])!\n\\mbox{$1}!g;
  $b =~ s/\n\n+/__SEP__/g;  
  $b =~ s/\n/~\\\\\n/g;  
  $b =~ s/__SEP__/\n\n/g;  
  $b =~ s{"}{'}g;
  $b =~ s{\&}{\\\&}g;
  $b =~ s{\%}{\\\%}g;
  $b =~ s{\#}{\\\#}g;
  #"\\begin{myverse}$b\\end{myverse}"
  $b
}
sub _geraIndexEntry{
 my $a = shift;
 my $r = "";
 for('type', 'singer','author','music','lyrics','index'){
    for(@{$a->{head}{$_}}){ 
        s!\(?\?\)?!!;
	s/\s*:\s*/!/g;
        $r .= "\\index{$_}\n"; } }
 $r
} 

sub getmusic{
  my %opt=(dir => ".");
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  my $filename = shift;
  print STDERR "$filename\n";
  my $st =0;
  my $n =0;
  my ($dir,$name);
  if(! -f $filename && -f "$opt{dir}/$filename" ){ 
       $filename = "$opt{dir}/$filename"}
  ($name,$dir) = fileparse($filename, qr{\.lyr});
  open(FILE, "< $filename") or die "can't find '$filename' :-(((\n" ;
  my ($ti,$subti,$agrad,$tti,$in);
  my %music = (file => $name, body=> "");
  my %hea = (n => 0 , t => 1);

  while(<FILE>){
  if($st==0){        # cabecalho
    if (/\s*(\w+)\s*:\s*(.*?)\s*$/){
      $hea{lc($1)}=$2; 
      if(lc($1) eq "chorddef" || lc($1) eq "chordef"){ 
         my $r=$2;
         if($r=~m{(\S+)(?:\s|=)+(.+)}){ $music{learn_chords}{$1} = $2}
         else                   { warn("Invalid chord def '$r'\n")  }
      }
    }

    if (/^ *$/) {
      for('type', 'singer','author','music','lyrics'){
        $hea{$_} = [ split(/\s*[,;]\s*/,$hea{$_})]  if defined($hea{$_})
      }

      $st= $hea{t};
    
      ($ti,$subti,$agrad,$tti,$in) = titles(%hea);
      $music{title} = $ti;
      $music{subti} = $subti if $subti;
      $music{agrad} = $agrad if $agrad;
      $music{in}    = $in    if $in;
      $music{t}     = $hea{t};
      $music{head}  = {%hea}; 
       }
    }
  elsif($st==1 || $st == 7){    # corpo geral
      chop;
      if (/^title:\s*(.*)/i) { 
           %hea= ("title" => $1, "n" => ++$n );
           $st=0;}  
      elsif(/^htmlnot[ae]\s*:\s*(.*)/i){
           $music{notetitle}=$1 || "Nota";
           $music{notetype}="html";
           $st=3;}
      elsif(/^not[ae]:\s*(.*)/i){
           $music{notetitle}=$1 || "Nota";
           $music{notetype}="txt";
           $st=2;}
      elsif($st==7 && /\[/) {
           s!\[(.*?)\]!acorde($1)!ge;
           $music{head}{hasguitar}=1;
           $music{body} .= $_ . "\n";}
      elsif($st==1 && /^([^ ].*?)\s\s+(.*)$/) {
           my $letra = $1 ;
           my $acordes = $2 ;
           my @x=split(/\s+/,$acordes); 
           my $i=0; 
           $letra =~ s!_!
                    warn("missing chord in $music{file}:`$_'") unless $x[$i];
                    acorde($x[$i++])!ge;
           $music{body} .= "$letra". "\n"  if $letra ;
           $music{head}{hasguitar}=1;
           $music{body} .= "\n"  unless $letra ; }
      elsif(/^<abc>|\{soabc\}/i){ 
           mkdir("$dir/abc"); 
           if(younger("$dir/abc/$name.abc",$filename)){open(ABC,">/dev/null")}
           else {open(ABC, "> $dir/abc/$name.abc") 
                 or die ("cant create $dir/abc/$name.abc\n");}
           $st=5;}
      else                 { 
           $music{body} .= "$_\n";     
          }
    }
  elsif($st==2){
      chop;
      if (/^title:\s*(.*)/i) { 
           %hea= ("title" => $1, "n" => ++$n );
           $st=0;}  
      else                 { $music{nota} .= "$_<br>";}
    }
  elsif($st==3){
      chop;
      if (/^title:\s*(.*)/i) { 
           %hea= ("title" => $1, "n" => ++$n );
           $st=0;}  
      else                 { 
           $music{nota} .= "$_\n";}
    }
  elsif($st==4){
      chop;
      if (/^title:\s*(.*)/i) { 
           endpre();
           %hea= ("title" => $1, "n" => ++$n );
           $st=0;}  
      elsif(/^htmlnot[ae]\s*:\s*(.*)/i){
           endpre();
           $music{notetitle}=$1;
           $music{notetype}="html";
           $st=3;}
      elsif(/^(not[ae]):\s*(.*)/i){
           endpre();
           $music{notetitle}=$1;
           $music{notetype}="txt";
           $st=2;}
      else                 { $music{body}.= "$_\n";}
    }
  elsif($st==5){
     chop;
     if  (/^<\/abc>|\{eoabc\}/i) { 
       close ABC;
       my $ddd;
       my $urlop = "abc";
       if($opt{outputdir}){
        $ddd=$opt{outputdir};
        mkdir($ddd);
        mkdir("$ddd/abc");
       }
       else{
         $ddd=$dir;
         $urlop = "$baseurl/abc";
       }

       abc2eps("$dir/abc/$name.abc", "$ddd/abc/$name-abc.eps");
       abc2eps({small=>1},"$dir/abc/$name.abc","$ddd/abc/$name-abc-small.eps");
       abc2png("$dir/abc/$name.abc","$ddd/abc/$name.abc.png");
       system("abc2midi $dir/abc/$name.abc -o $ddd/abc/$name.mid> /dev/null");
       $music{abcp} = "$ddd/abc/$name-abc";
       $music{abcpsmall} = "$ddd/abc/$name-abc-small";
       $music{abceps} = "$ddd/abc/$name-abc.eps";
       $music{abcepssmall} = "$ddd/abc/$name-abc-small.eps";
       $music{abcmid} = "$ddd/abc/$name.mid";
       $music{abcraster} = "$ddd/abc/$name.abc.png";
       $music{abcmidurl} = "$urlop/$name.mid";
       $music{abcrasterurl} = "$urlop/$name.abc.png";
       $st=1; 
     }
     else { $music{abc} .= "$_\n";
            print ABC "$_\n";}
    }
  }
  if($music{head}{hasguitar}){
    my @acordes = ($music{body} =~ m!<chr>(.*?)</chr>!g);
    my %a; 
    @a{@acordes}=@acordes;
    $music{acordes}=[sort keys %a];
  }
  $music{body} =~ s/ +\n/\n/g;
  $music{body} =~ s/^\n+//;
  $music{body} =~ s/\n+$//;
  $music{body} = corus($music{body});
  +{%music};
}

sub corus{
  my $a=shift;
  $a =~ s/\{soc\}\s*/<corus>/g;
  $a =~ s/\s*\{eoc\}/<\/corus>/g;
  $a
}

sub acorde{
  my $a=shift;
  $a =~ s/(\S+)/<chr>$1<\/chr>/g;
  $a
}

sub titles{ ## ($tit,$subtit,$agrad,($tit,autor*),$in)
  my %hea = @_ ;

  my $agrad= (defined $hea{from} ? "($hea{from})": "").
             (defined $hea{date} ? "($hea{date})": "");
  if (defined $hea{jeito}) { $agrad .= " (jeito de $hea{jeito})";}
  if (defined $hea{comm})  { $agrad .= " \n ($hea{comm})";}
         
  my $tti = [$hea{title},
            (map {$_? @$_ : () } @hea{'singer','author','music','lyrics'})];
  
  my $ti = $hea{title};
  $ti =~ s/(^\s+)|\s*[*=]\s*//;
  
  my $subti ="";
  if (defined $hea{author}) { $subti .="Letra e música: ".
     join(", ", @{$hea{author}})."; "}
  if (defined $hea{music})  { $subti .="Música: ". 
     join(", ",@{$hea{music}})."; "}
  if (defined $hea{lyrics}) { $subti .="Letra: ".
     join(", ",@{$hea{lyrics}})."; "}
  if (defined $hea{singer}) { $subti .="Intérprete: ".
     join(", ",@{$hea{singer}})."; "}
  if (defined $hea{type})   { $subti .=" (".
     join(", ",@{$hea{type}}).") "}

  my $in="";
  if (defined $hea{in})     { $in .=" In: $hea{in}; "}
  if (defined $hea{inbook}) { $in .=" In: $hea{inbook}; "}

($ti,$subti,$agrad,$tti,$in)
}

sub abc2eps{
  my %opt =(); 
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  my $file=shift;
  my $out;
  ###system("abcm2ps -s 1 -c -E  -w 18.9cm $file")
  if($opt{small}){ 
     $out = shift || "$file-small.eps";
     return if younger($out, $file);
     print STDERR ("abcm2ps -c -E -w 12cm $file > $out");
     system("abcm2ps -c -E -w 12cm $file > /dev/null");}
  else{ 
     $out = shift || "$file.eps";
     return if younger($out, $file);
	 system("abcm2ps -c -E -w 19cm $file > /dev/null");}
  rename("Out001.eps",$out); 
  system("epstopdf $out")==0;
}

sub abc2png{
  my $file=shift;
  my $out =shift || "$file.png";
  return if younger($out, $file);
  ###system("abcm2ps -s 1 -c -O _Out.ps -w 19cm $file > /dev/null");
  system("abcm2ps -c -E -w 19cm $file > /dev/null");
  system("convert -density 96 Out001.eps $out");
#  system("convert -density 111 Out001.eps $out");
#  system("gs -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r100 -dBATCH -dNOPAUSE -q -sDEVICE=pnggray -sOutputFile=_Out%d.png _Out.ps ");

#  for (<_Out*.png>){system("mogrify -crop 0x0  $_")};
#  rename("_Out1.png",$out);
#  unlink("_Out.ps");
  unlink("Out001.eps");
#  system("abcm2ps -c -O _Out.ps -w 19cm $file > /dev/null");
}

sub younger{  ## f1 exists and is younger then f2 (for make f1)
 my ($f1,$f2)=@_;
 (-e $f1 && -M $f2 >= -M $f1) 
}

sub songsort{
  my %opt =(); 
  if(ref($_[0])){ %opt = (%opt , %{shift(@_)}); }
  my @l;
  for my $f ( @_){
    my $fname=$f;
    if(! -f $f && -f "$opt{dir}/$f" ){ $f= "$opt{dir}/$f"}
 
    my $a = `grep "title" '$f'` || "Sem título";
    chomp $a;
    $a =~ s/title\s*:\s*([*=]\s*)?//;
    push(@l,[$fname,_normt($a)]); }

  map {$_->[0]} (sort {$a->[1] cmp $b->[1]} @l )
}

sub _normt{     ## remove inicial articles
 my $t = lc(shift);
 $t =~ s/^(a|o|as|os|um|uma|the|le|la|les|un|une)\s+//;
 $t;
}

sub make{ 
  my $f=shift;
  open(MAKEFILE,"| make -f - $f") or die("cant make $f");
  print MAKEFILE <<'.';
SHELL = /bin/bash
.SUFFIXES: .ptex .html .a3ps .agps .grep .list .tex .ps .pdf .a5ps .agpdf .a5pdf -a3pdf

.tex.ps:
	- latex $* 
	- latex $*
	makeindex -c $*
	- latex $*
	dvips -o $@ $*

.tex.pdf:
	- pdflatex $* 
	- pdflatex $*
	makeindex -c $*
	- pdflatex $*

.ps.a5ps:
	smallbook $< $@

.ps.a3ps:
	smallbook -a3 $< $@

.ps.agps:
	smallbook -ag $< $@


.pdf.a3pdf:
	psmallbook -a3 -o=$@ $< 

.pdf.a5pdf:
	psmallbook -o=$@ $< 

.pdf.agpdf:
	psmallbook -ag -o=$@ $< 

.

  close MAKEFILE;
}

1
__END__

for (`/bin/ls -1t *.lyr about.*.html`) {
   chop;
   ($file = $_) =~ s!(.*).lyr!$1!;
   @hea = read_array($_);
   for (@hea) {html($file,$_) unless $file eq "today.";}
}
print "\\enl\n";

=head1 NAME

lyra - Perl extension for

=head1 SYNOPSIS

  use lyra;
  lyra::mksongbook( { pageformat => "a5"}, qw{ f1.lyr f2.lyr ... )
  lyra::mksongbook( { pageformat => "agenda", column=> 1}, ... )

  lyra::mkhtml( { outputdir => "HTML"}, f1.lyr ... )

  lyra::mkdumper( f1.lyr ... )

  lyra::younger(f1,f2)

  lyra::abc2png(in,[out]);
  lyra::abc2eps({small=>1},in,[out]);
  lyra::abc2eps(in,[out]);

  lyra::setbaseurl(url)
  
  @flist = lyra::songsort(@file_list)   #sort by titles

=head1 DESCRIPTION

=head2 Function C<mksongbook>

Several options available for  tunning the songbook layout

  my $opt ={ tit=> "Música em português",
             column => 2,
             abc => 2,  (score in one column)
             color=> 0, (Bool)
             maketitle  => 1, (Bool)
             nostart => 0, (Bool)
             index => 1, (Bool)
             pageformat=>'a4',
             aut =>"Arquivo de música de língua portuguesa" 
             newpage =>'\pagebreak[2]', (how to change pages)
             outputfile => filename (def: STDOUT)
             ls => 14pt    (letter size - def: 11pt?)
  };

  mksongbook($opt, lyr1, lyr2, ...)



  $style={singlepage =>{ column => 2, maketitle  => 0, nostart => 0, 
                 index => 0, pageformat=>'a4', newpage =>'', },
          a4 => { pageformat=>'a4',column => 2,abc=>2,nostart => 0, 
                 index => 1,maketitle  => 1 }, 
          agenda => { pageformat=>'agenda',column => 1,abc=>1,nostart => 0, 
                 index => 1,maketitle  => 1 }, 
          a5 => {pageformat=>'b5',column => 2,abc=>1,nostart => 0, 
                 index => 1,maketitle  => 1 }, 
         }


=head2 EXPORT

=head1 AUTHOR

=head1 SEE ALSO

smallbook(1). (http://natura.di.uminho.pt)

chord(3pm). (http://natura.di.uminho.pt)

perl(1).

=cut

=head1 NAME

lyr2  - convert "lyr" notation to LaTeX(PS,PDF) or HTML

=head1 SYNOPSIS

 lyr2 [options] files
 options:
   -nostart   no "\documentclass.... "
   -nomaketitle   dont put a big title/author in document
   -pageformat=...
   -tit="..."    to define a title
   -aut="..."    to define a author
   -htlm         to produce HTML
   -column=1     to produce single column
   -abc2col      to produce twocolumn abc
   -nocolor      to produce black and white latex
   -outputdir    directory to put output files

=head1 DESCRIPTION

=head2 EXPORT

=head1 DEPENDENCIES

abc2midi

 yum install abcMIDI

abcn2ps

=head1 AUTHOR

J.Joao Almeida, jj@di.uminho.pt

=cut      

__DATA__
####a4=
\RequirePackage[a4paper,top=2cm,left=2.5cm,right=2cm,bottom=1.5cm,nohead,nofoot]{geometry}

####agenda=
\usepackage[paperwidth=116mm, paperheight=246mm, left=15mm, right=15mm,
top=15mm, bottom=12mm, mag=900 ]{geometry}
\usepackage{times}
\leftmargini 1.2em
\leftmarginii 1.2em
\leftmarginiii 1.2em
\leftmarginiv 1.2em
\leftmarginv 1.2em
\leftmarginvi 1.2em
\leftmargin\leftmargini 

####b5=
\RequirePackage[b5paper,mag=1193,top=2cm,left=1.5cm,right=1.5cm,bottom=1.5cm,nohead,nofoot]{geometry}
\leftmargini 1.2em
\leftmarginii 1.2em
\leftmarginiii 1.2em
\leftmarginiv 1.2em
\leftmarginv 1.2em
\leftmarginvi 1.2em
\leftmargin\leftmargini

####a5=
\usepackage[a5paper,mag=1414]{geometry}
\leftmargini 1.2em
\leftmarginii 1.2em
\leftmarginiii 1.2em
\leftmarginiv 1.2em
\leftmarginv 1.2em
\leftmarginvi 1.2em
\leftmargin\leftmargini

####latex=
\documentclass[portuges,a4paper]{article}
##page##
\usepackage{babel}
\usepackage[utf8]{inputenc}
\usepackage{t1enc}
\usepackage{makeidx}
\usepackage{fancyvrb}
\usepackage{graphicx}
\makeindex
\begin{document}
\VerbatimFootnotes
\columnsep .3in
\newenvironment{myverse}
               { \advance\leftmargin -3.0em
                 \advance\rightmargin -3.0em
                 %%\begin{verse}
               }%
               { %%\end{verse}
               }
\newcommand{\chordjj}[2]{\begin{tabular}[b]{@{}l@{}}{\footnotesize\sf
#1}\mbox{ }\\#2\\\end{tabular}}
\newcommand{\chord}[1]{\raisebox{-0.8ex}{\makebox[0pt][l]{\vbox{\vss\hbox{\scriptsize\bf#1}\vss\hbox{\vbox{\rule{0pt}{0.5ex}}}}}}}

\title{Cancioneiro Infantil}
\author{AMPP}
\date{Dezembro 2006}
\maketitle
\vfill
\parindent 0pt
\tableofcontents
\\parskip 1.8em

##body##
\printindex
\end{document}

