Release HTML manual pages.

Add python3 to the basic set of ports in order to build releases.
This commit is contained in:
Jonas 'Sortie' Termansen 2021-07-17 17:43:39 +02:00
parent 2e51481549
commit 23b3271fca
6 changed files with 419 additions and 3 deletions

View File

@ -620,6 +620,10 @@ $(SORTIX_RELEASE_DIR)/$(RELEASE)/README: README $(SORTIX_RELEASE_DIR)/$(RELEASE)
.PHONY: release-man
release-man: $(SORTIX_RELEASE_DIR)/$(RELEASE)/man/ports.list
.PHONY: release-man-html
release-man-html: release-man
RELEASE="$(RELEASE)" build-aux/manhtml.sh $(SORTIX_RELEASE_DIR)/$(RELEASE)/man
.PHONY: release-readme
release-readme: $(SORTIX_RELEASE_DIR)/$(RELEASE)/README
@ -627,12 +631,12 @@ release-readme: $(SORTIX_RELEASE_DIR)/$(RELEASE)/README
release-arch: release-builds release-readme release-repository
.PHONY: release-shared
release-shared: release-man release-readme release-scripts
release-shared: release-man release-man-html release-readme release-scripts
.PHONY: release
release: release-arch release-shared
cd $(SORTIX_RELEASE_DIR)/$(RELEASE) && \
find . -type f '!' -name sha256sum -exec sha256sum '{}' ';' | \
find . -type f '!' -name sha256sum '!' -name '*.html' -exec sha256sum '{}' ';' | \
sed -E 's,^([^ ]* )\./,\1,' | \
LC_ALL=C sort -k 2 > sha256sum

3
build-aux/footer.html Normal file
View File

@ -0,0 +1,3 @@
</article>
</body>
</html>

9
build-aux/header.html Normal file
View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@title@</title>
</head>
<body>
<article>

398
build-aux/manhtml.sh Executable file
View File

@ -0,0 +1,398 @@
#!/bin/sh
set -e
export LC_ALL=C
SECTIONS="1 2 3 4 5 6 7 8 9"
if [ -z ${SORTIX_SITE_OFFICIAL+x} ]; then
SORTIX_SITE_OFFICIAL="https://sortix.org/"
fi
if [ -z ${SORTIX_RELEASE_SITE+x} ]; then
SORTIX_RELEASE_SITE="https://pub.sortix.org/sortix/release"
fi
if [ -z ${MANHTML_TO_SITE_ROOT+x} ]; then
MANHTML_TO_SITE_ROOT=.
fi
if [ -z ${MANHTML_TEMPLATE+x} ]; then
MANHTML_TEMPLATE="$(dirname -- "$(realpath -- "$(which -- "$0")")")"
fi
if [ -z ${MANHTML_RELEASES+x} ]; then
MANHTML_RELEASES="current nightly"
fi
if [ -z ${RELEASE+x} ]; then
RELEASE="current"
fi
if [ -z ${RELEASE_STRING+x} ]; then
if [ "$RELEASE" = current ]; then
RELEASE_STRING="Sortix"
else
RELEASE_STRING="Sortix $RELEASE"
fi
fi
if [ $# -lt 1 ]; then
echo "Usage: $0 mandir $#" >&2
exit 1
fi
if [ ! -e "$1/ports.list" ]; then
echo "$0: No ports.list in $1" >&2
exit 1
fi
cd "$1"
backwards() {
echo "$1" | tr -cd / | sed 's,/,../,g'
}
tositeofficial() {
BACKWARDS=$(backwards "$1")
case "$SORTIX_SITE_OFFICIAL" in
http*) echo "$SORTIX_SITE_OFFICIAL" ;;
*) echo "$BACKWARDS$SORTIX_SITE_OFFICIAL" ;;
esac
}
tositeroot() {
echo "$(backwards "$1")$MANHTML_TO_SITE_ROOT"
}
frontpage() {
tositeofficial "$1" | sed 's/^$/./g'
}
begin_html() {
cat "$MANHTML_TEMPLATE/header.html" | sed "s|@title@|$1|g"
}
header() {
cat << EOF
<h1>$1</h1>
EOF
}
section() {
cat << EOF
<h2 id="$2"><a href="#$2">$1</a></h2>
EOF
}
bp() {
echo "<p>"
}
ep() {
echo "</p>"
}
link() {
cat << EOF
<a href="$1">$2</a>$3<br />
EOF
}
end_html() {
cat "$MANHTML_TEMPLATE/footer.html"
}
finalize_html_stdout() {
sed -e "s,@root@,$(tositeroot "$1"),g" \
-e "s,@official@,$(tositeofficial "$1"),g" \
-e "s,@frontpage@,$(frontpage "$1"),g" \
-e "s,@year@,$(date +%Y),g"
}
finalize_html() {
if [ "$VERBOSE" = 1 ]; then
echo "$1" >&2
fi
finalize_html_stdout "$1" > "$1"
}
section_name() {
case "$1" in
1) echo "General Commands Manual";;
2) echo "System Calls Manual";;
3) echo "Library Functions Manual";;
4) echo "Device Drivers Manual";;
5) echo "File Formats Manual";;
6) echo "Games Manual";;
7) echo "Miscellaneous Information Manual";;
8) echo "System Manager's Manual";;
9) echo "Kernel Developer's Manual";;
esac
}
# TODO: This doesn't work for headers in manual pages like addr2line(1) that
# doesn't use mdoc(7), so the sections don't have id attributes.
selflink() {
python3 -c '
import re
import sys
id_map = {}
first_pass = []
for line in sys.stdin.readlines():
result = ""
while True:
match = re.search("(.*?)<h(.)( id=\"([^\">]*)\")?>(.*?)</h.>(.*)", line, flags=re.DOTALL)
if match is None:
result += line
break
lead = match.group(1)
hl = match.group(2)
oldid = match.group(4)
h = match.group(5)
rest = match.group(6)
id = h.lower().replace(" ", "-").replace("%", "%25");
if oldid is not None:
id_map[oldid] = id
result += lead + "<h" + hl + " id=\"" + id + "\"><a href=\"#" + id + "\">" + h + "</a></h" + hl + ">"
line = rest
first_pass.append(result)
for line in first_pass:
result = ""
while True:
match = re.search("(.*?)<a class=\"link-sec\" href=\"#([^\">]*)\">(.*?)</a>(.*)", line, flags=re.DOTALL)
if match is None:
result += line
break
lead = match.group(1)
id = match.group(2)
text = match.group(3)
rest = match.group(4)
if id in id_map:
id = id_map[id]
result += lead + "<a class=\"link-sec\" href=\"#" + id + "\">" + text + "</a>"
line = rest
print(result, end="")
'
}
see_other_releases() {
if [ "$2" = true ]; then
echo '<div style="text-align: right; float: right;">'
else
bp
echo "View in release:"
fi
for OTHER_RELEASE in $MANHTML_RELEASES; do
if [ "$RELEASE" = "$OTHER_RELEASE" ]; then
OTHER_RELEASE_URL=$(backwards "$1")"$1"
elif [ "$OTHER_RELEASE" = current ]; then
OTHER_RELEASE_URL=$(tositeofficial "$1")"man/$1"
elif echo "$OTHER_RELEASE" | grep -Eq '^[0-9]+.[0-9]+$'; then
OTHER_RELEASE_URL=$(tositeofficial "$1")"release/$OTHER_RELEASE/man/$1"
else
OTHER_RELEASE_URL="$SORTIX_RELEASE_SITE/$OTHER_RELEASE/man/$1"
fi
if [ "$OTHER_RELEASE" = "$RELEASE" ]; then
printf ' <b><a href="%s">%s</a></b>' "$OTHER_RELEASE_URL" "$OTHER_RELEASE"
else
printf ' <a href="%s">%s</a>' "$OTHER_RELEASE_URL" "$OTHER_RELEASE"
fi
done
if [ "$2" = true ]; then
echo '</div>'
else
ep
fi
}
see_stable() {
if [ "$2" = true ]; then
see_other_releases "$@"
fi
case "$RELEASE" in
current)
if [ "$2" != true ]; then
see_other_releases "$@"
fi
;;
*dev* | nightly | volatile)
if [ "$2" = true ]; then
header "$RELEASE_STRING manual"
else
see_other_releases "$@"
fi
bp
cat << EOF
This manual documents $RELEASE_STRING, a development build that has not
been officially released. You can instead view
<a href="@official@man/$1">this document in the latest official manual</a>.
EOF
ep
;;
*)
if [ "$2" = true ]; then
header "$RELEASE_STRING manual"
else
see_other_releases "$@"
fi
bp
cat << EOF
This manual documents $RELEASE_STRING. You can instead view
<a href="@official@man/$1">this document in the latest official manual</a>.
EOF
ep
;;
esac
}
undocumented_see_also() {
(cat && echo "../man1/man.1.html") |
sort |
(while read FILE; do
NAME=$(expr x"$FILE" : x'.*/\([^/]*\)\.[0-9]\.html$')
SECTION=$(expr x"$FILE" : x'.*\.\([0-9]\)\.html$')
printf ".Xr $NAME $SECTION /"
done) | sed -e 's| /$|\\|' -e 's|/|,\\|g' | tr '/' ',' | tr '\\' '\n'
}
echo "Generating manhtml index"
(begin_html "$RELEASE_STRING manual page index"
header "$RELEASE_STRING manual page index"
see_stable ""
section "Introductory manual pages" "introductory"
bp
link "man7/installation.7.html" "installation(7)"
link "man7/upgrade.7.html" "upgrade(7)"
link "man7/user-guide.7.html" "user-guide(7)"
link "man7/development.7.html" "development(7)"
link "man7/cross-development.7.html" "cross-development(7)"
if [ -f "man7/following-development.7" ]; then
link "man7/following-development.7.html" "following-development(7)"
fi
if [ -f "man7/porting.7" ]; then
link "man7/porting.7.html" "porting(7)"
fi
ep
section "Sortix manual pages" "system"
bp
link "system.html" "System manual pages"
for section in $SECTIONS; do
link "system.html#$section" "System Section $section - $(section_name $section)"
done
section "All manual pages" "all"
link "all.html" "All manual pages"
for section in $SECTIONS; do
link "man$section/" "Section $section - $(section_name $section)"
done
ep
section "Ports manual pages" "ports"
bp
cat ports.list | sort |
while read port; do
if [ -s "$port.list" ]; then
link "$port.html" "$port"
else
link "$port.html" "$port" " (no manual pages)"
fi
done
ep
end_html) | finalize_html index.html
(echo system && cat ports.list) |
while read port; do
echo "Generating manhtml index for $port"
(if [ "$port" = system ]; then prettyport="System"; else prettyport=$port; fi
begin_html "$prettyport manual pages" &&
header "$prettyport manual pages" &&
see_stable "$port.html"
section_not_begun=true
for section in $SECTIONS; do
section_not_begun=true
mkdir -p "man$section"
grep -E "^/share/man/man$section/.*\.$section$" "$port.list" | sort |
while read manpage; do
if $section_not_begun; then
section "Section $section - $(section_name $section)" "$section"
bp
section_not_begun=false
fi
manpage=$(basename -- "$manpage")
name=$(echo "$manpage" | sed "s/\.$section$//")
link "man$section/$manpage.html" "$name($section)"
if [ "x$port" = xsystem ]; then
mandoc -Tlint "man$section/$manpage" 1>&2 || true
fi
done
if ! $section_not_begun; then
ep
fi
done
if [ ! -s "$port.list" ]; then
echo "<p>$prettyport contains no manual pages.</p>"
fi
end_html) | finalize_html $port.html
done
for section in $SECTIONS; do
echo "Generating manhtml index for section $section"
mkdir -p "man$section"
(begin_html "Section $section - $(section_name $section)" &&
header "Section $section - $(section_name $section)" &&
see_stable "man$section/"
ls man$section | sort | grep -E "\.$section$" |
while read manpage; do
manpage=$(basename -- "$manpage")
name=$(echo "$manpage" | sed "s/\.$section$//")
link "$manpage.html" "$name($section)"
done
if ! ls man$section | grep -Eq "\.$section$"; then
echo "<p>Section $section contains no manual pages.</p>"
fi
end_html) | finalize_html man$section/index.html
done
for section in $SECTIONS; do
find man$section -type f | sort | grep -E "\.$section$" |
while read manpage; do
filename=$(basename -- "$manpage")
name=$(expr "x$filename" : 'x\(.*\)\.[^.]*')
echo Generating manhtml $manpage
(begin_html "$name($section)"
see_stable "$manpage.html" true
mandoc -Thtml -Ofragment,man=../man%S/%N.%S.html "$manpage" | selflink
end_html) | finalize_html "$manpage.html"
done
done
(find . -name '*.html' | while read FILE; do
grep -Eoh 'href=\"../man[[:digit:]]/[^/]+\.html\"' "$FILE" || true
done) | sort -u | grep -Eo 'man[[:digit:]]/[^/]+\.html' | sed 's/\.html$//' |
while read manpage; do
if ! [ -e "$manpage" ]; then
echo "Generating undocumented manhtml for $manpage"
filename=$(basename -- "$manpage")
name=$(expr "x$filename" : 'x\(.*\)\.[^.]*')
NAME=$(echo "$filename" | tr '[:lower:]' '[:upper:]')
section=$(expr "x$manpage" : 'x.*\.\([^.]*\)')
(begin_html "$name($section)"
see_stable "$manpage.html" true
(cat man7/undocumented.7 |
grep -Ev '^\.Xr man 1$' |
sed -e "s/UNDOCUMENTED/$NAME/g" -e "s/undocumented/$name/g" &&
grep -rl -F -- "../$manpage.html" . |
grep -E '\.html$' |
undocumented_see_also) |
mandoc -Thtml -Oman=../man%S/%N.%S.html | selflink
end_html) | finalize_html "$manpage.html"
fi
done
echo "Generating manhtml index for all"
(begin_html "All manual pages for Sortix"
header "All manual pages for Sortix"
see_stable "all.html"
for section in $SECTIONS; do
section "Section $section" "$section"
bp
ls man$section | sort | grep -E "\.$section$" |
while read manpage; do
name=$(echo "$manpage" | sed "s/\.$section$//")
link "man$section/$manpage.html" "$name($section)"
done
ep
done
end_html) | finalize_html all.html

View File

@ -1,3 +1,3 @@
set_minimal="cut dash e2fsprogs grep grub mdocml sed xargs"
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurses libstdc++ nano make patch pkg-config tar vim xz xorriso"
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurses libstdc++ nano make patch pkg-config python tar vim xz xorriso"
sets="basic minimal"

View File

@ -34,6 +34,8 @@ GRUB (for iso creation)
xorriso (for iso creation)
.It
mtools (for iso creation) (if on UEFI systems)
.It
mandoc (for html manuals if building a release directory)
.El
.Pp
GRUB with BIOS support is required.