Newer
Older
Handbook / make-includes / build_content_rules.make
################################################################################
#
# Standard variables and rules for building everything associated with a
# content file, including graphics and supporting files. Only content
# files that have such supporting files need to have (custom) rules
# defined for them, all other content files will be handled by make's
# default behaviour.
#
# Note that all versions of the graphics for a content file will be
# generated, regardless of whether we are building the web or print
# versions. This may seem a little wasteful, but there are two points to
# consider here:
# 
# 	1. At the time this makefile is executed, we have no easy way
# 	   to determine which "build mode" we are in. (It could be done
# 	   with exported variables from the parent makefile, but see below.)
# 
# 	2. This makefile will only be executed once for the document in
# 	   question anyway, because once make has processed the parent
# 	   file, that file will be considered "up-to-date", and make will
# 	   therefore not come back to it again, even though both the print
# 	   and web targets depend on it.
# 
# So, even if we just were clever enough to set up conditionals based on
# the "build mode", if we just went "make", we would almost certainly find
# that make would build either the web graphics only, or the print
# graphics only, but not both. We therefore leave this file as is, and
# build both web and print graphics regardless. It doesn't take that much
# longer anyway, especially since we won't be regenerating all of the
# graphics for _everything_ when only one file has changed :)
#
################################################################################


################################################################################
#
# Given that we print out our own messages, I see no point in splurging
# "Entering...leaving directory" messages all over the screen. It's hard
# enough to figure out what's going on already :)
#
MAKEFLAGS=--no-print-directory


################################################################################
#
# Path to the build directory. This must be passed in from the calling
# environment. We don't default to the current directory because it makes
# it more difficult to clean up.
#
BUILD_DIR?=$(error The variable BUILD_DIR has not been defined)


################################################################################
#
# Paths. All original graphics should normally be in ./graphics or
# ./images (where . represents the current content directory), and derived
# versions should normally be placed in $(BUILD_DIR). If you want
# something different, write your own rules, you deviant!
#
vpath %-web.png $(BUILD_DIR)
vpath %-web-zoom.png $(BUILD_DIR)
# vpath %-web-hires.png $(BUILD_DIR)
vpath %-print.pdf $(BUILD_DIR)
vpath %.svg graphics images
vpath %.eps graphics images
vpath %.ps graphics images
vpath %-print.png $(BUILD_DIR)
vpath %.png graphics images
vpath %.pdf graphics images


################################################################################
#
# List of possible targets. If you need to add to this for a specific
# case, use TARGETS+=xxx in the actual makefile.
#
TARGETS:=all clean web-clean print-clean targets debug

.PHONY: $(TARGETS)


################################################################################
#
# Default rule, for those who are misguided enough to try running a bare
# "make" on the makefile.
#
all:
	$(error You need to call this makefile with the name of a specific content file as the target)


################################################################################
#
# Build EPS from Inkscape SVG source.
#
%.eps: %.svg
	$(INKSCAPE) --file=$< --export-text-to-path --without-gui --export-eps=$@


################################################################################
#
# Build correctly cropped PDF (for printing) from source EPS or PS. See below
# for handling PDF sources.
#
# Notes on ps2eps options:
#
#   --loose expands the bounding box by one "point" (= pixel?), preventing
#   it from cropping too closely. However, even this doesn't seem to be
#   enough in all cases, thus:
#
#   --nohires (not --no-hires as specified in the help) prevents it
#   generating a hi-res bounding box, which seems to fix things in most
#   cases.
#
#   --ignoreBB because it seems to occasionally wig out and generate
#   bizarre crap for the bounding box, which then causes GhostScript to
#   crash (e.g., I've seen it generate a bounding box of 246 53 0 0, which
#   is just plain impossible). The help suggests using this if
#   "BoundingBox in output seems to be wrong". I think this counts :)
#
#   ps2eps seems to have a problem with determining the bounding box of one
#   of the graphics files (the St Germain ERD), which is solved by passing the
#   --gsbbox option.
#
# Notes on gs options:
#
#   -dEPSCrop forces gs to crop the EPS image to its bounding box. If not
#   specified, gs renders the EPS on the default paper size.
#
#   If the fonts go weird in generated PDFs (in particular, they go jaggy
#   at high resolutions), add -dNOCACHE to the gs commands. While this is
#   supposedly only "only for debugging" according to the documentation,
#   in GhostScript 8.15 this seemed to fix the font rendering issue. It
#   appears to have been fixed in GhostScript 8.51?
#
%-print.pdf: %.eps
	@$(ANNOUNCE) "Generating $@ (print)"
	@$(PS2EPS) --ignoreBB --nohires --loose --gsbbox < $< | $(PS2PDF) -dEPSCrop - $@
	@$(MV) $@ $(BUILD_DIR)

%-print.pdf: %.ps
	@$(ANNOUNCE) "Generating $@ (print)"
	@$(PS2EPS) --ignoreBB --nohires --loose --gsbbox < $< | $(PS2PDF) -dEPSCrop - $@
	@$(MV) $@ $(BUILD_DIR)


################################################################################
#
# Build correctly cropped PNGs for web display from source EPS, PS or PDF.
#
# It might seem to make more sense to generate the PNGs from the print
# EPS, which has already been appropriately cropped (see above). However,
# the results of directory searches using vpath are rather unpredictable
# when the source file is not guaranteed to exist. If we depended on
# %-print.eps, which is generated by the rule above, it's not guaranteed
# that the file will exist at the time that make performs its directory
# search (which seems to be done statically). The source EPS isn't
# generated and can thus be guaranteed to always exist. Give me guaranteed
# correct operation over efficiency any day! :)
#
# Build 96 DPI version for normal web display
#
%-web.png: %.eps
	@$(ANNOUNCE) "Generating $@ (web)"
	@$(PS2EPS) --ignoreBB --nohires --loose --gsbbox < $< | \
		$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -dEPSCrop -r96 \
		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ -
	@$(MV) $@ $(BUILD_DIR)

%-web.png: %.ps
	@$(ANNOUNCE) "Generating $@ (web)"
	@$(PS2EPS) --ignoreBB --nohires --loose --gsbbox < $< | \
		$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -dEPSCrop -r96 \
		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ -
	@$(MV) $@ $(BUILD_DIR)

%-web.png: %.pdf
	@$(ANNOUNCE) "Generating $@ (web)"
	$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -r96 \
		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ $<
	@$(MV) $@ $(BUILD_DIR)
#
# Build 144 DPI version for zoomed web display
#
%-web-zoom.png: %.eps
	@$(ANNOUNCE) "Generating $@ (zoomed web)"
	@$(PS2EPS) --ignoreBB --nohires --loose --gsbbox < $< | \
		$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -dEPSCrop -r144 \
		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ -
	@$(MV) $@ $(BUILD_DIR)

%-web-zoom.png: %.ps
	@$(ANNOUNCE) "Generating $@ (zoomed web)"
	@$(PS2EPS) --ignoreBB --nohires --loose --gsbbox < $< | \
		$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -dEPSCrop -r144 \
		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ -
	@$(MV) $@ $(BUILD_DIR)

%-web-zoom.png: %.pdf
	@$(ANNOUNCE) "Generating $@ (zoomed web)"
	$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -r144 \
		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ $<
	@$(MV) $@ $(BUILD_DIR)

#
# Are 600 DPI versions even needed?? They don't seem to be used anywhere...
#
# %-web-hires.png: %.eps
# 	@$(ANNOUNCE) "Generating $@ (600 dpi)"
# 	@$(GS) -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=png16m -dEPSCrop -r600 \
# 		-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=$@ $<
# 	@$(MV) $@ $(BUILD_DIR)


################################################################################
#
# Some graphics start out as bitmaps (e.g., screenshots) and will
# therefore not have an EPS version. We assume that the source for such
# images is a PNG file instead. We don't need to generate anything; rather
# we just copy the original file to the build directory, because we're
# using PNG for the web version anyway, and PDFLaTeX supports PNG
# natively.
#
%-print.png: %.png
	@$(ANNOUNCE) "Generating $@ (print)"
	@$(CP) $< $(BUILD_DIR)/$@

%-web.png: %.png
	@$(ANNOUNCE) "Generating $@ (web)"
	@$(CP) $< $(BUILD_DIR)/$@


################################################################################
#
# There may be a few graphics that already come in PDF form (e.g., generated
# from Visio originals). We don't need to generate anything; rather
# we just copy the original file to the build directory.
#
%-print.pdf: %.pdf
	@$(ANNOUNCE) "Generating $@ (print)"
	@$(CP) $< $(BUILD_DIR)/$@


################################################################################
#
# Clean up. These targets are probably no longer needed, as the build
# versions are now generated in the build directory. There should
# consequently be no extraneous files floating around in the content
# directory that need to be cleaned.
#
# clean: web-clean print-clean
# 
# web-clean:
# 	$(RM) -f *.png
# 
# print-clean:
# 	$(RM) -f *.pdf


################################################################################
#
# Debugging information, mostly lists of the generated variables.
#
debug:
	@$(ANNOUNCE) Externally defined variables
	@$(ECHO) "ALL_PAPERS_ROOT = [$(ALL_PAPERS_ROOT)]"
	@$(ECHO) "TEACHING_SHARED = [$(TEACHING_SHARED)]"
	@$(ECHO) "HANDBOOK_INSTALL_ROOT = [$(HANDBOOK_INSTALL_ROOT)]"
	@$(ECHO) "BUILD_DIR = [$(BUILD_DIR)]"
	@$(ANNOUNCE) Internally defined variables
	@$(ECHO) "GLOBAL_HANDBOOK_INCLUDE = [$(GLOBAL_HANDBOOK_INCLUDE)]"
	@$(ECHO) "LOCAL_HANDBOOK_INCLUDE = [$(LOCAL_HANDBOOK_INCLUDE)]"
	@$(ECHO) "PAPER_INCLUDE_PATH = [$(PAPER_INCLUDE_PATH)]"
	@$(ECHO) "LATEX_INIT_FILE = [$(LATEX_INIT_FILE)]"


################################################################################
#
# Print out the list of targets. Handy for when you forget!
#
targets:
	@$(ECHO) $(TARGETS)