+MANUALS = $(MANUALS_TELY) $(MANUALS_TEXI) $(MANUALS_TRANSLATION)
+MANUALS_TELY := $(notdir $(wildcard $(top-src-dir)/Documentation/*.tely))
+MANUALS_TEXI := contributor.texi
+
+# Harvest the translated manuals.
+# - Store each manual in a language-specific macro, e.g. when we find
+# de/learning.tely we add learning.tely to MANUALS_de,
+# - Store each manual with an added language suffix in MANUALS_TRANSLATION,
+# e.g. learning.de.tely for the German learning manual.
+$(eval $(foreach l,$(WEB_LANGS),\
+ $(eval MANUALS_$(l) := $(notdir $(wildcard $(top-src-dir)/Documentation/$(l)/*.tely))) \
+ $(eval MANUALS_TRANSLATION += $(MANUALS_$(l):%.tely=%.$(l).tely)) \
+))
+
+# The web.texi manuals, English and translated
+MANUALS_WEB := web.texi $(WEB_LANGS:%=web.%.texi)
+
+# The basename of all manuals (basename includes the language suffix)
+MANUALS_BASE = $(basename $(MANUALS) $(MANUALS_WEB))
+
+
+#######################
+### Dependency tracking
+
+# Find the file $(1) within the texinfo include dirs and return its path.
+# If not found, i.e. it is a generated file, then the file is ignored.
+find-texi = \
+$(firstword \
+ $(wildcard $(dir $<)$(1)) \
+ $(wildcard $(top-src-dir)/Documentation/$(1)) \
+)
+
+# Recursively scan the file $(1) for @include, search for included files
+# within the texinfo include dirs, and return all dependencies.
+scan-texi = \
+ $(foreach f, $(shell echo | sed -ne "/^@include[[:space:]]/s/@include//p" $(1)), \
+ $(call find-texi,$(f)) \
+ $(call scan-texi,$(call find-texi,$(f))) \
+)
+
+# Find dependencies for the target $@, based on the texinfo source file $<,
+# and write the dependencies to a .dep file.
+DO_TEXI_DEP = ( mkdir -p $(dir $@) && echo ./$@: $(call scan-texi,$<) > $@.dep ) &&
+
+# This is where we import the .dep files so that `make' knows about
+# the various dependencies.
+-include dummy.dep $(wildcard $(OUT)/*.dep) $(wildcard $(OUT)/*/*.dep)
+
+
+###################
+### Generated files
+
+bib-itexi-src-files := $(notdir $(wildcard $(BIB_ITEXI)/*.itexi))
+bib-itexi-files = $(bib-itexi-src-files:%=$(OUT)/%)
+
+css-src-files := $(notdir $(wildcard $(top-src-dir)/Documentation/css/*.css))
+css-files = $(css-src-files:%=$(OUT)/website/css/%)
+
+example-src-files := $(notdir $(wildcard $(EXAMPLES)/*))
+example-files = $(example-src-files:%=$(OUT)/website/ly-examples/%)
+
+misc-src-files := $(notdir $(wildcard $(top-src-dir)/Documentation/misc/*.*))
+misc-files += $(misc-src-files:%=$(OUT)/website/misc/%)
+
+picture-src-files := $(notdir $(wildcard $(PICTURES)/*))
+picture-files = $(picture-src-files:%=$(OUT)/website/pictures/%)
+
+pdf-src-files := $(notdir $(wildcard $(PDFS)/*))
+pdf-files = $(pdf-src-files:%=$(OUT)/website/pdf/%)
+
+post-files = $(OUT)/website/index.html
+
+root-files = $(OUT)/.htaccess \
+ $(OUT)/website/.htaccess \
+ $(OUT)/website/favicon.ico \
+ $(OUT)/website/tweets.xml \
+ $(OUT)/website/robots.txt
+
+texinfo-files = $(OUT)/index.html $(WEB_LANGS:%=$(OUT)/%/index.html)
+
+version-files = $(OUT)/version.itexi $(OUT)/weblinks.itexi
+
+xref-files = $(MANUALS_BASE:%=$(OUT)/%.xref-map)
+
+
+###########
+### Targets
+
+.PHONY: website website-bibs website-css website-examples website-misc \
+ website-pictures website-post website-test website-texinfo \
+ website-version website-xrefs check-setup website-pdf
+
+check-setup:
+ifeq ($(LILYPOND_WEB_MEDIA_GIT),)
+ echo "Need a LILYPOND_WEB_MEDIA_GIT environment variable!"
+ exit 1
+endif
+
+website: check-setup website-post website-examples website-pictures website-css website-misc website-pdf
+
+website-bibs: website-version $(OUT) $(bib-itexi-files)
+
+website-css: $(OUT)/website/css $(css-files)
+
+website-examples: $(OUT)/website/ly-examples $(example-files)
+
+website-misc: $(OUT)/website $(OUT)/website/misc $(misc-files) $(root-files)
+
+website-pictures: $(OUT)/website/pictures $(OUT)/pictures $(picture-files)
+
+website-pdf: $(OUT)/website/pdf $(pdf-files)
+
+website-post: website-texinfo $(post-files)