1####################################################################
2# Help.awk                                                         #
3####################################################################
4
5# Return version as a string.
6function getVersion(    build, gitHead) {
7    initAudioPlayer()
8    initPager()
9    Platform = Platform ? Platform : detectProgram("uname", "-s", 1)
10    if (ENVIRON["TRANS_BUILD"])
11        build = "-" ENVIRON["TRANS_BUILD"]
12    else {
13        gitHead = getGitHead()
14        build = gitHead ? "-git:" gitHead : ""
15    }
16
17    return ansi("bold", sprintf("%-22s%s%s\n\n", Name, Version, build)) \
18        sprintf("%-22s%s\n", "platform", Platform)                      \
19        sprintf("%-22s%s\n", "terminal type", ENVIRON["TERM"])          \
20        sprintf("%-22s%s\n", "bi-di emulator", BiDiTerm ? BiDiTerm :
21                "[N/A]")                                                \
22        sprintf("%-22s%s\n", "gawk (GNU Awk)", PROCINFO["version"])     \
23        sprintf("%s\n", FriBidi ? FriBidi :
24                "fribidi (GNU FriBidi) [NOT INSTALLED]")                \
25        sprintf("%-22s%s\n", "audio player", AudioPlayer ? AudioPlayer :
26                "[NOT INSTALLED]")                                      \
27        sprintf("%-22s%s\n", "terminal pager", Pager ? Pager :
28                "[NOT INSTALLED]")                                      \
29        sprintf("%-22s%s\n", "web browser", Option["browser"] != NONE ?
30                Option["browser"] :"[NONE]")                            \
31        sprintf("%-22s%s (%s)\n", "user locale", UserLocale, getName(UserLang)) \
32        sprintf("%-22s%s\n", "home language", Option["hl"])             \
33        sprintf("%-22s%s\n", "source language", join(Option["sls"], "+")) \
34        sprintf("%-22s%s\n", "target language", join(Option["tl"], "+")) \
35        sprintf("%-22s%s\n", "translation engine", Option["engine"])    \
36        sprintf("%-22s%s\n", "proxy", Option["proxy"] ? Option["proxy"] :
37                "[NONE]")                                               \
38        sprintf("%-22s%s\n", "user-agent", Option["user-agent"] ? Option["user-agent"] :
39                "[NONE]")                                               \
40        sprintf("%-22s%s\n", "ip version", Option["ip-version"] ? Option["ip-version"] :
41                "[DEFAULT]")                                            \
42        sprintf("%-22s%s\n", "theme", Option["theme"])                  \
43        sprintf("%-22s%s\n", "init file", InitScript ? InitScript : "[NONE]") \
44        sprintf("\n%-22s%s", "Report bugs to:", "https://github.com/soimort/translate-shell/issues")
45}
46
47# Return help message as a string.
48function getHelp() {
49    return "Usage:  " ansi("bold", Command)                             \
50        " [" ansi("underline", "OPTIONS") "]"                           \
51        " [" ansi("underline", "SOURCES") "]"                           \
52        ":[" ansi("underline", "TARGETS") "]"                           \
53        " [" ansi("underline", "TEXT") "]..." RS                        \
54        RS "Information options:" RS                                    \
55        ins(1, ansi("bold", "-V") ", " ansi("bold", "-version")) RS     \
56        ins(2, "Print version and exit.") RS                            \
57        ins(1, ansi("bold", "-H") ", " ansi("bold", "-help")) RS        \
58        ins(2, "Print help message and exit.") RS                       \
59        ins(1, ansi("bold", "-M") ", " ansi("bold", "-man")) RS         \
60        ins(2, "Show man page and exit.") RS                            \
61        ins(1, ansi("bold", "-T") ", " ansi("bold", "-reference")) RS   \
62        ins(2, "Print reference table of languages and exit.") RS       \
63        ins(1, ansi("bold", "-R") ", " ansi("bold", "-reference-english")) RS \
64        ins(2, "Print reference table of languages (in English names) and exit.") RS \
65        ins(1, ansi("bold", "-L ") ansi("underline", "CODES")           \
66            ", " ansi("bold", "-list ") ansi("underline", "CODES")) RS  \
67        ins(2, "Print details of languages and exit.") RS               \
68        ins(1, ansi("bold", "-S") ", " ansi("bold", "-list-engines")) RS \
69        ins(2, "List available translation engines and exit.") RS       \
70        ins(1, ansi("bold", "-U") ", " ansi("bold", "-upgrade")) RS     \
71        ins(2, "Check for upgrade of this program.") RS                 \
72        RS "Translator options:" RS                                     \
73        ins(1, ansi("bold", "-e ") ansi("underline", "ENGINE")          \
74            ", " ansi("bold", "-engine ") ansi("underline", "ENGINE")) RS \
75        ins(2, "Specify the translation engine to use.") RS             \
76        RS "Display options:" RS                                        \
77        ins(1, ansi("bold", "-verbose")) RS                             \
78        ins(2, "Verbose mode. (default)") RS                            \
79        ins(1, ansi("bold", "-b") ", " ansi("bold", "-brief")) RS       \
80        ins(2, "Brief mode.") RS                                        \
81        ins(1, ansi("bold", "-d") ", " ansi("bold", "-dictionary")) RS  \
82        ins(2, "Dictionary mode.") RS                                   \
83        ins(1, ansi("bold", "-identify")) RS                            \
84        ins(2, "Language identification.") RS                           \
85        ins(1, ansi("bold", "-show-original ") ansi("underline", "Y/n")) RS \
86        ins(2, "Show original text or not.") RS                         \
87        ins(1, ansi("bold", "-show-original-phonetics ") ansi("underline", "Y/n")) RS \
88        ins(2, "Show phonetic notation of original text or not.") RS    \
89        ins(1, ansi("bold", "-show-translation ") ansi("underline", "Y/n")) RS \
90        ins(2, "Show translation or not.") RS                           \
91        ins(1, ansi("bold", "-show-translation-phonetics ") ansi("underline", "Y/n")) RS \
92        ins(2, "Show phonetic notation of translation or not.") RS      \
93        ins(1, ansi("bold", "-show-prompt-message ") ansi("underline", "Y/n")) RS \
94        ins(2, "Show prompt message or not.") RS                        \
95        ins(1, ansi("bold", "-show-languages ") ansi("underline", "Y/n")) RS \
96        ins(2, "Show source and target languages or not.") RS           \
97        ins(1, ansi("bold", "-show-original-dictionary ") ansi("underline", "y/N")) RS \
98        ins(2, "Show dictionary entry of original text or not.") RS     \
99        ins(1, ansi("bold", "-show-dictionary ") ansi("underline", "Y/n")) RS \
100        ins(2, "Show dictionary entry of translation or not.") RS       \
101        ins(1, ansi("bold", "-show-alternatives ") ansi("underline", "Y/n")) RS \
102        ins(2, "Show alternative translations or not.") RS              \
103        ins(1, ansi("bold", "-w ") ansi("underline", "NUM")             \
104            ", " ansi("bold", "-width ") ansi("underline", "NUM")) RS   \
105        ins(2, "Specify the screen width for padding.") RS              \
106        ins(1, ansi("bold", "-indent ") ansi("underline", "NUM")) RS    \
107        ins(2, "Specify the size of indent (number of spaces).") RS     \
108        ins(1, ansi("bold", "-theme ") ansi("underline", "FILENAME")) RS \
109        ins(2, "Specify the theme to use.") RS                          \
110        ins(1, ansi("bold", "-no-theme")) RS                            \
111        ins(2, "Do not use any other theme than default.") RS           \
112        ins(1, ansi("bold", "-no-ansi")) RS                             \
113        ins(2, "Do not use ANSI escape codes.") RS                      \
114        ins(1, ansi("bold", "-no-autocorrect")) RS                      \
115        ins(2, "Do not autocorrect. (if defaulted by the translation engine)") RS \
116        ins(1, ansi("bold", "-no-bidi")) RS                             \
117        ins(2, "Do not convert bidirectional texts.") RS                \
118        ins(1, ansi("bold", "-bidi")) RS                                \
119        ins(2, "Always convert bidirectional texts.") RS                \
120        ins(1, ansi("bold", "-no-warn")) RS                             \
121        ins(2, "Do not write warning messages to stderr.") RS           \
122        ins(1, ansi("bold", "-dump")) RS                                \
123        ins(2, "Print raw API response instead.") RS                    \
124        RS "Audio options:" RS                                          \
125        ins(1, ansi("bold", "-p, -play")) RS                            \
126        ins(2, "Listen to the translation.") RS                         \
127        ins(1, ansi("bold", "-speak")) RS                               \
128        ins(2, "Listen to the original text.") RS                       \
129        ins(1, ansi("bold", "-n ") ansi("underline", "VOICE")           \
130            ", " ansi("bold", "-narrator ") ansi("underline", "VOICE")) RS \
131        ins(2, "Specify the narrator, and listen to the translation.") RS \
132        ins(1, ansi("bold", "-player ") ansi("underline", "PROGRAM")) RS \
133        ins(2, "Specify the audio player to use, and listen to the translation.") RS \
134        ins(1, ansi("bold", "-no-play")) RS                             \
135        ins(2, "Do not listen to the translation.") RS                  \
136        ins(1, ansi("bold", "-no-translate")) RS                        \
137        ins(2, "Do not translate anything when using -speak.") RS       \
138        ins(1, ansi("bold", "-download-audio")) RS                      \
139        ins(2, "Download the audio to the current directory.") RS       \
140        ins(1, ansi("bold", "-download-audio-as ") ansi("underline", "FILENAME")) RS \
141        ins(2, "Download the audio to the specified file.") RS          \
142        RS "Terminal paging and browsing options:" RS                   \
143        ins(1, ansi("bold", "-v") ", " ansi("bold", "-view")) RS        \
144        ins(2, "View the translation in a terminal pager.") RS          \
145        ins(1, ansi("bold", "-pager ") ansi("underline", "PROGRAM")) RS \
146        ins(2, "Specify the terminal pager to use, and view the translation.") RS \
147        ins(1, ansi("bold", "-no-view") ", " ansi("bold", "-no-pager")) RS \
148        ins(2, "Do not view the translation in a terminal pager.") RS   \
149        ins(1, ansi("bold", "-browser ") ansi("underline", "PROGRAM")) RS \
150        ins(2, "Specify the web browser to use.") RS                    \
151        ins(1, ansi("bold", "-no-browser")) RS                          \
152        ins(2, "Do not open the web browser.") RS                       \
153        RS "Networking options:" RS                                     \
154        ins(1, ansi("bold", "-x ") ansi("underline", "HOST:PORT")       \
155            ", " ansi("bold", "-proxy ") ansi("underline", "HOST:PORT")) RS \
156        ins(2, "Use HTTP proxy on given port.") RS                      \
157        ins(1, ansi("bold", "-u ") ansi("underline", "STRING")          \
158            ", " ansi("bold", "-user-agent ") ansi("underline", "STRING")) RS \
159        ins(2, "Specify the User-Agent to identify as.") RS             \
160        ins(1, ansi("bold", "-4") ", " ansi("bold", "-ipv4")            \
161            ", " ansi("bold", "-inet4-only")) RS                        \
162        ins(2, "Connect only to IPv4 addresses.") RS                    \
163        ins(1, ansi("bold", "-6") ", " ansi("bold", "-ipv6")            \
164            ", " ansi("bold", "-inet6-only")) RS                        \
165        ins(2, "Connect only to IPv6 addresses.") RS                    \
166        RS "Interactive shell options:" RS                              \
167        ins(1, ansi("bold", "-I") ", " ansi("bold", "-interactive") ", " ansi("bold", "-shell")) RS \
168        ins(2, "Start an interactive shell.") RS                        \
169        ins(1, ansi("bold", "-E") ", " ansi("bold", "-emacs")) RS       \
170        ins(2, "Start the GNU Emacs front-end for an interactive shell.") RS \
171        ins(1, ansi("bold", "-no-rlwrap")) RS                           \
172        ins(2, "Do not invoke rlwrap when starting an interactive shell.") RS \
173        RS "I/O options:" RS                                            \
174        ins(1, ansi("bold", "-i ") ansi("underline", "FILENAME")        \
175            ", " ansi("bold", "-input ") ansi("underline", "FILENAME")) RS \
176        ins(2, "Specify the input file.") RS                            \
177        ins(1, ansi("bold", "-o ") ansi("underline", "FILENAME")        \
178            ", " ansi("bold", "-output ") ansi("underline", "FILENAME")) RS \
179        ins(2, "Specify the output file.") RS                           \
180        RS "Language preference options:" RS                            \
181        ins(1, ansi("bold", "-l ") ansi("underline", "CODE")            \
182            ", " ansi("bold", "-hl ") ansi("underline", "CODE")         \
183            ", " ansi("bold", "-lang ") ansi("underline", "CODE")) RS   \
184        ins(2, "Specify your home language.") RS                        \
185        ins(1, ansi("bold", "-s ") ansi("underline", "CODES")           \
186            ", " ansi("bold", "-sl ") ansi("underline", "CODES")        \
187            ", " ansi("bold", "-source ") ansi("underline", "CODES")    \
188            ", " ansi("bold", "-from ") ansi("underline", "CODES")) RS  \
189        ins(2, "Specify the source language(s), joined by '+'.") RS     \
190        ins(1, ansi("bold", "-t ") ansi("underline", "CODES")           \
191            ", " ansi("bold", "-tl ") ansi("underline", "CODES")        \
192            ", " ansi("bold", "-target ") ansi("underline", "CODES")    \
193            ", " ansi("bold", "-to ") ansi("underline", "CODES")) RS    \
194        ins(2, "Specify the target language(s), joined by '+'.") RS     \
195        RS "Text preprocessing options:" RS                             \
196        ins(1, ansi("bold", "-j") ", " ansi("bold", "-join-sentence")) RS \
197        ins(2, "Treat all arguments as one single sentence.") RS        \
198        RS "Other options:" RS                                          \
199        ins(1, ansi("bold", "-no-init")) RS                             \
200        ins(2, "Do not load any initialization script.") RS             \
201        RS "See the man page " Command "(1) for more information."
202}
203
204# Show man page.
205function showMan(    temp) {
206    if (ENVIRON["TRANS_MANPAGE"]) {
207        initPager()
208        Groff = detectProgram("groff", "--version")
209        if (Pager && Groff) {
210            temp = "echo -E \"${TRANS_MANPAGE}\""
211            temp = temp PIPE                                            \
212                Groff " -Wall -mtty-char -mandoc -Tutf8 "               \
213                "-rLL=" Option["width"] "n -rLT=" Option["width"] "n"
214            switch (Pager) {
215            case "less":
216                temp = temp PIPE                                        \
217                    Pager " -s -P\"\\ \\Manual page " Command "(1) line %lt (press h for help or q to quit)\""
218                break
219            case "most":
220                temp = temp PIPE Pager " -Cs"
221                break
222            default: # more
223                temp = temp PIPE Pager
224            }
225            system(temp)
226            return
227        }
228    }
229    if (fileExists(ENVIRON["TRANS_DIR"] "/man/" Command ".1"))
230        system("man " parameterize(ENVIRON["TRANS_DIR"] "/man/" Command ".1") SUPERR)
231    else if (system("man " Command SUPERR))
232        print getHelp()
233}
234
235# Return a reference table of languages as a string.
236# Parameters:
237#     displayName = "endonym" or "name"
238function getReference(displayName,
239                      ####
240                      code, col, cols, i, j, name, num, r, rows, saveSortedIn,
241                      t1, t2) {
242    # number of language codes with stable support
243    num = 0
244    for (code in Locale)
245        if (Locale[code]["support"] != "unstable")
246            num++
247    rows = int(num / 3) + (num % 3 ? 1 : 0)
248    cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR
249    i = 0
250    saveSortedIn = PROCINFO["sorted_in"]
251    PROCINFO["sorted_in"] = displayName == "endonym" ? "@ind_num_asc" :
252        "compName"
253    for (code in Locale) {
254        # show languages only with stable support
255        if (Locale[code]["support"] != "unstable") {
256            col = int(i / rows)
257            append(cols[col], code)
258            i++
259        }
260    }
261    PROCINFO["sorted_in"] = saveSortedIn
262
263    if (displayName == "endonym") {
264        r = "┌" replicate("─", 23) "┬" replicate("─", 23) "┬" replicate("─", 23) "┐" RS
265        for (i = 0; i < rows; i++) {
266            r = r "│"
267            for (j = 0; j < 3; j++) {
268                if (cols[j][i]) {
269                    t1 = getDisplay(cols[j][i])
270                    switch (cols[j][i]) { # fix rendered text width
271                    case "he":
272                        t1 = sprintf(" %-18s", t1)
273                        break
274                    case "ur":
275                        t1 = sprintf(" %-17s", t1)
276                        break
277                    case "hi": case "gu": case "km": case "kn":
278                    case "my": case "ne": case "pa": case "si":
279                    case "ta": case "te": case "yi":
280                        t1 = sprintf(" %-16s", t1)
281                        break
282                    case "yue":
283                        t1 = sprintf(" %-13s", t1)
284                        break
285                    case "ja": case "ko":
286                        t1 = sprintf(" %-12s", t1)
287                        break
288                    case "zh-CN": case "zh-TW":
289                        t1 = sprintf(" %-11s", t1)
290                        break
291                    default:
292                        if (length(t1) <= 15)
293                            t1 = sprintf(" %-15s", t1)
294                    }
295                    switch (length(cols[j][i])) {
296                    case 1: case 2: case 3: case 4:
297                        t2 = sprintf("- %s │", ansi("bold", sprintf("%4s", cols[j][i])))
298                        break
299                    case 5:
300                        t2 = sprintf("- %s│", ansi("bold", cols[j][i]))
301                        break
302                    case 6:
303                        t2 = sprintf("-%s│", ansi("bold", cols[j][i]))
304                        break
305                    case 7:
306                        t2 = sprintf("-%s", ansi("bold", cols[j][i]))
307                        break
308                    default:
309                        t2 = ansi("bold", cols[j][i])
310                    }
311                    r = r t1 t2
312                } else
313                    r = r sprintf("%23s│", NULLSTR)
314            }
315            r = r RS
316        }
317        r = r "└" replicate("─", 23) "┴" replicate("─", 23) "┴" replicate("─", 23) "┘"
318    } else {
319        r = "┌" replicate("─", 23) "┬" replicate("─", 23) "┬" replicate("─", 23) "┐" RS
320        for (i = 0; i < rows; i++) {
321            r = r "│"
322            for (j = 0; j < 3; j++) {
323                if (cols[j][i]) {
324                    t1 = getName(cols[j][i])
325                    if (length(t1) > 15)
326                        t1 = substr(t1, 1, 12) "..."
327                    t1 = sprintf(" %-15s", t1)
328                    switch (length(cols[j][i])) {
329                    case 1: case 2: case 3: case 4:
330                        t2 = sprintf("- %s │", ansi("bold", sprintf("%4s", cols[j][i])))
331                        break
332                    case 5:
333                        t2 = sprintf("- %s│", ansi("bold", cols[j][i]))
334                        break
335                    case 6:
336                        t2 = sprintf("-%s│", ansi("bold", cols[j][i]))
337                        break
338                    case 7:
339                        t2 = sprintf("-%s", ansi("bold", cols[j][i]))
340                        break
341                    default:
342                        t2 = ansi("bold", cols[j][i])
343                    }
344                    r = r t1 t2
345                } else
346                    r = r sprintf("%23s│", NULLSTR)
347            }
348            r = r RS
349        }
350        r = r "└" replicate("─", 23) "┴" replicate("─", 23) "┴" replicate("─", 23) "┘"
351    }
352    return r
353}
354
355# Return detailed information of languages as a string.
356function getList(codes,    code, i, r, saveSortedIn) {
357    r = NULLSTR
358    if (!isarray(codes))
359        r = getDetails(codes)
360    else if (anything(codes)) {
361        saveSortedIn = PROCINFO["sorted_in"]
362        PROCINFO["sorted_in"] = "@ind_num_asc"
363        for (i in codes)
364            r = (r ? r RS prettify("target-seperator", replicate(Option["chr-target-seperator"], Option["width"])) RS \
365                 : r) getDetails(codes[i])
366        PROCINFO["sorted_in"] = saveSortedIn
367    } else
368        r = getDetails(Option["hl"])
369    return r
370}
371