Files
mercury/doc/make_manpage
Julien Fischer 36f270de03 Avoid duplicate copyright sections in mmc.1 manual page.
compiler/handle_options.m:
    Do not prefix the copyright section of the usage message
    with "Copyright:" since this causes the make_manpage script
    to include a second COPYRIGHT section.

doc/make_manpage:
    Skip over lines beginning with "Copyright" since the script
    generates a standard copyright notice at the end of each
    manual page.
2023-09-04 15:44:33 +10:00

252 lines
6.3 KiB
Awk
Executable File

#!/usr/bin/awk -f
#-----------------------------------------------------------------------------#
# Copyright (C) 1997-1998, 2002, 2006 The University of Melbourne.
# Copyright (C) 2013, 2019, 2023 The Mercury team.
# This file may only be copied under the terms of the GNU General
# Public Licence - see the file COPYING in the Mercury distribution.
#-----------------------------------------------------------------------------#
#
# make_manpage: create Unix man page from help message.
#
# Usage: <program> --help | awk -f make_manpage
#
# This file takes the output of `<program> --help'
# and turns it into a Unix-style man page by
# massaging it a bit and inserting some extra stuff that is
# the same for all the Mercury man pages.
# Strip leading whitespace.
function lstrip(s) {
sub(/^[\t ]+/, "", s)
return s
}
# Replace tabs with spaces.
function replace_tabs(s) {
gsub(/\t/, " ", s)
return s
}
# Escape characters (add as required).
function escape(s) {
gsub(/\\/, "\\\\", s)
gsub(/-/, "\\-", s)
return s
}
# Escape characters for text that appears at the start of a line.
function escape_sol(s) {
s = escape(s)
sub(/^\./, "\\\\\\&.", s)
return s
}
# Return indentation level due to leading whitespace.
function count_indent(s, chars, i, n) {
sub(/[^\t ].*$/, "", s)
split(s, chars, "")
n = 0
for (i = 1; i <= length(s); i++) {
if (chars[i] == " ") {
n++
} else if (chars[i] == "\t") {
n = n + 8 - (n%8)
}
}
return n
}
BEGIN {
name = "" # program name
accum = "" # accumulate output
new_para = 0 # whether a paragraph separator is required
indent_para = 0 # whether to indent the next paragraph
have_notes = 0 # have output the NOTES section
have_verbatim = 0 # have verbatim text
}
# Single-word section heading with trailing text, e.g.
# Name: foo
# Usage: foo [options]
/^[A-Z][a-z]*:[\t ]/ {
section = $1
sub(/:$/, "", section)
if (section == "Name" && !name) {
name = $2
}
if (section == "Usage") {
section = "Synopsis"
}
accum = accum ".SH " escape(toupper(section)) "\n"
text = $0
gsub(/^.*:[\t ]/, "", text)
accum = accum escape_sol(lstrip(text)) "\n"
new_para = 0
indent_para = 0
next
}
# Add a NOTES section before ARGUMENTS or OPTIONS.
!have_notes && /^(Arguments|Options):$/ {
accum = accum \
".SH NOTES\n" \
".I " escape(name) "\n" \
"is one of the development tools\n" \
"that are part of the Mercury distribution.\n" \
".PP\n" \
"This manual page is limited to a brief summary.\n" \
"For further information see the Mercury User's Guide.\n"
have_notes = 1
}
# Section heading without trailing text, e.g.
# Options:
# Environment variables:
/^[A-Z][\/A-Za-z ]*:$/ {
section = $0
sub(/:.*$/, "", section)
# Stop early for mercury_config at "Configure options".
if (name == "mercury_config" && section == "Configure options") {
exit
}
accum = accum ".SH " escape(toupper(section)) "\n"
new_para = 0
indent_para = 0
next
}
# Sub-section heading without trailing text, e.g.
# High-level (HLDS -> HLDS) optimizations:
/^[\t ]+[A-Z].*:$/ && name != "mprof_merge_runs" {
accum = accum ".SS " escape(lstrip($0)) "\n"
new_para = 0
indent_para = 0
next
}
# Options, e.g.
# -f, --foo
# --foo-bar:
#
# This currently does not allow arbitrary whitespace before
# the dash because mtags has text lines that begin with dash.
/^( |\t)-/ {
line = lstrip($0)
sub(/:$/, "", line)
# Remove tab alignment in mmc --help
line = replace_tabs(line)
accum = accum ".TP\n"
accum = accum ".B " escape(line) "\n"
new_para = 0
indent_para = 1
next
}
# Special case for mmake targets, e.g.
# <module>.depend:
# clean:
name == "mmake" && section == "Targets" && /^\t.*:$/ {
line = lstrip($0)
sub(/:$/, "", line)
accum = accum ".TP\n"
accum = accum ".B " escape(line) "\n"
new_para = 0
indent_para = 1
next
}
# Special case for mprof_merge_runs usage text.
# (This could be extended to other "verbatim" text.)
name == "mprof_merge_runs" && section == "Usage" && /^\t\t./ {
accum = accum ".Vb\n"
accum = accum escape_sol(lstrip($0)) "\n"
accum = accum ".Ve\n"
have_verbatim = 1
next
}
# Blank line.
/^[\t ]*$/ {
new_para = 1
next
}
# Main text.
{
indent = count_indent($0)
if (indent < prev_indent) {
indent_para = 0
}
line = lstrip($0)
# Ensure Copyright messages start on new line.
if (line ~ /^Copyright \(C\)/) {
next
}
if (new_para) {
if (indent_para) {
accum = accum ".IP\n"
} else {
accum = accum ".PP\n"
}
new_para = 0
}
accum = accum escape_sol(line) "\n"
prev_indent = indent
}
END {
if (have_verbatim) {
# Define Vb macro.
print ".de Vb"
print ".PP"
print ".nf" # no-fill
print ".RS" # relative margin indent
print ".."
# Define Ve macro.
print ".de Ve"
print ".RE" # end indent
print ".fi" # fill mode
print ".."
}
# date is passed in by Mmakefile as not all awk implementations support
# strftime().
#date = strftime("%Y-%m-%d")
manual = "Mercury Programmer's Manual"
print ".TH " toupper(name) " 1 \"" date "\" \"" manual "\""
# Delete unnecessary .PP and .IP
gsub(/(\.[PI]P\n)+\.SH /, ".SH ", accum)
gsub(/(\.[PI]P\n)+\.SS /, ".SS ", accum)
gsub(/(\.[PI]P\n)+\.TP\n/, ".TP\n", accum)
gsub(/(\.[PI]P\n)+$/, "", accum)
# Squeeze verbatim lines into blocks.
if (have_verbatim) {
gsub(/\.Ve\n.Vb\n/, "", accum)
}
printf "%s", accum
print ".SH AUTHORS"
print "The Mercury team."
print ".SH COPYRIGHT"
print "This program and its documentation are copyright by"
print "the University of Melbourne and the Mercury team."
print "They may be copied only under the terms of the"
print "GNU General Public License \\-"
print "see the file COPYING in the Mercury distribution."
print ".SH SEE ALSO"
print "The Mercury User's Guide."
print ".PP"
print "<http://www.mercurylang.org/information/documentation.html>"
}