#
#  fmt_lyx.pl
#
#  $Id: fmt_lyx.pl,v 1.5 1998/01/08 19:54:09 cg Exp $
#
#  Lyx-specific driver stuff
#
#  © Copyright 1996, Cees de Groot
#
package SGMLTools::fmt_lyx;
use strict;

use FileHandle;
use SGMLTools::CharEnts;
use SGMLTools::Vars;

my $lyx = {};
$lyx->{NAME} = "lyx";
$lyx->{HELP} = "";
$lyx->{OPTIONS} = [
];
$lyx->{preNSGMLS} = sub {
  $global->{NsgmlsOpts} .= " -ifmtlyx ";
  $global->{NsgmlsPrePipe} = "awk '{print \$0 \" \"}' $global->{file} ";
};

$Formats{$lyx->{NAME}} = $lyx;

# passed to `parse_data' below in lyx_preASP
my $lyx_escape = sub {
    my ($data) = @_;

    return ($data);
};

#
#  Take the nsgmls output, and prepare it a bit
#

$lyx->{preASP} = sub
{
  my ($infile, $outfile) = @_;
  # note the conversion of `sdata_dirs' list to an anonymous array to
  # make a single argument
  # Note also that presently LyX works only with isolatin1
  # The single exception backslash is treated bellow

  my $char_maps = load_char_maps ('.2l1b', [ Text::EntityMap::sdata_dirs() ]);

  while (<$infile>)
    {

      # It is necessary to escape backslash (\) to (\backslash)
      # char \
      s|\\\\|\Q\\backslash\E |g;
      # bsol& entity
      s/\Q\|[bsol\E  \Q]\|/\Q\\backslash\E /g;

      if (/^-/)
      {
	  my ($str) = $';
	  chop ($str);
	  print $outfile "-" . parse_data ($str, $char_maps, $lyx_escape) . "\n";
      }
      elsif (/^A/)
      {
	  /^A(\S+) (IMPLIED|CDATA|NOTATION|ENTITY|TOKEN)( (.*))?$/
	      || die "bad attribute data: $_\n";
	  my ($name,$type,$value) = ($1,$2,$4);
	  if ($type eq "CDATA")
	  {
	      # CDATA attributes get translated also
	      $value = parse_data ($value, $char_maps, $lyx_escape);
	  }
	  print $outfile "A$name $type $value\n";
      }
      else
      {
	  print $outfile $_;
      }

    }
  return 0;
};


#
#  Take the sgmlsasp output, and make something
#  useful from it.
#
$lyx->{postASP} = sub
{
  my $infile = shift;
  my $outfile= new FileHandle ">$global->{filename}.lyx";

  my $ident_level=-1;
  my $verbatim=0;
  my $tag=0;
  my $verb_last_line="";
  my @level_layout;

  while(<$infile>)
    {
      chomp;
      # For LyX file clarity
      s|\\backslash|\n\\backslash\n|;

      #  the list's layouts: Itemize; Enumerate and Description
      # as they can nest $ident_level counts the level

      if(m|^\@itemize\@|o)
        {
	  $ident_level++;
	  $level_layout[$ident_level]="Itemize";
	  print $outfile "\n\\begin_deeper\n" if($ident_level);
	  next;
        }

      if(m|^\@/itemize\@|o)
        {
	  print $outfile "\n\\end_deeper\n" if($ident_level);
	  $ident_level--;
	  next;
        }

      if(m|^\@enumerate\@|)
        {
	  $ident_level++;
	  $level_layout[$ident_level]="Enumerate";
	  print $outfile "\n\\begin_deeper\n" if($ident_level);
	  next;
        }

      if(m|^\@/enumerate\@|)
        {
          print $outfile "\n\\end_deeper\n" if($ident_level);
          $ident_level--;
          next;
        }

      if(m|^\@descrip\@|)
        {
          $ident_level++;
          print $outfile "\n\\begin_deeper\n" if($ident_level);
          next;
        }

      if(m|^\@/descrip\@|)
        {
          print $outfile "\n\\end_deeper\n" if($ident_level);
          $ident_level--;
          next;
        }

      if(m|^\@tag\@|)
        {
	  print $outfile "\\layout Description\n\n";
	  $_=<$infile>;
	  $tag=1;
        }

      if(m|^\@/tag@|)
        {
	  $tag=0;
	  $_=<$infile>;
	  $_=" ".<$infile>;
          redo;
        }

      if($tag)
        {
	  s|\s|\n\\protected_separator\n|g;
	  print $outfile "$_\n";
	  next;
        }

      if(m|^\@item\@|)
        {
	  print $outfile "\\layout $level_layout[$ident_level]\n";
	  next;
        }

      #  Verbatim layout
      # $verb_last_line is used to supress the \newline
      # from last line

      if(m|^\@verb\@|)
        {
	  $verbatim=1;
	  print $outfile "\\layout Verbatim\n\n";
	  $_=<$infile>;
	  $verb_last_line = <$infile>;
	  $verb_last_line =~ s|\s|\n\\protected_separator\n|g;
	  next;
        }

      if(m|^\@/verb\@|)
        {
          $verbatim=0;
	  print $outfile "$verb_last_line\n";
          next;
        }

      if($verbatim)
        {
          print $outfile "$verb_last_line\\newline\n";
	  s|\s|\n\\protected_separator\n|g;
	  $verb_last_line=$_."\n";
	  next;
        }

      #  Supress blank lines and lines with a single whitespace
      my $spool=0;
      while(m|^$| or m|^\s$|g)
        {
	  $_=<$infile>;
	  chomp;
	  $spool++;
        }
      
      if(m|^\\layout (\w*)|)
        {
	  #  Supress void Standard layout
	  # we need this because <sect> and friends
	  # are translated as <p><sect> and <p> is
	  # \layout Standard

	  if($1 eq "Standard")
	    {
	      do
	        {
		  $_=<$infile>;
		  chomp;
	        }
	      while(m|^$| or m|^\s$|g);

	      print $outfile "\\layout Standard\n\n" if(!m|^\\layout| and !m|^\@|);

	      $_.="\n";
	      redo;	        
	    }

	  print $outfile "$_\n\n";
	  next;
        }

      $_.="\n";
      # redo if there was any empty line
      redo if($spool);

      print $outfile $_;

    }

  $outfile->close;
  return 0;
};

1;

