Skip to content

Commit 5a7cdcc

Browse files
committed
docs: deduplicate per-language images into a shared build-time pool
The HTML build copied every referenced image into all 8 language trees, so the built tree was ~324MB, mostly duplicate image bytes. The image resolver, previously used only for the PDF build, now runs for HTML too and rewrites every image src (and click-to-enlarge link) to a shared pool: a generic image to image/<srcrel> and a localized foo_<lang> variant to <lang>/image/<srcrel>, where <srcrel> is the path relative to docs/src. .html-images-stamp then materialises the pool as real files, one copy per unique image. No post-build pass and no symlinks (a server may lack FollowSymLinks). The 8-language tree drops to ~120MB. The page language is passed explicitly as lcnc-lang to both the HTML and PDF builds: the Asciidoctor 2.0 CLI has no sourcemap option and the render-tree path does not encode the language, so the previous path-based detection was unreliable. This replaces the CI-only dedup-docs.py pass, which is removed.
1 parent 9af46f6 commit 5a7cdcc

2 files changed

Lines changed: 223 additions & 86 deletions

File tree

docs/src/Submakefile

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ $(4)/%.pdf: $(1)/%.adoc .adoc-images-stamp $$(DOC_FONTS) | svgs_made_from_dots
967967
--sourcemap \
968968
-a compat-mode \
969969
-a "doc-languages=$$(LANGUAGES)" \
970+
-a "lcnc-lang=$3" \
970971
-a xref-root=$$(dir $$<) \
971972
-a "xref-exclude=$(2)" \
972973
-a "scriptdir=$$(DOC_SRCDIR)/" \
@@ -1102,36 +1103,40 @@ $(foreach L,$(LANGUAGES),$(eval $(call HTML_COPY_RULE,$(L))))
11021103
.images-stamp: .adoc-images-stamp .html-images-stamp
11031104
touch $@
11041105

1105-
# Image copy from sources into the output tree. HTML files for English
1106-
# live at $(DOC_OUT_HTML)/en/<topic>/X.html; for translations at
1107-
# $(DOC_OUT_HTML)/<lang>/<topic>/X.html. The source images are in
1108-
# $(DOC_SRCDIR)/<topic>/ regardless of language (translations are
1109-
# image-symlinked to English originals via the sed below). Generated SVGs are
1110-
# not in src; fall back to the English build tree where they render.
1111-
#
1112-
# src="..." covers displayed images; href="...png" covers click-to-enlarge
1113-
# targets from image:thumb[link=...] (which would otherwise 404). The
1114-
# extension filter keeps page/anchor hrefs out.
1106+
# Materialise the shared image pool. image_resolver has already rewritten
1107+
# every HTML src/href to a pool path (image/<srcrel> or <lang>/image/<srcrel>);
1108+
# here we copy each referenced image to the location its link points at. All
1109+
# languages' generic refs resolve to the one shared image/ tree, so the first
1110+
# copy wins and the existence guard skips the rest: no per-language duplication,
1111+
# no symlinks (a server may lack FollowSymLinks), and a no-op second build.
1112+
# DEST comes from the page dir + the ref; <srcrel> finds the source under
1113+
# $(DOC_SRCDIR) (or the English build tree for generated SVGs).
11151114
#
11161115
# Depend on .lang-switcher-stamp so this runs after the post-processor has
11171116
# rewritten the HTML in place; otherwise that later rewrite leaves this stamp
11181117
# older than its inputs and the image copy re-fires on every subsequent make.
11191118
.html-images-stamp: $(DOC_TARGETS_HTML) .lang-switcher-stamp
1120-
set -e; for HTML_FILE in $^; do \
1121-
HTML_REL=$$(echo $$HTML_FILE | sed 's%^$(DOC_OUT_HTML)/%%'); \
1122-
LANG=$$(echo $$HTML_REL | cut -d/ -f1); \
1123-
REST=$$(echo $$HTML_REL | cut -d/ -f2-); \
1124-
HTML_DIR=$$(dirname $$REST | cut -d/ -f1); \
1125-
for IMAGE_FILE in $$(grep -oE '(src|href)="[^"]+"' $$HTML_FILE | sed -E 's/^(src|href)="//;s/"$$//' | grep -vE '^https?:|^data:|^/|lcnc-docs\.svg' | grep -iE '\.(png|jpe?g|gif|svg|webp)$$'); do \
1126-
IMAGE_DIR=$$(dirname $$IMAGE_FILE); \
1127-
IMAGE_PATH=$(DOC_SRCDIR)/$$HTML_DIR/$$IMAGE_FILE; \
1128-
if [ ! -e $$IMAGE_PATH ] ; then \
1129-
IMAGE_PATH=$(DOC_OUT_ADOC)/en/$$HTML_DIR/$$IMAGE_FILE; \
1130-
fi; \
1131-
mkdir -p $(DOC_OUT_HTML)/$$LANG/$$HTML_DIR/$$IMAGE_DIR; \
1132-
cp -f $$IMAGE_PATH $(DOC_OUT_HTML)/$$LANG/$$HTML_DIR/$$IMAGE_FILE; \
1119+
set -e; \
1120+
HTMLROOT=$$(realpath $(DOC_OUT_HTML)); \
1121+
place() { \
1122+
PAGE_DIR=$$(dirname $$1); \
1123+
for REF in $$(grep -oE '(src|href)="[^"]+"' $$1 | sed -E 's/^(src|href)="//;s/"$$//' | grep -vE '^https?:|^data:|^#|^/|lcnc-docs\.svg' | grep -iE '\.(png|jpe?g|gif|svg|webp)$$'); do \
1124+
DEST=$$(realpath -m "$$PAGE_DIR/$$REF"); \
1125+
case $$DEST in $$HTMLROOT/*) ;; *) echo "html-images: out-of-tree $$DEST (page $$1)" >&2; exit 1;; esac; \
1126+
[ -e "$$DEST" ] && continue; \
1127+
REL=$${DEST#$$HTMLROOT/}; \
1128+
case $$REL in \
1129+
image/*) SRCREL=$${REL#image/}; SRC=$(DOC_SRCDIR)/$$SRCREL; [ -e "$$SRC" ] || SRC=$(DOC_OUT_ADOC)/en/$$SRCREL;; \
1130+
*/image/*) L=$${REL%%/*}; SRCREL=$${REL#*/image/}; SRC=$(DOC_SRCDIR)/$$SRCREL; [ -e "$$SRC" ] || SRC=$(DOC_OUT_ADOC)/$$L/$$SRCREL;; \
1131+
*) echo "html-images: unexpected pool dest $$REL (page $$1)" >&2; exit 1;; \
1132+
esac; \
1133+
if [ ! -e "$$SRC" ] ; then echo "html-images: no source for $$REL (page $$1)" >&2; exit 1; fi; \
1134+
mkdir -p "$$(dirname "$$DEST")"; \
1135+
cp -f "$$SRC" "$$DEST"; \
11331136
done; \
1134-
done > $@.new && mv $@.new $@
1137+
}; \
1138+
for HTML_FILE in $(DOC_TARGETS_HTML); do place $$HTML_FILE; done \
1139+
> $@.new && mv $@.new $@
11351140

11361141
# mb2hal_HOWTO.ini lives in the docs source tree next to mb2hal.adoc, so the
11371142
# English build includes it directly. Copy it into the per-language build
@@ -1157,10 +1162,12 @@ $(foreach L,$(LANGUAGES),$(eval $(call HTML_COPY_RULE,$(L))))
11571162
cp -f emc/usr_intf/gmoccapy/release_notes.txt $(DOC_OUT_HTML)/$$lang/gui/gmoccapy_release_notes.txt ; \
11581163
done) > $@.new && mv $@.new $@
11591164

1160-
# Copy all images used by translated adoc files into the directories
1161-
# with translated adoc files. The .translateddocs-stamp prerequisite
1162-
# only exists when BUILD_DOCS_TRANSLATED=yes; without it the rule has
1163-
# no work to do (filter-out yields empty) so we skip the dep too.
1165+
# Stage the images used by translated adoc files into the translated adoc
1166+
# tree, so asciidoctor-pdf can read them at render time. The .translateddocs-stamp
1167+
# prerequisite only exists when BUILD_DOCS_TRANSLATED=yes; without it the rule
1168+
# has no work to do (filter-out yields empty) so we skip the dep too. HTML
1169+
# image placement is no longer done here: the image_resolver rewrites HTML src
1170+
# to the shared pool and .html-images-stamp materialises it.
11641171
ifeq ($(BUILD_DOCS_TRANSLATED),yes)
11651172
ADOC_IMAGES_STAMP_DEPS := $(DOC_DIR)/.translateddocs-stamp
11661173
endif
@@ -1176,13 +1183,10 @@ endif
11761183
IMAGE_PATH=$(DOC_OUT_ADOC)/en/$$EN_DIR/$$IMAGE_FILE; \
11771184
fi; \
11781185
TIMAGE_PATH=$(DOC_OUT_ADOC)/$$ADOC_DIR/$$IMAGE_FILE; \
1179-
HIMAGE_PATH=$(DOC_OUT_HTML)/$$ADOC_DIR/$$IMAGE_FILE; \
11801186
mkdir -p $(DOC_OUT_ADOC)/$$ADOC_DIR/$$IMAGE_DIR; \
1181-
mkdir -p $(DOC_OUT_HTML)/$$ADOC_DIR/$$IMAGE_DIR; \
11821187
if [ ! -e $$TIMAGE_PATH ] ; then \
11831188
echo "Generating $$TIMAGE_PATH for $$ADOC_FILE"; \
11841189
cp -f $$IMAGE_PATH $$TIMAGE_PATH; \
1185-
cp -f $$IMAGE_PATH $$HIMAGE_PATH; \
11861190
fi ; \
11871191
done; \
11881192
done > $@.new && mv $@.new $@
@@ -1207,13 +1211,20 @@ $(DOC_OUT_ADOC)/en/%.html: LCNC_CSSREL=$(shell python3 -c "print('../' * (1 + '$
12071211
# $4 xref-exclude pattern (English filters all lang subdirs; translated
12081212
# trees are rooted inside their own lang dir so the exclude is empty).
12091213
define ASCIIDOCTOR_HTML_RULE
1210-
$$(patsubst %.adoc,$2/%.html,$$(DOC_SRCS_$(call toUC,$1)_SMALL)): $2/%.html: $2/%.adoc $$(DOC_SRCDIR)/docinfo.html $$(DOC_SRCDIR)/docinfo-header.html
1214+
# Order-only dep on .adoc-images-stamp so translated images are staged before
1215+
# the resolver probes for them at render (it also falls back to docs/src).
1216+
$$(patsubst %.adoc,$2/%.html,$$(DOC_SRCS_$(call toUC,$1)_SMALL)): $2/%.html: $2/%.adoc $$(DOC_SRCDIR)/docinfo.html $$(DOC_SRCDIR)/docinfo-header.html | .adoc-images-stamp
12111217
$$(ECHO) "Building '$1' adoc to html: " $$<
12121218
$$(Q)asciidoctor -r $$(realpath $$(DOC_SRCDIR))/extensions/xref_resolver.rb \
1219+
-r $$(realpath $$(DOC_SRCDIR))/extensions/image_resolver.rb \
12131220
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_hal.rb \
12141221
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_ngc.rb \
12151222
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_ini.rb \
12161223
-a compat-mode \
1224+
-a "doc-languages=$$(LANGUAGES)" \
1225+
-a "lcnc-lang=$1" \
1226+
-a "lcnc-srcdir=$$(realpath $$(DOC_SRCDIR))" \
1227+
-a "lcnc-adocdir=$$(realpath $$(DOC_OUT_ADOC))" \
12171228
-a xref-root=$3 \
12181229
-a "xref-exclude=$4" \
12191230
-a "relindir=$$(shell dirname $$*)" \

0 commit comments

Comments
 (0)