latexmk:由于第一次 latex 运行后要创建文件而导致大量运行

latexmk:由于第一次 latex 运行后要创建文件而导致大量运行

我有一个乳胶文件,其中包含许多最初不存在但在运行过程中创建的文件latexmk

\documentclass{article}
\usepackage{functional}
\usepackage{import}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{transparent}
\usepackage{listings}

...

\begin{document}

% \lstinputlisting[language=tex, basicstyle=\tiny,
% breaklines, lastline=25,
% float, captionpos=b, label={lst:ptx}, 
% caption={The ptx-file for a fig-file}]{F4_01fig2dev.ptx}

\fileIfExistTF{F4_01fig2dev.ptx}{x\lstinputlisting{F4_01fig2dev.ptx}}{\input{F4_01fig2dev.ptx}}
%\lstinputlisting{F4_01fig2dev.ptx}
\import{}{F4_01fig2dev.ptx}
%\import{}{F4_04mp2mps.ptx}

\import{}{F4_03someGnuplot.ptx}

\includegraphics{F4_05someMetapost.mps}

%\import{}{F4_06svg2pdf.ptx}%
\def\svgwidth{0.5\textwidth}%
\import{}{F4_07someSvg.ptx}

\end{document}

看起来,latexmk它会一直运行,lualatex直到第一个要包含的文件不存在。它以致命错误结束,但继续创建第一个包含的文件。然后它运行lualatex第二次,由于第二个文件丢失而导致第二个致命错误。同样,在某些规则中,它会被创建,然后它继续运行。

这会导致运行次数超过要包含的文件数。可能需要额外运行才能稳定下来。

我觉得这不令人满意。如何解决这个问题?我想知道是否有可能采取完全不同的方式?或者让 lualatex 不会因为每个丢失的文件而停止?因此 lualatex 运行的次数不取决于包含的文件的数量。

根据以下建议,我修改了我的解决方案:在\begin{document}我添加的前面

\usepackage{functional}
\usepackage{letltxmacro}
\LetLtxMacro\latexlstinputlisting\lstinputlisting
\renewcommand{\lstinputlisting}[2][]{\fileIfExistTF{#2}{\latexlstinputlisting[#1]{#2}}{\typeout{No file #2.}}}
\LetLtxMacro\lateximport\import
\renewcommand{\import}[2]{\fileIfExistTF{#2}{\lateximport{#1}{#2}}{\typeout{No file #1#2.}}}
\LetLtxMacro\latexincludegraphics\includegraphics
\renewcommand{\includegraphics}[2][]{\fileIfExistTF{#2}{\latexincludegraphics[#1]{#2}}{\typeout{No file #2.}}}

对于这个特殊文件,的运行次数lualatex确实减少了。但我并不满意。重新定义似乎相当危险。例如,\input天真地重新定义似乎会影响\includegraphics

更糟糕的是,\input可以与没有结尾的文件一起使用xxx.tex。因此,对于\includegrapics。在这种正常用法下,当前解决方案不起作用。

有什么建议么?

也许我的.latexmkrc文件有用

#!/usr/bin/env perl

# to create pdf via lualatex 
#$pdflatex = 'lualatex -file-line-error %O %S';

# PDF-generating modes are:
# 1: pdflatex, as specified by $pdflatex variable (still largely in use)
# 2: postscript conversion, as specified by the $ps2pdf variable (useless)
# 3: dvi conversion, as specified by the $dvipdf variable (useless)
# 4: lualatex, as specified by the $lualatex variable (best)
# 5: xelatex, as specified by the $xelatex variable (second best)
$pdf_mode = 4;# specifies creation of pdf via lualatex 

# If additional parameters must be passed to lualatex 
#'svg' package.
# It converts raw SVG files to the PDF+PDF_TEX combo using InkScape.
# $lualatex = "lualatex --shell-escape";

# note that -recorder is implicitly added 
$latex2pdfOptions = "-interaction=nonstopmode -synctex=1 -shell-escape";
$lualatex = "lualatex $latex2pdfOptions %O %S";

#$postscript_mode = $dvi_mode = 0;

# to configure bibtex 
$bibtex_use=2;

# this cannot be done according to the according latex maven plugin, 
# because the according parameter maxNumReRunsLatex may be set to -1 
# which signifies an infinite number of runs. 
$max_repeat=30;

# default are tex and eps, but could also be pdf and ptx and mps
# Currently, all those files are given with explicit endings, 
# so no extensions to be added. 
#add_input_ext('');

# It is what it seems to be: clean inludes what was generated by cus 
$cleanup_includes_cusdep_generated = 1;
$cleanup_includes_generated = 1;

#$makeindex = 'makeindex %O -o %D %S'; # the default

# TBD: clarify: xdv and dvi seem to be internal. 
# maybe missing other extensions in conjunction with synctex
$clean_ext .= " %R.synctex.gz";

# bbl does not work
#@generated_exts = (@generated_exts, 'lol', 'bbl', 'glo', 'ist') 
#print "Hello!"
#foreach (@generated_exts) {
#print "Generated exts: $_\n";
#}
#print "clean_ext\n";
# Here @generated_exts is ('aux', 'fls', 'log', # generated by latex already
# 'toc', 'lof', 'lot', 'out', # generated by latex conditionally 
# 'idx', 'ind', 'blg', 'ilg', # concerning indices 
# # strange enough: nothing for bibtex 
# 'xdv', 'bcf'

# extensions ext to be deleted by latexmk -c 
# Note that the file names are %R.ext. 
# this may cause problems with extensions containing a dot. 
# Also this is not general enough 
# if the generated file deviates from %R by more than an extension. 
# In this case, use $clean_ext$
# Here, $clean_ext is empty. 
# list of listings, whereas lof and lot are already present. 
push @generated_exts, "lol";
push @generated_exts, "dvi", "xdv";
# for beamer class 
push @generated_exts, "nav", "snm", "vrb";

# why are .ist and xdy not under generated_exts? 
# note that currently, either %R or what is present is the extension only! 
# this does not make sense very much. 
# $clean_ext .= " stateMachine.log"; does not work, because stateMachine.log is the extension! 

# should be under indexing 
$clean_ext .= " %R.ist %R.xdy %R-*.ind %R-*.idx %R-*.ilg %R-*.ind";


add_cus_dep('fig', 'ptx', 0, 'fig2dev');
sub fig2dev {
  $file = $_[0];
  print("$file");
  rdb_add_generated("$file.eps", "$file.pdf", "$file.ptx");
  my $GenOptions = "";
  my $PtxOptions = "";
  my $PdfEpsOptions = "";
  print("create from $file.fig");
  rdb_add_generated("$file.ptx", "$file.pdf", "$file.eps");
  #fig2dev -L pstex    <fig2devGenOptions> <fig2devPdfEpsOptions>        xxx.fig xxx.eps   
  #fig2dev -L pdftex   <fig2devGenOptions> <fig2devPdfEpsOptions>        xxx.fig xxx.pdf   
  #fig2dev -L pdftex_t <fig2devGenOptions> <fig2devPtxOptions>    -p xxx xxx.fig xxx.ptx

  my $ret1 = system("fig2dev -L  pstex   $GenOptions $PdfEpsOptions       $file.fig $file.eps");
  my $ret2 = system("fig2dev -L pdftex   $GenOptions $PdfEpsOptions       $file.fig $file.pdf");
  my $ret3 = system("fig2dev -L pdftex_t $GenOptions $PtxOptions -p $file $file.fig $file.ptx");


  return ($ret1 or $ret2 or $ret3);
}

add_cus_dep('gp', 'ptx', 0, 'gnuplot');
sub gnuplot {
  $file = $_[0];
  print("create from $file.gp");
  rdb_add_generated("$file.ptx", "$file.pdf", "$file.eps");
  my $nuplotOptions = "";
  my $ret1 = system("gnuplot -e \"set terminal cairolatex pdf $gnuplotOptions;\
            set output '$file.ptx';\
            load '$file.gp'\"");
  # my $ret2 = system("gnuplot -e \"set terminal cairolatex eps $gnuplotOptions;\
  #           set output '$file.ptx';\
  #           load '$file.gp'\"");
  return $ret;
}

# metapost rule from http://tex.stackexchange.com/questions/37134
#add_cus_dep('mp', 'mps', 0, 'mpost');
add_cus_dep('mp', 'mps', 0, 'mpost');
sub mpost {
  my $file = $_[0];
  print("create from $file.mp");
  rdb_add_generated("$file.mps", "$file.fls", "$file.log");
  my ($name, $path) = fileparse($file);
  pushd($path);
  my $return = system("mpost -interaction=nonstopmode -recorder -s prologues=2 -s 'outputtemplate=\"%j.mps\"' $name");
  popd();
  return $return;
}


add_cus_dep('svg', 'ptx', 0, 'inkscape');
sub inkscape {
  my $file = $_[0];
  print("create from $file.svg");
  rdb_add_generated("$file.ptx", "$file.pdf");
  my $ret1 = system("inkscape -D --export-filename=$file.pdf --export-latex $file.svg ");
  #my $ret2 = system("inkscape -D --export-filename=$file.eps --export-latex $file.svg ");
  #use File::Copy;
  # This works only for pdf, not for eps. 
  #unlink($file.pdf_tex) or die "cannot unlink $file.pdf_tex";
  rename("$file.pdf_tex", "$file.ptx");# or die "cannot move $file.pdf_tex";
  return $ret1;# or $ret2;
}


# graphics for xfig (not appropriate for mixed tex/pdf)

# add_cus_dep('fig', 'pdf', 0, 'fig2pdf');

# sub fig2pdf {
# system( "fig2dev -Lpdf \"$_[0].fig\" \"$_[0].pdf\"" );
# }


# use splitindex 
$makeindex = 'internal splitindex';

sub splitindex {
   # Use splitindex instead of makeindex.
   # The splitindex programe starts from an .idx file, makes a set of
   #   other .idx files for separate indexes, and then runs makeindex to
   #   make corresponding .ind files.
   # However, it is possible that the document uses the splitindex
   #   package, but in a way compatible with the standard methods
   #   compatible with makeindex, i.e., with a single index and with the
   #   use of the \printindex command.
   #   Then we need to invoke makeindex.
   # In addition, latexmk assumes that makeindex or its replacement makes
   #   an .ind file from an .idx file, and latexmk gives an error if it
   #   doesn't exist, we need to make an .ind file.
   # Both problems are solved by running makeindex and then splitindex.
   # Note: errors are returned by makeindex and splitindex for things
   #   like a missing input file.  No error is returned for lines in an
   #   input file that are in an incorrect format; they are simply
   #   ignored.  So no problem is caused by lines in the .idx file
   #   that are generated by splitindex in a format incompatible with
   #   makeindex.
   my $ret1 = system( "makeindex", $$Psource );
   my $ret2 = system( "splitindex", $$Psource );
   return $ret1 || $ret2;
}


add_cus_dep( 'acn', 'acr', 0, 'makeglossaries' );
add_cus_dep( 'glo', 'gls', 0, 'makeglossaries' );
push @generated_exts, 'glo', 'gls', 'glg';
push @generated_exts, 'acn', 'acr', 'alg';
push @generated_exts, "ist"; # index stylefile created by the glossaries package 

#$clean_ext .= " acr acn alg glo gls glg";# TBD: clarify: better in @generated_exts? 

sub makeglossaries {
     my ($base_name, $path) = fileparse( $_[0] );
     my @args = ( "-q", "-d", $path, $base_name );
     if ($silent) { unshift @args, "-q"; }
     return system "makeglossaries", "-d", $path, $base_name; 
}

sub run_makeglossaries {
    my ($base_name, $path) = fileparse( $_[0] ); #handle -outdir param by splitting path and file, ...
    pushd $path; # ... cd-ing into folder first, then running makeglossaries ...

    if ( $silent ) {
        # system "makeglossaries -q '$base_name'"; #unix
        system "makeglossaries", "-q", "$base_name"; #windows
    }
    else {
        # system "makeglossaries '$base_name'"; #unix
        system "makeglossaries", "$base_name"; #windows
    };

    popd; # ... and cd-ing back again
}


# !!! ONLY WORKS WITH VERSION 4.54 or higher of latexmk
#TBD: take into account: modified: 
#  '$_[0]'->


# #############
# # makeindex #
# #############
# @ist = glob("*.ist");
# if (scalar(@ist) > 0) {
#         $makeindex = "makeindex -s $ist[0] %O -o %D %S";
# }


# glossaries new with bib2gls 

# push @generated_exts, 'glstex', 'glg';

# add_cus_dep('aux', 'glstex', 0, 'run_bib2gls');

# sub run_bib2gls {
#     if ( $silent ) {
#         my $ret = system "bib2gls --silent --group $_[0]";
#     } else {
#         my $ret = system "bib2gls --group $_[0]";
#     };
    
#     my ($base, $path) = fileparse( $_[0] );
#     if ($path && -e "$base.glstex") {
#         rename "$base.glstex", "$path$base.glstex";
#     }

#     # Analyze log file.
#     local *LOG;
#     $LOG = "$_[0].glg";
#     if (!$ret && -e $LOG) {
#         open LOG, "<$LOG";
#       while (<LOG>) {
#             if (/^Reading (.*\.bib)\s$/) {
#               rdb_ensure_file( $rule, $1 );
#           }
#       }
#   close LOG;
#     }
#     return $ret;
# }





$pythontex = 'pythontexW %R';#'pythontexW %O %R';
push @generated_exts, "pytxcode", "plg";
push @generated_exts, "depytx", "dplg";

$clean_ext .= " pythontex-files-%R/* pythontex-files-%R";
#$extra_rule_spec{'pythontex'}  = [ 'internal', '', 'mypythontex', "%Y%R.pytxcode", "%Ypythontex-files-%R/%R.pytxmcr", "%R", 1 ];
$extra_rule_spec{'pythontex'} = [ 'internal', '', 'mypythontex', "%R.pytxcode", "pythontex-files-%R/%R.pytxmcr", "%R", 1 ];

sub mypythontex {
   my $result_dir = $aux_dir1."pythontex-files-$$Pbase";
   my $ret = Run_subst( $pythontex, 2 );
   rdb_add_generated( glob "$result_dir/*" );
   #my $fh = new FileHandle $$Pdest, "r";
   open( my $fh, "<", $$Pdest );
   if ($fh) {
      print "path: $ENV{PATH}";
      while (<$fh>) {
         if ( /^%PythonTeX dependency:\s+'([^']+)';/ ) {
         print "Found pythontex dependency '$1'\n";
             rdb_ensure_file( $rule, $aux_dir1.$1 );
     }
      }
      undef $fh;
   }
   else {
       warn "mypythontex: I could not read '$$Pdest'\n",
            "  to check dependencies\n";
   }
   return $ret;
}


# for htlatex 
push @generated_exts, "4tc", "4ct", "tmp", "xref", "css", "idv", "lg";
# TBD: for -C remove also html and xhtml
# TBD: check that this plugin also removes all these extensions.. think of lg. 


# biblatex
# push @generated_exts, "run.xml";# does run.xml work? 
# $clean_ext .= " %R-blx.bib";

答案1

有一个简单的解决方案:更换

\input{F4_01fig2dev.ptx}

\wlog{No file F4_01fig2dev.ptx.}

它确实执行了它所读取的操作——将该字符串写入日志文件,该文件将由 latexmk 进行处理。

另一种方法是\typeout通常同时在日志文件和终端中输入。

(正如 Ulrike 在评论中暗示的那样,但除了阅读源代码之外,还需要花费一些精力来弄清楚“latexmk 需要什么”......)

另一个可能的魔术字符串! LaTeX Error: File F4_01fig2dev.ptx not found.}通常由 打印\input,但实际上没有“内置”函数来打印出这个字符串。

摘自 source2e


不可否认的是,这个技巧并不是很令人满意,因为它对魔法字符串“无文件”进行了硬编码,但许多软件包都是这样做的……

  • latexmk 文档建议了类似的技巧

    latexmk 文档

  • pythontex源代码:

    pythontex 源代码

  • LaTeX 源代码:

    LaTeX 源代码

  • 一些答案暗示了这个技巧: 1 2 3 4 5 6

相关内容