4
\$\begingroup\$

I have created a GNUMake building system for pandoc. It has grown quite a bit, I wonder if I can optimize it further. Would it be possible, for instance, that it only runs a target if the output hasn't changed since last run?

.DEFAULT_GOAL := pdf

INPUTDIR=$(CURDIR)/source
OUTPUTDIR=$(CURDIR)/output
STYLEDIR=$(CURDIR)/style
NAME = $(notdir $(shell basename "$(CURDIR)"))

FILFILES = $(wildcard style/*.py)

FILTER := $(foreach FILFILES, $(FILFILES), --filter $(FILFILES))
TEXFLAGS = --filter pandoc-crossref --filter pandoc-citeproc $(FILTER) --latex-engine=xelatex

ifeq ($(shell test -e "$(STYLEDIR)/template.tex" && echo -n yes),yes)
    TEXTEMPLATE = "--template=$(STYLEDIR)/template.tex"
endif

ifeq ($(shell test -e "$(STYLEDIR)/reference.docx" && echo -n yes),yes)
    DOCXTEMPLATE = "--reference-docx=$(STYLEDIR)/reference.docx"
endif

help:

    @echo '                                                                       '
    @echo 'Makefile for automated typography using pandoc.                         '
    @echo 'Version 1.0                        '
    @echo '                                                                       '
    @echo 'Usage:                                                                 '
    @echo '   make prepare    first time use, setting the directories     '
    @echo '   make html       generate a web version             '
    @echo '   make pdf        generate a PDF file             '
    @echo '   make docx       generate a Docx file            '
    @echo '   make tex        generate a Latex file               '
    @echo '   make beamer     generate a beamer presentation              '
    @echo '   make all        generate all files                 '
    @echo '   make update     update the makefile to last version       '
    @echo '   make            will fallback to PDF               '
    @echo '                                                                       '
    @echo 'It implies some directories in the filesystem: source, output and style'
    @echo 'It also implies that the bibliography will be defined via the yaml     '
    @echo '                                                                       '
    @echo 'Depends on pandoc-citeproc and pandoc-crossref                         '
    @echo 'Get local templates with: pandoc -D latex/html/etc                     '
    @echo '                                                                       '



all : tex docx html epub pdf


pdf:
    pandoc "$(INPUTDIR)/"*.md \
    -o "$(OUTPUTDIR)/$(NAME).pdf" \
    $(TEXTEMPLATE) \
    $(TEXFLAGS) 2>pandoc.log
    xdg-open "$(OUTPUTDIR)/$(NAME).pdf"

tex:
    pandoc "$(INPUTDIR)"/*.md \
    --filter pandoc-crossref \
    --filter pandoc-citeproc \
    -o "$(OUTPUTDIR)/$(NAME).tex" \
    --latex-engine=xelatex

docx:
    pandoc "$(INPUTDIR)"/*.md \
    --filter pandoc-crossref \
    --filter pandoc-citeproc \
    $(DOCXTEMPLATE) \
    --toc \
    -o "$(OUTPUTDIR)/$(NAME).docx"

html:
    pandoc "$(INPUTDIR)"/*.md \
    -o "$(OUTPUTDIR)/$(NAME).html" \
    --include-in-header="$(STYLEDIR)/style.css" \
    -t html5 \
    --toc \
    --standalone \
    --filter pandoc-crossref \
    --filter pandoc-citeproc \
    --number-sections
    rm -rf "$(OUTPUTDIR)/source"
    mkdir "$(OUTPUTDIR)/source"
    cp -r "$(INPUTDIR)/figures" "$(OUTPUTDIR)/source/figures"

epub:
    pandoc "$(INPUTDIR)"/*.md \
    -o "$(OUTPUTDIR)/$(NAME).epub" \
    --toc \
    --standalone \
    --filter pandoc-crossref \
    --filter pandoc-citeproc
    rm -rf "$(OUTPUTDIR)/source"
    mkdir "$(OUTPUTDIR)/source"
    cp -r "$(INPUTDIR)/figures" "$(OUTPUTDIR)/source/figures"

beamer:
    pandoc "$(INPUTDIR)/"*.md \
    -t beamer \
    -o "$(OUTPUTDIR)/$(NAME).pdf" \
    $(TEXTEMPLATE) \
    $(TEXFLAGS) 2>pandoc.log
    xdg-open "$(OUTPUTDIR)/$(NAME).pdf"

prepare:
    mkdir "output"
    mkdir "source"
    mkdir "style"

update:
    wget http://tiny.cc/mighty_make -O Makefile

clean:
    rm -f "$(OUTPUTDIR)/" *.md *.html *.pdf *.tex *.docx

.PHONY: help pdf docx html tex clean
\$\endgroup\$
1
  • \$\begingroup\$ Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. \$\endgroup\$ – Zeta Aug 12 '17 at 12:01
1
\$\begingroup\$

only runs a target if the output hasn't changed since last run

Consider writing rules like this:

%.pdf: %.md
        pandoc -o $@ $<

For that to work, the current all: ... pdf would need to mention particular *.pdf files, perhaps by globbing: $(patsubst %.md,%.pdf,*.md)

\$\endgroup\$
3
  • \$\begingroup\$ The problem is that pandoc will generate one pdf from several md files, I can't figure out how to handle this in the syntax you suggest... \$\endgroup\$ – lf_araujo Aug 12 '17 at 5:53
  • \$\begingroup\$ I frequently write Makefiles that start with all: foo.pdf bar.pdf baz.pdf, followed by the generic %.pdf rule I mentioned above. So that would be three invocations of pandoc in my example. If you're not willing to list particular targets after "all", I was thinking you could get patsubst globbing to do it for you. \$\endgroup\$ – J_H Aug 12 '17 at 16:24
  • \$\begingroup\$ Thank you, your suggestion really helped and the makefile now recognizes the files that changed. I made an example of it in use here. \$\endgroup\$ – lf_araujo Aug 13 '17 at 2:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.