############################################################################ # # Name: 1.20 # # Title: utilities for displaying passages # # Author: Richard L. Goerwitz # # Version: passutil.icn # ############################################################################ # # Contains: # # display_passage(ref), which displays ref, but fails if ref # either can't be converted to a bitmap or else can, but # doesn't correspond to any text in the main file # # listpassage(l, msg, width), which displays the lines contained # in list l, truncating them to width, and displaying msg # both near the top of the screen and on the status line # # writepassage(l, msg, switch), which writes list l to a file # (the name of which it prompts the user to enter); if switch # is nonnull, then it appends l to the file the user enters, # rather then overwriting it # # get_{next,prev}_passage(), which generates the bitmap for the # next/previous reference in the KJV file # # push_shell(), which suspends bibleref, and starts up either # /bin/sh, or the program named in the SHELL environment # variable. # ############################################################################ # # Links: ./rewrap.icn # # See also: ./bibleref.icn # ############################################################################ procedure display_passage(passage_ref) local msg, d_list, bitmap, text static width # global kjv_filename initial { # decide how long to make lines. The display procedures # listpassage leaves a margin on the left (8 spaces). On # a typical display, it looks nice to leave about nine # spaces on the other side. This leaves getval("co")-17 # spaces left for text in between. The space left for # text here is stored in the static variable "width." width := (18 < getval("co")-17) | quit("display_passage","your terminal is too narrow",98) } # Try to convert passage_ref to a retrieve-format bitmap. if type(passage_ref) == "string" then { *passage_ref > 0 | fail bitmap := ref_2_bitmap(passage_ref, kjv_filename) | fail } # If the passage_ref is not a string, the it's probably already # been converted; try to use it as-is. else bitmap := passage_ref repeat { message("Locating text in main file...") # Now check to see if the passage is present in the indexed text. text := bitmap_2_text(bitmap, kjv_filename) | { err_message("No such passage in " || kjv_filename || ".") fail } # Rewrap passage to width characters per line; put them into a list. d_list := [] every put(d_list, rewrap(text, width-1)) put(d_list, rewrap(&null, width-1)) # Get the name of the current passage, using standard abbrevs. msg := convertb(bitmap, kjv_filename) # Display passage. bitmap := listpassage(bitmap, d_list, msg, width) | fail # If bitmap ends up null, then return. if /bitmap then return } end procedure listpassage(bitmap, l, msg, width) local offset, ss, done, i, j, n, rsp, result, prompt static lines, top_margin initial { (lines := getval("li")-4) > 6 | quit("listpassage", "your terminal isn't tall enough", 96) top_margin := 3 } # "l" is a list of lines to print # "msg" is the message to put on the status line # "width" gives the length to which lines in l are truncated offset := 0 repeat { # Set up top margin. every j := 1 to top_margin do { iputs(igoto(getval("cm"), 1, j)) if j = 2 then { writes(repl(" ",3)) underline() writes(msg) } normal(); iputs(getval("ce")) } i := 0 while *l >= (ss := offset + (lines > (i +:= 1))) do { iputs(igoto(getval("cm"), 1, i+top_margin)) normal(); iputs(getval("ce")) writes(repl(" ", 8), l[ss][1:\width|0]) } # If we haven't reached the end of the displayable screen, # then clear lines until we reach it... if i-1 ~= lines then { every j := (i+top_margin) to lines+1 do { iputs(igoto(getval("cm"), 1, j)) normal(); iputs(getval("ce")) } } status_line("** " || \msg || " **" | "", "", "c") # If there's more to do, but we're at the end of the display, # then... if *l > lines-1 & (offset+i) ~= (*l+1) then { rsp := snarf_input("Enter passage or !/a/b/c/m/w/+/- _ (q to quit viewing): ") if result := display_passage(rsp) then { return result } else { case map(rsp) of { "" : offset := (*l > (offset+1)) "!" : push_shell() "a" : write_passage(l, msg, "append") "b" : offset := (0 < offset-lines+1) | 0 "c" : next "m" : offset := (*l > (offset+i-1)) "+" : return get_next_bitmap(bitmap) "-" : return get_prev_bitmap(bitmap) "q" : return "w" : write_passage(l, msg) default : err_message("Command invalid in this context.") } } } # ...otherwise, we've displayed everything. else { prompt := "c/w/+/- (q to go to previous menu): " if *l <= lines then rsp:= snarf_input("Enter passage or !/a/" || prompt) | next else rsp := snarf_input("Enter passage or !/a/b/" || prompt) | next if result := display_passage(rsp) then { return result } else { case map(rsp) of { "!" : push_shell() "a" : write_passage(l, msg, "append") "b" : offset := (0 < offset-lines+1) | 0 "c"|"" : next "m" : next "+" : return get_next_bitmap(bitmap) "-" : return get_prev_bitmap(bitmap) "q" : return "w" : write_passage(l, msg) default : err_message("Command invalid in this context.") } } } } end procedure write_passage(passage_list, msg, switch) local fname, outtext, firstchar # Get straight whether we are appending or clobbering. (/switch := "w") | (switch := "a") until \outtext do { fname := snarf_input("Enter filename (! for shell; q to quit): ") fname ? { firstchar := move(1) | "" case firstchar of { "" : fail "!" : push_shell() & initialize_screen() "q" : pos(0) & fail default : { outtext := open(fname, switch) | { case switch of { "a" : err_message("Can't append to "|| fname||".") "w" : err_message("Cannot write to "|| fname||".") default : quit("write_passage","internal error",80) } } } } } } message("Writing.") write(outtext, "::", msg) every write(outtext,!passage_list) close(outtext) message("Done.") return end procedure get_next_bitmap(lastone) local next_bitmap initial message("Reading limits file...") next_bitmap := NextBitmap(lastone, kjv_filename) | { err_message(convertb(lastone, kjv_filename) || " has no successor.") return lastone } return next_bitmap end procedure get_prev_bitmap(lastone) local prev_bitmap initial message("Reading limits file...") prev_bitmap := PrevBitmap(lastone, kjv_filename) | { err_message(convertb(lastone, kjv_filename) || " has no predecessor.") return lastone } return prev_bitmap end procedure push_shell() local status static shell initial shell := getenv("SHELL") | "/bin/sh" tab(match("!")) clear() if pos(0) then status := system(shell) else { status := system(shell || " -c '" || tab(0) || "'") write("\n\n") message("Please press return to re-enter Bibleref.") read(&input) } clear() return status end