# # menu.icn # copyright 1992 Ronald Florence # @(#) version 1.1 (ron@mlfarm.com, 12 May 1992) # # See xmenu.icn for the X-Windows/X-Icon version. # # configuration: # indexfile := full path of index file # data_dir := recipe directory # pager := optional external pager (instead of built-in pager) # Print_cmd := pretty-printer and/or spooler (for OS with pipes) # regexparser := (ms-dos only) findre ReFind # for ms-dos, use: link iolib, findre link iolib, regexp link iolib global Pipes, Print_cmd procedure main(arg) local indexfile, data_dir, pager, zcat, hits, online, keys, pchar, egrep, meta_keys, egrep_cmd, k, index, m, found, search, putout, out, recipe, rpath, rf, regexparser # configuration indexfile := getenv("INDEXFILE") | "%INDEXFILE%" data_dir := getenv("RECIPEDIR") | "%DATADIR%" pager := getenv("PAGER") | "%PAGER%" Print_cmd := "%PRINTCMD%" regexparser := # end of configuration (*arg > 0) | stop("usage: menu keyword [regexp,...]") close(open(indexfile)) | stop("can't read index") hits := [] online := [] keys := [] pchar := &ascii[32:127] Pipes := "pipes" == &features # If we have pipes and egrep (Unix), # separate the keywords into those with # metacharacters and those without. If # there are none with metacharacters, pop # one off the non-meta list to use with # an egrep search. if \Pipes & close(open("/bin/" | "/usr/bin/" | "/usr/ucb/" || "egrep")) then { meta_keys := [] egrep_cmd := "cat " || indexfile regexparser := find every k := !arg do put(if metas(k) then meta_keys else keys, map(k)) \meta_keys[1] | put(meta_keys, pop(keys)) every k := !meta_keys do egrep_cmd ||:= " | egrep -i '" || k || "'" index := open(egrep_cmd || " 2>&1", "rp") } # Without pipes and egrep use findre # or ReFind for the regular expression # search. S-l-o-w. else { index := open(indexfile) every put(keys, map(!arg)) } # The search is a generator, breaking # when the find or regexparser fails. We # then put online recipes in one list # and the reference recipes in another. every !index ? { \egrep_cmd & find("error"|"grep") & stop("search expression error") m := map(&subject) found := 1 every k := !keys do { search := if /egrep & metas(k) then regexparser else find search(k, m) | break found := &null } \found & { put(if ="Comp-" then online else hits, left(tab(many(pchar)), 20) || (tab(upto(pchar)), tab(many(pchar)))) tab(0) } } *hits + *online = 0 & stop("No matching recipes.") \hits[1] & more("RECIPES", hits) \online[1] & repeat { more("ON-LINE RECIPES", online) writes("\nEnter recipe numbers(s): ") read() ? { (*&subject = 0) | upto('qQ') & exit(1) # Print code for the built-in pager. putout := if upto('pP') then print else more while tab(upto(&digits)) do { out := [] recipe := tab(many(&digits)) rpath := data_dir || recipe if close(open(rpath)) then { if *pager > 0 then system(pager || " " || rpath) # Put the recipe in a list, so more # will know how big it is. else rf := open(rpath) & every put(out, !rf) } else if \Pipes then { rpath ||:= ".Z" if *pager > 0 then system("zcat " || rpath || " | " || pager) else { rf := open("zcat " || rpath, "rp") every put(out, !rf) close(rf) } | write("Can't find " || rpath) } \out[1] & putout("RECIPE " || recipe, out, "End of Recipe " || recipe) } } } end procedure print(recipe, head) local prn, rp, mode if \Print_cmd & \Pipes then { Print_cmd ? { prn := (\tab(find("%s")) || head) | tab(0) move(2) & prn ||:= tab(0) } mode := "wp" } else if not "MS-DOS" == &features then return write("Sorry, not configured to print.") else { mode := "w" prn := "PRN" } rp := open(prn, "wp") every write(rp, !recipe) return close(rp) end # Procedured modified from R.Goerwitz # to detect whether a keyword contains # meta-characters, e.g., whether we # need a regular expression search. procedure metas(str) str ? { tab(many('*+?|')) while tab(upto('\\*+()|?.$^[')) do { if ="\\" then move(1) | stop("badly-formed search string") else return .&pos } } fail end # This is kluged to not clear the # screen or show the percentage # after -MORE- for the lists of recipes. procedure more(header, what, footer) static lines local ans initial { writes(getval("cl")) lines := 0 } /footer | { writes(getval("cl")) lines := 0 } \header & { write(getval("md"|"so") || header || ":" || getval("me"|"se")) lines +:= 1 } every !what ? { write(tab(0)) ((lines +:= 1 + *&subject/getval("co")) % (getval("li") - 1) = 0) & { writes(getval("so") || "-MORE-") \footer & writes("(", (100 > (lines - 2)*100/*what) | 100, "%)") writes(getval("se")) ans := read() & writes(getval("up") || getval("ce")) upto('nNqQ', ans) & fail } } \footer & { writes(getval("so") || footer || getval("se")) read() & writes(getval("up") || getval("ce")) } end