# Build all Debian packaging examples and produce documentation
# Copyright (C) 2015 Osamu Aoki
# vim: set ts=8 sw=8 noet:

.PHONY: all build clean distclean
# build document
all: build

# Before building this documentation, you need to update examples/ directory
# setup and start bash inside sid-chroot
# move into "examples/" with "cd examples"
#   update Makefile and run "make groom"
#   run "make" to update *.slog
#   commit changes "git commit -a"

# Normalize build environment (Debian default is LANG=C etc.)
LC_ALL := C.UTF-8
export LC_ALL

# Used as $(call check-command, <command>, <package>)
define check-command
set -e; if ! which $(1) >/dev/null; then \
  echo "Missing command: $(1), install package: $(2)"; \
  false; \
fi
endef

#######################################################################
# Document translation strategy: use po4a
# 1. Generate $(BASEXML) using AsciiDoc with docbook4 backend
#    (Ease of writing main contents)
# 2. Make docbook 5 source $(MANUAL).en.x01 with db4-upgrade.xsl
# 3. Write the info header section as $(HEADXML)
# 4. Merge $(HEADXML) and $(MANUAL).en.x01 as $(MANUAL).en.x02
# 5. Generate po/$(MANUAL).pot from $(MANUAL).en.x02 with po4a
# 6. Translate po/$(MANUAL).pot and create po/<lang>.po
# 7. Generate $(MANUAL).<lang>.x02 from $(MANUAL).en.x02 and po/<lang>.po
#    using po4a
# 8. Make $(MANUAL).<lang>.xml from $(MANUAL).<lang>.x02
# 9. Build html, ... from $(MANUAL).<lang>.xml
#######################################################################
# Build documentation
MANUAL	:= debmake-doc
DEBEMAIL := osamu@debian.org
DEBFULLNAME := "Osamu Aoki"
ASCIIDOC_DIR := asciidoc
BASEXML := $(ASCIIDOC_DIR)/$(MANUAL).xml
HEADXML := $(ASCIIDOC_DIR)/head.txt
XSLT_DIR := xslt
BASEDIR := $(CURDIR)/basedir
TMPDIR := $(CURDIR)/tmp
# set SOURCE_DATE_EPOCH if unset (when not called from debhelper)
SOURCE_DATE_EPOCH ?= $(shell dpkg-parsechangelog -STimestamp || date -R -u)
# Export for reproducible PDF build
#  2020: https://tex.stackexchange.com/questions/568235/how-do-i-configure-pdflatex-to-output-binary-equivalent-pdfs-if-the-input-tex-fi
#  2015: https://tex.stackexchange.com/questions/229605/reproducible-latex-builds-compile-to-a-file-which-always-hashes-to-the-same-va
export SOURCE_DATE_EPOCH
FORCE_SOURCE_DATE = 1
export FORCE_SOURCE_DATE
# date in changelog
SOURCE_DATE := $(shell date -u +'%F %T %Z' --date=@$(SOURCE_DATE_EPOCH))

# languages translated with PO files (not used now)
LANGPO ?= ja zh-cn zh-tw de ru pt
# languages to skip generation of PDF files (not used now)
NOPDF ?=
# languages to build document
LANGALL := en $(LANGPO)
SRC_PO := $(addsuffix .po, $(addprefix  po4a/po/, $(LANGPO)))
SRC_X02 := $(addsuffix .x02, $(addprefix  $(MANUAL)., $(LANGPO)))
SRC_X03 := $(addsuffix .x03, $(addprefix  $(MANUAL)., $(LANGPO)))
SRC_XML := $(addsuffix .xml, $(addprefix  $(MANUAL)., $(LANGALL)))
#######################################################################
# Build time determined text
# version of the debmake command used
DEBMAKEVERSION := $(shell cat examples/debhello-0.0_build-1/step999.slog)
# version of this Debian package (debian/changelog)
DEBVERSION ?= $(shell { dpkg-parsechangelog -SVersion || echo "vcs-0.0" ; })
# short date of this Debian package (debian/changelog)
DEBDATE ?= $(shell { date --utc +'%Y-%m-%d' -d"`dpkg-parsechangelog -SDate`" || date +'(No changelog) %Y-%m-%d' ; })
# debhelper compat = debhelper major version
DHCOMPAT ?= $(shell { dpkg-query -f'$${source:Version}' -W debhelper|sed 's/\..*$$//' ; })
#######################################################################
# Constants for asciidoc -> xml -> any conversion
# Program name and option
XSLT := xsltproc --novalid --nonet --xinclude
MKDIRP := mkdir -p
MSGCAT := msgcat
MSGFMT := msgfmt
MSGMERGE := msgmerge --update --previous
MSGATTRIB := msgattrib
DPO := po4a/po
DBLATEX	:= dblatex
# Change $(DRAFTMODE) from "yes" to "maybe" when this document
# should go into production mode
#export DRAFTMODE := yes
export DRAFTMODE := maybe
#######################################################################

build: $(wildcard $(ASCIIDOC_DIR)/*.txt)
	: # ========================== BUILD DOCS =============================
	# process ASCIIDOC after $(pkg) targets even under the parallel build
	$(MAKE) base-xml
	echo "LC_ALL='$(LC_ALL)'"
	echo "LANGPO='$(LANGPO)'"
	echo "LANGALL='$(LANGALL)'"
	echo "NOPDF='$(NOPDF)'"
	echo "BASEDIR='$(BASEDIR)'"
	echo "TMPDIR='$(TMPDIR)'"
	$(MAKE) all-xml	                # XML docs for all PO
	-mkdir -p $(TMPDIR)
	-mkdir -p $(BASEDIR)/html
	# leave fuzzy status in the package build log
	-cat fuzzy.log
	$(MAKE) css
	$(MAKE) html
	$(MAKE) txt
	$(MAKE) pdf
	#$(MAKE) epub

clean:
	: # ========================== CLEAN SOURCE ===========================
	echo "LC_ALL='$(LC_ALL)'"
	echo "NOPDF='$(NOPDF)'"
	echo "BASEDIR='$(BASEDIR)'"
	echo "TMPDIR='$(TMPDIR)'"
	-rm -rf $(TMPDIR)
	-rm -rf po4a-tmp
	-$(MAKE) -C $(ASCIIDOC_DIR) clean
	-$(MAKE) -C examples clean

distclean: clean

dbk:
	-mkdir -p $(TMPDIR)
	-mkdir -p $(BASEDIR)/html
	$(MAKE) -C $(ASCIIDOC_DIR) xml
	$(MAKE) css html

.PHONY: dbk

#######################################################################
# Normal doc content as English base xml
$(BASEXML): $(wildcard $(ASCIIDOC_DIR)/*.txt)
	$(MAKE) -C $(ASCIIDOC_DIR) xml  # base XML doc (FUll ASCII)

# set last chapter as appendix.
$(MANUAL).en.x01: $(BASEXML)
	@$(call check-command, xsltproc, xsltproc)
	$(XSLT) $(XSLT_DIR)/modappendix.xsl $< > $@ # x01: last chapter as appendix/UTF-8

# header is manually written and main content is generated from asciidoc
$(MANUAL).en.x02: $(MANUAL).en.x01 $(HEADXML)
	cat $(HEADXML) > $@
	sed -e '1,/<\/info>/d' $(MANUAL).en.x01 >> $@ # x02: add header

# remove <screen>...</screen> and xmlns (empirically determined)
# Following -- xslt/screen.xsl doesn't work to remove <screen>-taged element
# <book xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
# Following -- xslt/screen.xsl seems to work but complains about link, results become db4
# <book lang="en">
# Following -- xslt/screen.xsl work and no-complain on linking
# <book xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
# TODO: try libsaxonb-java or xalan instead of xsltproc
$(MANUAL).en.x03: $(MANUAL).en.x02
	@$(call check-command, xsltproc, xsltproc)
	sed -e 's/<book xmlns=.*xmlns:xl/<book xmlns:xl/' $<  >$@.tmp
	$(XSLT) $(XSLT_DIR)/screen.xsl $@.tmp > $@ # x03: no <screen>
	rm -f $@.tmp

# po4a/po4a-x02.cfg -- on x03 to generate po (no xml)
$(MANUAL).po-pre.stamp: $(MANUAL).en.x03
	-mkdir -p $(TMPDIR)
	po4a -v po4a/po4a-x03.cfg

# po4a/po4a.cfg -- on x02 to generate xml
$(MANUAL).po.stamp: $(MANUAL).po-pre.stamp
	-mkdir -p $(TMPDIR)
	rm -rf po4a-tmp
	cp -r po4a po4a-tmp
	po4a -v po4a-tmp/po4a-x02.cfg

$(SRC_X02): $(MANUAL).po.stamp

fuzzy.log: $(MANUAL).po-pre.stamp
	: > fuzzy.log
	for lang in $(LANGPO); do \
	MESS1="no-obsolete  $$lang  `$(MSGATTRIB) --no-obsolete  po4a/po/$$lang.po |grep ^msgid |sed 1d|wc -l`";\
	MESS2="untranslated $$lang  `$(MSGATTRIB) --untranslated po4a/po/$$lang.po |grep ^msgid |sed 1d|wc -l`";\
	MESS3="fuzzy        $$lang  `$(MSGATTRIB) --fuzzy        po4a/po/$$lang.po |grep ^msgid |sed 1d|wc -l`";\
	echo "$$MESS1" >>fuzzy.log ; \
	echo "$$MESS2" >>fuzzy.log ; \
	echo "$$MESS3" >>fuzzy.log ; \
	echo "" >>fuzzy.log ; \
	done

$(MANUAL).%.xml: $(MANUAL).%.x02
	sed \
	-e "s/@@@debmakeversion@@@/$(DEBMAKEVERSION)/g" \
	-e "s/@@@debversion@@@/$(DEBVERSION)/g" \
	-e "s/@@@debdate@@@/$(DEBDATE)/g" \
	-e "s/@@@dhcompat@@@/$(DHCOMPAT)/g" \
	< $^ > $@

.FORCE:
	echo "FORCE"

doc-clean:
	-rm -f *.swp *~ *.tmp
	-rm -f po4a/po/*~
	-rm -rf $(TMPDIR)
	-rm -rf $(BASEDIR)
	-rm -rf $(LANGALL)
	-rm -r $(MANUAL).po.stamp
	-rm -r $(MANUAL).po-pre.stamp
	-rm -f $(addsuffix .x00, $(addprefix $(MANUAL)., $(LANGALL)))
	-rm -f $(addsuffix .x01, $(addprefix $(MANUAL)., $(LANGALL)))
	-rm -f $(addsuffix .x02, $(addprefix $(MANUAL)., $(LANGALL)))
	-rm -f $(addsuffix .x03, $(addprefix $(MANUAL)., $(LANGALL)))
	-rm -f $(addsuffix .xml, $(addprefix $(MANUAL)., $(LANGALL)))
	-rm -f fuzzy.log

clean: doc-clean

#######################################################################
.PHONY: base-xml
base-xml: $(BASEXML)

#######################################################################
.PHONY: po
po: $(MANUAL).po.stamp

#######################################################################
.PHONY: all-xml
all-xml: $(SRC_XML) $(ENT_ALL) fuzzy.log

#######################################################################
.PHONY: doc-all
doc-all: css html txt

#######################################################################
# $ make test      # build html for testing (for Translator)
#######################################################################
.PHONY: doc-test
doc-test: html css

#######################################################################
# $ make test-*       # test targets with consistent naming
#######################################################################
.PHONY: test-spell test-po test-asciidoc test-html
test-po:
	@$(call check-command, msgcat, gettext)
	set -e ; for XX in $(foreach LX, $(LANGPO), $(DPO)/$(LX).po); do \
	bin/xmlpo $$XX ;\
	done
	echo "clean non-English PO source"

test-spell:
	set -e ; for XX in $(wildcard $(ASCIIDOC_DIR)/*.txt); do \
	ispell -o -p $(ASCIIDOC_DIR)/spell.dic $$XX ; \
	done
	echo "clean English ASCIIDOC source"

test-asciidoc:
	set -e; cd $(ASCIIDOC_DIR) ; $(MAKE) all

test-html:
	-mkdir -p $(TMPDIR)
	-mkdir -p $(BASEDIR)/html
	$(MAKE) -C $(ASCIIDOC_DIR) xml
	$(MAKE) css html

#######################################################################
# $ make wrap       # wrap all PO
#######################################################################
.PHONY: wrap nowrap wip
wrap:
	@$(call check-command, msgcat, gettext)
	for XX in $(foreach LX, $(LANGPO), $(DPO)/$(LX).po); do \
	$(MSGCAT) -o $$XX $$XX ;\
	done
nowrap:
	@$(call check-command, msgcat, gettext)
	for XX in $(foreach LX, $(LANGPO), $(DPO)/$(LX).po); do \
	$(MSGCAT) -o $$XX --no-wrap $$XX ;\
	done

# remove obsolete
wrapx:
	@$(call check-command, msgcat, gettext)
	for XX in $(foreach LX, $(LANGPO), $(DPO)/$(LX).po); do \
	$(MSGATTRIB) --no-obsolete -o $$XX $$XX ;\
	done

# remove obsolete
nowrapx:
	@$(call check-command, msgcat, gettext)
	for XX in $(foreach LX, $(LANGPO), $(DPO)/$(LX).po); do \
	$(MSGATTRIB) --no-wrap --no-obsolete -o $$XX $$XX ;\
	done

wip:
	@$(call check-command, msgattrib, gettext)
	for XX in $(foreach LX, $(LANGPO), $(DPO)/$(LX).po); do \
	$(MSGATTRIB) -o $$XX.fuzz --fuzzy        $$XX ;\
	$(MSGATTRIB) -o $$XX.untr --untranslated $$XX ;\
	done

#######################################################################
# $ make css       # update CSS and DIMG in $(BASEDIR)
#######################################################################
.PHONY: css
css:
	-rm -rf $(BASEDIR)/html/images
	mkdir -p $(BASEDIR)/html/images
	cp -f $(XSLT_DIR)/debian.css $(BASEDIR)/html/debian.css
	echo "AddCharset UTF-8 .txt" > $(BASEDIR)/html/.htaccess
	cd png ; \
	cp caution.png home.png important.png next.png note.png \
		prev.png tip.png warning.png $(BASEDIR)/html/images

#######################################################################
# $ make html      # update all HTML in $(BASEDIR)
#######################################################################
.PHONY: html
html:	$(foreach LX, $(LANGALL), $(BASEDIR)/html/index.$(LX).html) fuzzy.log
	cat fuzzy.log

$(BASEDIR)/html/index.%.html: $(MANUAL).%.xml
	@$(call check-command, xsltproc, xsltproc)
	-mkdir -p $(BASEDIR)/html
	$(XSLT) --stringparam base.dir $(BASEDIR)/html \
                --stringparam html.ext .$*.html \
                $(XSLT_DIR)/style-html.xsl $<

#######################################################################
# $ make txt       # update all Plain TEXT in $(BASEDIR)
#######################################################################
.PHONY: txt
txt:	$(foreach LX, $(LANGALL), $(BASEDIR)/$(MANUAL).$(LX).txt.gz)

# style-txt.xsl provides work around for hidden URL links by appending them explicitly.
$(BASEDIR)/$(MANUAL).%.txt.gz: $(MANUAL).%.xml
	@$(call check-command, w3m, w3m)
	@$(call check-command, xsltproc, xsltproc)
	-mkdir -p $(BASEDIR)
	@test -n "`which w3m`"  || { echo "ERROR: w3m not found. Please install the w3m package." ; false ;  }
	$(XSLT) $(XSLT_DIR)/style-txt.xsl $< | LC_ALL=C.UTF-8 \
	  w3m -o display_charset=UTF-8 -cols 70 -dump -no-graph -T text/html | \
	  gzip -n -9 - > $@


#######################################################################
# $ make pdf       # update all PDF in $(BASEDIR)
#######################################################################
.PHONY: pdf nopdf
pdf:	$(foreach LX, $(LANGALL), $(BASEDIR)/$(MANUAL).$(LX).pdf)

nopdf: $(TMPDIR)/nopdf.pdf

$(TMPDIR)/nopdf.pdf: nopdf.tex
	cp -f nopdf.tex $(TMPDIR)/nopdf.tex
	cd "$(TMPDIR)"; \
	xelatex nopdf.tex

$(foreach LX, $(NOPDF), $(BASEDIR)/$(MANUAL).$(LX).pdf): $(TMPDIR)/nopdf.pdf
	cp $(TMPDIR)/nopdf.pdf $@


# dblatex.xsl provide work around for hidden URL links by appending them explicitly.
$(BASEDIR)/$(MANUAL).%.pdf: $(MANUAL).%.xml
	@$(call check-command, dblatex, dblatex)
	@$(call check-command, xsltproc, xsltproc)
	-mkdir -p $(BASEDIR)
	@test -n "`which $(DBLATEX)`"  || { echo "ERROR: dblatex not found. Please install the dblatex package." ; false ;  }
	export TEXINPUTS=".:"; \
	export TMPDIR="$(TMPDIR)"; \
	$(XSLT) $(XSLT_DIR)/dblatex.xsl $<  | \
	sed -e "s/│/|/g"  -e "s/├/+/g" -e "s/─/-/g" -e "s/└/+/g"     | \
	$(DBLATEX) --style=db2latex \
		--debug \
		--backend=xetex \
		--xsl-user=$(XSLT_DIR)/user_param.xsl \
		--xsl-user=$(XSLT_DIR)/xetex_param.xsl \
		--param=draft.mode=$(DRAFTMODE) \
		--param=doc.lot.show="" \
		--param=lingua=$* \
		--output=$@ - || { \
		echo "Error message here may be ignored as long as PDF(language=$*) file is generated."; \
		if test -e $@ ; then \
	             echo "PDF($@) build successfully"; true ; \
		else \
		     echo "PDF($@) is missing"; false ; \
		fi }

#######################################################################
# $ make tex       # update all TeX source in $(BASEDIR)
#######################################################################
.PHONY: tex
tex:	$(foreach LX, $(LANGALL), $(BASEDIR)/$(MANUAL).$(LX).tex)

# dblatex.xsl provide work around for hidden URL links by appending them explicitly.
$(BASEDIR)/$(MANUAL).%.tex: $(MANUAL).%.xml
	-mkdir -p $(BASEDIR)
	@test -n "`which $(DBLATEX)`"  || { echo "ERROR: dblatex not found. Please install the dblatex package." ; false ;  }
	export TEXINPUTS=".:"; \
	export TMPDIR="$(TMPDIR)"; \
	$(XSLT) $(XSLT_DIR)/dblatex.xsl $<  | \
	sed -e "s/│/|/g"  -e "s/├/+/g" -e "s/─/-/g" -e "s/└/+/g"     | \
	$(DBLATEX) --style=native \
		--debug \
		--type=tex \
		--backend=xetex \
		--xsl-user=$(XSLT_DIR)/user_param.xsl \
		--xsl-user=$(XSLT_DIR)/xetex_param.xsl \
		--param=draft.mode=$(DRAFTMODE) \
		--param=doc.lot.show="" \
		--param=lingua=$* \
		--output=$@ - || { \
		echo "Error message here may be ignored as long as PDF(language=$*) file is generated."; \
		if test -e $@ ; then \
	             echo "tex source ($@) build successfully"; true ; \
		else \
		     echo "tex source ($@) is missing"; false ; \
		fi }

#######################################################################
# $ make epub      # update all epub in $(BASEDIR)
#######################################################################
.PHONY: epub
epub:	$(foreach LX, $(LANGALL), $(BASEDIR)/$(MANUAL).$(LX).epub)

$(BASEDIR)/$(MANUAL).%.epub: $(MANUAL).%.xml
	@$(call check-command, xsltproc, xsltproc)
	-mkdir -p $(TMPDIR)/$*/
	cd $(TMPDIR)/$*/ ; $(XSLT) $(CURDIR)/$(XSLT_DIR)/style-epub.xsl $(CURDIR)/$<
	cp -f $(XSLT_DIR)/mimetype $(TMPDIR)/$*/mimetype
	cp -f $(XSLT_DIR)/debian.css $(TMPDIR)/$*/OEBPS/debian.css
	cp -f $(XSLT_DIR)/debian-openlogo.png $(TMPDIR)/$*/OEBPS/debian-openlogo.png
	find  $(TMPDIR)/$*/ | xargs -n1 touch -d"$(SOURCE_DATE)"
	cd $(TMPDIR)/$*/ ; zip --latest-time -r $@ ./

#######################################################################
# $ make package
#######################################################################
.PHONY: package
# Use this target on devel branch source
package:
	git deborig -f HEAD
	sbuild

