asciiman: fixes, improve mandoc compatibility

This commit is contained in:
Přemysl Eric Janouch 2022-10-09 00:07:07 +02:00
parent cbeb4e3133
commit 0e86ffe7c3
Signed by: p
GPG Key ID: A0420B94F92B9493
2 changed files with 36 additions and 12 deletions

View File

@ -25,7 +25,7 @@ This project also hosts a number of supporting scripts written in portable AWK:
asciiman.awk:: asciiman.awk::
A fallback manual page generator for AsciiDoc documents, A fallback manual page generator for AsciiDoc documents,
motivated by the hugeness of AsciiDoc's and Asciidoctor's dependency trees. motivated by the hugeness of AsciiDoc's and Asciidoctor's dependency trees.
It uses the _man_ macro package. Just like them, it uses the _man_ macro package.
cmake-parser.awk:: cmake-parser.awk::
Parses the CMake language to the extent that is necessary to reliably Parses the CMake language to the extent that is necessary to reliably

View File

@ -1,4 +1,4 @@
# asciiman.awk: stupid AsciiDoc to manual page converter # asciiman.awk: simplified AsciiDoc to manual page converter
# #
# Copyright (c) 2022, Přemysl Eric Janouch <p@janouch.name> # Copyright (c) 2022, Přemysl Eric Janouch <p@janouch.name>
# SPDX-License-Identifier: 0BSD # SPDX-License-Identifier: 0BSD
@ -11,7 +11,7 @@
# - Heading underlines must match in byte length exactly. # - Heading underlines must match in byte length exactly.
# - Only a small subset of syntax is supported overall. # - Only a small subset of syntax is supported overall.
# #
# Also beware that the output has only been tested with GNU troff. # Also beware that the output has only been tested with GNU troff and mandoc.
# Attributes can be passed via environment variables starting with "asciidoc-". # Attributes can be passed via environment variables starting with "asciidoc-".
function fatal(message) { function fatal(message) {
@ -20,6 +20,10 @@ function fatal(message) {
exit 1 exit 1
} }
function haveattribute(name) {
return name in Attrs || ("asciidoc-" name) in ENVIRON
}
function getattribute(name) { function getattribute(name) {
if (!(name in Attrs) && ("asciidoc-" name) in ENVIRON) if (!(name in Attrs) && ("asciidoc-" name) in ENVIRON)
Attrs[name] = ENVIRON["asciidoc-" name] Attrs[name] = ENVIRON["asciidoc-" name]
@ -27,13 +31,15 @@ function getattribute(name) {
} }
function expand(s, attr, v) { function expand(s, attr, v) {
# TODO: This should not expand unknown attribute names.
while (match(s, /[{][^{}]*[}]/)) { while (match(s, /[{][^{}]*[}]/)) {
s = substr(s, 1, RSTART - 1) \ attr = substr(s, RSTART + 1, RLENGTH - 2)
getattribute(substr(s, RSTART + 1, RLENGTH - 2)) \ if (haveattribute(attr))
substr(s, RSTART + RLENGTH) v = v substr(s, 1, RSTART - 1) getattribute(attr)
else
v = v substr(s, 1, RSTART + RLENGTH - 1)
s = substr(s, RSTART + RLENGTH)
} }
return s return v s
} }
function escape(s) { function escape(s) {
@ -109,12 +115,20 @@ function format(line, v) {
return v return v
} }
function flushspace() {
if (NeedSpace) {
print ".sp"
NeedSpace = 0
}
}
function inline(line) { function inline(line) {
if (!line) { if (!line) {
print ".sp" NeedSpace = 1
return return
} }
flushspace()
line = format(escape(expand(line))) line = format(escape(expand(line)))
# Strip empty URL descriptions, otherwise useful for demarking the end. # Strip empty URL descriptions, otherwise useful for demarking the end.
@ -145,15 +159,21 @@ function process(firstline) {
return 0 return 0
} }
# mandoc(1) automatically precedes section headers with blank lines.
if (length(firstline) == length($0) && /^-+$/) { if (length(firstline) == length($0) && /^-+$/) {
print ".SH \"" escape(toupper(expand(firstline))) "\"" print ".SH \"" escape(toupper(expand(firstline))) "\""
NeedSpace = 0
return 0 return 0
} }
if (length(firstline) == length($0) && /^~+$/) { if (length(firstline) == length($0) && /^~+$/) {
print ".SS \"" escape(expand(firstline)) "\"" print ".SS \"" escape(expand(firstline)) "\""
NeedSpace = 0
return 0 return 0
} }
if (firstline ~ /^(-{4,}|[.]{4,})$/) { if (firstline ~ /^(-{4,}|[.]{4,})$/) {
flushspace()
print ".if n .RS 4" print ".if n .RS 4"
print ".nf" print ".nf"
print ".fam C" print ".fam C"
@ -172,12 +192,14 @@ function process(firstline) {
return 0 return 0
} }
if (match(firstline, /^\/\//)) { if (match(firstline, /^\/\//)) {
print ".\\\" " firstline print ".\\\"" substr(firstline, RSTART + RLENGTH)
return 1 return 1
} }
# We generally assume these block end with a blank line. # We generally assume these block end with a blank line.
if (match(firstline, /^[[:space:]]*[*][[:space:]]+/)) { if (match(firstline, /^[[:space:]]*[*][[:space:]]+/)) {
flushspace()
# Bullet magic copied over from AsciiDoc/Asciidoctor generators. # Bullet magic copied over from AsciiDoc/Asciidoctor generators.
print ".RS 4" print ".RS 4"
print ".ie n \\{\\" print ".ie n \\{\\"
@ -198,10 +220,12 @@ function process(firstline) {
break break
} }
print ".RE" print ".RE"
print ".sp" NeedSpace = 1
return !!$0 return !!$0
} }
if (match(firstline, /^[[:space:]]+/)) { if (match(firstline, /^[[:space:]]+/)) {
flushspace()
print ".if n .RS 4" print ".if n .RS 4"
print ".nf" print ".nf"
print ".fam C" print ".fam C"
@ -233,7 +257,7 @@ function process(firstline) {
break break
} }
print ".RE" print ".RE"
print ".sp" NeedSpace = 1
return !!$0 return !!$0
} }
inline(firstline) inline(firstline)