# ================ Customization for dot2tex: ================================

push @generated_exts, '%R-dot2tex-fig*.tex', '%R-dot2tex-fig*.dot',
                     '%R-dot2tex-fig*.dot2texopts';
add_cus_dep( 'dot', 'tex', 0, 'dot2tex' );

# Fancy: prefix string for each *latex by "internal" mylatex and basename of tex file
#foreach my $name ( 'latex', 'pdflatex', 'lualatex', 'xelatex' ) {
#   ${$name} = "internal mylatex %B ". ${$name};
#}

$latex    = 'internal mylatex %B latex %O %S';
$lualatex = 'internal mylatex %B lualatex %O %S';
$pdflatex = 'internal mylatex %B pdflatex %O %S';
$xelatex  = 'internal mylatex %B xelatex %O %S';


#---------------------------------

sub dot2tex {
   # Context for a dot2tex custom dependency assumed.

   # Default options:
   my $opts = '--figonly -fpgf -tmath';

   # File that contains the option string. (Written after analysis of the
   # log file for the previous *latex run.)
   my $opt_file = "$_[0].dot2texopts";

   # Ensure that it is known as a source file of this rule, since some
   # changes in the main .tex could affect the options only, but not the
   # contents of the .dot file
   rdb_ensure_file( $rule, $opt_file );

   if ( -e $opt_file && open( my $fh, '<', $opt_file ) ) {
       $opts = <$fh>;
       close $opt_file;
   }
   else { warn "dot2tex: Cannot open '$opt_file'\n"; }

   my @cmd = ( 'dot2tex', split(/\s+/, $opts), '-o', $$Pdest, $$Psource );
   print "dot2tex command line to execute:\n ", join( ' ', @cmd), "\n";
   return system @cmd;
}

#---------------------------------

sub mylatex {
   # Context for a *latex rule assumed.
   # Run *latex as specified in my arguments, and then process the log file
   # to deal with dot2tex conversions needed by the dot2texi package.

   my ($base, @cmd) = @_;
   my $log_name = "$aux_dir1$base.log";

   my $return = system @cmd;
   &examine_log_for_dot2tex( $log_name );
   return $return;
}

#---------------------------------

sub examine_log_for_dot2tex {
  # Context for a *latex rule assumed.
  # From the log file given in the argument to this subroutine,
  # find places where dot2tex would be invoked if *latex were used with
  # the -shell-escape option.  This invocation is on .dot files created
  # by the dot2texi package.
  # Find the basename of the .dot and .tex files (all assumed to be
  # relative to the aux dir).  (Basename includes a possible path
  # component.)
  # Ensure that for each .dot file the .tex file is in the source file of
  # the current rule, so that latexmk will know to make a corresponding
  # custom dependency.
  # Put the option string in a file where the custom dependency for the
  # dot-to-tex conversion can find it.

  my $log_name = $_[0];

  # Map of basenames_with_relative_path of dot/tex file to option string
  my %found = ();

  open( my $log_fh, '<', $log_name )
     or ( warn( "examine_log_for_dot2tex: Can't read '$log_name'\n" ),
          return
        );
LINE:
  while (my $line = <$log_fh> ) {
      # Aim: find lines of form runsystem\(dot2tex followed by options
      #      followed by "-o file.tex file.dot)", for some value of file.
      #      Allow for continuation lines.
      # Often use /.../x with x option to regex, to get space in pattern
      # ignored, for readability

      # Ignore lines with wrong start:
      if ( $line !~ /^runsystem\(dot2tex \s+ (.*)$/x ) { next; }

      # Rest of command line (after dot2tex) is in $1.
      my $args = $1;

      # Only keep going if arguments begin with options and have -o (for
      # output file):
      if ( $args !~ /(-.*) \s+ -o \s+ (.*) $/x ) {
         next LINE;
      }

      # Putative options for command, then source and dest file:
      my ($opts, $file_part) = ($1, $2);
      # Remove superfluous space:
      $opts =~ s/\s+/ /g;
      $opts =~ s/\s*$//;
      if ( $opts !~ /^(-\S+\s*)*$/x ) {
         warn "Putative options for dot2tex in '$opts' aren't options\n";
         next LINE;
      }
      my $attempts = 0;

CONT_LINE:
      while ($attempts < 2) {
          $attempts++;
          if ($file_part =~ /^(.+) \.tex \s+ \1 \.dot\)/x ) {
              ($found{$1} = $opts) =~ s/\s+/ /g;
              last CONT_LINE;
          }
          if (length($line) >= 80) {
             if (eof($log_fh)) { last LINE; }
             $file_part .= <$log_fh>;
             # Remove trailing new line characters:
             $file_part =~ s/[\n\r]$//;
          }
          else { last CONT_LINE; }
      }
  }
  close $log_fh;

  my @missing_files = ();
  while (my ($base, $opts) = each %found) {
      my $dot = "$aux_dir1$base.dot";
      my $tex = "$aux_dir1$base.tex";
      # File to save options for dot2tex command, so cusdep can read them:
      my $opt_file = "$aux_dir1$base.dot2texopts";

      write_to_file( $opt_file, "$opts\n" );
      if (! -e $tex) { push @missing_files, $tex; }
  }
  if (@missing_files) {
      # No-file lines for missing .tex files will tell latexmk to try
      # to find a cusdep to make them:
      append_to_file( $log_name, map("No file $_.\n", @missing_files) );
  }
}

#---------------------------------

sub write_to_file {
 # Usage: write_to_file( name, items to write )
 my $file = shift;
 open( my $fh, ">", $file )
   or (warn "Cannot write to '$file'\n", return 0 );
 print $fh @_;
 close( $fh );
}

#---------------------------------

sub append_to_file {
 # Usage: append_to_file( name, items to write )
 my $file = shift;
 open( my $fh, ">>", $file )
   or (warn "Cannot append to '$file'\n", return 0 );
 print $fh @_;
 close( $fh );
}

#---------------------------------