Makefile:在子目录中构建LaTeX文件,每个文件有两个版本

时间:2014-10-01 14:46:27

标签: makefile latex latex-environment

我有以下文件夹结构

   1st-grade-math-class/
      common/
        mystyle.sty
        mysubstyle.sty
        fonts/
          font1.ttf
          font2.ttf
          font3.ttf
      week01/
        handout.tex
        image1.pdf
        image2.pdf
      week02/
        handout.tex
        image1.pdf
        image2.pdf
      ...
      week13/
        handout.tex
      output/
        [empty]

我想创建一个Makefile - 以最好的方式 - 执行以下操作:

  • 确保我在TEXINPUTS中正确包含 common 目录

  • handout.tex 编译成PDF(使用pdflatex或xelatex)并将其作为 output01-handout-位于输出目录中student.pdf

  • 编译 handout.tex ,将一行LaTeX预先添加到文件的开头(设置一个标志)为PDF并将其放在输出中目录为 week01-handout-teacher.pdf

  • 清理所有内容(日志,辅助文件等)

我不知道除了在每个子目录中手动复制一个基本的Makefile / bash脚本之外,我不知道怎么做,然后用for循环逐个调用它们。

我非常感谢有关如何构建此进程的帮助,理想情况是在根目录中使用单个Makefile。感谢。

更新:我故意不想提供有关我如何编译LaTeX的任何细节,以防有人提出比我目前用法更好的建议。现在我正在使用Latexmk(它已经是LaTeX的类似make的包装器):

  • latexmk -pdf file.tex 生成 file.pdf
  • 添加代码行,我做一个简单的回声"代码行" > temp.tex和cat handout.tex>> temp.tex,然后是相同的latexmk命令
  • 目录中的
  • latexmk -c file.tex 清除用于编译file.tex的所有临时文件
  • TEXINPUTS是TeX路径变量,让TeX找到(在其路径中)样式文件:我执行TEXINPUTS = full-path-to / common,然后在编译之前导出TEXINPUTS。

如果有人有更好的建议,我愿意接受。

2 个答案:

答案 0 :(得分:1)

这样的事情应该做你想要的我相信:

OUTDIR := output

# Tell make to export this environment variable to all recipe lines it runs.
export TEXINPUTS := $(abspath common)

# Get the list of all of our week directories.
weekdirs := $(wildcard week*)
#$(info weekdirs:$(weekdirs))

# Create student output filenames from week directory names.
STUDENT_HANDOUTS := $(patsubst %,$(OUTDIR)/%-handout-student.pdf,$(weekdirs))
#$(info STUDENT_HANDOUTS:$(STUDENT_HANDOUTS))

# Create teacher output filenames from week directory names.
TEACHER_HANDOUTS := $(patsubst %,$(OUTDIR)/%-handout-teacher.pdf,$(weekdirs))
#$(info TEACHER_HANDOUTS:$(TEACHER_HANDOUTS))

# Default target depends on all output files.
all: $(STUDENT_HANDOUTS) $(TEACHER_HANDOUTS)

# Pattern rule for building pdf files.
%.pdf:
        @echo + Making $@ from $^
        @echo cd $(@D) && echo latexmx -pdf $(abspath $<)
        @echo cd $(@D) && echo latexmk -c $(abspath $<)

# Static pattern rule mapping student output files to input files.
$(STUDENT_HANDOUTS) : $(OUTDIR)/%-handout-student.pdf : %/handout.tex

# Pattern rule to generate temporary input files from original input files.
%/handout-tmp.tex: %/handout.tex
        @echo echo 'line of code' '>' $@
        @echo cat $^ '>>' $@

# Static pattern rule mapping teacher output files to (temporary) input files.
$(TEACHER_HANDOUTS) : $(OUTDIR)/%-handout-teacher.pdf : %/handout-tmp.tex

取消注释$(info)行以查看变量如何组合在一起。

在创建输出文件后,它使用latexmk -c来清理辅助文件。

答案 1 :(得分:1)

技术1 echo foo >$@; cat $< >>$@之前的事情是我之前做过的事情;我觉得这很合理。

技术2 。另一种方法是让您的.tex文档或其使用的包文件包含如下行:

\InputIfFileExists{lecturenotes.config}{}{}

这允许您在makefile中进行某些调整,例如:

# any bits of configuration that should be in all the .config files
SWITCHES=\makeindex

%-notes.pdf: %.tex
        printf '$(SWITCHES)\\ExecuteOptions{sidenotes}\n' >lecturenotes.config
        TEXINPUTS=styles: pdflatex $<
        mv ${<:.tex=.pdf} $@    
        rm lecturenotes.config

%-single.pdf: %.tex
        printf '$(SWITCHES)\\ExecuteOptions{oneside}\n' >lecturenotes.config
        TEXINPUTS=styles: pdflatex $<
        mv ${<:.tex=.pdf} $@
        rm lecturenotes.config

技术3 。从外部控制LaTeX的第三种方法是在文档中(或在包文件中)包含:

\newif\ifdemonstrator
\expandafter\ifx\csname demonstrator\endcsname\relax
  \demonstratorfalse
\else
  \demonstratortrue
\fi
...
\ifdemonstrator
    \typeout{Demonstrator is TRUE}
\else
    \typeout{Demonstrator is FALSE}
\fi

然后用:

打电话给乳胶
%-plain.pdf: %.tex
    latex $<
    mv ${<:.tex=.pdf} $@

%-demo.pdf: %.tex
    latex --jobname ${<:.tex=} '\def\demonstrator{x}\input{$<}`
    mv ${<:.tex=.pdf} $@

技术1是一种钝器,但如果需要的话,它非常轻巧。

技术2可能是最整洁的设计,但它稍微有些努力。

技术3可能是我在这种情况下最常用的技术。