Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
# All ignores for the documentation tree live here (not in the top-level
# .gitignore). Paths are relative to docs/.

# Rendered output: HTML, PDF, and po4a-translated .adoc all land under build/.
# Rendered output: HTML, PDF, po4a-translated .adoc, components_gen.adoc, the
# per-topic .html, and the .dot-rendered SVGs all land under build/ now.
build/

# Intermediate .html asciidoctor writes beside each source .adoc before the
# copy step moves it into build/html/.
src/*/*.html

# Generated component manpage list (gen_complist.py).
src/hal/components_gen.adoc

# SVGs rendered from the .dot sources in src/code/ (CMS_buffer.svg is committed).
src/code/homing.svg
src/code/homing_es.svg
src/code/hss.svg
src/code/hss_es.svg
src/code/task-state-transitions.svg
src/code/task-state-transitions_es.svg

# Troff manpages generated from .adoc by the asciidoctor manpage backend.
man/man1/
man/man3/
Expand Down
2 changes: 1 addition & 1 deletion docs/po4a.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
[type: AsciiDoc_def] src/hal/canonical-devices.adoc $lang:build/adoc/$lang/hal/canonical-devices.adoc
[type: AsciiDoc_def] src/hal/comp.adoc $lang:build/adoc/$lang/hal/comp.adoc
[type: AsciiDoc_def] src/hal/components.adoc $lang:build/adoc/$lang/hal/components.adoc
[type: AsciiDoc_def] src/hal/components_gen.adoc $lang:build/adoc/$lang/hal/components_gen.adoc
[type: AsciiDoc_def] build/adoc/en/hal/components_gen.adoc $lang:build/adoc/$lang/hal/components_gen.adoc
[type: AsciiDoc_def] src/hal/general-ref.adoc $lang:build/adoc/$lang/hal/general-ref.adoc
[type: AsciiDoc_def] src/hal/hal-examples.adoc $lang:build/adoc/$lang/hal/hal-examples.adoc
[type: AsciiDoc_def] src/hal/halmodule.adoc $lang:build/adoc/$lang/hal/halmodule.adoc
Expand Down
71 changes: 59 additions & 12 deletions docs/src/Submakefile
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,11 @@ endif
# hence $(MAN_SRCS) as a real prereq (the script is content-stable via
# write_if_changed, so re-running over the same set is a no-op for
# mtime, which keeps downstream po4a from re-firing every build).
$(DOC_SRCDIR)/hal/components_gen.adoc: $(DOC_SRCDIR)/gen_complist.py $(DOC_SRCDIR)/hal/components.adoc $(MAN_SRCS) | manpages
$(DOC_OUT_ADOC)/en/hal/components_gen.adoc: $(DOC_SRCDIR)/gen_complist.py $(DOC_SRCDIR)/hal/components.adoc $(MAN_SRCS) | manpages
@mkdir -p $(dir $@)
python3 $(DOC_SRCDIR)/gen_complist.py $(DOC_SRCDIR)/hal/components.adoc

$(DOC_DIR)/po/documentation.pot: $(addprefix $(DOC_SRCDIR)/, $(DOC_SRCS_EN)) $(DOC_SRCDIR)/hal/components_gen.adoc
$(DOC_DIR)/po/documentation.pot: $(addprefix $(DOC_SRCDIR)/, $(DOC_SRCS_EN)) $(DOC_OUT_ADOC)/en/hal/components_gen.adoc
cd $(DOC_DIR) && ${TIME_CMD} po4a $(PO4A_VERBOSE) --msgmerge-opt='-v' --no-translations po4a.cfg
@touch $@
pofiles: $(DOC_DIR)/po/documentation.pot
Expand All @@ -293,7 +294,7 @@ ifeq ($(BUILD_DOCS_TRANSLATED),yes)
# rewriting every docs/po/*.po with a fresh POT-Creation-Date on each build
# (dirty tree + mtime cascade). Building needs only `po4a --no-update`;
# pot/po extraction stays on the explicit `pofiles` target.
$(DOC_DIR)/.translateddocs-stamp: $(DOC_SRCDIR)/hal/components_gen.adoc $(wildcard $(DOC_DIR)/po/*.po) | manpages
$(DOC_DIR)/.translateddocs-stamp: $(DOC_OUT_ADOC)/en/hal/components_gen.adoc $(wildcard $(DOC_DIR)/po/*.po) | manpages
cd $(DOC_DIR) && ${TIME_CMD} po4a $(PO4A_VERBOSE) --msgmerge-opt='-v' --no-update po4a.cfg
@touch $@
translateddocs: $(DOC_DIR)/.translateddocs-stamp
Expand Down Expand Up @@ -425,9 +426,20 @@ clean-manpages:
clean-translated:
-$(RM) -r $(GENERATED_TRANSLATED)

DOTFILES=$(shell find . -name "*.dot") $(shell find ../docs/src/ -name "*.dot")
# Docs .dot render into build/adoc/en/<topic> so docs/src stays clean. Other
# .dot (e.g. src/emc/motion/homing.dot, not a doc) still render beside source.
DOC_DOTFILES := $(shell find $(DOC_SRCDIR) -name '*.dot')
DOC_DOT_SVGS := $(patsubst $(DOC_SRCDIR)/%.dot,$(DOC_OUT_ADOC)/en/%.svg,$(DOC_DOTFILES))
OTHER_DOTFILES := $(filter-out $(DOC_DOTFILES),$(shell find . -name '*.dot'))
.PHONY: svgs_made_from_dots
svgs_made_from_dots: $(DOTFILES:.dot=.svg)
svgs_made_from_dots: $(DOC_DOT_SVGS) $(OTHER_DOTFILES:.dot=.svg)

$(DOC_OUT_ADOC)/en/%.svg: $(DOC_SRCDIR)/%.dot
@mkdir -p $(@D)
dot -Tsvg -Gbgcolor=transparent -o$@ $<

# Pattern-rule outputs; .SECONDARY so the -j build keeps them (see staging rule).
.SECONDARY: $(DOC_DOT_SVGS)

ifeq ($(BUILD_DOCS_PDF),yes)
docs: pdfdocs
Expand Down Expand Up @@ -521,7 +533,7 @@ $(DOC_OUT_HTML)/rouge-github.css: $(DOC_SRCDIR)/render-rouge-css.rb
# with HTML-existence-dependent content (different miss_in_man set),
# bumping mtime past .pot and re-triggering po4a on the next build.
# Broken-link validation against generated HTML is checkref's job.
$(DOC_DIR)/.gen_complist-stamp: $(DOC_SRCDIR)/hal/components_gen.adoc $(MAN_HTML_TARGETS)
$(DOC_DIR)/.gen_complist-stamp: $(DOC_OUT_ADOC)/en/hal/components_gen.adoc $(MAN_HTML_TARGETS)
mkdir -p $(DOC_OUT_HTML)/en/hal
@touch $@

Expand Down Expand Up @@ -830,7 +842,7 @@ $(4)/%.pdf: $(1)/%.adoc .adoc-images-stamp $$(DOC_FONTS) | svgs_made_from_dots
|| (X=$$$$?; rm -f $$@ $$@.raw; exit $$$$X)
@test -f $$@
endef
$(eval $(call ASCIIDOCTOR_PDF_RULE,$(DOC_SRCDIR),^($(LANGUAGES_MATCH))/,en,objects))
$(eval $(call ASCIIDOCTOR_PDF_RULE,$(DOC_OUT_ADOC)/en,^($(LANGUAGES_MATCH))/,en,objects))
$(eval $(call ASCIIDOCTOR_PDF_RULE,$(DOC_OUT_ADOC),,$$(firstword $$(subst /, ,$$*)),$(DOC_OUT_ADOC)))

# Manual pages PDF: previously produced from the generated troff files
Expand Down Expand Up @@ -901,7 +913,7 @@ $(DOC_OUT_HTML)/en/pdf/LinuxCNC_Manual_Pages_en.pdf: objects/LinuxCNC_Manual_Pag
|| (X=$$?; rm -f $@ $@.raw; exit $$X)
@test -f $@

depends/%.d: $(DOC_SRCDIR)/%.adoc $(DOC_SRCDIR)/asciideps .include-stamp
depends/%.d: $(DOC_OUT_ADOC)/en/%.adoc $(DOC_SRCDIR)/asciideps .include-stamp
$(ECHO) Depending $<
@mkdir -p $(dir $@)
$(Q)$(DOC_SRCDIR)/asciideps $< > $@.tmp
Expand All @@ -925,7 +937,7 @@ $(foreach L,$(LANGUAGES),$(eval $(call TRANSLATED_DEP_RULE,$(L))))
# to $(DOC_OUT_HTML)/<lang>/<topic>/X.html (the asciidoctor pattern rule
# emits the .html sibling to the .adoc; no separate copy step needed for
# translations). We model both with one static pattern set per lang.
$(DOC_TARGETS_HTML_EN): $(DOC_OUT_HTML)/en/%.html: $(DOC_SRCDIR)/%.html
$(DOC_TARGETS_HTML_EN): $(DOC_OUT_HTML)/en/%.html: $(DOC_OUT_ADOC)/en/%.html
@mkdir -p $(dir $@)
@cp $< $@

Expand All @@ -943,7 +955,8 @@ $(foreach L,$(LANGUAGES),$(eval $(call HTML_COPY_RULE,$(L))))
# live at $(DOC_OUT_HTML)/en/<topic>/X.html; for translations at
# $(DOC_OUT_HTML)/<lang>/<topic>/X.html. The source images are in
# $(DOC_SRCDIR)/<topic>/ regardless of language (translations are
# image-symlinked to English originals via the sed below).
# image-symlinked to English originals via the sed below). Generated SVGs are
# not in src; fall back to the English build tree where they render.
.html-images-stamp: $(DOC_TARGETS_HTML)
set -e; for HTML_FILE in $^; do \
HTML_REL=$$(echo $$HTML_FILE | sed 's%^$(DOC_OUT_HTML)/%%'); \
Expand All @@ -953,6 +966,9 @@ $(foreach L,$(LANGUAGES),$(eval $(call HTML_COPY_RULE,$(L))))
for IMAGE_FILE in $$(grep -oE 'src="[^"]+"' $$HTML_FILE | sed 's/src="//;s/"$$//' | grep -vE '^https?:|^data:|^/'); do \
IMAGE_DIR=$$(dirname $$IMAGE_FILE); \
IMAGE_PATH=$(DOC_SRCDIR)/$$HTML_DIR/$$IMAGE_FILE; \
if [ ! -e $$IMAGE_PATH ] ; then \
IMAGE_PATH=$(DOC_OUT_ADOC)/en/$$HTML_DIR/$$IMAGE_FILE; \
fi; \
mkdir -p $(DOC_OUT_HTML)/$$LANG/$$HTML_DIR/$$IMAGE_DIR; \
cp -f $$IMAGE_PATH $(DOC_OUT_HTML)/$$LANG/$$HTML_DIR/$$IMAGE_FILE; \
done; \
Expand Down Expand Up @@ -996,6 +1012,10 @@ endif
for IMAGE_FILE in $$(grep -E ^image:[^[:space:]] $$ADOC_FILE | sed -E "s/image:+([^[]+)\[/\nimage:\1\n/g" | grep image: | cut -d: -f2-); do \
IMAGE_DIR=$$(dirname $$IMAGE_FILE); \
IMAGE_PATH=$$(echo $(DOC_SRCDIR)/$$ADOC_DIR/$$IMAGE_FILE | sed -E 's%/src/($(LANGUAGES_MATCH))/%/src/%'); \
if [ ! -e $$IMAGE_PATH ] ; then \
EN_DIR=$$(echo $$ADOC_DIR | sed -E 's%^($(LANGUAGES_MATCH))/%%'); \
IMAGE_PATH=$(DOC_OUT_ADOC)/en/$$EN_DIR/$$IMAGE_FILE; \
fi; \
TIMAGE_PATH=$(DOC_OUT_ADOC)/$$ADOC_DIR/$$IMAGE_FILE; \
HIMAGE_PATH=$(DOC_OUT_HTML)/$$ADOC_DIR/$$IMAGE_FILE; \
mkdir -p $(DOC_OUT_ADOC)/$$ADOC_DIR/$$IMAGE_DIR; \
Expand Down Expand Up @@ -1046,7 +1066,34 @@ $$(patsubst %.adoc,$2/%.html,$$(DOC_SRCS_$(call toUC,$1)_SMALL)): $2/%.html: $2/
-o $$@ $$< || (X=$$$$?; rm -f $$@; exit $$$$X)
endef

$(eval $(call ASCIIDOCTOR_HTML_RULE,en,$(DOC_SRCDIR),$(DOC_SRCDIR),^($(LANGUAGES_MATCH))/))
# Stage English sources (.adoc, images, code fixtures like
# gui/panelui_handler.py) into build/adoc/en so English renders from the build
# tree like translations: docs/src stays clean and includes resolve relatively.
# components_gen.adoc generates straight into build/adoc/en/hal; svgs_made_from_dots
# runs first. find|tar avoids an rsync dependency. The stamp lives in build/ so
# docclean drops it and the next build re-stages.
EN_STAGE_TYPES := -name '*.adoc' -o -name '*.png' -o -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.svg' -o -name '*.py'
EN_STAGE_SRCS := $(shell find $(DOC_SRCDIR) \( $(EN_STAGE_TYPES) \))
$(DOC_BUILD)/.stage-en-stamp: $(EN_STAGE_SRCS) | svgs_made_from_dots
@mkdir -p $(DOC_OUT_ADOC)/en
$(Q)dest=$$(cd $(DOC_OUT_ADOC)/en && pwd); \
cd $(DOC_SRCDIR) && find . \( $(EN_STAGE_TYPES) \) -print0 \
| tar --null -cf - -T - | (cd "$$dest" && tar -xpf -)
@touch $@

# Staged .adoc come from the stamp. Order-only (|), like the translated rule
# above: staging finishes before any consumer reads. components_gen.adoc keeps
# its own rule above. tar -p preserves mtimes, so consumers still rebuild on
# source change.
$(DOC_OUT_ADOC)/en/%.adoc: | $(DOC_BUILD)/.stage-en-stamp ;

# Pattern-rule outputs used only as prerequisites: mark .SECONDARY so make does
# not delete them as intermediates mid -j build (like the .SECONDARY above).
EN_STAGED_ADOC := $(patsubst $(DOC_SRCDIR)/%,$(DOC_OUT_ADOC)/en/%,$(filter %.adoc,$(EN_STAGE_SRCS)))
.SECONDARY: $(EN_STAGED_ADOC)

# English now renders from build/adoc/en, the same model as the translations.
$(eval $(call ASCIIDOCTOR_HTML_RULE,en,$(DOC_OUT_ADOC)/en,$(DOC_OUT_ADOC)/en,^($(LANGUAGES_MATCH))/))
$(foreach lang,$(LANGUAGES), \
$(eval $(call ASCIIDOCTOR_HTML_RULE,$(lang),$(DOC_OUT_ADOC),$(DOC_OUT_ADOC)/$(lang),)))

Expand Down Expand Up @@ -1083,7 +1130,7 @@ docclean:
-rm -f $(DOC_DIR)/.translateddocs-stamp
-rm -f $(DOC_DIR)/.gen_complist-stamp
-rm -f $(DOC_DIR)/.checkref-*-stamp
-rm -f $(DOTFILES:.dot=.svg)
-rm -f $(OTHER_DOTFILES:.dot=.svg)


MAN_DEPS := $(patsubst $(DOC_DIR)/man/%, depends/%.d, $(MAN_SRCS))
Expand Down
3 changes: 2 additions & 1 deletion docs/src/gen_complist.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def write_if_changed(path, content):
return False
except FileNotFoundError:
pass
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
f.write(content)
return True
Expand Down Expand Up @@ -84,7 +85,7 @@ def generate_complist(complist_path):
file1.close()
miss_in_list = man_files.difference(complist_doc)

gen_filename = '../docs/src/hal/components_gen.adoc'
gen_filename = '../docs/build/adoc/en/hal/components_gen.adoc'
parts = []
if len(miss_in_list) > 0:
parts.append('\n== Not categorized (auto generated from man pages)\n')
Expand Down
Loading