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
17 changes: 15 additions & 2 deletions docs/src/Submakefile
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ $(foreach L,$(LANGUAGES), \
# from docs/build/man/<lang>/manN. cssrel is ../../../ for both: each output
# sits at docs/build/html/<lang>/man/manN/X.html (4 levels under html/).
define MAN_HTML_RULE
$(DOC_OUT_HTML)/$(1)/man/%.html: $(2)/% $(DOC_SRCDIR)/docinfo.html $(DOC_SRCDIR)/docinfo-header.html
$(DOC_OUT_HTML)/$(1)/man/%.html: $(2)/% $(DOC_SRCDIR)/docinfo.html $(DOC_SRCDIR)/docinfo-header.html | manpages
@$$(ECHO) Formatting $$(notdir $$<) as HTML
@mkdir -p $$(dir $$@)
$$(Q)if grep -q '^\.so' $$<; then \
Expand Down Expand Up @@ -771,12 +771,14 @@ $(DOC_OUT_HTML)/$(1)/man/%.html: $(2)/% $(DOC_SRCDIR)/docinfo.html $(DOC_SRCDIR)
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_hal.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_ngc.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_ini.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/man_xref.rb \
--doctype=manpage \
--backend=html5 \
-a compat-mode \
-a mansource=LinuxCNC \
-a manmanual='LinuxCNC Documentation' \
-a "lcnc-cssrel=../../../" \
-a "manxref-root=$$(realpath $(2))" \
-a "lcnc-lang-label=$(LANG_LABEL_$(1))" \
-a "lcnc-subpath=$$(patsubst $(DOC_OUT_HTML)/$(1)/%,%,$$@)" \
-a docinfo=shared \
Expand Down Expand Up @@ -1203,6 +1205,14 @@ $(DOC_OUT_ADOC)/%.html: LCNC_CSSREL=$(shell python3 -c "print('../' * '$*'.count
# of the output depth. Add the +1 here, matching the $(DOC_SRCDIR) rule above.
$(DOC_OUT_ADOC)/en/%.html: LCNC_CSSREL=$(shell python3 -c "print('../' * (1 + '$*'.count('/')))")

# man_xref linkbase: relative path from this html page to its language's
# man/man<N>/ dirs. CSSREL points one level above the lang root (at the html
# root, where the css lives); the man tree sits inside the lang root, so this
# is CSSREL with one fewer "../" plus "man/". Translated stems include the
# lang dir; the English stem omits it, hence the extra step, mirroring CSSREL.
$(DOC_OUT_ADOC)/%.html: MANXREF_LINKBASE=$(shell python3 -c "print('../' * ('$*'.count('/') - 1) + 'man/')")
$(DOC_OUT_ADOC)/en/%.html: MANXREF_LINKBASE=$(shell python3 -c "print('../' * '$*'.count('/') + 'man/')")

# asciidoctor HTML rule used for every language.
# $1 lang tag (en, de, ...)
# $2 source root: $(DOC_SRCDIR) for English (DOC_SRCS_EN paths have no
Expand All @@ -1214,13 +1224,16 @@ $(DOC_OUT_ADOC)/en/%.html: LCNC_CSSREL=$(shell python3 -c "print('../' * (1 + '$
define ASCIIDOCTOR_HTML_RULE
# Order-only dep on .adoc-images-stamp so translated images are staged before
# the resolver probes for them at render (it also falls back to docs/src).
$$(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
$$(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 manpages
$$(ECHO) "Building '$1' adoc to html: " $$<
$$(Q)asciidoctor -r $$(realpath $$(DOC_SRCDIR))/extensions/xref_resolver.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/image_resolver.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_hal.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_ngc.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/rouge_ini.rb \
-r $$(realpath $$(DOC_SRCDIR))/extensions/man_xref.rb \
-a "manxref-root=$$(realpath $$(if $$(filter en,$1),$$(DOC_MAN),$$(DOC_MAN)/$1))" \
-a "manxref-linkbase=$$(MANXREF_LINKBASE)" \
-a compat-mode \
-a "doc-languages=$$(LANGUAGES)" \
-a "lcnc-lang=$1" \
Expand Down
2 changes: 1 addition & 1 deletion docs/src/drivers/hostmot2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ Each StepGen instance has the following pins and parameters:
position = counts / position_scale

* 'step_type' - (u32, RW) Output format, like the step_type modparam to
the software stegen(9) component.
the software stepgen(9) component.
0 = Step/Dir, 1 = Up/Down, 2 = Quadrature. In
Quadrature mode (step_type=2), the stepgen outputs one complete Gray
cycle (00 \-> 01 \-> 11 \-> 10 \-> 00) for each 'step' it takes.
Expand Down
125 changes: 125 additions & 0 deletions docs/src/extensions/man_xref.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# docs/src/extensions/man_xref.rb
#
# Asciidoctor postprocessor that turns manpage cross-references in the
# conventional name(section) form (e.g. "halcmd(1)") into clickable links to
# the sibling HTML page ../man<section>/<name>.<section>.html.
#
# * Index-gated: a token is linked only when a page <name>.<section> exists
# in the troff tree, so false positives never resolve and stay plain text
# ("feed(2)"/"arc(3)" enum values in motion(9); external open(2)/udev(8);
# typo'd or renamed API names).
# * Never links a page to itself.
# * Skips text inside <a> <code> <pre> <script> <style> <head> <title> <h1>,
# so code samples, tag attributes and existing links are left untouched.
# * Case-insensitive match ("AXIS(1)" => axis.1); visible text kept verbatim.
#
# Used for both the HTML manpages (sibling links under man/) and the narrative
# manuals (User/HAL/Integrator), which reference man pages in the same
# name(section) form and now link across into ../man/man<N>/.
#
# manxref-root (passed from the Submakefile) points at the troff man tree
# docs/build/man[/<lang>], whose man<N>/ dirs enumerate every page including
# generated component pages and .so stubs. Absent => no-op, safe to always load.
# manxref-linkbase is the relative path from the page to those man<N>/ dirs
# (default "../" for a sibling manpage; narrative pages pass their own depth).

require 'asciidoctor'
require 'asciidoctor/extensions'

module LinuxCNCDocs
class ManXref < Asciidoctor::Extensions::Postprocessor
# Manpage sections LinuxCNC ships and cross-references between.
SECTIONS = %w[1 3 9].freeze

# Elements whose text content must never be rewritten.
PROTECTED = %w[a code pre script style head title h1].freeze

# One name(section) token. Name starts with a letter/underscore so
# version-like "3.5(1)" never matches; the section is a single digit.
TOKEN = /\b([A-Za-z_][A-Za-z0-9_.\-]*)\((\d)\)/.freeze

# Cache the per-root index across the many pages of one asciidoctor run.
@index_cache = {}
class << self; attr_reader :index_cache; end

# Build "name-downcased\tsection" => "man<N>/<name>.html" from the
# troff man tree. Filenames are the authoritative existence list.
def self.build_index(root)
key = File.expand_path(root)
cached = index_cache[key]
return cached if cached

idx = {}
SECTIONS.each do |sec|
dir = File.join(root, "man#{sec}")
next unless File.directory?(dir)
suffix = ".#{sec}"
Dir.foreach(dir) do |fn|
next unless fn.end_with?(suffix)
name = fn[0...-suffix.length]
next if name.empty?
# Rendered HTML keeps the section in the filename: the troff page
# man<N>/<name>.<N> becomes man<N>/<name>.<N>.html.
idx["#{name.downcase}\t#{sec}"] = "man#{sec}/#{fn}.html"
end
end
index_cache[key] = idx
end

# Split HTML into an alternating stream of text runs and tags, tracking a
# stack of PROTECTED elements; yield only text runs that are safe to edit.
def self.each_editable_text(html)
depth = 0
pos = 0
out = +''
html.scan(/([^<]+)|(<[^>]*>)/) do
text, tag = Regexp.last_match(1), Regexp.last_match(2)
if text
out << (depth.zero? ? yield(text) : text)
else
out << tag
m = /\A<\s*(\/?)\s*([A-Za-z][A-Za-z0-9]*)/.match(tag)
if m && PROTECTED.include?(m[2].downcase) && !tag.end_with?('/>')
depth += (m[1] == '/' ? -1 : 1)
depth = 0 if depth < 0
end
end
pos += 1
end
out
end

def process(document, output)
root = document.attr('manxref-root')
return output if root.nil? || root.empty?

idx = self.class.build_index(root)
return output if idx.empty?

self_name = (document.attr('mantitle') || '').downcase
self_vol = (document.attr('manvolnum') || '').to_s

# Relative path from this page to the man<N>/ dirs. Manpages sit beside
# each other under man/, so the default reaches a sibling section dir;
# narrative pages pass their own depth-adjusted base (../man/, ../../man/).
base = document.attr('manxref-linkbase')
base = '../' if base.nil? || base.empty?

self.class.each_editable_text(output) do |text|
text.gsub(TOKEN) do
whole = Regexp.last_match(0)
name = Regexp.last_match(1)
sec = Regexp.last_match(2)
# Never link a page to itself.
next whole if name.downcase == self_name && sec == self_vol
href = idx["#{name.downcase}\t#{sec}"]
href ? %(<a class="man-xref" href="#{base}#{href}">#{whole}</a>) : whole
end
end
end
end
end

Asciidoctor::Extensions.register do
postprocessor LinuxCNCDocs::ManXref
end
2 changes: 1 addition & 1 deletion docs/src/man/man1/hal_manualtoolchange.1.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,4 @@ net tool-changed-btn hal_manualtoolchange.change_button <= parport.0.pin-15-in

== SEE ALSO

motion(1), iocontrol(1), halcmd(1).
motion(9), iocontrol(1), halcmd(1).
2 changes: 1 addition & 1 deletion docs/src/man/man3/hal_add_funct_to_thread.3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ Call only from realtime init code, not from other realtime or non-realtime code.

== SEE ALSO

hal_thread_new(3), hal_export_funct(3)
hal_create_thread(3), hal_export_funct(3)
Loading