From f10f61ace4d4aa527e11af1924d9005029b68341 Mon Sep 17 00:00:00 2001
From: Christoph Groth <christoph.groth@cea.fr>
Date: Sat, 16 Mar 2013 16:58:56 +0100
Subject: [PATCH] doc image generation: revise Makefile and generate_diffs

The Makefile now does not require any maintenance when adding/removing images
and tutorial scripts.  generate_diffs only overwrites diffs if they have
changed.
---
 TODO                                          |  3 -
 doc/Makefile                                  | 90 +++++++------------
 .../{generate-diffs.sh => generate-diffs}     |  8 +-
 doc/source/tutorial/README                    |  2 +-
 4 files changed, 39 insertions(+), 64 deletions(-)
 rename doc/source/images/{generate-diffs.sh => generate-diffs} (67%)

diff --git a/TODO b/TODO
index ecca0e45..3c346880 100644
--- a/TODO
+++ b/TODO
@@ -80,7 +80,4 @@ Roughly in order of importance.                                     -*-org-*-
 * Adopt mincut/maxflow algorithm from networkx or python-graph to find the best
   representation of a lead unit cell.
 
-* Improve logic of generate_diffs.sh
-  Do not overwrite the diffs that do not need to be updated.
-
 * Tutorial choose either "A [B]" or "A in units of B" consistently.
diff --git a/doc/Makefile b/doc/Makefile
index 29f773db..0accc5cc 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -19,27 +19,22 @@ PAPEROPT_a4     = -D latex_paper_size=a4
 PAPEROPT_letter = -D latex_paper_size=letter
 ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
 
-# In difference to the original Makefile, we convert all SVG files to PDF for
-# LaTeX output.  For HTML output, we don't create PNGs but rather use the SVG
-# files directly.
+# We convert all SVG files to PDF for LaTeX output.  For HTML output, we don't
+# create PNGs but rather use the SVG files directly.
 IMAGESOURCES    = $(shell find source -name "*.svg")
-GENERATEDPDF    = $(patsubst %.svg, %.pdf, $(IMAGESOURCES))
-
-expand = $(foreach name, $(foreach fig, $(2), $(1)_$(fig)), \
-source/images/$(name).png source/images/$(name).pdf)
-
-# Generated images.
-1_IMAGES = $(call expand, quantum_wire, result sys)
-2A_IMAGES = $(call expand, spin_orbit, result)
-2B_IMAGES = $(call expand, quantum_well, result)
-2C_IMAGES = $(call expand, ab_ring, result sys note1 note2)
-3A_IMAGES = $(call expand, band_structure, result)
-3B_IMAGES = $(call expand, closed_system, result sys)
-4_IMAGES = $(call expand, graphene, result sys1 sys2 bs)
-5A_IMAGES = $(call expand, superconductor_band_structure, result)
-5B_IMAGES = $(call expand, superconductor_transport, result)
-ALL_IMAGES = $(1_IMAGES)  $(2A_IMAGES) $(2B_IMAGES) $(2C_IMAGES) $(3A_IMAGES) \
-$(3B_IMAGES) $(4_IMAGES) $(5A_IMAGES) $(5B_IMAGES)
+GENERATEDPDF    = $(patsubst %.svg,%.pdf,$(IMAGESOURCES))
+
+# Image generation from patched tutorial scripts
+#
+# As make does not support the generation of multiple targets by a single
+# invocation of a (non-implicit) rule, we use a trick: We pretend to be
+# generating a single (empty) flag file per invocation.  The image files are
+# generated as well, but only as side-effects.  Each flag file is used to
+# remember the time at which the corresponding image-generating script was run.
+# This works perfectly unless the actual output files are deleted without
+# deleting the corresponding flag file.
+SCRIPTS = $(patsubst source/images/%.diff,%,$(wildcard source/images/*.py.diff))
+FLAGS = $(patsubst %.py,source/images/.%_flag,$(SCRIPTS))
 
 .PHONY: help clean realclean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
 
@@ -61,35 +56,38 @@ clean:
 	-rm -rf source/reference/generated
 
 realclean: clean
-	-rm -f $(ALL_IMAGES) source/images/.*_flag source/images/[a-zA-Z]*.py
+	-rm -f $(FLAGS)
+	-rm -f $(patsubst %,source/images/%,$(SCRIPTS))
+	-rm -f $(patsubst %.py,source/images/%_*.png,$(SCRIPTS))
+	-rm -f $(patsubst %.py,source/images/%_*.pdf,$(SCRIPTS))
 
-html:	$(ALL_IMAGES)
+html:	$(FLAGS)
 	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
 	@echo
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
 
-dirhtml: $(ALL_IMAGES)
+dirhtml: $(FLAGS)
 	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
 	@echo
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
 
-pickle: $(ALL_IMAGES)
+pickle: $(FLAGS)
 	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
 	@echo
 	@echo "Build finished; now you can process the pickle files."
 
-json:   $(ALL_IMAGES)
+json:   $(FLAGS)
 	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
 	@echo
 	@echo "Build finished; now you can process the JSON files."
 
-htmlhelp: $(ALL_IMAGES)
+htmlhelp: $(FLAGS)
 	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
 	@echo
 	@echo "Build finished; now you can run HTML Help Workshop with the" \
 	      ".hhp project file in $(BUILDDIR)/htmlhelp."
 
-qthelp: $(ALL_IMAGES)
+qthelp: $(FLAGS)
 	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
 	@echo
 	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
@@ -98,7 +96,7 @@ qthelp: $(ALL_IMAGES)
 	@echo "To view the help file:"
 	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/kwant.qhc"
 
-latex:  $(GENERATEDPDF) $(ALL_IMAGES)
+latex:  $(GENERATEDPDF) $(FLAGS)
 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
 	@echo
 	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@@ -124,43 +122,19 @@ doctest:
 %.pdf: %.svg
 	inkscape --export-pdf=$@ $<
 
-
 # Make the image generation scripts by patching tutorial scipts.
 .SECONDARY:
 %.py: %.py.diff
 	@grep -v '^#HIDDEN' source/tutorial/$(notdir $@) >$@
 	@patch $@ $<
 
-# Generation of tutorial images.  This requires some make trickery, see
-# http://article.gmane.org/gmane.comp.gnu.make.general/5806
+# The image generation scripts depend on their unpatched originals
+define makedep
+source/images/$(1): source/tutorial/$(1)
+endef
+$(foreach name,$(SCRIPTS),$(eval $(call makedep,$(name))))
 
+# Generation of images
 .%_flag: %.py
 	cd $(dir $<) && python $(notdir $<)
 	@touch $@
-
-$(1_IMAGES): source/images/.quantum_wire_flag
-	@:
-
-$(2A_IMAGES): source/images/.spin_orbit_flag
-	@:
-
-$(2B_IMAGES): source/images/.quantum_well_flag
-	@:
-
-$(2C_IMAGES): source/images/.ab_ring_flag
-	@:
-
-$(3A_IMAGES): source/images/.band_structure_flag
-	@:
-
-$(3B_IMAGES): source/images/.closed_system_flag
-	@:
-
-$(4_IMAGES): source/images/.graphene_flag
-	@:
-
-$(5A_IMAGES): source/images/.superconductor_band_structure_flag
-	@:
-
-$(5B_IMAGES): source/images/.superconductor_transport_flag
-	@:
diff --git a/doc/source/images/generate-diffs.sh b/doc/source/images/generate-diffs
similarity index 67%
rename from doc/source/images/generate-diffs.sh
rename to doc/source/images/generate-diffs
index e83521ef..d78525ea 100755
--- a/doc/source/images/generate-diffs.sh
+++ b/doc/source/images/generate-diffs
@@ -4,9 +4,13 @@
 # that are kept under vesion control instead of the scripts themselves.
 
 for f in [a-zA-Z]*.py; do
-    echo $f
     # We use custom labels to suppress the time stamps which are unnecessary
     # here and would only lead to noise in version control.
     grep -v '#HIDDEN' ../tutorial/$f |
-    diff -u --label original --label modified - $f >$f.diff
+    diff -u --label original --label modified - $f >$f.diff_
+    if cmp $f.diff_ $f.diff >/dev/null 2>&1; then
+        rm $f.diff_
+    else
+        mv $f.diff_ $f.diff
+    fi
 done
diff --git a/doc/source/tutorial/README b/doc/source/tutorial/README
index b7174b90..b8473b1e 100644
--- a/doc/source/tutorial/README
+++ b/doc/source/tutorial/README
@@ -7,5 +7,5 @@ and running ``make doc/source/images/SCRIPT.py`` in doc.  Now examine the newly
 created doc/source/images/SCRIPT.py.  If you do not like the result or the
 patch did not apply, edit doc/source/images/SCRIPT.py until you like it.  You
 can run `make html` during your edits to check things.  Finally, even if you
-did not edit the script, execute generate-diffs.sh in doc/source/images.  If
+did not edit the script, execute generate-diffs in doc/source/images.  If
 the patches applied cleanly the diff files will usually stay unchanged.
-- 
GitLab