###############################################################################
#
# How To Use this Makefile
#------------------------------------------------------------------------------
# Let's say you have a markdown source file named foo.md in the 'fr' directory
#
#  - `make fr/foo.pdf` will build a PDF from fr/foo.md
#  - `make fr/foo.epub` will build an EPUB from fr/foo.md
#  - `make all` will build all source files in all formats
#  - `make clean` will remove all build artifacts
#
# Pandoc or docker ?
#------------------------------------------------------------------------------
#
#  - by default, we use pandoc to compile documents
#  - if pandoc is not installed, we use a docker image instead
#    see https://github.com/dalibo/pandocker/
#  - use `DOCKER=latest make all` to force make to use docker
#
###############################################################################


###############################################################################
# Folders

SOURCES=en fr
DEST=_build

PATHS := $(shell find $(SOURCES) -maxdepth 1 -mindepth 1 -type d)
PATHS := $(filter-out %/include %/medias, $(PATHS))
WORKSHOPS := $(notdir $(PATHS))
INDEX := $(shell find $(SOURCES) -type f -name index.md)
THEME := $(realpath theme/)

###############################################################################
# Functions

ECHO=$(info Compiling $^ into $@)
DIR=`dirname $^`

###############################################################################
# Sources and default formats

# README files and other documentation markdown files are not compiled
EXCLUDE_FILES=.*\(LICENSE\|README\|QUICKSTART\|CONTRIBUTING\|SYNTAX\|INSTALL\|AUTHORS\)\.md
EXCLUDE_SRC=$(shell find $(SOURCES) -regex "$(EXCLUDE_FILES)" -type f)

# SRC is the list of all the source markdown files
SRC := $(filter-out $(EXCLUDE_SRC), $(shell find $(PATHS) -maxdepth 1 -type f -name '*.md'))

# See make help to know which are really supported
# Uncommented formats are generated by default
SRC_FORMATS = FILE.md
#SRC_FORMATS+= FILE.docx
#SRC_FORMATS+= FILE.epub
SRC_FORMATS+= FILE.handout.html
#SRC_FORMATS+= FILE.odt
#SRC_FORMATS+= FILE.tex
SRC_FORMATS+= FILE.pdf
#SRC_FORMATS+= FILE.beamer.pdf
SRC_FORMATS+= FILE.slides.html
#SRC_FORMATS+= FILE.slides.local.html
#SRC_FORMATS+= FILE.slides.s5.html

###############################################################################
# Pandoc
#

# Parameters common to pandoc when called directly and through docker
PANDOC_HEADERS=theme/metadata.yml
PANDOC_PARAMS?=--filter=pandoc-jinja --filter=pandoc-include

# PANDOC_MARKDOWN_FLAVOR=markdown-smart
PANDOC_MARKDOWN_FLAVOR=markdown-escaped_line_breaks

# Common arguments
PANDOC_ARGS?=--from=$(PANDOC_MARKDOWN_FLAVOR) \
             --metadata-file=$(PANDOC_HEADERS) \
             --strip-comments \
             --resource-path=.:theme

# by default we use the local pandoc (if installed)
PANDOC_BIN?=pandoc
PANDOC:=$(PANDOC_BIN) $(PANDOC_PARAMS) $(PANDOC_ARGS)

# if pandoc is not installed, force docker use
ifeq (, $(shell which $(PANDOC_BIN)))
  # do not forget to update .gitlab-ci.yml too
  PANDOCKER_TAG?=stable
  # PANDOCKER_TAG?=23.03

  # --privileged is necessary for people using SELinux
  # --rm removes the container after execution
  PANDOC:=docker run \
    --privileged --rm -it \
    --volume `pwd`:/pandoc --volume $(THEME):/pandoc/theme \
    dalibo/pandocker:$(PANDOCKER_TAG) $(PANDOC_PARAMS) $(PANDOC_ARGS)
endif

# Default templates
PANDOC_PDF_TEMPLATE?=eisvogel
PANDOC_HTML_TEMPLATE?=uikit

# Relative path to resources
PANDOC_RESOURCES=--resource-path=$(DIR) --metadata=include-entry:$(DIR)

##########################
# Pandoc Compilation Flags

MARKDOWN_FLAGS=--to markdown
# Included in make all
HTML_FLAGS=--to html --template=$(PANDOC_HTML_TEMPLATE) \
           --embed-resources --standalone --toc --toc-depth=2 \
		   --css theme/dalibo.uikit.css \
		   $(PANDOC_RESOURCES)
PDF_FLAGS=--template=$(PANDOC_PDF_TEMPLATE) \
          --pdf-engine=xelatex \
          --pdf-engine-opt=-shell-escape \
          --toc --number-sections \
          --top-level-division=chapter \
          --filter=pandoc-cover \
          --filter=pandoc-latex-environment \
		  $(PANDOC_RESOURCES)
EPUB_FLAGS=$(PANDOC_RESOURCES)
# Force the use of the revealjs cache inside pandocker
REVEAL_FLAGS=--to revealjs --standalone --variable=revealjs-url:file:/// \
             --css theme/dalibo.reveal.css --embed-resources \
		     $(PANDOC_RESOURCES)
# NOT included in make All
S5_FLAGS=--to s5 --embed-resources --standalone $(PANDOC_RESOURCES)
# NOT supported
BEAMER_FLAGS= -st beamer $(PANDOC_RESOURCES)
ODT_FLAGS=$(PANDOC_RESOURCES)
DOC_FLAGS=$(PANDOC_RESOURCES)

###############################################################################
# HTML handout

HTML_OJBS=$(SRC:.md=.handout.html)
OBJS += $(HTML_OJBS)

%.handout.html: %.md
	$(ECHO)
	$(PANDOC) $(HTML_FLAGS) $^ -o $@

###############################################################################
# Marketing markdown

%.pdf.md: %.md
	$(ECHO)
	cat $^ \
	  $(THEME)/marketing/notes.md \
	  $(THEME)/marketing/publications.md \
	  $(THEME)/marketing/backcover.md > $@

###############################################################################
# Peecho and Nocover PDF handouts

PEECHO_OBJS=$(SRC:.md=.pdf)
OBJS += $(PEECHO_OBJS)

%.pdf: %.pdf.md
	$(ECHO)
	$(PANDOC) $(PDF_FLAGS) $^ -o $@

PDF_OBJS=$(SRC:.md=.nocover.pdf)
OBJS += $(PDF_OBJS)

%.nocover.pdf: %.md
	$(ECHO)
	$(PANDOC) $(PDF_FLAGS) $^ -o $@

###############################################################################
# Reveal Slides

REVEAL_OBJS=$(SRC:.md=.slides.html)
OBJS += $(REVEAL_OBJS)

%.slides.html: %.md
	$(ECHO)
	$(PANDOC) $(REVEAL_FLAGS) $^ -o $@

REVEAL_LOCAL_OBJS=$(SRC:.md=.slides.local.html)
OBJS += $(REVEAL_LOCAL_OBJS)

%.slides.local.html: %.md
	$(ECHO)
	$(PANDOC) $(REVEAL_LOCAL_FLAGS) $^ -o $@

###############################################################################
# Epub handout

EPUB_OBJS=$(SRC:.md=.epub)
OBJS += $(EPUB_OBJS)

%.epub: %.md
	$(ECHO)
	$(PANDOC) $(EPUB_FLAGS) $^ -o $@

###############################################################################
# DOCX and ODT handouts

DOCX_OBJS=$(SRC:.md=.docx)
OBJS += $(DOCX_OBJS)

%.docx: %.md
	$(ECHO)
	$(PANDOC) $(DOCX_FLAGS) $^ -o $@

ODT_OBJS=$(SRC:.md=.odt)
OBJS += $(ODT_OBJS)

%.odt: %.md
	$(ECHO)
	$(PANDOC) $(ODT_FLAGS) $^ -o $@

###############################################################################
# Others slides

BEAMER_OBJS=$(SRC:.md=.beamer.pdf)
OBJS += $(BEAMER_OBJS)

%.beamer.pdf: %.md
	$(ECHO)
	TEXMFHOME=$(DLB)/beamer	$(PANDOC) $(BEAMER_FLAGS) $^ -o $@

S5_OJBS=$(SRC:.md=.slides.s5.html)
OBJS += $(S5_OJBS)

%.slides.s5.html: %.md
	$(ECHO)
	$(PANDOC) $(S5_FLAGS) $^ -o $@

###############################################################################
# Others formats rules

JSON_OBJS=$(SRC:.md=.json)
OBJS += $(JSON_OBJS)

%.json: %.md
	$(ECHO)
	$(PANDOC) $(JSON_FLAGS) $^ -o $@

TEX_OBJS=$(SRC:.md=.tex)
OBJS += $(TEX_OBJS)

%.tex: %.md
	$(ECHO)
	$(PANDOC) $(TEX_FLAGS) $^ -o $@

%.all:  %.html %.tex %.beamer.pdf %.pdf %.odt %.docx %.epub
	$(ECHO)

###############################################################################
# Index
INDEX_OJBS=$(INDEX:.md=.html)
OBJS += $(INDEX_OJBS)

%/index.html: %/index.md
	$(PANDOC) -t html5 --embed-resources --standalone $^ -o $@

###############################################################################
# Global Targets

all: reveal html pdf epub index

# Dynamic target definition
define workshop_target =
  $(lastword $(subst /, ,$(dir $(1)))): $(subst FILE, $(basename $(1)),$(SRC_FORMATS)) index
endef

# Invoke markdown rules for each workshop directory
$(foreach src, $(SRC), $(eval $(call workshop_target,$(src))))

# Supported formats
beamer: $(BEAMER_OBJS)
docx: $(DOCX_OBJS)
epub: $(EPUB_OBJS)
html: $(HTML_OJBS)
json: $(JSON_OBJS)
nocover_pdf: $(PDF_OBJS)
odt: $(ODT_OBJS)
pdf: $(PEECHO_OBJS)
reveal: $(REVEAL_OBJS)
tex: $(TEX_OBJS)
index: $(INDEX_OJBS)

clean:
	rm -f $(OBJS)
	rm -r $(DEST)

test:
	@echo $(OBJS) | tr " " "\n"

# stage generated files into _build directory, needed by deploy CI stage
deploy:
	for LANG in en fr ; do \
	  mkdir -p $(DEST)/$$LANG ;\
	  find $$LANG \( -name "*.html" -or -name "*.pdf" -or -name "*.epub" \) \
	    -print -exec cp {} _build/$$LANG \; ;\
	done

# stage all archived files from _archives to $(DEST) directory
archives: deploy
	for LANG in en fr ; do \
	  mkdir -p $(DEST)/$$LANG ;\
	  find _archives/$$LANG \( -name "*.html" -or -name "*.pdf" -or -name "*.epub" \) \
	    -print -exec cp {} $(DEST)/$$LANG \; ;\
	done
