Latexmk 无法看到 .fmt 格式文件的依赖关系

Latexmk 无法看到 .fmt 格式文件的依赖关系

我在一台小型上网本上使用 latex,对于一般大小的文件(目前约 150 页),编译速度已经相当慢。因此,我正在寻找各种方法来加快编译速度。

在这次搜索中,我发现这一页解释如何“预编译序言”,或者从 Latex 的角度讲,如何创建自定义格式文件。这样就足够了。

但是我的序言并不像它应该的那样静态,我不断在其中添加或修改定义。为了混合这两种解决方案,目前,我将 Makefile 与 一起使用latexmk,makefile 处理.fmt文件的重新生成(如果需要),并latexmk妥善处理其余部分。

但我对此有两个问题:

  • 集成emacs在处理单个文件时编译整个文档(make需要在适当的目录中调用)
  • latexmk每次修改前言时都不会重新编译文件,因为它不算作依赖项。

所以我想找到一种方法来摆脱这个 Makefile,并完成所有的事情latexmk

我编辑了我的.latexmkrc以包括以下内容:

pdflatex = 'pdflatex -fmt main %O %S';

add_input_ext('pdflatex','fmt');

add_cus_dep('tex', 'fmt', 1, 'compilepreamble');
sub compilepreamble {
    print "Preamble compiling...\n";
    $command = '&.pdflatex ./fmt/preamble.tex\dump';
    system("pdflatex -ini -jobname='$_[0]' '$command'");
};   

但是这样,如果文件main.fmt不存在或者文件fmt/preamble.tex已更新,main.fmt则不会重新生成文件。实际上,在第一种情况下,我收到错误消息,pdflatex提示找不到main.fmt格式文件。所以我明白latexmk甚至没有尝试构建main.fmt,这可能不是我自定义依赖项中的问题。但是,我认为我已经添加了使其正常工作所需的一切。

那么...我是不是忘了什么?有办法解决吗?还是说这是个无望的任务?

答案1

您忘记了自定义依赖项旨在使输入和输出文件仅在扩展名上有所不同,例如,转换foo.ltxfoo.fmt。但它们无法转换fmt/preamble.texmain.fmt。第二个但不太严重的问题是,当 pdfLaTeX 找不到 .fmt文件时,它会在屏幕上显示错误消息,但它不会将错误消息放入日志文件中(因此latexmk无法检测到缺少文件)。

如果将前言文件重命名为main.ltx(不在子目录中),则以下初始化代码应该可以工作:

$recorder = 1;
$pdflatex = 'pdflatex -fmt main %O %S';
add_input_ext('pdflatex','fmt');
add_cus_dep('ltx', 'fmt', 1, 'compilepreamble');
sub compilepreamble {
    print "Preamble compiling for '$_[0]'...\n";
    my $fls_file = "$_[0].fls";
    my $source = "$_[0].ltx";
    my $fmt_file = "$_[0].fmt";
    my $return = system( "pdflatex", "-interaction=batchmode",
                         "-ini", "-recorder", "-jobname=$_[0]",
                         "&pdflatex $source \\dump" );
    if ($return) { 
        warn "Error in making format file '$fmt_file'\n";
       return $return;
    }
    my %input_files = ();
    my %output_files = ();
    $return = parse_fls( $fls_file, \%input_files, \%output_files );
    if ($return) {
        warn "No fls file '$fls_file' made; I cannot get dependency data\n";
        return 0; 
    }
    # Use latexmk's internal variables and subroutines for setting the
    #   dependency information.
    # Note that when this subroutine is called to implement a custom
    #   dependency, the following variables are set:
    #       $rule  contains the name of the current rule (as in the
    #              fdb_latexmk file)
    #       $PHsource is a pointer to a hash of source file
    #              information for the rule.  The keys of the hash are
    #              the names of the source files of the rule.
    foreach my $file (keys %input_files) {
        rdb_ensure_file( $rule, $file );
    }
    foreach my $file (keys %$PHsource) {
        if ( ! exists $input_files{$file} ) {
            print "   Source file of previous run '$file' ",
                  "IS NO LONGER IN USE\n";
            rdb_remove_files( $rule, $file );
        }
    }
    return 0;
};

我使用了扩展名.ltx,以便.tex您可以拥有与主文件具有相同基本名称的前言文件。

pdflatex -ini ...第一次需要手动运行来创建.fmt文件。之后latexmk应该会自动处理。

编辑(2012 年 4 月 2 日):我改进了代码,以便它能够检测 所使用的文件的依赖关系pdflatex -ini。这使用了 的一些内部变量和子例程latexmk

相关内容