1# Copyright The Numerical Algorithms Group Limited 1992-94.
2#
3# This awk script is meant to be using in the following way:
4#
5#      awk -f syscmd.awk ug16.htex
6#
7# with, perhaps, appropriate path information added.  This script
8# reads Chapter 16 of the FriCAS User Guide and generates individual
9# ASCII files that describe each of the system commands.  It handles
10# tex macros and flows lines together.  Should ug16.htex get updated,
11# this script should be checked to make sure it is still processing
12# all the tex macros.
13#
14# Author: Robert S. Sutor (IBM Research)
15
16BEGIN   {
17        inFile   = 0
18        fileName = ""
19        secNum = 0
20        chapNum = "A"
21        indent = 0
22        seenUnind = 1
23        inDescriptionItem = 0
24        flow = 1
25        flowBuffer = ""
26        lastLineWasBlank = 0
27        debug = 0
28        debugIndent = ""
29        screenWidth = 78
30}
31
32# lines to discard
33/^%/ || /^\\syscmdindex/ || /^\\index/ || /^\\head{chapter}{/     {
34        next
35}
36
37/^\\head{section}{/     {
38        flushFlowBuffer()
39        line   = substr($0,16)
40        syscmd = substr(line,1,index(line,"}")-1)
41        startFile(syscmd)
42        next
43}
44
45(inFile == 0)           {
46        next
47}
48
49/^\\begin{enumerate}/ || /^\\begin{itemize}/  || /^\\begin{description}/ || /^\\begin{simpleList}/ {
50        flushFlowBuffer()
51        ind +=2
52        printBlankLine()
53        next
54}
55
56/^\\end{enumerate}/ || /^\\end{itemize}/ || /^\\end{simpleList}/ {
57        flushFlowBuffer()
58        ind -=2
59        printBlankLine()
60        next
61}
62
63/^\\begin{center}/   {
64# assume each line is to be centered
65        flushFlowBuffer()
66        printBlankLine()
67        getline
68        while ($1 != "\\end{center}") {
69          gsub(/\\\\/,"")
70          $0 = cleanLine($0)
71          l = length($0)
72          if (l >= screenWidth)
73            print $0 > fileName
74          else {
75            for (i = 0; i < (screenWidth - l) / 2; i++)
76              printf(" ") > fileName
77            print $0 > fileName
78          }
79          lastLineWasBlank = 0
80          getline
81        }
82        printBlankLine()
83        next
84}
85
86/^\\end{description}/   {
87        flushFlowBuffer()
88        ind -=2
89        if (inDescriptionItem) {
90          inDescriptionItem = 0
91          ind -=2
92        }
93        printBlankLine()
94        next
95}
96
97/^\\beginmenu/          {
98        flushFlowBuffer()
99        ind +=2
100        next
101}
102
103/^\\endmenu/          {
104        flushFlowBuffer()
105        ind -=2
106        next
107}
108
109/^\\beginImportant/ || /^\\endImportant/        {
110        flushFlowBuffer()
111        print "------------------------------------------------------------------------------" > fileName
112        next
113}
114
115/^\\par\\noindent{\\bf / {
116        flushFlowBuffer()
117        line = substr($0,19)
118        gsub(/}/," ",line)
119        printIndented(line)
120        next
121}
122
123/^\\begin{verbatim}/ {
124        flushFlowBuffer()
125        flow = 0
126        printBlankLine()
127        next
128}
129
130/^\\end{verbatim}/        {
131        flow = 1
132        printBlankLine()
133        next
134}
135
136/^\\item\\menuitemstyle{/       {
137        flushFlowBuffer()
138        line = substr($0,21)
139        gsub(/}/," ",line)
140        printIndented("o "line)
141        next
142}
143
144/^\\item\[/     { # description item
145        flushFlowBuffer()
146        if (inDescriptionItem) {
147          ind -=2
148        }
149        inDescriptionItem = 1
150        gsub(/\\item\[/,"")
151        gsub(/\]/,"")
152        printIndented(cleanLine($0))
153        ind +=2
154        next
155}
156
157/^\\item/       {
158        flushFlowBuffer()
159        printIndented("- "substr(cleanLine($0),6))
160        next
161}
162
163/^\\ind/        {
164        flushFlowBuffer()
165        if (seenUnind) {
166          ind +=2
167          seenUnind = 0
168        }
169        gsub(/\\ind/,"")
170        # now fall through
171}
172
173/^\\menuspadref{/ {
174        flushFlowBuffer()
175        $0 = extractArg($0,1)
176        printIndented("o "cleanLine($0))
177        next
178}
179
180/^\\titledspadref{/ {
181        flushFlowBuffer()
182        $0 = extractArg($0,1)
183        printIndented("o "cleanLine($0))
184        next
185}
186
187# a blank line
188($1 == "") {
189        if (! lastNameWasBlank) {
190                if (flow)
191                        flushFlowBuffer()
192                printBlankLine()
193        }
194}
195
196# a regular line
197        {
198        ui = index($0,"\\unind")
199        if (ui) {
200          gsub(/\\unind/,"")
201          seenUnind = 1
202        }
203        if (flow) {
204          if (flowBuffer == "")
205                flowBuffer = $0
206          else
207                flowBuffer = flowBuffer " " $0
208        }
209        else
210           printIndented($0)
211        if (ui) {
212          flushFlowBuffer()
213          ind -=2
214        }
215}
216
217END     {
218        flushFlowBuffer()
219        if (inFile) {
220          close(fileName)
221        }
222        system("cat Introduction.help >> help.help")
223        system("rm Introduction.help")
224}
225
226# -- functions -----------------------------------------------------------
227
228function startFile(syscmd)        {
229        if (inFile) {
230          close(fileName)
231        }
232
233        print "Processing " syscmd
234
235        if (substr(syscmd,1,1) == ")")
236                fileName = substr(syscmd,2)".help"
237        else
238                fileName = syscmd".help"
239        inFile = 1
240        ++secNum
241
242        print "====================================================================" > fileName
243        printf("%s.%s.  %s\n",chapNum,secNum,syscmd) > fileName
244        print "====================================================================" > fileName
245        print " " > fileName
246}
247
248function printIndented(s,    i)  {
249        lastLineWasBlank = 0
250        for (i = 0; i < ind; i += 2)
251                printf("  ") > fileName
252        print s > fileName
253}
254
255function cleanLine(line,     p,pref,n,a,p2,pref2,n2,a2) {
256debugEnter("cleanLine")
257
258        gsub(/\\tt /,"",line)
259        gsub(/\\it /,"",line)
260
261        # first handle some macros
262
263        p = index(line,"\\texht")
264        while (p > 0) {
265          pref = (p == 1) ? ""  : substr(line,1,p-1)
266          line = substr(line,p)
267          n = endMacroIndex(line,2)
268          a = extractArg(line,2)
269          # Transform "\lispmemolink{X}{Y}" to "[X]".
270          p2 = index(a,"\\lispmemolink")
271          if (p2 > 0) {
272            pref2 = (p2 == 1) ? ""  : substr(a,1,p2-1)
273            a = substr(a,p2)
274            n2 = endMacroIndex(a,2)
275            a2 = "[" extractArg(a,1) "]"
276            a = a2 " " substr(a,n2+1)
277            if (p2 != 1)
278              a = pref2 " " a
279          }
280          line = a " " substr(line,n+1)
281          if (p != 1)
282            line = pref " " line
283          p = index(line,"\\texht")
284        }
285        p = index(line,"\\spadref")
286        while (p > 0) {
287          pref = (p == 1) ? ""  : substr(line,1,p-1)
288          line = substr(line,p)
289          n = endMacroIndex(line,1)
290          a = extractArg(line,1)
291          if ("ugSysCmd" == substr(a,1,8))
292            a = "description of command )" substr(a,9)
293          else
294            a = "the FriCAS User Guide index"
295          line = a " " substr(line,n+1)
296          if (p != 1)
297            line = pref " " line
298          p = index(line,"\\spadref")
299        }
300        p = index(line,"\\spadgloss")
301        while (p > 0) {
302          pref = (p == 1) ? ""  : substr(line,1,p-1)
303          line = substr(line,p)
304          n = endMacroIndex(line,1)
305          a = extractArg(line,1)
306          line = a " " substr(line,n+1)
307          if (p != 1)
308            line = pref " " line
309          p = index(line,"\\spadgloss")
310        }
311        p = index(line,"\\footnote")
312        while (p > 0) {
313          pref = (p == 1) ? ""  : substr(line,1,p-1)
314          line = substr(line,p)
315          n = endMacroIndex(line,1)
316          a = extractArg(line,1)
317          line = "(" a ") " substr(line,n+1)
318          if (p != 1)
319            line = pref " " line
320          p = index(line,"\\footnote")
321        }
322        p = index(line,"\\eth")
323        while (p > 0) {
324          pref = (p == 1) ? ""  : substr(line,1,p-1)
325          line = substr(line,p)
326          n = endMacroIndex(line,1)
327          a = extractArg(line,1)
328          line = a"th" substr(line,n+1)
329          if (p != 1)
330            line = pref " " line
331          p = index(line,"\\eth")
332        }
333        p = index(line,"\\lispwindowlink")
334        while (p > 0) {
335          pref = (p == 1) ? ""  : substr(line,1,p-1)
336          line = substr(line,p)
337          n = endMacroIndex(line,2)
338          a = extractArg(line,1)
339          line = "[" a "] " substr(line,n+1)
340          if (p != 1)
341            line = pref " " line
342          p = index(line,"\\lispwindowlink")
343        }
344
345        # now do some global substitutions
346
347        gsub(/\\%/,"%",line)
348        gsub(/\\_/,"_",line)
349        gsub(/\\\$/,"$",line)
350        gsub(/\\Language/,"FriCAS",line)
351        gsub(/\\HyperName/,"HyperDoc",line)
352        gsub(/\\aldor/,"Aldor",line)
353        gsub(/\\Browse/,"Browse",line)
354        gsub(/\\lanb/,"[",line)
355        gsub(/\\ranb/,"]",line)
356        gsub(/\\vertline/,"|",line)
357        gsub(/\{\\tt /,"",line)
358        gsub(/\{\\it /,"",line)
359        gsub(/\{\\it/,"",line)
360        gsub(/\{\\bf /,"",line)
361        gsub(/\{\\sf /,"",line)
362        gsub(/\\Lisp\{/,"Lisp",line)
363        gsub(/\\noindent /,"",line)
364        gsub(/\\noindent/,"",line)
365        gsub(/\\spad\{/,"",line)
366        gsub(/\\smath\{/,"",line)
367        gsub(/\\spadsys/,"",line)
368        gsub(/\\spadSyntax/,"",line)
369        gsub(/\\spadtype/,"",line)
370        gsub(/\\userfun/,"",line)
371        gsub(/\\spadfun/,"",line)
372        gsub(/\{/,"",line)
373        gsub(/\}/,"",line)
374
375debugExit("cleanLine","%s",line)
376        return line
377}
378
379function debugEnter(name) {
380        if (debug) {
381          printf("%sEntering  %s\n",debugIndent,name)
382          debugIndent = debugIndent "  "
383        }
384}
385
386function debugExit(name,format,retval) {
387        if (debug) {
388          debugIndent = substr(debugIndent,3)
389          if (format != "") {
390            printf("%sExiting:  %s ("format")\n",debugIndent,name,retval)
391          }
392          else
393            printf("%sExiting:  %s\n",debugIndent,name)
394        }
395}
396
397function endMacroIndex(line,parms,    pp,x,bc,cc) {
398# assumes start of line is a macro call and returns position of final "}"
399debugEnter("endMacroIndex")
400        x = 0
401        pp = index(line,"{")
402        if (pp != 0) {
403          bc = 1
404          for (x = pp+1; ; x++) {
405            cc = substr(line,x,1)
406            if (cc == "{")
407              bc++
408            else if (cc == "}") {
409              bc--
410              if (bc == 0) {
411                parms--
412                if (parms == 0)
413                  break
414              }
415            }
416          }
417        }
418debugExit("endMacroIndex","%d",x)
419        return x
420}
421
422function extractArg(line,num,   p,arg) {
423# assumes line is a macro call and extracts the num-th arg
424debugEnter("extractArg")
425        arg = ""
426        p = index(line,"{")
427        if (p != 0) {
428          line = substr(line,p)
429
430          if (num > 1) {
431            p = endMacroIndex(line,num-1)
432            line = substr(line,p+1)
433          }
434          p = endMacroIndex(line,1)
435          arg = substr(line,2,p-2)
436        }
437debugExit("extractArg","%s",arg)
438        return arg
439}
440
441function printBlankLine() {
442        if (lastLineWasBlank == 0) {
443          print " " > fileName
444          lastLineWasBlank = 1
445        }
446}
447
448function flushFlowBuffer(   ii) {
449debugEnter("flushFlowBuffer")
450        if (inFile && (flowBuffer != "")) {
451                flowBuffer = cleanLine(flowBuffer)
452                gsub(/  /," ",flowBuffer)
453                while (ind + length(flowBuffer) > screenWidth ) {
454                  for (ii = screenWidth - ind; ii > 0; ii--) {
455                    if (substr(flowBuffer,ii,1) == " ")
456                      break;
457                  }
458                  if (ii == 0)
459                    break;
460                  printIndented(substr(flowBuffer,1,ii-1))
461                  flowBuffer = substr(flowBuffer,ii+1)
462                }
463                if (flowBuffer != "")
464                  printIndented(flowBuffer)
465                flowBuffer = ""
466        }
467debugExit("flushFlowBuffer")
468}
469