#!/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: --help | awk -f make_manpage # # This file takes the output of ` --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. # .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 "" }