@@ -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.
11641171ifeq ($(BUILD_DOCS_TRANSLATED),yes)
11651172ADOC_IMAGES_STAMP_DEPS := $(DOC_DIR)/.translateddocs-stamp
11661173endif
@@ -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).
12091213define 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