Close command in curl and curlPost

Close command in curl and curlPost

####################################################################
# Utils.awk                                                        #
####################################################################

# Detect gawk version.
function initGawk(    group) {
    Gawk = "gawk"
    GawkVersion = PROCINFO["version"]

    split(PROCINFO["version"], group, ".")
    if (group[1] < 4) {
        e("[ERROR] Oops! Your gawk (version " GawkVersion ") "          \
          "appears to be too old.\n"                                    \
          "        You need at least gawk 4.0.0 to run this program.")
        exit 1
    }
}

# Detect external bidirectional algorithm utility (fribidi);
# Fallback to Unix `rev` if not found.
function initBiDi() {
    FriBidi = detectProgram("fribidi", "--version", 1)
    BiDiNoPad = FriBidi ? "fribidi --nopad" : "rev" SUPERR
    BiDi = FriBidi ? "fribidi --width %s" :
        "rev" SUPERR "| sed \"s/'/\\\\\\'/\" | xargs printf '%%s '"
}

# Detect external readline wrapper (rlwrap).
function initRlwrap() {
    Rlwrap = detectProgram("rlwrap", "--version")
}

# Detect emacs.
function initEmacs() {
    Emacs = detectProgram("emacs", "--version")
}

# Detect curl.
function initCurl() {
    Curl = detectProgram("curl", "--version")
}

# Log any value if debugging is enabled.
function l(value, name, inline, heredoc, valOnly, numSub, sortedIn) {
    if (Option["debug"]) {
        if (name)
            da(value, name, inline, heredoc, valOnly, numSub, sortedIn)
        else
            d(value)
    }
}

# Return a log message if debugging is enabled.
function m(string) {
    if (Option["debug"])
        return ansi("cyan", string) RS
}

# Return 1 if the first version is newer than the second; otherwise return 0.
function newerVersion(ver1, ver2,    i, group1, group2) {
    split(ver1, group1, ".")
    split(ver2, group2, ".")
    for (i = 1; i <= 4; i++) {
        if (group1[i] + 0 > group2[i] + 0)
            return 1
        else if (group1[i] + 0 < group2[i] + 0)
            return 0
    }
    return 0
}

# Fork a rlwrap process as the wrapper. Return non-zero if failed,
function rlwrapMe(    i, command) {
    initRlwrap()

    if (!Rlwrap) {
        l(">> not found: rlwrap")
        return 1
    }

    if (ENVIRON["TRANS_ENTRY"]) {
        command = Rlwrap " " ENVIRON["TRANS_ENTRY"] " "                 \
            parameterize("-no-rlwrap") # never fork rlwrap again!
    } else if (fileExists(ENVIRON["TRANS_DIR"] "/" EntryScript)) {
        command = Rlwrap " sh "                                         \
            parameterize(ENVIRON["TRANS_DIR"] "/" EntryScript)          \
            " - " parameterize("-no-rlwrap") # never fork rlwrap again!
    } else {
        l(">> not found: $TRANS_ENTRY or EntryPoint")
        return 1
    }
    for (i = 1; i < length(ARGV); i++)
        if (ARGV[i])
            command = command " " parameterize(ARGV[i])

    l(">> forking: " command)
    if (!system(command)) {
        l(">> process exited with code 0")
        exit ExitCode
    } else {
        l(">> process exited with non-zero return code")
        return 1
    }
}

# Fork an emacs process as the front-end. Return non-zero if failed,
function emacsMe(    i, params, el, command) {
    initEmacs()

    if (!Emacs) {
        l(">> not found: emacs")
        return 1
    }

    params = ""
    for (i = 1; i < length(ARGV); i++)
        if (ARGV[i])
            params = params " " parameterize(ARGV[i], "\"")
    if (ENVIRON["TRANS_ENTRY"]) {
        el = "(progn (setq explicit-shell-file-name \"" ENVIRON["TRANS_ENTRY"] "\") " \
            "(setq explicit-" Command "-args '(\"-I\" \"-no-rlwrap\"" params ")) " \
            "(command-execute 'shell) (rename-buffer \"" Name "\"))"
    } else if (fileExists(ENVIRON["TRANS_DIR"] "/" EntryScript)) {
        el = "(progn (setq explicit-shell-file-name \"" "sh" "\") "     \
            "(setq explicit-" "sh" "-args '(\"" ENVIRON["TRANS_DIR"] "/" EntryScript "\" \"-I\" \"-no-rlwrap\"" params ")) " \
            "(command-execute 'shell) (rename-buffer \"" Name "\"))"
    } else {
        l(">> not found: $TRANS_ENTRY or EntryPoint")
        return 1
    }
    command = Emacs " --eval " parameterize(el)

    l(">> forking: " command)
    if (!system(command)) {
        l(">> process exited with code 0")
        exit ExitCode
    } else {
        l(">> process exited with non-zero return code")
        return 1
    }
}

# Fetch the content of a URL. Return a null string if failed.
function curl(url, output,    command, content, line) {
    initCurl()

    if (!Curl) {
        l(">> not found: curl")
        w("[WARNING] curl is not found.")
        return NULLSTR
    }

    command = Curl " --location --silent"
    if (Option["proxy"])
        command = command " --proxy " parameterize(Option["proxy"])
    if (Option["user-agent"])
        command = command " --user-agent " parameterize(Option["user-agent"])
    command = command " " parameterize(url)
    if (output) {
        command = command " --output " parameterize(output)
        system(command)
        return NULLSTR
    }
    content = NULLSTR
    while ((command |& getline line) > 0)
        content = (content ? content "\n" : NULLSTR) line
    close(command)
    return content
}

# Fetch the content of a URL. Return a null string if failed.
function curlPost(url, data, output,    command, content, line) {
    initCurl()

    if (!Curl) {
        l(">> not found: curl")
        w("[WARNING] curl is not found.")
        return NULLSTR
    }

    command = Curl " --location --silent"
    if (Option["proxy"])
        command = command " --proxy " parameterize(Option["proxy"])
    if (Option["user-agent"])
        command = command " --user-agent " parameterize(Option["user-agent"])
    command = command " --request POST --data " parameterize(data)
    command = command " " parameterize(url)
    if (output) {
        command = command " --output " parameterize(output)
        system(command)
        return NULLSTR
    }
    content = NULLSTR
    while ((command |& getline line) > 0)
        content = (content ? content "\n" : NULLSTR) line
    close(command)
    return content
}

# Dump a Unicode string into a byte array. Return the length of the array.
# NOTE: can only be ran once for each text! Build a cache.
function dump(text, group,    command, temp) {
    # hexdump tricks:
    # (1) use -v (--no-squeezing)
    # (2) use "%u" (unsigned integers)
    command = "hexdump" " -v -e'1/1 \"%03u\" \" \"'"
    ("echo " parameterize(text) PIPE command) | getline temp
    split(temp, group, " ")
    return length(group) - 1
}

# Base64 encode a string.
# NOTE: can only be ran once for each text! Build a cache.
function base64(text,    command, temp) {
    command = "echo -n " parameterize(text) PIPE "base64"
    ("bash -c " parameterize(command, "\"")) | getline temp
    return temp
}

# Print a Unicode-escaped string. (requires GNU Bash)
# NOTE: can only be ran once for each text! Build a cache.
function uprintf(text,    command, temp) {
    command = "echo -en " parameterize(text)
    ("bash -c " parameterize(command, "\"")) | getline temp
    return temp
}

####################################################################
# Utils.awk                                                        #
####################################################################

# Detect gawk version.
function initGawk(    group) {
    Gawk = "gawk"
    GawkVersion = PROCINFO["version"]

    split(PROCINFO["version"], group, ".")
    if (group[1] < 4) {
        e("[ERROR] Oops! Your gawk (version " GawkVersion ") "          \
          "appears to be too old.\n"                                    \
          "        You need at least gawk 4.0.0 to run this program.")
        exit 1
    }
}

# Detect external bidirectional algorithm utility (fribidi);
# Fallback to Unix `rev` if not found.
function initBiDi() {
    FriBidi = detectProgram("fribidi", "--version", 1)
    BiDiNoPad = FriBidi ? "fribidi --nopad" : "rev" SUPERR
    BiDi = FriBidi ? "fribidi --width %s" :
        "rev" SUPERR "| sed \"s/'/\\\\\\'/\" | xargs printf '%%s '"
}

# Detect external readline wrapper (rlwrap).
function initRlwrap() {
    Rlwrap = detectProgram("rlwrap", "--version")
}

# Detect emacs.
function initEmacs() {
    Emacs = detectProgram("emacs", "--version")
}

# Detect curl.
function initCurl() {
    Curl = detectProgram("curl", "--version")
}

# Log any value if debugging is enabled.
function l(value, name, inline, heredoc, valOnly, numSub, sortedIn) {
    if (Option["debug"]) {
        if (name)
            da(value, name, inline, heredoc, valOnly, numSub, sortedIn)
        else
            d(value)
    }
}

# Return a log message if debugging is enabled.
function m(string) {
    if (Option["debug"])
        return ansi("cyan", string) RS
}

# Return 1 if the first version is newer than the second; otherwise return 0.
function newerVersion(ver1, ver2,    i, group1, group2) {
    split(ver1, group1, ".")
    split(ver2, group2, ".")
    for (i = 1; i <= 4; i++) {
        if (group1[i] + 0 > group2[i] + 0)
            return 1
        else if (group1[i] + 0 < group2[i] + 0)
            return 0
    }
    return 0
}

# Fork a rlwrap process as the wrapper. Return non-zero if failed,
function rlwrapMe(    i, command) {
    initRlwrap()

    if (!Rlwrap) {
        l(">> not found: rlwrap")
        return 1
    }

    if (ENVIRON["TRANS_ENTRY"]) {
        command = Rlwrap " " ENVIRON["TRANS_ENTRY"] " "                 \
            parameterize("-no-rlwrap") # never fork rlwrap again!
    } else if (fileExists(ENVIRON["TRANS_DIR"] "/" EntryScript)) {
        command = Rlwrap " sh "                                         \
            parameterize(ENVIRON["TRANS_DIR"] "/" EntryScript)          \
            " - " parameterize("-no-rlwrap") # never fork rlwrap again!
    } else {
        l(">> not found: $TRANS_ENTRY or EntryPoint")
        return 1
    }
    for (i = 1; i < length(ARGV); i++)
        if (ARGV[i])
            command = command " " parameterize(ARGV[i])

    l(">> forking: " command)
    if (!system(command)) {
        l(">> process exited with code 0")
        exit ExitCode
    } else {
        l(">> process exited with non-zero return code")
        return 1
    }
}

# Fork an emacs process as the front-end. Return non-zero if failed,
function emacsMe(    i, params, el, command) {
    initEmacs()

    if (!Emacs) {
        l(">> not found: emacs")
        return 1
    }

    params = ""
    for (i = 1; i < length(ARGV); i++)
        if (ARGV[i])
            params = params " " parameterize(ARGV[i], "\"")
    if (ENVIRON["TRANS_ENTRY"]) {
        el = "(progn (setq explicit-shell-file-name \"" ENVIRON["TRANS_ENTRY"] "\") " \
            "(setq explicit-" Command "-args '(\"-I\" \"-no-rlwrap\"" params ")) " \
            "(command-execute 'shell) (rename-buffer \"" Name "\"))"
    } else if (fileExists(ENVIRON["TRANS_DIR"] "/" EntryScript)) {
        el = "(progn (setq explicit-shell-file-name \"" "sh" "\") "     \
            "(setq explicit-" "sh" "-args '(\"" ENVIRON["TRANS_DIR"] "/" EntryScript "\" \"-I\" \"-no-rlwrap\"" params ")) " \
            "(command-execute 'shell) (rename-buffer \"" Name "\"))"
    } else {
        l(">> not found: $TRANS_ENTRY or EntryPoint")
        return 1
    }
    command = Emacs " --eval " parameterize(el)

    l(">> forking: " command)
    if (!system(command)) {
        l(">> process exited with code 0")
        exit ExitCode
    } else {
        l(">> process exited with non-zero return code")
        return 1
    }
}

# Fetch the content of a URL. Return a null string if failed.
function curl(url, output,    command, content, line) {
    initCurl()

    if (!Curl) {
        l(">> not found: curl")
        w("[WARNING] curl is not found.")
        return NULLSTR
    }

    command = Curl " --location --silent"
    if (Option["proxy"])
        command = command " --proxy " parameterize(Option["proxy"])
    if (Option["user-agent"])
        command = command " --user-agent " parameterize(Option["user-agent"])
    command = command " " parameterize(url)
    if (output) {
        command = command " --output " parameterize(output)
        system(command)
        return NULLSTR
    }
    content = NULLSTR
    while ((command |& getline line) > 0)
        content = (content ? content "\n" : NULLSTR) line
    return content
}

# Fetch the content of a URL. Return a null string if failed.
function curlPost(url, data, output,    command, content, line) {
    initCurl()

    if (!Curl) {
        l(">> not found: curl")
        w("[WARNING] curl is not found.")
        return NULLSTR
    }

    command = Curl " --location --silent"
    if (Option["proxy"])
        command = command " --proxy " parameterize(Option["proxy"])
    if (Option["user-agent"])
        command = command " --user-agent " parameterize(Option["user-agent"])
    command = command " --request POST --data " parameterize(data)
    command = command " " parameterize(url)
    if (output) {
        command = command " --output " parameterize(output)
        system(command)
        return NULLSTR
    }
    content = NULLSTR
    while ((command |& getline line) > 0)
        content = (content ? content "\n" : NULLSTR) line
    return content
}

# Dump a Unicode string into a byte array. Return the length of the array.
# NOTE: can only be ran once for each text! Build a cache.
function dump(text, group,    command, temp) {
    # hexdump tricks:
    # (1) use -v (--no-squeezing)
    # (2) use "%u" (unsigned integers)
    command = "hexdump" " -v -e'1/1 \"%03u\" \" \"'"
    ("echo " parameterize(text) PIPE command) | getline temp
    split(temp, group, " ")
    return length(group) - 1
}

# Base64 encode a string.
# NOTE: can only be ran once for each text! Build a cache.
function base64(text,    command, temp) {
    command = "echo -n " parameterize(text) PIPE "base64"
    ("bash -c " parameterize(command, "\"")) | getline temp
    return temp
}

# Print a Unicode-escaped string. (requires GNU Bash)
# NOTE: can only be ran once for each text! Build a cache.
function uprintf(text,    command, temp) {
    command = "echo -en " parameterize(text)
    ("bash -c " parameterize(command, "\"")) | getline temp
    return temp
}


CWS gnumake3: replacement of cygpath by variables was broken

#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
#
# This file is part of OpenOffice.org.
#
# OpenOffice.org is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# only, as published by the Free Software Foundation.
#
# OpenOffice.org is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License version 3 for more details
# (a copy is included in the LICENSE file that accompanied this code).
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with OpenOffice.org.  If not, see
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************

# this awk script mangles makedepend output for a single object file
# usage:
# awk -f .../processdeps.awk \
#     -v OUTDIR=outdir \
#     -v SRCDIR=srcdir \
#     -v WORKDIR=workdir \
#     -v REPODIR=repodir \
#     -v OBJECTFILE=objectfile
# called like this the script will read from stdin
# and write to stdout. It will:
#  - replace the objectfile with the one given on the commandline
#  - normalize paths to mixed paths (replacing all \ with /)
#  - replace the string given as WORKDIR with $(WORKDIR)/
#  - replace the string given as OUTDIR with $(OUTDIR)/
#  - replace the string given as SRCDIR with $(SRCDIR)/
#  - replace the string given as REPODIR with $(REPODIR)/
#  - translates absolute mixed windows paths to cygwin paths by
#    substituting a path starting with X:... to /cygdrive/X/...

function mangle_path(path) {
    gsub("\\\\", "/", path);
    if( path ~ /^[a-zA-Z]:/ )
        path = tolower(substr(path,0,1)) substr(path,2);
    gsub(WORKDIR, "$(WORKDIR)/", path);
    gsub(OUTDIR, "$(OUTDIR)/", path);
    gsub(SRCDIR, "$(SRCDIR)/", path);
    gsub(REPODIR, "$(REPODIR)/", path);
    if( path ~ /^[a-zA-Z]:/ )
        path = "/cygdrive/" tolower(substr(path,0,1)) substr(path,3);
    return path;
}

BEGIN {
   WORKDIR = tolower(substr(WORKDIR,0,1)) substr(WORKDIR,2);
   OUTDIR = tolower(substr(OUTDIR,0,1)) substr(OUTDIR,2);
   SRCDIR = tolower(substr(SRCDIR,0,1)) substr(SRCDIR,2);
   REPODIR = tolower(substr(REPODIR,0,1)) substr(REPODIR,2);
#   print "# WORKDIR=" WORKDIR;
#   print "# OUTDIR=" OUTDIR;
#   print "# SRCDIR=" SRCDIR;
#   print "# REPODIR=" REPODIR;
   print mangle_path(OBJECTFILE) ": \\";
}

/^[^#]/ {
    print "\t" mangle_path($2) " \\";
}

END {
    print "\n";
}

#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
#
# This file is part of OpenOffice.org.
#
# OpenOffice.org is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# only, as published by the Free Software Foundation.
#
# OpenOffice.org is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License version 3 for more details
# (a copy is included in the LICENSE file that accompanied this code).
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with OpenOffice.org.  If not, see
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************

# this awk script mangles makedepend output for a single object file
# usage:
# awk -f .../processdeps.awk \
#     -v OUTDIR=outdir \
#     -v SRCDIR=srcdir \
#     -v WORKDIR=workdir \
#     -v REPODIR=repodir \
#     -v OBJECTFILE=objectfile
# called like this the script will read from stdin
# and write to stdout. It will:
#  - replace the objectfile with the one given on the commandline
#  - normalize paths to mixed paths (replacing all \ with /)
#  - replace the string given as WORKDIR with $(WORKDIR)/
#  - replace the string given as OUTDIR with $(OUTDIR)/
#  - replace the string given as SRCDIR with $(SRCDIR)/
#  - replace the string given as REPODIR with $(REPODIR)/
#  - translates absolute mixed windows paths to cygwin paths by
#    substituting a path starting with X:... to /cygdrive/X/...

function mangle_path(path) {
    gsub("\\\\", "/", path);
    if( path ~ /^[a-zA-Z]:/ )
        path = toupper(substr(path,0,1)) substr(path,2);
    gsub(WORKDIR, "$(WORKDIR)/", path);
    gsub(OUTDIR, "$(OUTDIR)/", path);
    gsub(SRCDIR, "$(SRCDIR)/", path);
    gsub(REPODIR, "$(REPODIR)/", path);
    if( path ~ /^[a-zA-Z]:/ )
        path = "/cygdrive/" tolower(substr(path,0,1)) substr(path,3);
    return path;
}

BEGIN {
#   print "# WORKDIR=" WORKDIR;
#   print "# OUTDIR=" OUTDIR;
#   print "# SRCDIR=" SRCDIR;
#   print "# REPODIR=" REPODIR;
    print mangle_path(OBJECTFILE) ": \\";
}

/^[^#]/ {
    print "\t" mangle_path($2) " \\";
}

END {
    print "\n";
}


Make debian happier (cherry picked from commit eb52c44c0ce952817ff48821d037eaa6d93cd7c1)

#!/usr/bin/awk -f
# Simplified approach: only pick out lines with round definitions
/^\(\(round.*\)\)$/ {
	print $0;
}

#!/usr/bin/gawk -f
# Simplified approach: only pick out lines with round definitions
/^\(\(round.*\)\)$/ {
	print $0;
}


Help: adjust wrong alphabetical order

Help: adjust wrong alphabetical order

####################################################################
# Help.awk                                                         #
####################################################################

# Return version as a string.
function getVersion() {
    return Name " " Version
}

# Return a list of language codes as a string.
# Parameters:
#     displayName = "endonym" or "name"
function getReference(displayName) {
    if (displayName == "name")
        return "┌─────────────────────────────┬──────────────────────┬─────────────────┐" RS \
            "│ " Locale["af"]["name"] "           - " ansi("bold", "af") "    │ " \
            Locale["ha"]["name"] "          - " ansi("bold", "ha") "  │ " \
            Locale["fa"]["name"] "    - " ansi("bold", "fa") " │" RS    \
            "│ " Locale["sq"]["name"] "            - " ansi("bold", "sq") "    │ " \
            Locale["he"]["name"] "         - " ansi("bold", "he") "  │ " \
            Locale["pl"]["name"] "     - " ansi("bold", "pl") " │" RS   \
            "│ " Locale["ar"]["name"] "              - " ansi("bold", "ar") "    │ " \
            Locale["hi"]["name"] "          - " ansi("bold", "hi") "  │ " \
            Locale["pt"]["name"] " - " ansi("bold", "pt") " │" RS       \
            "│ " Locale["hy"]["name"] "            - " ansi("bold", "hy") "    │ " \
            Locale["hmn"]["name"] "          - " ansi("bold", "hmn") " │ " \
            Locale["pa"]["name"] "    - " ansi("bold", "pa") " │" RS    \
            "│ " Locale["az"]["name"] "         - " ansi("bold", "az") "    │ " \
            Locale["hu"]["name"] "      - " ansi("bold", "hu") "  │ "   \
            Locale["ro"]["name"] "   - " ansi("bold", "ro") " │" RS     \
            "│ " Locale["eu"]["name"] "              - " ansi("bold", "eu") "    │ " \
            Locale["is"]["name"] "      - " ansi("bold", "is") "  │ "   \
            Locale["ru"]["name"] "    - " ansi("bold", "ru") " │" RS    \
            "│ " Locale["be"]["name"] "          - " ansi("bold", "be") "    │ " \
            Locale["ig"]["name"] "           - " ansi("bold", "ig") "  │ " \
            Locale["sr"]["name"] "    - " ansi("bold", "sr") " │" RS    \
            "│ " Locale["bn"]["name"] "             - " ansi("bold", "bn") "    │ " \
            Locale["id"]["name"] "     - " ansi("bold", "id") "  │ "    \
            Locale["st"]["name"] "    - " ansi("bold", "st") " │" RS    \
            "│ " Locale["bs"]["name"] "             - " ansi("bold", "bs") "    │ " \
            Locale["ga"]["name"] "          - " ansi("bold", "ga") "  │ " \
            Locale["si"]["name"] "    - " ansi("bold", "si") " │" RS    \
            "│ " Locale["bg"]["name"] "           - " ansi("bold", "bg") "    │ " \
            Locale["it"]["name"] "        - " ansi("bold", "it") "  │ " \
            Locale["sk"]["name"] "     - " ansi("bold", "sk") " │" RS   \
            "│ " Locale["ca"]["name"] "             - " ansi("bold", "ca") "    │ " \
            Locale["ja"]["name"] "       - " ansi("bold", "ja") "  │ "  \
            Locale["sl"]["name"] "  - " ansi("bold", "sl") " │" RS      \
            "│ " Locale["ceb"]["name"] "             - " ansi("bold", "ceb") "   │ " \
            Locale["jv"]["name"] "       - " ansi("bold", "jv") "  │ "  \
            Locale["so"]["name"] "     - " ansi("bold", "so") " │" RS   \
            "│ " Locale["ny"]["name"] "            - " ansi("bold", "ny") "    │ " \
            Locale["kn"]["name"] "        - " ansi("bold", "kn") "  │ " \
            Locale["es"]["name"] "    - " ansi("bold", "es") " │" RS    \
            "│ " Locale["zh-CN"]["name"] "  - " ansi("bold", "zh-CN") " │ " \
            Locale["kk"]["name"] "         - " ansi("bold", "kk") "  │ " \
            Locale["su"]["name"] "  - " ansi("bold", "su") " │" RS      \
            "│ " Locale["zh-TW"]["name"] " - " ansi("bold", "zh-TW") " │ " \
            Locale["km"]["name"] "          - " ansi("bold", "km") "  │ " \
            Locale["sw"]["name"] "    - " ansi("bold", "sw") " │" RS    \
            "│ " Locale["hr"]["name"] "            - " ansi("bold", "hr") "    │ " \
            Locale["ko"]["name"] "         - " ansi("bold", "ko") "  │ " \
            Locale["sv"]["name"] "    - " ansi("bold", "sv") " │" RS    \
            "│ " Locale["cs"]["name"] "               - " ansi("bold", "cs") "    │ " \
            Locale["lo"]["name"] "            - " ansi("bold", "lo") "  │ " \
            Locale["tg"]["name"] "      - " ansi("bold", "tg") " │" RS  \
            "│ " Locale["da"]["name"] "              - " ansi("bold", "da") "    │ " \
            Locale["la"]["name"] "          - " ansi("bold", "la") "  │ " \
            Locale["ta"]["name"] "      - " ansi("bold", "ta") " │" RS \
            "│ " Locale["nl"]["name"] "               - " ansi("bold", "nl") "    │ " \
            Locale["lv"]["name"] "        - " ansi("bold", "lv") "  │ " \
            Locale["te"]["name"] "     - " ansi("bold", "te") " │" RS   \
            "│ " Locale["en"]["name"] "             - " ansi("bold", "en") "    │ " \
            Locale["lt"]["name"] "     - " ansi("bold", "lt") "  │ "    \
            Locale["th"]["name"] "       - " ansi("bold", "th") " │" RS \
            "│ " Locale["eo"]["name"] "           - " ansi("bold", "eo") "    │ " \
            Locale["mk"]["name"] "     - " ansi("bold", "mk") "  │ "    \
            Locale["tr"]["name"] "    - " ansi("bold", "tr") " │" RS    \
            "│ " Locale["et"]["name"] "            - " ansi("bold", "et") "    │ " \
            Locale["mg"]["name"] "       - " ansi("bold", "mg") "  │ " \
            Locale["uk"]["name"] "  - " ansi("bold", "uk") " │" RS      \
            "│ " Locale["tl"]["name"] "            - " ansi("bold", "tl") "    │ " \
            Locale["ms"]["name"] "          - " ansi("bold", "ms") "  │ " \
            Locale["ur"]["name"] "       - " ansi("bold", "ur") " │" RS \
            "│ " Locale["fi"]["name"] "             - " ansi("bold", "fi") "    │ " \
            Locale["ml"]["name"] "      - " ansi("bold", "ml") "  │ " \
            Locale["uz"]["name"] "      - " ansi("bold", "uz") " │" RS \
            "│ " Locale["fr"]["name"] "              - " ansi("bold", "fr") "    │ " \
            Locale["mt"]["name"] "        - " ansi("bold", "mt") "  │ " \
            Locale["vi"]["name"] " - " ansi("bold", "vi") " │" RS \
            "│ " Locale["gl"]["name"] "            - " ansi("bold", "gl") "    │ " \
            Locale["mi"]["name"] "          - " ansi("bold", "mi") "  │ " \
            Locale["cy"]["name"] "      - " ansi("bold", "cy") " │" RS \
            "│ " Locale["ka"]["name"] "            - " ansi("bold", "ka") "    │ " \
            Locale["mr"]["name"] "        - " ansi("bold", "mr") "  │ " \
            Locale["yi"]["name"] "    - " ansi("bold", "yi") " │" RS \
            "│ " Locale["de"]["name"] "              - " ansi("bold", "de") "    │ " \
            Locale["mn"]["name"] "      - " ansi("bold", "mn") "  │ " \
            Locale["yo"]["name"] "     - " ansi("bold", "yo") " │" RS \
            "│ " Locale["el"]["name"] "               - " ansi("bold", "el") "    │ " \
            Locale["my"]["name"] "        - " ansi("bold", "my") "  │ " \
            Locale["zu"]["name"] "       - " ansi("bold", "zu") " │" RS \
            "│ " Locale["gu"]["name"] "            - " ansi("bold", "gu") "    │ " \
            Locale["ne"]["name"] "         - " ansi("bold", "ne") "  │ " \
            "                │" RS \
            "│ " Locale["ht"]["name"] "      - " ansi("bold", "ht") "    │ " \
            Locale["no"]["name"] "      - " ansi("bold", "no") "  │ " \
            "                │" RS \
            "└─────────────────────────────┴──────────────────────┴─────────────────┘"
    else
        return "┌──────────────────────┬───────────────────────┬─────────────────────┐" RS \
            "│ " Locale["af"]["display"] "      - " ansi("bold", "af") "  │ " \
            Locale["hu"]["display"] "           - " ansi("bold", "hu") " │ " \
            Locale["pl"]["display"] "      - " ansi("bold", "pl") "    │" RS \
            "│ " Locale["ar"]["display"] "        - " ansi("bold", "ar") "  │ " \
            Locale["hy"]["display"] "          - " ansi("bold", "hy") " │ " \
            Locale["pt"]["display"] "   - " ansi("bold", "pt") "    │" RS \
            "│ " Locale["az"]["display"] "   - " ansi("bold", "az") "  │ " \
            Locale["id"]["display"] " - " ansi("bold", "id") " │ " \
            Locale["ro"]["display"] "      - " ansi("bold", "ro") "    │" RS \
            "│ " Locale["be"]["display"] "     - " ansi("bold", "be") "  │ " \
            Locale["ig"]["display"] "             - " ansi("bold", "ig") " │ " \
            Locale["ru"]["display"] "     - " ansi("bold", "ru") "    │" RS \
            "│ " Locale["bg"]["display"] "      - " ansi("bold", "bg") "  │ " \
            Locale["is"]["display"] "         - " ansi("bold", "is") " │ " \
            Locale["si"]["display"] "        - " ansi("bold", "si") "    │" RS \
            "│ " Locale["bn"]["display"] "          - " ansi("bold", "bn") "  │ " \
            Locale["it"]["display"] "         - " ansi("bold", "it") " │ " \
            Locale["sk"]["display"] "  - " ansi("bold", "sk") "    │" RS \
            "│ " Locale["bs"]["display"] "       - " ansi("bold", "bs") "  │ " \
            Locale["ja"]["display"] "           - " ansi("bold", "ja") " │ " \
            Locale["sl"]["display"] " - " ansi("bold", "sl") "    │" RS \
            "│ " Locale["ca"]["display"] "         - " ansi("bold", "ca") "  │ " \
            Locale["jv"]["display"] "        - " ansi("bold", "jv") " │ " \
            Locale["so"]["display"] "    - " ansi("bold", "so") "    │" RS \
            "│ " Locale["ceb"]["display"] "        - " ansi("bold", "ceb") " │ " \
            Locale["ka"]["display"] "          - " ansi("bold", "ka") " │ " \
            Locale["sq"]["display"] "       - " ansi("bold", "sq") "    │" RS \
            "│ " Locale["cs"]["display"] "        - " ansi("bold", "cs") "  │ " \
            Locale["kk"]["display"] "       - " ansi("bold", "kk") " │ " \
            Locale["sr"]["display"] "      - " ansi("bold", "sr") "    │" RS \
            "│ " Locale["cy"]["display"] "        - " ansi("bold", "cy") "  │ " \
            Locale["km"]["display"] "         - " ansi("bold", "km") " │ " \
            Locale["st"]["display"] "     - " ansi("bold", "st") "    │" RS \
            "│ " Locale["da"]["display"] "          - " ansi("bold", "da") "  │ " \
            Locale["kn"]["display"] "             - " ansi("bold", "kn") " │ " \
            Locale["su"]["display"] "  - " ansi("bold", "su") "    │" RS \
            "│ " Locale["de"]["display"] "        - " ansi("bold", "de") "  │ " \
            Locale["ko"]["display"] "           - " ansi("bold", "ko") " │ " \
            Locale["sv"]["display"] "     - " ansi("bold", "sv") "    │" RS \
            "│ " Locale["el"]["display"] "       - " ansi("bold", "el") "  │ " \
            Locale["la"]["display"] "           - " ansi("bold", "la") " │ " \
            Locale["sw"]["display"] "   - " ansi("bold", "sw") "    │" RS \
            "│ " Locale["en"]["display"] "        - " ansi("bold", "en") "  │ " \
            Locale["lo"]["display"] "              - " ansi("bold", "lo") " │ " \
            Locale["ta"]["display"] "        - " ansi("bold", "ta") "    │" RS \
            "│ " Locale["eo"]["display"] "      - " ansi("bold", "eo") "  │ " \
            Locale["lt"]["display"] "         - " ansi("bold", "lt") " │ " \
            Locale["te"]["display"] "       - " ansi("bold", "te") "    │" RS \
            "│ " Locale["es"]["display"] "        - " ansi("bold", "es") "  │ " \
            Locale["lv"]["display"] "         - " ansi("bold", "lv") " │ " \
            Locale["tg"]["display"] "      - " ansi("bold", "tg") "    │" RS \
            "│ " Locale["et"]["display"] "          - " ansi("bold", "et") "  │ " \
            Locale["mg"]["display"] "         - " ansi("bold", "mg") " │ " \
            Locale["th"]["display"] "         - " ansi("bold", "th") "    │" RS \
            "│ " Locale["eu"]["display"] "        - " ansi("bold", "eu") "  │ " \
            Locale["mi"]["display"] "            - " ansi("bold", "mi") " │ " \
            Locale["tl"]["display"] "     - " ansi("bold", "tl") "    │" RS \
            "│ " Locale["fa"]["display"] "          - " ansi("bold", "fa") "  │ " \
            Locale["mk"]["display"] "       - " ansi("bold", "mk") " │ " \
            Locale["tr"]["display"] "      - " ansi("bold", "tr") "    │" RS \
            "│ " Locale["fi"]["display"] "          - " ansi("bold", "fi") "  │ " \
            Locale["ml"]["display"] "           - " ansi("bold", "ml") " │ " \
            Locale["uk"]["display"] "  - " ansi("bold", "uk") "    │" RS \
            "│ " Locale["fr"]["display"] "       - " ansi("bold", "fr") "  │ " \
            Locale["mn"]["display"] "           - " ansi("bold", "mn") " │ " \
            Locale["ur"]["display"] "        - " ansi("bold", "ur") "    │" RS \
            "│ " Locale["ga"]["display"] "        - " ansi("bold", "ga") "  │ " \
            Locale["mr"]["display"] "            - " ansi("bold", "mr") " │ " \
            Locale["uz"]["display"] " - " ansi("bold", "uz") "    │" RS \
            "│ " Locale["gl"]["display"] "         - " ansi("bold", "gl") "  │ " \
            Locale["ms"]["display"] "    - " ansi("bold", "ms") " │ " \
            Locale["vi"]["display"] "  - " ansi("bold", "vi") "    │" RS \
            "│ " Locale["gu"]["display"] "         - " ansi("bold", "gu") "  │ " \
            Locale["mt"]["display"] "            - " ansi("bold", "mt") " │ " \
            Locale["yi"]["display"] "       - " ansi("bold", "yi") "    │" RS \
            "│ " Locale["ha"]["display"] "          - " ansi("bold", "ha") "  │ " \
            Locale["my"]["display"] "          - " ansi("bold", "my") " │ " \
            Locale["yo"]["display"] "      - " ansi("bold", "yo") "    │" RS \
            "│ " Locale["he"]["display"] "          - " ansi("bold", "he") "  │ " \
            Locale["ne"]["display"] "            - " ansi("bold", "ne") " │ " \
            Locale["zh-CN"]["display"] "    - " ansi("bold", "zh-CN") " │" RS \
            "│ " Locale["hi"]["display"] "          - " ansi("bold", "hi") "  │ " \
            Locale["nl"]["display"] "       - " ansi("bold", "nl") " │ " \
            Locale["zh-TW"]["display"] "    - " ansi("bold", "zh-TW") " │" RS \
            "│ " Locale["hmn"]["display"] "          - " ansi("bold", "hmn") " │ " \
            Locale["no"]["display"] "            - " ansi("bold", "no") " │ " \
            Locale["zu"]["display"] "     - " ansi("bold", "zu") "    │" RS \
            "│ " Locale["hr"]["display"] "       - " ansi("bold", "hr") "  │ " \
            Locale["ny"]["display"] "           - " ansi("bold", "ny") " │ " \
            "                    │" RS \
            "│ " Locale["ht"]["display"] " - " ansi("bold", "ht") "  │ " \
            Locale["pa"]["display"] "            - " ansi("bold", "pa") " │ " \
            "                    │" RS \
            "└──────────────────────┴───────────────────────┴─────────────────────┘"
}

# Return help message as a string.
function getHelp() {
    return "Usage:\t" Command " [options] [source]:[target] [" ansi("underline", "text") "] ..." RS \
        "\t" Command " [options] [source]:[target1]+[target2]+... [" ansi("underline", "text") "] ..." RS RS \
        "Options:" RS                                                   \
        I ansi("bold", "-V, -version") RS                               \
        I I "Print version and exit." RS                                \
        I ansi("bold", "-H, -h, -help") RS                              \
        I I "Print this help message and exit." RS                      \
        I ansi("bold", "-M, -m, -manual") RS                            \
        I I "Show the manual." RS                                       \
        I ansi("bold", "-r, -reference") RS                             \
        I I "Print a list of languages (displayed in endonyms) and their ISO 639 codes for reference, and exit." RS \
        I ansi("bold", "-R, -reference-english") RS                     \
        I I "Print a list of languages (displayed in English names) and their ISO 639 codes for reference, and exit." RS \
        I ansi("bold", "-v, -verbose") RS                               \
        I I "Verbose mode. (default)" RS                                \
        I ansi("bold", "-b, -brief") RS                                 \
        I I "Brief mode." RS                                            \
        I ansi("bold", "-no-ansi") RS                                   \
        I I "Don't use ANSI escape codes in the translation." RS        \
        I ansi("bold", "-w [num], -width [num]") RS                     \
        I I "Specify the screen width for padding when displaying right-to-left languages." RS \
        I ansi("bold", "-browser [program]") RS                         \
        I I "Specify the web browser to use." RS                        \
        I ansi("bold", "-p, -play") RS                                  \
        I I "Listen to the translation." RS                             \
        I ansi("bold", "-player [program]") RS                          \
        I I "Specify the command-line audio player to use, and listen to the translation." RS \
        I ansi("bold", "-x [proxy], -proxy [proxy]") RS                 \
        I I "Use proxy on given port." RS                               \
        I ansi("bold", "-I, -interactive") RS                           \
        I I "Start an interactive shell, invoking `rlwrap` whenever possible (unless `-no-rlwrap` is specified)." RS \
        I ansi("bold", "-no-rlwrap") RS                                 \
        I I "Don't invoke `rlwrap` when starting an interactive shell with `-I`." RS \
        I ansi("bold", "-E, -emacs") RS                                 \
        I I "Start an interactive shell within GNU Emacs, invoking `emacs`." RS \
        I ansi("bold", "-prompt [prompt_string]") RS                    \
        I I "Customize your prompt string in the interactive shell." RS \
        I ansi("bold", "-prompt-color [color_code]") RS                 \
        I I "Customize your prompt color in the interactive shell." RS  \
        I ansi("bold", "-i [file], -input [file]") RS                   \
        I I "Specify the input file name." RS                           \
        I ansi("bold", "-o [file], -output [file]") RS                  \
        I I "Specify the output file name." RS                          \
        I ansi("bold", "-l [code], -lang [code]") RS                    \
        I I "Specify your own, native language (\"home/host language\")." RS \
        I ansi("bold", "-s [code], -source [code]") RS                  \
        I I "Specify the source language (language of the original text)." RS \
        I ansi("bold", "-t [codes], -target [codes]") RS                \
        I I "Specify the target language(s) (language(s) of the translated text)." RS RS \
        "See the man page " Command "(1) for more information."
}

####################################################################
# Help.awk                                                         #
####################################################################

# Return version as a string.
function getVersion() {
    return Name " " Version
}

# Return a list of language codes as a string.
# Parameters:
#     displayName = "endonym" or "name"
function getReference(displayName) {
    if (displayName == "name")
        return "┌─────────────────────────────┬──────────────────────┬─────────────────┐" RS \
            "│ " Locale["af"]["name"] "           - " ansi("bold", "af") "    │ " \
            Locale["ha"]["name"] "          - " ansi("bold", "ha") "  │ " \
            Locale["fa"]["name"] "    - " ansi("bold", "fa") " │" RS    \
            "│ " Locale["sq"]["name"] "            - " ansi("bold", "sq") "    │ " \
            Locale["he"]["name"] "         - " ansi("bold", "he") "  │ " \
            Locale["pl"]["name"] "     - " ansi("bold", "pl") " │" RS   \
            "│ " Locale["ar"]["name"] "              - " ansi("bold", "ar") "    │ " \
            Locale["hi"]["name"] "          - " ansi("bold", "hi") "  │ " \
            Locale["pt"]["name"] " - " ansi("bold", "pt") " │" RS       \
            "│ " Locale["hy"]["name"] "            - " ansi("bold", "hy") "    │ " \
            Locale["hmn"]["name"] "          - " ansi("bold", "hmn") " │ " \
            Locale["pa"]["name"] "    - " ansi("bold", "pa") " │" RS    \
            "│ " Locale["az"]["name"] "         - " ansi("bold", "az") "    │ " \
            Locale["hu"]["name"] "      - " ansi("bold", "hu") "  │ "   \
            Locale["ro"]["name"] "   - " ansi("bold", "ro") " │" RS     \
            "│ " Locale["eu"]["name"] "              - " ansi("bold", "eu") "    │ " \
            Locale["is"]["name"] "      - " ansi("bold", "is") "  │ "   \
            Locale["ru"]["name"] "    - " ansi("bold", "ru") " │" RS    \
            "│ " Locale["be"]["name"] "          - " ansi("bold", "be") "    │ " \
            Locale["ig"]["name"] "           - " ansi("bold", "ig") "  │ " \
            Locale["sr"]["name"] "    - " ansi("bold", "sr") " │" RS    \
            "│ " Locale["bn"]["name"] "             - " ansi("bold", "bn") "    │ " \
            Locale["id"]["name"] "     - " ansi("bold", "id") "  │ "    \
            Locale["st"]["name"] "    - " ansi("bold", "st") " │" RS    \
            "│ " Locale["bs"]["name"] "             - " ansi("bold", "bs") "    │ " \
            Locale["ga"]["name"] "          - " ansi("bold", "ga") "  │ " \
            Locale["si"]["name"] "    - " ansi("bold", "si") " │" RS    \
            "│ " Locale["bg"]["name"] "           - " ansi("bold", "bg") "    │ " \
            Locale["it"]["name"] "        - " ansi("bold", "it") "  │ " \
            Locale["sk"]["name"] "     - " ansi("bold", "sk") " │" RS   \
            "│ " Locale["ca"]["name"] "             - " ansi("bold", "ca") "    │ " \
            Locale["ja"]["name"] "       - " ansi("bold", "ja") "  │ "  \
            Locale["sl"]["name"] "  - " ansi("bold", "sl") " │" RS      \
            "│ " Locale["ceb"]["name"] "             - " ansi("bold", "ceb") "   │ " \
            Locale["jv"]["name"] "       - " ansi("bold", "jv") "  │ "  \
            Locale["so"]["name"] "     - " ansi("bold", "so") " │" RS   \
            "│ " Locale["ny"]["name"] "            - " ansi("bold", "ny") "    │ " \
            Locale["kn"]["name"] "        - " ansi("bold", "kn") "  │ " \
            Locale["es"]["name"] "    - " ansi("bold", "es") " │" RS    \
            "│ " Locale["zh-CN"]["name"] "  - " ansi("bold", "zh-CN") " │ " \
            Locale["kk"]["name"] "         - " ansi("bold", "kk") "  │ " \
            Locale["su"]["name"] "  - " ansi("bold", "su") " │" RS      \
            "│ " Locale["zh-TW"]["name"] " - " ansi("bold", "zh-TW") " │ " \
            Locale["km"]["name"] "          - " ansi("bold", "km") "  │ " \
            Locale["sw"]["name"] "    - " ansi("bold", "sw") " │" RS    \
            "│ " Locale["hr"]["name"] "            - " ansi("bold", "hr") "    │ " \
            Locale["ko"]["name"] "         - " ansi("bold", "ko") "  │ " \
            Locale["sv"]["name"] "    - " ansi("bold", "sv") " │" RS    \
            "│ " Locale["cs"]["name"] "               - " ansi("bold", "cs") "    │ " \
            Locale["lo"]["name"] "            - " ansi("bold", "lo") "  │ " \
            Locale["tg"]["name"] "      - " ansi("bold", "tg") " │" RS  \
            "│ " Locale["da"]["name"] "              - " ansi("bold", "da") "    │ " \
            Locale["la"]["name"] "          - " ansi("bold", "la") "  │ " \
            Locale["ta"]["name"] "      - " ansi("bold", "ta") " │" RS \
            "│ " Locale["nl"]["name"] "               - " ansi("bold", "nl") "    │ " \
            Locale["lv"]["name"] "        - " ansi("bold", "lv") "  │ " \
            Locale["te"]["name"] "     - " ansi("bold", "te") " │" RS   \
            "│ " Locale["en"]["name"] "             - " ansi("bold", "en") "    │ " \
            Locale["lt"]["name"] "     - " ansi("bold", "lt") "  │ "    \
            Locale["th"]["name"] "       - " ansi("bold", "th") " │" RS \
            "│ " Locale["eo"]["name"] "           - " ansi("bold", "eo") "    │ " \
            Locale["mk"]["name"] "     - " ansi("bold", "mk") "  │ "    \
            Locale["tr"]["name"] "    - " ansi("bold", "tr") " │" RS    \
            "│ " Locale["et"]["name"] "            - " ansi("bold", "et") "    │ " \
            Locale["mg"]["name"] "       - " ansi("bold", "mg") "  │ " \
            Locale["uk"]["name"] "  - " ansi("bold", "uk") " │" RS      \
            "│ " Locale["tl"]["name"] "            - " ansi("bold", "tl") "    │ " \
            Locale["ms"]["name"] "          - " ansi("bold", "ms") "  │ " \
            Locale["ur"]["name"] "       - " ansi("bold", "ur") " │" RS \
            "│ " Locale["fi"]["name"] "             - " ansi("bold", "fi") "    │ " \
            Locale["ml"]["name"] "      - " ansi("bold", "ml") "  │ " \
            Locale["uz"]["name"] "      - " ansi("bold", "uz") " │" RS \
            "│ " Locale["fr"]["name"] "              - " ansi("bold", "fr") "    │ " \
            Locale["mt"]["name"] "        - " ansi("bold", "mt") "  │ " \
            Locale["vi"]["name"] " - " ansi("bold", "vi") " │" RS \
            "│ " Locale["gl"]["name"] "            - " ansi("bold", "gl") "    │ " \
            Locale["mi"]["name"] "          - " ansi("bold", "mi") "  │ " \
            Locale["cy"]["name"] "      - " ansi("bold", "cy") " │" RS \
            "│ " Locale["ka"]["name"] "            - " ansi("bold", "ka") "    │ " \
            Locale["mr"]["name"] "        - " ansi("bold", "mr") "  │ " \
            Locale["yi"]["name"] "    - " ansi("bold", "yi") " │" RS \
            "│ " Locale["de"]["name"] "              - " ansi("bold", "de") "    │ " \
            Locale["my"]["name"] "        - " ansi("bold", "my") "  │ " \
            Locale["yo"]["name"] "     - " ansi("bold", "yo") " │" RS \
            "│ " Locale["el"]["name"] "               - " ansi("bold", "el") "    │ " \
            Locale["mn"]["name"] "      - " ansi("bold", "mn") "  │ " \
            Locale["zu"]["name"] "       - " ansi("bold", "zu") " │" RS \
            "│ " Locale["gu"]["name"] "            - " ansi("bold", "gu") "    │ " \
            Locale["ne"]["name"] "         - " ansi("bold", "ne") "  │ " \
            "                │" RS \
            "│ " Locale["ht"]["name"] "      - " ansi("bold", "ht") "    │ " \
            Locale["no"]["name"] "      - " ansi("bold", "no") "  │ " \
            "                │" RS \
            "└─────────────────────────────┴──────────────────────┴─────────────────┘"
    else
        return "┌──────────────────────┬───────────────────────┬─────────────────────┐" RS \
            "│ " Locale["af"]["display"] "      - " ansi("bold", "af") "  │ " \
            Locale["hu"]["display"] "           - " ansi("bold", "hu") " │ " \
            Locale["pl"]["display"] "      - " ansi("bold", "pl") "    │" RS \
            "│ " Locale["ar"]["display"] "        - " ansi("bold", "ar") "  │ " \
            Locale["hy"]["display"] "          - " ansi("bold", "hy") " │ " \
            Locale["pt"]["display"] "   - " ansi("bold", "pt") "    │" RS \
            "│ " Locale["az"]["display"] "   - " ansi("bold", "az") "  │ " \
            Locale["id"]["display"] " - " ansi("bold", "id") " │ " \
            Locale["ro"]["display"] "      - " ansi("bold", "ro") "    │" RS \
            "│ " Locale["be"]["display"] "     - " ansi("bold", "be") "  │ " \
            Locale["ig"]["display"] "             - " ansi("bold", "ig") " │ " \
            Locale["ru"]["display"] "     - " ansi("bold", "ru") "    │" RS \
            "│ " Locale["bg"]["display"] "      - " ansi("bold", "bg") "  │ " \
            Locale["is"]["display"] "         - " ansi("bold", "is") " │ " \
            Locale["si"]["display"] "        - " ansi("bold", "si") "    │" RS \
            "│ " Locale["bn"]["display"] "          - " ansi("bold", "bn") "  │ " \
            Locale["it"]["display"] "         - " ansi("bold", "it") " │ " \
            Locale["sk"]["display"] "  - " ansi("bold", "sk") "    │" RS \
            "│ " Locale["bs"]["display"] "       - " ansi("bold", "bs") "  │ " \
            Locale["ja"]["display"] "           - " ansi("bold", "ja") " │ " \
            Locale["sl"]["display"] " - " ansi("bold", "sl") "    │" RS \
            "│ " Locale["ca"]["display"] "         - " ansi("bold", "ca") "  │ " \
            Locale["jv"]["display"] "        - " ansi("bold", "jv") " │ " \
            Locale["so"]["display"] "    - " ansi("bold", "so") "    │" RS \
            "│ " Locale["ceb"]["display"] "        - " ansi("bold", "ceb") " │ " \
            Locale["ka"]["display"] "          - " ansi("bold", "ka") " │ " \
            Locale["sq"]["display"] "       - " ansi("bold", "sq") "    │" RS \
            "│ " Locale["cs"]["display"] "        - " ansi("bold", "cs") "  │ " \
            Locale["kk"]["display"] "       - " ansi("bold", "kk") " │ " \
            Locale["sr"]["display"] "      - " ansi("bold", "sr") "    │" RS \
            "│ " Locale["cy"]["display"] "        - " ansi("bold", "cy") "  │ " \
            Locale["km"]["display"] "         - " ansi("bold", "km") " │ " \
            Locale["st"]["display"] "     - " ansi("bold", "st") "    │" RS \
            "│ " Locale["da"]["display"] "          - " ansi("bold", "da") "  │ " \
            Locale["kn"]["display"] "             - " ansi("bold", "kn") " │ " \
            Locale["su"]["display"] "  - " ansi("bold", "su") "    │" RS \
            "│ " Locale["de"]["display"] "        - " ansi("bold", "de") "  │ " \
            Locale["ko"]["display"] "           - " ansi("bold", "ko") " │ " \
            Locale["sv"]["display"] "     - " ansi("bold", "sv") "    │" RS \
            "│ " Locale["el"]["display"] "       - " ansi("bold", "el") "  │ " \
            Locale["la"]["display"] "           - " ansi("bold", "la") " │ " \
            Locale["sw"]["display"] "   - " ansi("bold", "sw") "    │" RS \
            "│ " Locale["en"]["display"] "        - " ansi("bold", "en") "  │ " \
            Locale["lo"]["display"] "              - " ansi("bold", "lo") " │ " \
            Locale["ta"]["display"] "        - " ansi("bold", "ta") "    │" RS \
            "│ " Locale["eo"]["display"] "      - " ansi("bold", "eo") "  │ " \
            Locale["lt"]["display"] "         - " ansi("bold", "lt") " │ " \
            Locale["te"]["display"] "       - " ansi("bold", "te") "    │" RS \
            "│ " Locale["es"]["display"] "        - " ansi("bold", "es") "  │ " \
            Locale["lv"]["display"] "         - " ansi("bold", "lv") " │ " \
            Locale["tg"]["display"] "      - " ansi("bold", "tg") "    │" RS \
            "│ " Locale["et"]["display"] "          - " ansi("bold", "et") "  │ " \
            Locale["mg"]["display"] "         - " ansi("bold", "mg") " │ " \
            Locale["th"]["display"] "         - " ansi("bold", "th") "    │" RS \
            "│ " Locale["eu"]["display"] "        - " ansi("bold", "eu") "  │ " \
            Locale["mi"]["display"] "            - " ansi("bold", "mi") " │ " \
            Locale["tl"]["display"] "     - " ansi("bold", "tl") "    │" RS \
            "│ " Locale["fa"]["display"] "          - " ansi("bold", "fa") "  │ " \
            Locale["mk"]["display"] "       - " ansi("bold", "mk") " │ " \
            Locale["tr"]["display"] "      - " ansi("bold", "tr") "    │" RS \
            "│ " Locale["fi"]["display"] "          - " ansi("bold", "fi") "  │ " \
            Locale["ml"]["display"] "           - " ansi("bold", "ml") " │ " \
            Locale["uk"]["display"] "  - " ansi("bold", "uk") "    │" RS \
            "│ " Locale["fr"]["display"] "       - " ansi("bold", "fr") "  │ " \
            Locale["mn"]["display"] "           - " ansi("bold", "mn") " │ " \
            Locale["ur"]["display"] "        - " ansi("bold", "ur") "    │" RS \
            "│ " Locale["ga"]["display"] "        - " ansi("bold", "ga") "  │ " \
            Locale["mr"]["display"] "            - " ansi("bold", "mr") " │ " \
            Locale["uz"]["display"] " - " ansi("bold", "uz") "    │" RS \
            "│ " Locale["gl"]["display"] "         - " ansi("bold", "gl") "  │ " \
            Locale["ms"]["display"] "    - " ansi("bold", "ms") " │ " \
            Locale["vi"]["display"] "  - " ansi("bold", "vi") "    │" RS \
            "│ " Locale["gu"]["display"] "         - " ansi("bold", "gu") "  │ " \
            Locale["mt"]["display"] "            - " ansi("bold", "mt") " │ " \
            Locale["yi"]["display"] "       - " ansi("bold", "yi") "    │" RS \
            "│ " Locale["ha"]["display"] "          - " ansi("bold", "ha") "  │ " \
            Locale["my"]["display"] "          - " ansi("bold", "my") " │ " \
            Locale["yo"]["display"] "      - " ansi("bold", "yo") "    │" RS \
            "│ " Locale["he"]["display"] "          - " ansi("bold", "he") "  │ " \
            Locale["ne"]["display"] "            - " ansi("bold", "ne") " │ " \
            Locale["zh-CN"]["display"] "    - " ansi("bold", "zh-CN") " │" RS \
            "│ " Locale["hi"]["display"] "          - " ansi("bold", "hi") "  │ " \
            Locale["nl"]["display"] "       - " ansi("bold", "nl") " │ " \
            Locale["zh-TW"]["display"] "    - " ansi("bold", "zh-TW") " │" RS \
            "│ " Locale["hmn"]["display"] "          - " ansi("bold", "hmn") " │ " \
            Locale["no"]["display"] "            - " ansi("bold", "no") " │ " \
            Locale["zu"]["display"] "     - " ansi("bold", "zu") "    │" RS \
            "│ " Locale["hr"]["display"] "       - " ansi("bold", "hr") "  │ " \
            Locale["ny"]["display"] "           - " ansi("bold", "ny") " │ " \
            "                    │" RS \
            "│ " Locale["ht"]["display"] " - " ansi("bold", "ht") "  │ " \
            Locale["pa"]["display"] "            - " ansi("bold", "pa") " │ " \
            "                    │" RS \
            "└──────────────────────┴───────────────────────┴─────────────────────┘"
}

# Return help message as a string.
function getHelp() {
    return "Usage:\t" Command " [options] [source]:[target] [" ansi("underline", "text") "] ..." RS \
        "\t" Command " [options] [source]:[target1]+[target2]+... [" ansi("underline", "text") "] ..." RS RS \
        "Options:" RS                                                   \
        I ansi("bold", "-V, -version") RS                               \
        I I "Print version and exit." RS                                \
        I ansi("bold", "-H, -h, -help") RS                              \
        I I "Print this help message and exit." RS                      \
        I ansi("bold", "-M, -m, -manual") RS                            \
        I I "Show the manual." RS                                       \
        I ansi("bold", "-r, -reference") RS                             \
        I I "Print a list of languages (displayed in endonyms) and their ISO 639 codes for reference, and exit." RS \
        I ansi("bold", "-R, -reference-english") RS                     \
        I I "Print a list of languages (displayed in English names) and their ISO 639 codes for reference, and exit." RS \
        I ansi("bold", "-v, -verbose") RS                               \
        I I "Verbose mode. (default)" RS                                \
        I ansi("bold", "-b, -brief") RS                                 \
        I I "Brief mode." RS                                            \
        I ansi("bold", "-no-ansi") RS                                   \
        I I "Don't use ANSI escape codes in the translation." RS        \
        I ansi("bold", "-w [num], -width [num]") RS                     \
        I I "Specify the screen width for padding when displaying right-to-left languages." RS \
        I ansi("bold", "-browser [program]") RS                         \
        I I "Specify the web browser to use." RS                        \
        I ansi("bold", "-p, -play") RS                                  \
        I I "Listen to the translation." RS                             \
        I ansi("bold", "-player [program]") RS                          \
        I I "Specify the command-line audio player to use, and listen to the translation." RS \
        I ansi("bold", "-x [proxy], -proxy [proxy]") RS                 \
        I I "Use proxy on given port." RS                               \
        I ansi("bold", "-I, -interactive") RS                           \
        I I "Start an interactive shell, invoking `rlwrap` whenever possible (unless `-no-rlwrap` is specified)." RS \
        I ansi("bold", "-no-rlwrap") RS                                 \
        I I "Don't invoke `rlwrap` when starting an interactive shell with `-I`." RS \
        I ansi("bold", "-E, -emacs") RS                                 \
        I I "Start an interactive shell within GNU Emacs, invoking `emacs`." RS \
        I ansi("bold", "-prompt [prompt_string]") RS                    \
        I I "Customize your prompt string in the interactive shell." RS \
        I ansi("bold", "-prompt-color [color_code]") RS                 \
        I I "Customize your prompt color in the interactive shell." RS  \
        I ansi("bold", "-i [file], -input [file]") RS                   \
        I I "Specify the input file name." RS                           \
        I ansi("bold", "-o [file], -output [file]") RS                  \
        I I "Specify the output file name." RS                          \
        I ansi("bold", "-l [code], -lang [code]") RS                    \
        I I "Specify your own, native language (\"home/host language\")." RS \
        I ansi("bold", "-s [code], -source [code]") RS                  \
        I I "Specify the source language (language of the original text)." RS \
        I ansi("bold", "-t [codes], -target [codes]") RS                \
        I I "Specify the target language(s) (language(s) of the translated text)." RS RS \
        "See the man page " Command "(1) for more information."
}


Main: change default User-Agent

Main: change default User-Agent

####################################################################
# Main.awk                                                         #
####################################################################

# Initialization.
function init() {
    initGawk()
    initBiDi()

    # (Languages.awk)
    initLocale()
    initUserLang()

    RS = "\n"

    ExitCode = 0

    Option["debug"] = 0

    # Display
    Option["verbose"] = 1
    Option["show-original"] = 1
    Option["show-original-phonetics"] = 1
    Option["show-translation"] = 1
    Option["show-translation-phonetics"] = 1
    Option["show-prompt-message"] = 1
    Option["show-languages"] = 1
    Option["show-original-dictionary"] = 0
    Option["show-dictionary"] = 1
    Option["show-alternatives"] = 1
    Option["width"] = ENVIRON["COLUMNS"] ? ENVIRON["COLUMNS"] - 2 : 0
    Option["indent"] = 4
    Option["no-ansi"] = 0
    Option["theme"] = "default"

    # Audio
    Option["play"] = 0
    Option["player"] = ENVIRON["PLAYER"]

    # Terminal paging and browsing
    Option["view"] = 0
    Option["pager"] = ENVIRON["PAGER"]
    Option["browser"] = ENVIRON["BROWSER"]

    # Networking
    Option["proxy"] = ENVIRON["HTTP_PROXY"] ? ENVIRON["HTTP_PROXY"] : ENVIRON["http_proxy"]
    Option["user-agent"] = ENVIRON["USER_AGENT"] ? ENVIRON["USER_AGENT"] : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) Version/8.0 Safari/602.1 Epiphany/3.18.2"

    # Interactive shell
    Option["no-rlwrap"] = 0
    Option["interactive"] = 0
    Option["emacs"] = 0

    # I/O
    Option["input"] = NULLSTR
    Option["output"] = STDOUT

    # Language preference
    Option["hl"] = ENVIRON["HOME_LANG"] ? ENVIRON["HOME_LANG"] : UserLang
    Option["sl"] = ENVIRON["SOURCE_LANG"] ? ENVIRON["SOURCE_LANG"] : "auto"
    Option["tl"][1] = ENVIRON["TARGET_LANG"] ? ENVIRON["TARGET_LANG"] : UserLang
}

# Initialization script.
function initScript(    file, line, script, temp) {
    # Find the initialization file
    file = ".trans"
    if (!fileExists(file)) {
        file = ENVIRON["HOME"] "/.translate-shell/init.trans"
        if (!fileExists(file)) {
            file = ENVIRON["HOME"] "/.config/translate-shell/init.trans"
            if (!fileExists(file)) {
                file = "/etc/translate-shell"
                if (!fileExists(file)) return
            }
        }
    }

    InitScript = file
    script = NULLSTR
    while (getline line < InitScript)
        script = script "\n" line
    loadOptions(script)

    # HACK: Option["tl"] must be an array
    if (!isarray(Option["tl"])) {
        temp = Option["tl"]
        delete Option["tl"]
        Option["tl"][1] = temp
    }
}

# Miscellany initialization.
function initMisc(    group, temp) {
    # (Translate.awk)
    initHttpService()

    # Initialize screen width if not set
    if (!Option["width"] && detectProgram("tput", "-V")) {
        "tput cols" | getline temp
        Option["width"] = temp ? temp - 2 : 64
    }

    # Disable ANSI escape codes if required
    if (Option["no-ansi"])
        delete AnsiCode

    # Initialize audio player or speech synthesizer
    if (Option["play"]) {
        if (!Option["player"]) {
            initAudioPlayer()
            Option["player"] = AudioPlayer ? AudioPlayer : Option["player"]
            if (!Option["player"])
                initSpeechSynthesizer()
        }

        if (!Option["player"] && !SpeechSynthesizer) {
            w("[WARNING] No available audio player or speech synthesizer.")
            Option["play"] = 0
        }
    }

    # Initialize pager
    if (Option["view"]) {
        if (!Option["pager"]) {
            initPager()
            Option["pager"] = Pager
        }

        if (!Option["pager"]) {
            w("[WARNING] No available terminal pager.")
            Option["view"] = 0
        }
    }

    # Initialize browser
    if (!Option["browser"]) {
        "xdg-mime query default text/html" SUPERR | getline Option["browser"]
        match(Option["browser"], "(.*).desktop$", group)
        Option["browser"] = group[1]
    }
}

# Main entry point.
BEGIN {
    init()

    if (!(belongsTo("-no-init", ARGV) || belongsTo("--no-init", ARGV)))
        initScript() # initialization script overrides default setting

    # Command-line options override initialization script
    pos = 0
    noargc = 0
    while (ARGV[++pos]) {
        ## Information options

        # -V, -version
        match(ARGV[pos], /^--?(V|vers(i(on?)?)?)$/)
        if (RSTART) {
            InfoOnly = "version"
            continue
        }

        # -H, -help
        match(ARGV[pos], /^--?(H|h(e(lp?)?)?)$/)
        if (RSTART) {
            InfoOnly = "help"
            continue
        }

        # -M, -man
        match(ARGV[pos], /^--?(M|m(a(n(u(al?)?)?)?)?)$/)
        if (RSTART) {
            InfoOnly = "manual"
            continue
        }

        # -T, -reference
        match(ARGV[pos], /^--?(T|ref(e(r(e(n(ce?)?)?)?)?)?)$/)
        if (RSTART) {
            InfoOnly = "reference"
            continue
        }

        # FIXME[1.0]: to be removed
        match(ARGV[pos], /^--?r$/)
        if (RSTART) {
            w("[WARNING] Option '-r' has been deprecated since version 0.9.\n" \
              "          Use option '-T' or '-reference' instead.")
            exit 1
        }

        # -R, -reference-english
        match(ARGV[pos], /^--?(R|reference-e(n(g(l(i(sh?)?)?)?)?)?)$/)
        if (RSTART) {
            InfoOnly = "reference-english"
            continue
        }

        # -L CODES, -list CODES
        match(ARGV[pos], /^--?(L|list)(=(.*)?)?$/, group)
        if (RSTART) {
            InfoOnly = "list"
            if (group[2]) {
                if (group[3]) split(group[3], Option["tl"], "+")
            } else
                split(ARGV[++pos], Option["tl"], "+")
            continue
        }

        # -U, -upgrade
        match(ARGV[pos], /^--?(U|upgrade)$/)
        if (RSTART) {
            InfoOnly = "upgrade"
            continue
        }

        # -N, -nothing
        match(ARGV[pos], /^--?(N|nothing)$/)
        if (RSTART) {
            InfoOnly = "nothing"
            continue
        }

        ## Display options

        # -verbose
        match(ARGV[pos], /^--?verbose$/)
        if (RSTART) {
            Option["verbose"] = 1 # default value
            continue
        }

        # -b, -brief
        match(ARGV[pos], /^--?b(r(i(ef?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = 0
            continue
        }

        # -d, -dictionary
        match(ARGV[pos], /^--?d(i(c(t(i(o(n(a(ry?)?)?)?)?)?)?)?)?$/)
        if (RSTART) {
            Option["show-original-dictionary"] = 1
            Option["show-dictionary"] = 0
            Option["show-alternatives"] = 0
            continue
        }

        # -identify
        match(ARGV[pos], /^--?id(e(n(t(i(fy?)?)?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = -1
            continue
        }

        # -show-original Y/n
        match(ARGV[pos], /^--?show-original(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-original"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-original-phonetics Y/n
        match(ARGV[pos], /^--?show-original-phonetics(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-original-phonetics"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-translation Y/n
        match(ARGV[pos], /^--?show-translation(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-translation"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-translation-phonetics Y/n
        match(ARGV[pos], /^--?show-translation-phonetics(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-translation-phonetics"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-prompt-message Y/n
        match(ARGV[pos], /^--?show-prompt-message(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-prompt-message"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-languages Y/n
        match(ARGV[pos], /^--?show-languages(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-languages"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-original-dictionary y/N
        match(ARGV[pos], /^--?show-original-dictionary(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-original-dictionary"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-dictionary Y/n
        match(ARGV[pos], /^--?show-dictionary(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-dictionary"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-alternatives Y/n
        match(ARGV[pos], /^--?show-alternatives(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-alternatives"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -w NUM, -width NUM
        match(ARGV[pos], /^--?w(i(d(th?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["width"] = group[4] ?
                (group[5] ? group[5] : Option["width"]) :
                ARGV[++pos]
            continue
        }

        # -indent NUM
        match(ARGV[pos], /^--?indent(=(.*)?)?$/, group)
        if (RSTART) {
            Option["indent"] = group[1] ?
                (group[2] ? group[2] : Option["indent"]) :
                ARGV[++pos]
            continue
        }

        # -theme FILENAME
        match(ARGV[pos], /^--?theme(=(.*)?)?$/, group)
        if (RSTART) {
            Option["theme"] = group[1] ?
                (group[2] ? group[2] : Option["theme"]) :
                ARGV[++pos]
            continue
        }

        # -no-theme
        match(ARGV[pos], /^--?no-theme$/)
        if (RSTART) {
            Option["theme"] = NULLSTR
            continue
        }

        # -no-ansi
        match(ARGV[pos], /^--?no-ansi$/)
        if (RSTART) {
            Option["no-ansi"] = 1
            continue
        }

        ## Audio options

        # -p, -play
        match(ARGV[pos], /^--?p(l(ay?)?)?$/)
        if (RSTART) {
            Option["play"] = 1
            continue
        }

        # -speak
        match(ARGV[pos], /^--?sp(e(ak?)?)?$/)
        if (RSTART) {
            Option["play"] = 2
            continue
        }

        # -player PROGRAM
        match(ARGV[pos], /^--?player(=(.*)?)?$/, group)
        if (RSTART) {
            if (!Option["play"]) Option["play"] = 1 # -play by default
            Option["player"] = group[1] ?
                (group[2] ? group[2] : Option["player"]) :
                ARGV[++pos]
            continue
        }

        # -no-play
        match(ARGV[pos], /^--?no-play$/)
        if (RSTART) {
            Option["play"] = 0
            continue
        }

        ## Terminal paging and browsing options

        # -v, -view
        match(ARGV[pos], /^--?v(i(ew?)?)?$/)
        if (RSTART) {
            Option["view"] = 1
            continue
        }

        # -pager PROGRAM
        match(ARGV[pos], /^--?pager(=(.*)?)?$/, group)
        if (RSTART) {
            Option["view"] = 1
            Option["pager"] = group[1] ?
                (group[2] ? group[2] : Option["pager"]) :
                ARGV[++pos]
            continue
        }

        # -no-view
        match(ARGV[pos], /^--?no-view$/)
        if (RSTART) {
            Option["view"] = 0
            continue
        }

        # -browser PROGRAM
        match(ARGV[pos], /^--?browser(=(.*)?)?$/, group)
        if (RSTART) {
            Option["browser"] = group[1] ?
                (group[2] ? group[2] : Option["browser"]) :
                ARGV[++pos]
            continue
        }

        ## Networking options

        # -x HOST:PORT, -proxy HOST:PORT
        match(ARGV[pos], /^--?(x|proxy)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["proxy"] = group[2] ?
                (group[3] ? group[3] : Option["proxy"]) :
                ARGV[++pos]
            continue
        }

        # -u STRING, -user-agent STRING
        match(ARGV[pos], /^--?(u|user-agent)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["user-agent"] = group[2] ?
                (group[3] ? group[3] : Option["user-agent"]) :
                ARGV[++pos]
            continue
        }

        ## Interactive shell options

        # -I, -interactive, -shell
        match(ARGV[pos], /^--?(I|int(e(r(a(c(t(i(ve?)?)?)?)?)?)?)?|shell)$/)
        if (RSTART) {
            Option["interactive"] = 1
            continue
        }

        # -E, -emacs
        match(ARGV[pos], /^--?(E|emacs)$/)
        if (RSTART) {
            Option["emacs"] = 1
            continue
        }

        # -no-rlwrap
        match(ARGV[pos], /^--?no-rlwrap$/)
        if (RSTART) {
            Option["no-rlwrap"] = 1
            continue
        }

        # FIXME[1.0]: to be removed
        # -prompt PROMPT_STRING
        match(ARGV[pos], /^--?prompt(=(.*)?)?$/, group)
        if (RSTART) {
            w("[ERROR] Option '-prompt' has been deprecated since version 0.9.\n" \
              "        Use configuration variable 'fmt-prompt' instead.")
            exit 1
        }

        # FIXME[1.0]: to be removed
        # -prompt-color COLOR_CODE
        match(ARGV[pos], /^--?prompt-color(=(.*)?)?$/, group)
        if (RSTART) {
            w("[ERROR] Option '-prompt-color' has been deprecated since version 0.9.\n" \
              "        Use configuration variable 'sgr-prompt' instead.")
            exit 1
        }

        ## I/O options

        # -i FILENAME, -input FILENAME
        match(ARGV[pos], /^--?i(n(p(ut?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["input"] = group[4] ?
                (group[5] ? group[5] : Option["input"]) :
                ARGV[++pos]
            continue
        }

        # -o FILENAME, -output FILENAME
        match(ARGV[pos], /^--?o(u(t(p(ut?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["output"] = group[5] ?
                (group[6] ? group[6] : Option["output"]) :
                ARGV[++pos]
            continue
        }

        ## Language preference options

        # -l CODE, -hl CODE, -lang CODE
        match(ARGV[pos], /^--?(l(a(ng?)?)?|hl)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["hl"] = group[4] ?
                (group[5] ? group[5] : Option["hl"]) :
                ARGV[++pos]
            continue
        }

        # -s CODE, -sl CODE, -source CODE
        match(ARGV[pos], /^--?s(o(u(r(ce?)?)?)?|l)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["sl"] = group[5] ?
                (group[6] ? group[6] : Option["sl"]) :
                ARGV[++pos]
            continue
        }

        # -t CODES, -tl CODE, -target CODES
        match(ARGV[pos], /^--?t(a(r(g(et?)?)?)?|l)?(=(.*)?)?$/, group)
        if (RSTART) {
            if (group[5]) {
                if (group[6]) split(group[6], Option["tl"], "+")
            } else
                split(ARGV[++pos], Option["tl"], "+")
            continue
        }

        # Shortcut format
        # 'CODE:CODE+...' or 'CODE=CODE+...'
        match(ARGV[pos], /^[{(\[]?([[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?(:|=)((@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?\+)*(@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?)[})\]]?$/, group)
        if (RSTART) {
            if (group[1]) Option["sl"] = group[1]
            if (group[4]) split(group[4], Option["tl"], "+")
            continue
        }

        ## Other options

        # -D, -debug
        match(ARGV[pos], /^--?(D|debug)$/)
        if (RSTART) {
            Option["debug"] = 1
            continue
        }

        # -no-init
        match(ARGV[pos], /^--?no-init/)
        if (RSTART) continue # skip

        # -, -no-op
        match(ARGV[pos], /^-(-?no-op)?$/)
        if (RSTART) continue # no operation, skip

        # --
        match(ARGV[pos], /^--$/)
        if (RSTART) {
            ++pos # skip the end-of-options option
            break # no more option from here
        }

        # non-option argument
        noargv[noargc++] = ARGV[pos]
    }

    # Handle interactive shell
    if (Option["interactive"] && !Option["no-rlwrap"])
        rlwrapMe() # interactive mode
    else if (Option["emacs"] && !Option["interactive"] && !Option["no-rlwrap"])
        if (emacsMe()) # emacs front-end
            Option["interactive"] = 1 # fallback to interactive mode

    # Get started

    initMisc()

    # Information-only session
    switch (InfoOnly) {
    case "version":
        print getVersion()
        exit ExitCode
    case "help":
        print getHelp()
        exit ExitCode
    case "manual":
        showMan()
        exit ExitCode
    case "reference":
        print getReference("endonym")
        exit ExitCode
    case "reference-english":
        print getReference("name")
        exit ExitCode
    case "list":
        print getList(Option["tl"])
        exit ExitCode
    case "upgrade":
        upgrade()
        exit ExitCode
    case "nothing":
        exit ExitCode
    }

    # Load theme (overrides command-line options) - slow
    setTheme()

    if (Option["interactive"])
        welcome()

    # More remaining non-option arguments
    if (pos < ARGC)
        for (i = pos; i < ARGC; i++)
            noargv[noargc++] = ARGV[i]

    if (noargc) {
        # Translate all non-option arguments
        for (i = 0; i < noargc; i++) {
            # Verbose mode: separator between sources
            if (Option["verbose"] && i > pos)
                p(prettify("source-seperator", replicate(Option["chr-source-seperator"], Option["width"])))

            translate(noargv[i], 1) # inline mode
        }

        # If input not specified, we're done
    } else {
        # If input not specified, use stdin
        if (!Option["input"]) Option["input"] = STDIN
    }

    # If input specified, start translating
    if (Option["input"])
        translateMain()

    exit ExitCode
}

####################################################################
# Main.awk                                                         #
####################################################################

# Initialization.
function init() {
    initGawk()
    initBiDi()

    # (Languages.awk)
    initLocale()
    initUserLang()

    RS = "\n"

    ExitCode = 0

    Option["debug"] = 0

    # Display
    Option["verbose"] = 1
    Option["show-original"] = 1
    Option["show-original-phonetics"] = 1
    Option["show-translation"] = 1
    Option["show-translation-phonetics"] = 1
    Option["show-prompt-message"] = 1
    Option["show-languages"] = 1
    Option["show-original-dictionary"] = 0
    Option["show-dictionary"] = 1
    Option["show-alternatives"] = 1
    Option["width"] = ENVIRON["COLUMNS"] ? ENVIRON["COLUMNS"] - 2 : 0
    Option["indent"] = 4
    Option["no-ansi"] = 0
    Option["theme"] = "default"

    # Audio
    Option["play"] = 0
    Option["player"] = ENVIRON["PLAYER"]

    # Terminal paging and browsing
    Option["view"] = 0
    Option["pager"] = ENVIRON["PAGER"]
    Option["browser"] = ENVIRON["BROWSER"]

    # Networking
    Option["proxy"] = ENVIRON["HTTP_PROXY"] ? ENVIRON["HTTP_PROXY"] : ENVIRON["http_proxy"]
    Option["user-agent"] = ENVIRON["USER_AGENT"] ? ENVIRON["USER_AGENT"] : "Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0"

    # Interactive shell
    Option["no-rlwrap"] = 0
    Option["interactive"] = 0
    Option["emacs"] = 0

    # I/O
    Option["input"] = NULLSTR
    Option["output"] = STDOUT

    # Language preference
    Option["hl"] = ENVIRON["HOME_LANG"] ? ENVIRON["HOME_LANG"] : UserLang
    Option["sl"] = ENVIRON["SOURCE_LANG"] ? ENVIRON["SOURCE_LANG"] : "auto"
    Option["tl"][1] = ENVIRON["TARGET_LANG"] ? ENVIRON["TARGET_LANG"] : UserLang
}

# Initialization script.
function initScript(    file, line, script, temp) {
    # Find the initialization file
    file = ".trans"
    if (!fileExists(file)) {
        file = ENVIRON["HOME"] "/.translate-shell/init.trans"
        if (!fileExists(file)) {
            file = ENVIRON["HOME"] "/.config/translate-shell/init.trans"
            if (!fileExists(file)) {
                file = "/etc/translate-shell"
                if (!fileExists(file)) return
            }
        }
    }

    InitScript = file
    script = NULLSTR
    while (getline line < InitScript)
        script = script "\n" line
    loadOptions(script)

    # HACK: Option["tl"] must be an array
    if (!isarray(Option["tl"])) {
        temp = Option["tl"]
        delete Option["tl"]
        Option["tl"][1] = temp
    }
}

# Miscellany initialization.
function initMisc(    group, temp) {
    # (Translate.awk)
    initHttpService()

    # Initialize screen width if not set
    if (!Option["width"] && detectProgram("tput", "-V")) {
        "tput cols" | getline temp
        Option["width"] = temp ? temp - 2 : 64
    }

    # Disable ANSI escape codes if required
    if (Option["no-ansi"])
        delete AnsiCode

    # Initialize audio player or speech synthesizer
    if (Option["play"]) {
        if (!Option["player"]) {
            initAudioPlayer()
            Option["player"] = AudioPlayer ? AudioPlayer : Option["player"]
            if (!Option["player"])
                initSpeechSynthesizer()
        }

        if (!Option["player"] && !SpeechSynthesizer) {
            w("[WARNING] No available audio player or speech synthesizer.")
            Option["play"] = 0
        }
    }

    # Initialize pager
    if (Option["view"]) {
        if (!Option["pager"]) {
            initPager()
            Option["pager"] = Pager
        }

        if (!Option["pager"]) {
            w("[WARNING] No available terminal pager.")
            Option["view"] = 0
        }
    }

    # Initialize browser
    if (!Option["browser"]) {
        "xdg-mime query default text/html" SUPERR | getline Option["browser"]
        match(Option["browser"], "(.*).desktop$", group)
        Option["browser"] = group[1]
    }
}

# Main entry point.
BEGIN {
    init()

    if (!(belongsTo("-no-init", ARGV) || belongsTo("--no-init", ARGV)))
        initScript() # initialization script overrides default setting

    # Command-line options override initialization script
    pos = 0
    noargc = 0
    while (ARGV[++pos]) {
        ## Information options

        # -V, -version
        match(ARGV[pos], /^--?(V|vers(i(on?)?)?)$/)
        if (RSTART) {
            InfoOnly = "version"
            continue
        }

        # -H, -help
        match(ARGV[pos], /^--?(H|h(e(lp?)?)?)$/)
        if (RSTART) {
            InfoOnly = "help"
            continue
        }

        # -M, -man
        match(ARGV[pos], /^--?(M|m(a(n(u(al?)?)?)?)?)$/)
        if (RSTART) {
            InfoOnly = "manual"
            continue
        }

        # -T, -reference
        match(ARGV[pos], /^--?(T|ref(e(r(e(n(ce?)?)?)?)?)?)$/)
        if (RSTART) {
            InfoOnly = "reference"
            continue
        }

        # FIXME[1.0]: to be removed
        match(ARGV[pos], /^--?r$/)
        if (RSTART) {
            w("[WARNING] Option '-r' has been deprecated since version 0.9.\n" \
              "          Use option '-T' or '-reference' instead.")
            exit 1
        }

        # -R, -reference-english
        match(ARGV[pos], /^--?(R|reference-e(n(g(l(i(sh?)?)?)?)?)?)$/)
        if (RSTART) {
            InfoOnly = "reference-english"
            continue
        }

        # -L CODES, -list CODES
        match(ARGV[pos], /^--?(L|list)(=(.*)?)?$/, group)
        if (RSTART) {
            InfoOnly = "list"
            if (group[2]) {
                if (group[3]) split(group[3], Option["tl"], "+")
            } else
                split(ARGV[++pos], Option["tl"], "+")
            continue
        }

        # -U, -upgrade
        match(ARGV[pos], /^--?(U|upgrade)$/)
        if (RSTART) {
            InfoOnly = "upgrade"
            continue
        }

        # -N, -nothing
        match(ARGV[pos], /^--?(N|nothing)$/)
        if (RSTART) {
            InfoOnly = "nothing"
            continue
        }

        ## Display options

        # -verbose
        match(ARGV[pos], /^--?verbose$/)
        if (RSTART) {
            Option["verbose"] = 1 # default value
            continue
        }

        # -b, -brief
        match(ARGV[pos], /^--?b(r(i(ef?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = 0
            continue
        }

        # -d, -dictionary
        match(ARGV[pos], /^--?d(i(c(t(i(o(n(a(ry?)?)?)?)?)?)?)?)?$/)
        if (RSTART) {
            Option["show-original-dictionary"] = 1
            Option["show-dictionary"] = 0
            Option["show-alternatives"] = 0
            continue
        }

        # -identify
        match(ARGV[pos], /^--?id(e(n(t(i(fy?)?)?)?)?)?$/)
        if (RSTART) {
            Option["verbose"] = -1
            continue
        }

        # -show-original Y/n
        match(ARGV[pos], /^--?show-original(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-original"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-original-phonetics Y/n
        match(ARGV[pos], /^--?show-original-phonetics(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-original-phonetics"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-translation Y/n
        match(ARGV[pos], /^--?show-translation(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-translation"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-translation-phonetics Y/n
        match(ARGV[pos], /^--?show-translation-phonetics(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-translation-phonetics"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-prompt-message Y/n
        match(ARGV[pos], /^--?show-prompt-message(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-prompt-message"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-languages Y/n
        match(ARGV[pos], /^--?show-languages(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-languages"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-original-dictionary y/N
        match(ARGV[pos], /^--?show-original-dictionary(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-original-dictionary"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-dictionary Y/n
        match(ARGV[pos], /^--?show-dictionary(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-dictionary"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -show-alternatives Y/n
        match(ARGV[pos], /^--?show-alternatives(=(.*)?)?$/, group)
        if (RSTART) {
            Option["show-alternatives"] = yn(group[1] ? group[2] : ARGV[++pos])
            continue
        }

        # -w NUM, -width NUM
        match(ARGV[pos], /^--?w(i(d(th?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["width"] = group[4] ?
                (group[5] ? group[5] : Option["width"]) :
                ARGV[++pos]
            continue
        }

        # -indent NUM
        match(ARGV[pos], /^--?indent(=(.*)?)?$/, group)
        if (RSTART) {
            Option["indent"] = group[1] ?
                (group[2] ? group[2] : Option["indent"]) :
                ARGV[++pos]
            continue
        }

        # -theme FILENAME
        match(ARGV[pos], /^--?theme(=(.*)?)?$/, group)
        if (RSTART) {
            Option["theme"] = group[1] ?
                (group[2] ? group[2] : Option["theme"]) :
                ARGV[++pos]
            continue
        }

        # -no-theme
        match(ARGV[pos], /^--?no-theme$/)
        if (RSTART) {
            Option["theme"] = NULLSTR
            continue
        }

        # -no-ansi
        match(ARGV[pos], /^--?no-ansi$/)
        if (RSTART) {
            Option["no-ansi"] = 1
            continue
        }

        ## Audio options

        # -p, -play
        match(ARGV[pos], /^--?p(l(ay?)?)?$/)
        if (RSTART) {
            Option["play"] = 1
            continue
        }

        # -speak
        match(ARGV[pos], /^--?sp(e(ak?)?)?$/)
        if (RSTART) {
            Option["play"] = 2
            continue
        }

        # -player PROGRAM
        match(ARGV[pos], /^--?player(=(.*)?)?$/, group)
        if (RSTART) {
            if (!Option["play"]) Option["play"] = 1 # -play by default
            Option["player"] = group[1] ?
                (group[2] ? group[2] : Option["player"]) :
                ARGV[++pos]
            continue
        }

        # -no-play
        match(ARGV[pos], /^--?no-play$/)
        if (RSTART) {
            Option["play"] = 0
            continue
        }

        ## Terminal paging and browsing options

        # -v, -view
        match(ARGV[pos], /^--?v(i(ew?)?)?$/)
        if (RSTART) {
            Option["view"] = 1
            continue
        }

        # -pager PROGRAM
        match(ARGV[pos], /^--?pager(=(.*)?)?$/, group)
        if (RSTART) {
            Option["view"] = 1
            Option["pager"] = group[1] ?
                (group[2] ? group[2] : Option["pager"]) :
                ARGV[++pos]
            continue
        }

        # -no-view
        match(ARGV[pos], /^--?no-view$/)
        if (RSTART) {
            Option["view"] = 0
            continue
        }

        # -browser PROGRAM
        match(ARGV[pos], /^--?browser(=(.*)?)?$/, group)
        if (RSTART) {
            Option["browser"] = group[1] ?
                (group[2] ? group[2] : Option["browser"]) :
                ARGV[++pos]
            continue
        }

        ## Networking options

        # -x HOST:PORT, -proxy HOST:PORT
        match(ARGV[pos], /^--?(x|proxy)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["proxy"] = group[2] ?
                (group[3] ? group[3] : Option["proxy"]) :
                ARGV[++pos]
            continue
        }

        # -u STRING, -user-agent STRING
        match(ARGV[pos], /^--?(u|user-agent)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["user-agent"] = group[2] ?
                (group[3] ? group[3] : Option["user-agent"]) :
                ARGV[++pos]
            continue
        }

        ## Interactive shell options

        # -I, -interactive, -shell
        match(ARGV[pos], /^--?(I|int(e(r(a(c(t(i(ve?)?)?)?)?)?)?)?|shell)$/)
        if (RSTART) {
            Option["interactive"] = 1
            continue
        }

        # -E, -emacs
        match(ARGV[pos], /^--?(E|emacs)$/)
        if (RSTART) {
            Option["emacs"] = 1
            continue
        }

        # -no-rlwrap
        match(ARGV[pos], /^--?no-rlwrap$/)
        if (RSTART) {
            Option["no-rlwrap"] = 1
            continue
        }

        # FIXME[1.0]: to be removed
        # -prompt PROMPT_STRING
        match(ARGV[pos], /^--?prompt(=(.*)?)?$/, group)
        if (RSTART) {
            w("[ERROR] Option '-prompt' has been deprecated since version 0.9.\n" \
              "        Use configuration variable 'fmt-prompt' instead.")
            exit 1
        }

        # FIXME[1.0]: to be removed
        # -prompt-color COLOR_CODE
        match(ARGV[pos], /^--?prompt-color(=(.*)?)?$/, group)
        if (RSTART) {
            w("[ERROR] Option '-prompt-color' has been deprecated since version 0.9.\n" \
              "        Use configuration variable 'sgr-prompt' instead.")
            exit 1
        }

        ## I/O options

        # -i FILENAME, -input FILENAME
        match(ARGV[pos], /^--?i(n(p(ut?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["input"] = group[4] ?
                (group[5] ? group[5] : Option["input"]) :
                ARGV[++pos]
            continue
        }

        # -o FILENAME, -output FILENAME
        match(ARGV[pos], /^--?o(u(t(p(ut?)?)?)?)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["output"] = group[5] ?
                (group[6] ? group[6] : Option["output"]) :
                ARGV[++pos]
            continue
        }

        ## Language preference options

        # -l CODE, -hl CODE, -lang CODE
        match(ARGV[pos], /^--?(l(a(ng?)?)?|hl)(=(.*)?)?$/, group)
        if (RSTART) {
            Option["hl"] = group[4] ?
                (group[5] ? group[5] : Option["hl"]) :
                ARGV[++pos]
            continue
        }

        # -s CODE, -sl CODE, -source CODE
        match(ARGV[pos], /^--?s(o(u(r(ce?)?)?)?|l)?(=(.*)?)?$/, group)
        if (RSTART) {
            Option["sl"] = group[5] ?
                (group[6] ? group[6] : Option["sl"]) :
                ARGV[++pos]
            continue
        }

        # -t CODES, -tl CODE, -target CODES
        match(ARGV[pos], /^--?t(a(r(g(et?)?)?)?|l)?(=(.*)?)?$/, group)
        if (RSTART) {
            if (group[5]) {
                if (group[6]) split(group[6], Option["tl"], "+")
            } else
                split(ARGV[++pos], Option["tl"], "+")
            continue
        }

        # Shortcut format
        # 'CODE:CODE+...' or 'CODE=CODE+...'
        match(ARGV[pos], /^[{(\[]?([[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?(:|=)((@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?\+)*(@?[[:alpha:]][[:alpha:]][[:alpha:]]?(-[[:alpha:]][[:alpha:]])?)?)[})\]]?$/, group)
        if (RSTART) {
            if (group[1]) Option["sl"] = group[1]
            if (group[4]) split(group[4], Option["tl"], "+")
            continue
        }

        ## Other options

        # -D, -debug
        match(ARGV[pos], /^--?(D|debug)$/)
        if (RSTART) {
            Option["debug"] = 1
            continue
        }

        # -no-init
        match(ARGV[pos], /^--?no-init/)
        if (RSTART) continue # skip

        # -, -no-op
        match(ARGV[pos], /^-(-?no-op)?$/)
        if (RSTART) continue # no operation, skip

        # --
        match(ARGV[pos], /^--$/)
        if (RSTART) {
            ++pos # skip the end-of-options option
            break # no more option from here
        }

        # non-option argument
        noargv[noargc++] = ARGV[pos]
    }

    # Handle interactive shell
    if (Option["interactive"] && !Option["no-rlwrap"])
        rlwrapMe() # interactive mode
    else if (Option["emacs"] && !Option["interactive"] && !Option["no-rlwrap"])
        if (emacsMe()) # emacs front-end
            Option["interactive"] = 1 # fallback to interactive mode

    # Get started

    initMisc()

    # Information-only session
    switch (InfoOnly) {
    case "version":
        print getVersion()
        exit ExitCode
    case "help":
        print getHelp()
        exit ExitCode
    case "manual":
        showMan()
        exit ExitCode
    case "reference":
        print getReference("endonym")
        exit ExitCode
    case "reference-english":
        print getReference("name")
        exit ExitCode
    case "list":
        print getList(Option["tl"])
        exit ExitCode
    case "upgrade":
        upgrade()
        exit ExitCode
    case "nothing":
        exit ExitCode
    }

    # Load theme (overrides command-line options) - slow
    setTheme()

    if (Option["interactive"])
        welcome()

    # More remaining non-option arguments
    if (pos < ARGC)
        for (i = pos; i < ARGC; i++)
            noargv[noargc++] = ARGV[i]

    if (noargc) {
        # Translate all non-option arguments
        for (i = 0; i < noargc; i++) {
            # Verbose mode: separator between sources
            if (Option["verbose"] && i > pos)
                p(prettify("source-seperator", replicate(Option["chr-source-seperator"], Option["width"])))

            translate(noargv[i], 1) # inline mode
        }

        # If input not specified, we're done
    } else {
        # If input not specified, use stdin
        if (!Option["input"]) Option["input"] = STDIN
    }

    # If input specified, start translating
    if (Option["input"])
        translateMain()

    exit ExitCode
}