93 lines · 4.4 KB · Shell
RawDownload
#!/bin/sh# SPDX-License-Identifier: ISC# Mirror every man/*.[1-9] page into ../docs/ as markdown, via mandoc's own# native "-T markdown" mode (mdoc -> markdown, not the other direction --# see the design discussion this came out of: pandoc's markdown -> man# writer emits font escapes mandoc doesn't implement and can't be linted# by check-docs.sh, so mdoc stays the one source of truth and this is# purely a generated, read-only view of it).## mandoc's own docs call -T markdown lossy ("a very weak markup language,# so all semantic markup is lost"), and two specific things it drops are# ugly enough on GitHub to fix with a small sed pass, kept to real# CommonMark syntax (not HTML -- an earlier version of this script# switched to -T html -O fragment wrapped in a .md extension, which# looked better on GitHub specifically but produces something that is# not actually markdown at all; any real markdown renderer/linter/# converter run over it would either choke or dump raw tags as literal# text. reverted: better to keep these as genuine, portable markdown with# two small known cosmetic gaps than something that only works in one# specific renderer's HTML-passthrough leniency):##  - .Xr cross-references render as inert "name(section)" text, since#    mandoc has no way to know these pages are about to sit next to each#    other as sibling files. rewritten below into a real markdown link#    for any Xr target that matches another page in this same sync run;#    a reference to something outside this project (errno(2), fnmatch(3),#    etc) has nothing to link to and is correctly left as plain text.#  - .Bl -tag list item bodies render as "> "-prefixed blockquotes (a#    nested list, e.g. providers.*.api_key inside clm-config(5), comes#    out doubly/triply nested as "> > "/"> > > "), which is a reasonable#    one-to-one mapping in isolation but reads badly on GitHub for a#    multi-paragraph body (nested-looking, not a real quotation). Since#    nothing in these pages is an actual quotation, every leading run of#    "> " is stripped from every such line, turning it back into a plain#    paragraph regardless of nesting depth.set -e MANDOC="${1:?usage: docs-sync.sh MANDOC MANDIR DOCSDIR}"MANDIR="${2:?usage: docs-sync.sh MANDOC MANDIR DOCSDIR}"DOCSDIR="${3:?usage: docs-sync.sh MANDOC MANDIR DOCSDIR}" mkdir -p "$DOCSDIR" # Build the sed program: one Xr-linking substitution per page about to be# generated in this run, plus the blanket "> " stripping rule.sedprog=$(mktemp)trap 'rm -f "$sedprog"' EXIT: > "$sedprog"for page in "$MANDIR"/*.[1-9]; do	[ -f "$page" ] || continue	base=$(basename "$page")	name=${base%.*}	section=${base##*.}	# Escape sed/BRE metacharacters in the page name (clm-tool's '-' is	# harmless as-is, but keep this robust for any future page name).	esc=$(printf '%s' "$name" | sed 's/[.[\*^$/]/\\&/g')	printf 's|%s(%s)|[%s(%s)](%s.md)|g\n' \		"$esc" "$section" "$name" "$section" "$name" >> "$sedprog"	# mandoc's markdown writer backslash-escapes every underscore in	# running text (markdown's own italic-delimiter character), so	# clm_agent(3) is literally "clm\_agent(3)" in the generated file.	# Only add this second substitution when the name actually has an	# underscore -- otherwise it's identical to the rule just above and	# would double-substitute already-linked text (e.g. clm(1) has no	# underscore, so without this guard both rules fire on the same	# span, producing "[[clm(1)](clm.md)](clm.md)").	case "$name" in	*_*)		escu=$(printf '%s' "$esc" | sed 's/_/\\\\_/g')		printf 's|%s(%s)|[%s(%s)](%s.md)|g\n' \			"$escu" "$section" "$name" "$section" "$name" >> "$sedprog"		;;	esacdone# Strip every leading "> " (mandoc's rendering of a .Bl -tag item body --# nested lists produce "> > ", "> > > ", etc, so repeat the substitution# on the same line rather than stripping only the outermost level).# Nothing in these pages is a real blockquote.printf 's|^\(> \)*||\n' >> "$sedprog" for page in "$MANDIR"/*.[1-9]; do	[ -f "$page" ] || continue	base=$(basename "$page")	name=${base%.*}	out="$DOCSDIR/$name.md"	# -I os=clm: pin the .Os trailer instead of letting it default to	# whatever uname()/os-release the machine running this happens to	# report (Debian here, OpenBSD elsewhere, etc) -- otherwise every	# re-sync from a different machine would diff on nothing but that,	# with no real content change.	"$MANDOC" -I os=clm -T markdown "$page" | sed -f "$sedprog" > "$out"	echo "wrote $out"done