#!/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 "<https://www.mercurylang.org/documentation/documentation.html>"
}
