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
Zeta
19.6k2 gold badges57 silver badges90 bronze badges
asked Aug 12, 2017 at 3:25
\$\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\$ Commented Aug 12, 2017 at 12:01

1 Answer 1

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)

answered Aug 12, 2017 at 5:34
\$\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\$ Commented Aug 12, 2017 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\$ Commented Aug 12, 2017 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\$ Commented Aug 13, 2017 at 2:05

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.