home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume23 / quranref / part01 next >
Encoding:
Text File  |  1991-10-19  |  34.7 KB  |  1,151 lines

  1. Newsgroups: comp.sources.misc
  2. From: goer@midway.uchicago.edu (Richard L. Goerwitz)
  3. Subject:  v23i067:  quranref - Holy Qur'an word and passage based retrievals, Part01/08
  4. Message-ID: <csm-v23i067=quranref.212044@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 750eeae3f5ebb7092a4730e97c859c57
  6. Date: Sat, 19 Oct 1991 02:22:04 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: goer@midway.uchicago.edu (Richard L. Goerwitz)
  10. Posting-number: Volume 23, Issue 67
  11. Archive-name: quranref/part01
  12. Environment: Icon
  13.  
  14. Program:  Quranref (built on top of Bibleref, a Bible concordance
  15.       program archived on cs.arizona.edu [icon/contrib/bible-
  16.       ref-2.1.tar.Z])
  17.  
  18. Requires: Icon version 8, a working, up-to-date Icon Program Library
  19.           (Icon ftp-able from cs.arizona.edu [icon/interpreter])
  20.           and M. H. Shakir's translation of the Holy Qur'an, as 
  21.           archived by Cary Maguire on princeton.edu (pub/Quran.tar.Z).
  22.  
  23.     This package, Quranref, offers simple tools for word and
  24. passage-based access to M. H. Shakir's translation of the Holy Qur'an.
  25. Quranref is quick, and fairly easy to install (assuming you possess
  26. the machine readable text, a sufficiently powerful machine, and know a
  27. little about Icon).  It will also run with stock terminals - even
  28. nasty old ones that leave magic cookies on your screen.  Quranref
  29. will, however, put a bit of a dent in your mass storage resources.
  30. Your 900k or so Qur'an text will get block Huffman encoded, which will
  31. bring it down to about 500k.  The freed space, however, will be
  32. gobbled up immediately by some 500k of auxiliary files, and by the
  33. 180k executable (more if you compile, rather than interpret).  In-core
  34. requirements for the executable start at about 300k, and go up from
  35. there (if your searches are complex enough, you could easily eat up a
  36. megabyte or two).  In brief: Quranref enjoys dining on your memory
  37. resources.  Once set up, though, it can operate with fairly minimal
  38. impact on the CPU.
  39.     With Quranref, you can perform most of the more basic,
  40. low-level functions commercial browsing packages offer (and perhaps a
  41. few not found in some of the commercial Qur'an study packages).  You
  42. can, for example,
  43.  
  44.     -  retrieve any passage by section:verse number
  45.     -  move forward or backward relative to the retrieved passage
  46.     -  search the entire Qur'an for words and/or word-patterns
  47.     -  search for word co-occurrences (or the absence thereof)
  48.     -  save passages and/or passage-lists for use with an editor
  49.  
  50. Although this program is hardly the product of any major research
  51. effort :-), it should prove sophisticated enough for casual use.  Its
  52. main fault right now is that it relies on a newly scanned text which
  53. is positively rife with errors.  The high number of errors is nothing
  54. unusual for a text put into machine readable form by current OCR
  55. technology, so no insult is intended to the people who rendered us
  56. this great service.  It is merely a fact about the current
  57. distribution that should be noted before attempting any serious
  58. research.
  59.  
  60. Richard L. Goerwitz <uunet!midway.uchicago.edu!goer>
  61.  
  62. ---- Cut Here and feed the following to sh ----
  63. #!/bin/sh
  64. # This is a shell archive (produced by shar 3.49)
  65. # To extract the files from this archive, save it to a file, remove
  66. # everything above the "!/bin/sh" line above, and type "sh file_name".
  67. #
  68. # made 09/29/1991 18:35 UTC by richard@zenu
  69. # Source directory /u/richard/Quranref/src
  70. #
  71. # existing files will NOT be overwritten unless -c is specified
  72. # This format requires very little intelligence at unshar time.
  73. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  74. #
  75. # This is part 1 of a multipart archive                                    
  76. # do not concatenate these parts, unpack them in order with /bin/sh        
  77. #
  78. # This shar contains:
  79. # length  mode       name
  80. # ------ ---------- ------------------------------------------
  81. #   6503 -rw-r--r-- bibleref.src
  82. #   3343 -r--r--r-- ref2bmap.icn
  83. #   3613 -r--r--r-- name2num.icn
  84. #   2889 -r--r--r-- convertb.icn
  85. #  14079 -r--r--r-- listutil.icn
  86. #   7564 -r--r--r-- passutil.icn
  87. #   2816 -r--r--r-- readfile.icn
  88. #   6533 -r--r--r-- srchutil.icn
  89. #    456 -r--r--r-- version.icn
  90. #   5988 -r--r--r-- complete.icn
  91. #    744 -r--r--r-- ipause.icn
  92. #   1205 -r--r--r-- inbits.icn
  93. #   4314 -r--r--r-- rewrap.icn
  94. #  20980 -r--r--r-- findre.icn
  95. #   7644 -r--r--r-- huffcode.icn
  96. #   1855 -r--r--r-- binsrch.icn
  97. #   5545 -r--r--r-- bmp2text.icn
  98. #   3560 -r--r--r-- initfile.icn
  99. #   7084 -r--r--r-- retrieve.icn
  100. #   7273 -r--r--r-- indexutl.icn
  101. #   6810 -r--r--r-- retrops.icn
  102. #   6627 -r--r--r-- whatnext.icn
  103. #  18055 -r--r--r-- iolib.icn
  104. #   6945 -r--r--r-- iscreen.icn
  105. #   5064 -r--r--r-- qur2rtv.icn
  106. #  21093 -r--r--r-- makeind.icn
  107. #   2423 -r--r--r-- gettokens.icn
  108. #   5587 -r--r--r-- Makefile.dist
  109. #  20638 -rw-r--r-- README
  110. #  15736 -rw-r--r-- README.rtv
  111. #   3067 -r--r--r-- outbits.icn
  112. #
  113. if test -r _shar_seq_.tmp; then
  114.     echo 'Must unpack archives in sequence!'
  115.     echo Please unpack part `cat _shar_seq_.tmp` next
  116.     exit 1
  117. fi
  118. # ============= bibleref.src ==============
  119. if test -f 'bibleref.src' -a X"$1" != X"-c"; then
  120.     echo 'x - skipping bibleref.src (File already exists)'
  121.     rm -f _shar_wnt_.tmp
  122. else
  123. > _shar_wnt_.tmp
  124. echo 'x - extracting bibleref.src (Text)'
  125. sed 's/^X//' << 'SHAR_EOF' > 'bibleref.src' &&
  126. X############################################################################
  127. X#
  128. X#    Name:     bibleref.icn
  129. X#
  130. X#    Title:     Bible Reference Finder
  131. X#
  132. X#    Author:     Richard L. Goerwitz
  133. X#
  134. X#    Version: 1.22
  135. X#
  136. X############################################################################
  137. X#
  138. X#  This program helps the user locate and browse passages from the
  139. X#  PD-SIG King James or CCAT Revised Standard Version of the Bible.
  140. X#  Startup syntax is
  141. X#
  142. X#      bibleref [-f filename] [-v]
  143. X#
  144. X#  where filename is the name of the indexed Bible text you wish to
  145. X#  peruse.  Because the KJV/RSV filename is hard-coded into the program,
  146. X#  you need not supply the -f argument.  It is available, though,
  147. X#  just in case you have indexed another biblical file, and wish to
  148. X#  use that instead.
  149. X#
  150. X#  If bibleref is called with a -v argument, it prints the version
  151. X#  number and patchlevel, then exits.
  152. X#
  153. X#  This particular file contains only the basic command loop, some
  154. X#  initialization routines, and some basic clearing/prompting/reading
  155. X#  utilities.  The other integral file is listutil.icn, which contains
  156. X#  all of the basic list and passage display routines.
  157. X#
  158. X############################################################################
  159. X#
  160. X#  Requires: UNIX, fully updated & installed Icon Program Library
  161. X#
  162. X############################################################################
  163. X#
  164. X#  Links: ./ref2bmap.icn ./name2num.icn ./convertb.icn ./complete.icn
  165. X#         ./binsrch.icn ./bmp2text.icn ./initfile.icn ./retrieve.icn
  166. X#         ./indexutl.icn ./retrops.icn ./whatnext.icn ./iolib.icn
  167. X#         ./iscreen.icn ./listutil.icn ./rewrap.icn ./passutil.icn
  168. X#         ./srchutil.icn ./readfile (and probably others I've forgotten)
  169. X#
  170. X#  Until incorporated into Icon, also link:  ./ipause.icn
  171. X#
  172. X#  See also: kjv2rtv.icn, makeind.icn, retrieve.icn, iolib.icn
  173. X#
  174. X############################################################################
  175. X
  176. Xglobal kjv_filename, lists
  177. Xrecord lst(l,pos,old_n,s,long)
  178. X
  179. X
  180. Xprocedure main(a)
  181. X
  182. X    local option_table, filename, prompt, intext, first, result
  183. X    # global lists
  184. X    initial {
  185. X    lists := []
  186. X    checkout_features()
  187. X    option_table := getopts(a, "f:v")
  188. X    if \option_table["v"] then abort("Bibleref", _version(), 0)
  189. X    kjv_filename := \option_table["f"] | "/usr/local/lib/bibleref/kjv.rtv"
  190. X    initialize_screen()
  191. X    message("Initializing offset file...")
  192. X    initfile(kjv_filename) |
  193. X        quit("main","can't locate "||kjv_filename,1)
  194. X    }
  195. X
  196. X    # Setup initial prompt.
  197. X    prompt := "Enter passage, or f to find a word (q to quit):  "
  198. X
  199. X    # Read user input.
  200. X    while intext := snarf_input(prompt) do {
  201. X
  202. X    trim(intext,'\t ') ? {
  203. X
  204. X        # See if the user has just input a passage reference.
  205. X        # If so, then display it...
  206. X        if display_passage(intext) then
  207. X        result := "yes"
  208. X
  209. X        # ...otherwise, see if his/her input matches any of the
  210. X        # following commands:
  211. X        else {
  212. X        first := move(1) | "c"
  213. X        case first of {
  214. X            "!" : push_shell() & initialize_screen()
  215. X            "c" : initialize_screen()        # c = clear
  216. X            "d" : display_list()             # d = display (a list)
  217. X            "f" : {                 # f = find a word
  218. X            if search_database() # insert new list into "lists"
  219. X            then display_list()  # stores it as a record (lst)
  220. X            }
  221. X            "l" : show_lists()             # l = list all lists
  222. X            "q" : {                 # q = quit program
  223. X            if pos(0) & "y" == snarf_input("Really quit? (y/n)  ")
  224. X            then break
  225. X            }
  226. X            "r" : readfile() & display_list()# r = read file from disk
  227. X            default : {                 # input error
  228. X            err_message("Unrecognized passage or command.")
  229. X            next
  230. X            }
  231. X        }
  232. X        }
  233. X        # If we have any tangible search results, or else have viewed
  234. X        # a passage, then alter the prompt to reflect the full range
  235. X        # of options.
  236. X        \result | *\lists > 0 &
  237. X        prompt := "Enter passage, or !/c/d/f/l/q/r:  "
  238. X    }
  239. X    }
  240. X
  241. X    # Clear, say goodbye, and exit with zero status.
  242. X    initialize_screen()
  243. X    message("Thanks for using Bibleref.")
  244. X    write(); exit(0)
  245. X
  246. Xend
  247. X
  248. X
  249. Xprocedure initialize_screen()
  250. X
  251. X    #
  252. X    # Initialize screen
  253. X    #
  254. X    local msg, short_message
  255. X
  256. X    pos(0) | {
  257. X    err_message("Garbage characters after \"c\" command.")
  258. X    fail
  259. X    }
  260. X
  261. X    msg := "\"Bibleref\" - a Bible browser by Richard Goerwitz"
  262. X    short_message := "\"Bibleref,\" by RG"
  263. X
  264. X    clear()
  265. X    status_line(msg, short_message, "c") &
  266. X    return
  267. X
  268. Xend
  269. X
  270. X
  271. Xprocedure snarf_input(prompt)
  272. X
  273. X    #
  274. X    # Read user input after displaying a prompt.
  275. X    #
  276. X    local command
  277. X    # global commands
  278. X
  279. X    /prompt := "Please input:  "
  280. X    message(prompt)
  281. X    return read() | ""
  282. X
  283. Xend
  284. X
  285. X
  286. Xprocedure err_message(msg)
  287. X
  288. X    #
  289. X    #  Display error message for 1 second; erase.
  290. X    #
  291. X    /msg := "Error."
  292. X    message(msg)
  293. X    ipause(700)        # until Icon gets a sleep function
  294. X    message("")
  295. X    return
  296. X
  297. Xend
  298. X    
  299. X
  300. Xprocedure status_message(msg)
  301. X
  302. X    #
  303. X    #  Display some status message on the highlighted status line.
  304. X    #
  305. X    status_line(msg) &
  306. X    return
  307. X
  308. Xend
  309. X    
  310. X
  311. Xprocedure checkout_features()
  312. X
  313. X    #
  314. X    # Check to see if we have the necessary terminal & OS features.
  315. X    #
  316. X    local capname
  317. X
  318. X    every capname := ("li","co","ce") do {
  319. X    getval(capname) | {
  320. X        quit("check_features",
  321. X         "terminal lacks "||capname||" capability", 2)
  322. X    }
  323. X    }
  324. X    find("UNIX",&features) |
  325. X    quit("check_features", "OS unsupported", 1)
  326. X    return
  327. X
  328. Xend
  329. X
  330. X
  331. Xprocedure quit(s1, s2, i)
  332. X    
  333. X    #
  334. X    # Move cursor to bottom screen line & abort, sending the message
  335. X    # s1: s2 to the user, and exiting with status i.
  336. X    #
  337. X    iputs(igoto(getval("cm"), 1, getval("li")))
  338. X    iputs(getval("ce"))
  339. X    abort(s1, s2, i)
  340. X
  341. Xend
  342. X
  343. X
  344. Xprocedure getopts(arg,optstring)
  345. X
  346. X    #
  347. X    # Get opts.  Based on Bob Alexander & Gregg Townsend's IPL
  348. X    # options procedure.
  349. X    #
  350. X    local x,i,c,otab,flist,o,p
  351. X
  352. X    /optstring := string(&letters)
  353. X    otab := table()
  354. X    flist := []
  355. X    while x := get(arg) do {
  356. X    x ? {
  357. X        if ="-" & not pos(0) then {
  358. X        if ="-" & pos(0) then break
  359. X        while c := move(1) do
  360. X            if i := find(c,optstring) + 1 then
  361. X            otab[c] :=
  362. X            if any(':+.',o := optstring[i]) then {
  363. X                        p := "" ~== tab(0) | get(arg) |
  364. X                quit("getopts", "No parameter following -"||c, 1)
  365. X                        case o of {
  366. X                ":": p
  367. X                "+": integer(p) |
  368. X                quit("getopts", "-"||c||" needs numeric", 1)
  369. X                ".": real(p) |
  370. X                quit("getopts", "-"||c||" needs numeric", 1)
  371. X            }
  372. X            }
  373. X            else 1
  374. X            else quit("getopts","Unrecognized option: -"||c, 1)
  375. X        }
  376. X        else put(flist,x)
  377. X    }
  378. X    }
  379. X    while push(arg,pull(flist))
  380. X    return otab
  381. X
  382. Xend
  383. SHAR_EOF
  384. true || echo 'restore of bibleref.src failed'
  385. rm -f _shar_wnt_.tmp
  386. fi
  387. # ============= ref2bmap.icn ==============
  388. if test -f 'ref2bmap.icn' -a X"$1" != X"-c"; then
  389.     echo 'x - skipping ref2bmap.icn (File already exists)'
  390.     rm -f _shar_wnt_.tmp
  391. else
  392. > _shar_wnt_.tmp
  393. echo 'x - extracting ref2bmap.icn (Text)'
  394. sed 's/^X//' << 'SHAR_EOF' > 'ref2bmap.icn' &&
  395. X############################################################################
  396. X#
  397. X#    Name:     ref2bmap.icn
  398. X#
  399. X#    Title:     convert English reference to a bitmap
  400. X#
  401. X#    Author:     Richard L. Goerwitz
  402. X#
  403. X#    Version: 1.15
  404. X#
  405. X############################################################################
  406. X#
  407. X#  Converts an English reference (e.g. "Ex 4:2" for the Bible; "4:2"
  408. X#  for the Quran) to a bitmap suitable for retrieval via
  409. X#  bitmap_2_text(bitmap, filename).  Syntax:
  410. X#
  411. X#      ref_2_bitmap(english_ref, filename)
  412. X#
  413. X#  fails if the requested conversion can't be performed on account of
  414. X#  a misspelling.  Aborts if the file whose name is given as arg 2
  415. X#  does not have a transparently [book:]chapter:verse organization
  416. X#  (i.e. IS.no must = 2 or 3).
  417. X#
  418. X############################################################################
  419. X#
  420. X#  Links: complete.icn, ./initfile.icn ./name2num.icn
  421. X#
  422. X############################################################################
  423. X
  424. X# Declared in indexutl.icn.
  425. X# record is(FS, s_len, len, no, is_case_sensitive)
  426. X# global IS
  427. X
  428. X# Declared in initfile.icn.
  429. X# global filestats
  430. X# record Fs(ind_filename,bmp_filename,lim_filename, IS, ofs_table,all_bitmaps)
  431. X
  432. X
  433. Xprocedure ref_2_bitmap(s, filename)
  434. X
  435. X    local bitmap, bookname, book_numeric, field, no
  436. X
  437. X    # Check for sloppy programming.
  438. X    /filename & abort("ref_2_bitmap","you called me without a filename",54)
  439. X
  440. X    # If necessary, initialize stats for the current file.
  441. X    #
  442. X    if /filestats | /filestats[filename]
  443. X    then initfile(filename)           # see initfile.icn
  444. X    IS := filestats[filename].IS
  445. X    1 < IS.no < 4 | abort("ref_2_bitmap","oops; IS.no is not = (2|3)",51)
  446. X
  447. X    # IS.len   = the number of bits needed to hold an integer
  448. X    #            representation of a single field in filename
  449. X    # IS.no    = number of fields in bitmaps for filename
  450. X    # s        = English Bible reference (e.g. Gen 8:10)
  451. X    # no       = number of fields minus one
  452. X
  453. X    no       := IS.no
  454. X    bookname := ""
  455. X    bitmap   := 0
  456. X
  457. X    s ? {
  458. X
  459. X    if IS.no = 3 then {
  460. X        no -:= 1
  461. X        # Find book name, convert it to an integer.
  462. X        bookname ||:= tab(any('1234')) | {
  463. X        (="first",  "1") |
  464. X        (="second", "2") |
  465. X        (="third",  "3") |
  466. X        (="fourth", "4")
  467. X        }
  468. X        tab(many(' '))
  469. X        bookname ||:= trim(tab(many(&letters ++ ' '))) | fail
  470. X        # Fail if the user gives us just a single letter...
  471. X        *bookname > 1 | fail
  472. X        # ...otherwise, convert book name into the correct value for
  473. X        # for this file, and fit it into a proper-length bit field.
  474. X        book_numeric :=  name2num(bookname) | fail
  475. X        bitmap := ior(bitmap, ishift(book_numeric, no * IS.len)) | fail
  476. X    }
  477. X    
  478. X    # Get book and verse fields.  Add them, shifted appropriately,
  479. X    # to bitmap.
  480. X    while tab(upto(&digits)) do {
  481. X        no -:= 1
  482. X        # If no goes below 0 then we have too many fields for the
  483. X        # file named in arg 2.
  484. X        no >= 0 | fail
  485. X        # If you prefer to abort with an error, uncomment this.
  486. X        # no >= 0 | abort("ref_2_bitmap", "impossible reference",52)
  487. X        bitmap := ior(bitmap, ishift(tab(many(&digits)), no * IS.len))
  488. X    }
  489. X    }
  490. X
  491. X    # If the current no is not 0, then we have either too many or too
  492. X    # few fields.  This check can be disabled, to allow for dummy
  493. X    # specifications (e.g. in a biblicat test, Exod would imply all of
  494. X    # the book of Exodus).
  495. X    no = 0 | fail
  496. X
  497. X    return bitmap
  498. X
  499. Xend
  500. SHAR_EOF
  501. true || echo 'restore of ref2bmap.icn failed'
  502. rm -f _shar_wnt_.tmp
  503. fi
  504. # ============= name2num.icn ==============
  505. if test -f 'name2num.icn' -a X"$1" != X"-c"; then
  506.     echo 'x - skipping name2num.icn (File already exists)'
  507.     rm -f _shar_wnt_.tmp
  508. else
  509. > _shar_wnt_.tmp
  510. echo 'x - extracting name2num.icn (Text)'
  511. sed 's/^X//' << 'SHAR_EOF' > 'name2num.icn' &&
  512. X############################################################################
  513. X#
  514. X#    Name:     name2num.icn
  515. X#
  516. X#    Title:     convert English book name to an integer
  517. X#
  518. X#    Author:     Richard L. Goerwitz
  519. X#
  520. X#    Version: 1.8
  521. X#
  522. X############################################################################
  523. X#
  524. X#  Used by ref_2_bitmap(), convertr(), etc.
  525. X#
  526. X############################################################################
  527. X
  528. X
  529. Xprocedure name2num(s)
  530. X
  531. X    # Map English book names or abbreviations to numeric values.
  532. X
  533. X    local n, b_name, tmp_names, i, nameset
  534. X    static names, abbrevtbl
  535. X    initial {
  536. X
  537. X    names :=     ["genesis", "exodus", "leviticus", "numbers",
  538. X              "deuteronomy", "joshua", "judges", "ruth",
  539. X              "1samuel", "2samuel", "1kings", "2kings",
  540. X              "1chronicles", "2chronicles", "ezra",
  541. X              "nehemiah", "esther", "job", "psalms",
  542. X              "proverbs", "ecclesiastes", "canticles",
  543. X              "isaiah", "jeremiah", "lamentations", "ezekiel",
  544. X              "daniel", "hosea", "joel", "amos", "obadiah",
  545. X              "jonah", "micah", "nahum", "habakkuk",
  546. X              "zephaniah", "haggai", "zechariah", "malachi",
  547. X              "matthew", "mark", "luke", "john", "acts",
  548. X              "romans", "1corinthians", "2corinthians",
  549. X              "galations", "ephesians", "philippians",
  550. X              "colossians", "1thessalonians",
  551. X              "2thessalonians", "1timothy", "2timothy",
  552. X              "titus", "philemon", "hebrews", "james",
  553. X              "1peter", "2peter", "1john", "2john", "3john",
  554. X              "jude", "revelation",
  555. X
  556. X              "gen", "exod", "lev", "num", "deut", "josh",
  557. X              "judg", "ruth", "1sam", "2sam", "1kgs", "2kgs",
  558. X              "1chr", "2chr", "ezra", "neh", "esth", "job",
  559. X              "pss", "prov", "qoh", "cant", "isa", "jer",
  560. X              "lam", "ezek", "dan", "hos", "joel", "amos",
  561. X              "obad", "jonah", "mic", "nahum", "hab", "zeph",
  562. X              "hag", "zech", "mal", "mat", "mark", "luke",
  563. X              "john", "acts", "rom", "1cor", "2cor", "gal",
  564. X              "eph", "phil", "col", "1thess", "2thess",
  565. X              "1tim", "2tim", "titus", "phlm", "heb", "jas",
  566. X              "1pet", "2pet", "1john", "2john", "3john",
  567. X              "jude", "rev",
  568. X
  569. X              "dt", "jdg", "jg", "rth", "sa1", "sa2", "ki1",
  570. X              "ki2", "ch1", "ch2", "jl", "mt", "mk", "lk",
  571. X              "jn", "co1", "co2", "th1", "th2", "ti1", "ti2",
  572. X              "phm", "pe1", "pe2", "jo1", "jo2", "jo3", "1jn",
  573. X              "2jn", "3jn",
  574. X
  575. X              "1esdras", "2esdras", "tobit", "judith",
  576. X              "additions to esther", "wisdom of solomon",
  577. X              "sirach prologue", "sirach", "baruch", "letter _
  578. X              of jeremiah", "prayer of azariah", "susanna",
  579. X              "bel and the dragon", "prayer of manasseh",
  580. X              "1maccabees", "2maccabees", "3maccabees",
  581. X              "4maccabees",
  582. X
  583. X              "1esdr", "2esdr", "tob", "jdt", "addesth",
  584. X              "wis", "sirp", "sir", "bar", "letjer", "prazar",
  585. X              "suz", "bel", "prman", "1macc", "2macc",
  586. X              "3macc", "4macc",
  587. X
  588. X              "song of songs", "solomon", "song of solomon",
  589. X
  590. X              "3ezra", "4ezra", "3esdras", "4esdras",
  591. X              "adesth", "ecclesiasticus", "ecclus", "epjer",
  592. X              "epistle of jeremiah", "s of 3 y", "s. of 3 y.",
  593. X              "manasseh"]
  594. X
  595. X        abbrevtbl := table()
  596. X    tmp_names := copy(names)
  597. X    every i := (1 to 66) | (1 to 66) |
  598. X        5|7|7|8|9|10|11|12|13|14|29|40|41|42|43|46|
  599. X        47|52|53|54|55|57|60|61|62|63|64|62|63|64|
  600. X        (67 to 84) | (67 to 84) | 22|22|22|
  601. X        67|68|67|68|71|74|74|76|76|77|77|80
  602. X    do {
  603. X        insert(abbrevtbl, get(tmp_names), i)
  604. X    }
  605. X    }
  606. X
  607. X    nameset := set()
  608. X    every insert(nameset, complete(map(s), names))
  609. X    case *nameset of {
  610. X    0 : fail
  611. X    1 : return abbrevtbl[!nameset]
  612. X    default : suspend abbrevtbl[!sort(nameset)]
  613. X    }
  614. X    
  615. Xend
  616. SHAR_EOF
  617. true || echo 'restore of name2num.icn failed'
  618. rm -f _shar_wnt_.tmp
  619. fi
  620. # ============= convertb.icn ==============
  621. if test -f 'convertb.icn' -a X"$1" != X"-c"; then
  622.     echo 'x - skipping convertb.icn (File already exists)'
  623.     rm -f _shar_wnt_.tmp
  624. else
  625. > _shar_wnt_.tmp
  626. echo 'x - extracting convertb.icn (Text)'
  627. sed 's/^X//' << 'SHAR_EOF' > 'convertb.icn' &&
  628. X############################################################################
  629. X#
  630. X#    Name:     convertb.icn
  631. X#
  632. X#    Title:     convert 3-field book,chap,verse bitmap into a human-
  633. X#                readable book chapter:verse reference
  634. X#
  635. X#    Author:     Richard L. Goerwitz
  636. X#
  637. X#    Version: 1.7
  638. X#
  639. X############################################################################
  640. X#
  641. X#  Links: complete.icn ./initfile.icn
  642. X#
  643. X############################################################################
  644. X
  645. X# Declared in indexutl.icn.
  646. X# record is(FS, s_len, len, no, is_case_sensitive)
  647. X# global IS
  648. X
  649. X# Declared in initfile.icn.
  650. X# global filestats
  651. X# record Fs(ind_filename,bmp_filename,lim_filename, IS, ofs_table,all_bitmaps)
  652. X
  653. Xprocedure convertb(bitmap, filename)
  654. X
  655. X    local no, reference, field_mask
  656. X
  657. X    # Check for sloppy programming.
  658. X    /filename & abort("convertb","you called me without a filename",70)
  659. X
  660. X    # If necessary, initialize stats for the current file.
  661. X    #
  662. X    if /filestats | /filestats[filename]
  663. X    then initfile(filename)           # see initfile.icn
  664. X    IS := filestats[filename].IS
  665. X    1 < IS.no < 4 | abort("convertb", "can't handle IS.no < 2 or > 3", 71)
  666. X
  667. X    # IS.len   = the number of bits needed to hold an integer
  668. X    #            representation of a single field in filename
  669. X    # IS.no    = number of fields in bitmaps for filename
  670. X
  671. X    no := IS.no-1
  672. X    field_mask := 2^(IS.len)-1
  673. X
  674. X    if IS.no = 3 then {
  675. X    # No need for mask here; add it just in case.
  676. X    reference  := Num2Name(
  677. X        iand(field_mask, ishift(bitmap, -(no*IS.len))), "kjv.rtv") |
  678. X        abort("convertb", "can't convert first field", 52)
  679. X    no -:= 1
  680. X    }
  681. X    else reference := ""
  682. X
  683. X    reference ||:= " " || iand(field_mask, ishift(bitmap, -(no*IS.len)))
  684. X    no -:= 1
  685. X    reference ||:= ":" || iand(field_mask, ishift(bitmap, -(no*IS.len)))
  686. X
  687. X    return reference
  688. X
  689. Xend
  690. X
  691. X
  692. X
  693. Xprocedure Num2Name(i)
  694. X
  695. X    # Map English book names or abbreviations to numeric values.
  696. X
  697. X    local names, n
  698. X    static num_table
  699. X    initial {
  700. X    names := [    "Gen", "Exod", "Lev", "Num", "Deut", "Josh",
  701. X              "Judg", "Ruth", "1Sam", "2Sam", "1Kgs", "2Kgs",
  702. X              "1Chr", "2Chr", "Ezra", "Neh", "Esth", "Job",
  703. X              "Pss", "Prov", "Qoh", "Cant", "Isa", "Jer",
  704. X              "Lam", "Ezek", "Dan", "Hos", "Joel", "Amos",
  705. X              "Obad", "Jonah", "Mic", "Nahum", "Hab", "Zeph",
  706. X              "Hag", "Zech", "Mal", "Mat", "Mark", "Luke",
  707. X              "John", "Acts", "Rom", "1Cor", "2Cor", "Gal",
  708. X              "Eph", "Phil", "Col", "1Thess", "2Thess",
  709. X              "1Tim", "2Tim", "Titus", "Phlm", "Heb", "Jas",
  710. X              "1Pet", "2Pet", "1John", "2John", "3John",
  711. X              "Jude", "Rev", "1Esdr", "2Esdr", "Tob", "Jdt",
  712. X              "Addest", "Wis", "Sirp", "Sir", "Bar", "Letjer",
  713. X              "Prazar", "Suz", "Bel", "Prman", "1Macc",
  714. X              "2Macc", "3Macc", "4Macc"]
  715. X
  716. X        num_table :=  table()
  717. X    every n := 1 to 84 do
  718. X        insert(num_table, n, get(names))
  719. X    }
  720. X
  721. X    return num_table[i]
  722. X
  723. Xend
  724. SHAR_EOF
  725. true || echo 'restore of convertb.icn failed'
  726. rm -f _shar_wnt_.tmp
  727. fi
  728. # ============= listutil.icn ==============
  729. if test -f 'listutil.icn' -a X"$1" != X"-c"; then
  730.     echo 'x - skipping listutil.icn (File already exists)'
  731.     rm -f _shar_wnt_.tmp
  732. else
  733. > _shar_wnt_.tmp
  734. echo 'x - extracting listutil.icn (Text)'
  735. sed 's/^X//' << 'SHAR_EOF' > 'listutil.icn' &&
  736. X############################################################################
  737. X#
  738. X#    Name:     1.26
  739. X#
  740. X#    Title:     bibleref list display utilities
  741. X#
  742. X#    Author:     Richard L. Goerwitz
  743. X#
  744. X#    Version: listutil.icn
  745. X#
  746. X############################################################################
  747. X#
  748. X#  Contains:
  749. X#
  750. X#      display_list(), which displays all passages in a given bitmap
  751. X#          list by calling listlist(), which converts the bitmaps to
  752. X#          human-readable format, and writes them to the screen
  753. X#
  754. X#      listlist(), on which see above,
  755. X#
  756. X#      writelist(), which writes a bitmap list in human readable form
  757. X#          to a file.
  758. X#
  759. X############################################################################
  760. X#
  761. X#  Links: uses push_shell(), which is in ./passutil.icn
  762. X#
  763. X############################################################################
  764. X
  765. X# Declared in bibleref.icn.  l is the list itself, pos is the viewer's
  766. X# last position in the list.  old_n is the last passage in the list that
  767. X# was viewed.  s is a brief indication of the search string used to gen-
  768. X# erate the list.
  769. X# record lst(l,pos,old_n,s,long)
  770. X
  771. Xglobal _subscripts        # get around unreachable coexpression bug
  772. X
  773. Xprocedure display_list()
  774. X
  775. X    #
  776. X    #  Display a retrieved "hit list."
  777. X    #
  778. X    local passage, subscr
  779. X
  780. X    #
  781. X    # We're in the midst of a scanning expression in the main
  782. X    # command loop.  If the "d" command was given with no arguments,
  783. X    # then default to the last list retrieved.
  784. X    #
  785. X    if pos(0) then {
  786. X    subscr := (0 ~= *lists) | {
  787. X        err_message("No lists have been created yet.")
  788. X        fail
  789. X    }
  790. X    }
  791. X    #
  792. X    # If we are not at pos(0) then we are to go to a specific list
  793. X    # in the list history.
  794. X    #
  795. X    else {
  796. X    if not {
  797. X        tab(upto('-+' ++ &digits)) &
  798. X        subscr := integer(tab(many('-+' ++ &digits))) &
  799. X        pos(0)
  800. X    }
  801. X    # If we don't have an integer, then the user has screwed
  802. X    # up somehow.
  803. X    then {
  804. X        err_message("Garbage characters after \"d\" command.")
  805. X        fail
  806. X    }
  807. X    # Check to be sure the subscript give is in range.
  808. X    lists[subscr] | {
  809. X        err_message("There is no list number "||subscr||".")
  810. X        fail
  811. X    }
  812. X    }
  813. X
  814. X    #
  815. X    # While listlist gives us a valid passage reference, display it.
  816. X    # When it returns &null or fails, quit.
  817. X    #
  818. X    repeat {
  819. X
  820. X        # Display the list (defaults above to the last list in the list
  821. X        # history).  Use listlist().  Arg 1 is the lst record, which
  822. X        # contains a list and a position to start viewing that list at.
  823. X        # The second arg to listlist tells the user the length of the
  824. X        # list.  The last arg specifies how many display columns we can
  825. X        # eat up before truncating.
  826. X     passage :=
  827. X        listlist(
  828. X            lists[subscr],
  829. X           "length = "||*lists[subscr].l||"; "||
  830. X           "search string = "||lists[subscr].s,
  831. X            getval("co")-10
  832. X            )                    |  fail
  833. X    if /passage then return
  834. X    else display_passage(passage)
  835. X    }
  836. Xend
  837. X
  838. X
  839. X
  840. Xprocedure listlist(lst_rec, msg, width)
  841. X
  842. X    local l, i, ss, j, n, ref, prompt, rsp, rsp2
  843. X    static lines
  844. X    initial lines := getval("li")-3
  845. X
  846. X    # "l" is a record of type lst, containing the list to print
  847. X    # "msg" is the message to put on the status line
  848. X    # "width" gives the length to which lines in l are truncated
  849. X    # "offset" gives the starting offset in l at which to begin
  850. X    #    printing (default 0).
  851. X
  852. X    l := lst_rec.l
  853. X
  854. X    repeat {
  855. X    i := 0
  856. X    while *l >= (ss := lst_rec.pos + (lines > (i +:= 1))) do {
  857. X        iputs(igoto(getval("cm"), 1, i))
  858. X        normal(); iputs(getval("ce"))
  859. X        writes(" ", left(ss||".",7))
  860. X        ref := convertb(l[ss], kjv_filename)
  861. X        if \lst_rec.long then
  862. X        ref ||:= ":  " || bitmap_2_text(l[ss], kjv_filename)
  863. X        if ss = \lst_rec.old_n then {
  864. X        # Boldface last viewed passage from this list.
  865. X        boldface(); writes(ref[1:\width|0])
  866. X        normal()
  867. X        } else writes(ref[1:\width|0])
  868. X    }
  869. X
  870. X    # If we haven't reached the end of the displayable screen,
  871. X    # then clear lines until we reach it...
  872. X    if i-1 ~= lines+1 then {
  873. X        every j := i to lines do {
  874. X        iputs(igoto(getval("cm"), 1, j))
  875. X        normal(); iputs(getval("ce"))
  876. X        }
  877. X    }
  878. X    # Display message on status line.
  879. X    status_line("-- " || \msg || " --" | "", "", "c")
  880. X
  881. X    # If we're to the end of the screen, and there's still more to
  882. X    # display, then...
  883. X    if *l > lines-1 & (lst_rec.pos+i) ~= (*l+1) then {
  884. X        rsp :=
  885. X        snarf_input("Press !/a/b/c/m/n/p/s/v/w (q = quit viewing):  ")
  886. X        case map(rsp) of {
  887. X        ""     : lst_rec.pos := (*l > (lst_rec.pos+1))
  888. X        "!"    : push_shell()
  889. X        "/"    : lst_rec.pos := search_list(lst_rec,rsp,lines)
  890. X        "?"    : lst_rec.pos := search_list(lst_rec,rsp,lines)
  891. X        "a"    : write_list(l, "append")
  892. X        "b"    : lst_rec.pos := (0 < lst_rec.pos-lines+1) | 0
  893. X        "c"    : next
  894. X        "l"    : lst_rec.long := { if /lst_rec.long then 1 else &null }
  895. X        "m"    : lst_rec.pos := (*l > (lst_rec.pos+i-1))
  896. X        "n"    : {
  897. X            n := \lst_rec.old_n+1 | {
  898. X            err_message("Type \"v\" to set the current passage.")
  899. X            next
  900. X            }
  901. X            if 0 < n <= *l then {
  902. X            if not (lst_rec.pos < n < lst_rec.pos+lines)
  903. X            then lst_rec.pos := (0 < n-2) | n-1
  904. X            lst_rec.old_n := n & (return l[n])
  905. X            } else err_message("Out of range.")
  906. X        }            
  907. X        "p"    : {
  908. X            n := \lst_rec.old_n-1 | {
  909. X            err_message("Type \"v\" to set the current passage.")
  910. X            next
  911. X            }
  912. X            if 0 < n <= *l then {
  913. X            if not (lst_rec.pos < n < lst_rec.pos+lines)
  914. X            then lst_rec.pos := (0 < n-2) | n-1
  915. X            lst_rec.old_n := n & (return l[n])
  916. X            } else err_message("Out of range.")
  917. X        }            
  918. X        "q"    : break
  919. X        "s"    : {
  920. X            l := (lst_rec.l := sort(lst_rec.l))
  921. X            lst_rec.old_n := &null
  922. X        }
  923. X        "v"    : {
  924. X            rsp2 := snarf_input("View which passage:  ")
  925. X            rsp2 == "q" & next
  926. X            rsp2 == ""  & rsp2 := lst_rec.old_n
  927. X            if n := integer(rsp2) then {
  928. X            if 0 < n <= *l then {
  929. X                if not (lst_rec.pos < n < lst_rec.pos+lines)
  930. X                then lst_rec.pos := (0 < n-2) | n-1
  931. X                lst_rec.old_n := n
  932. X                return l[n]
  933. X            } else err_message("Out of range.")
  934. X            } else err_message("Invalid passage number.")
  935. X        }
  936. X        "w"    : write_list(l)
  937. X        default : {
  938. X            if rsp ? {
  939. X            lst_rec.pos :=
  940. X                search_list(lst_rec,tab(any('?/')),lines)
  941. X            }
  942. X            then next
  943. X            else {
  944. X            if n := integer(rsp)-1 then {
  945. X                if 0 <= n < *l
  946. X                then lst_rec.pos := n
  947. X                else err_message("Out of range.")
  948. X            } else {
  949. X                err_message("Invalid command.")
  950. X            }
  951. X            }
  952. X        }
  953. X        }
  954. X    }
  955. X    # ...otherwise, we've displayed everything.
  956. X    else {
  957. X        prompt := "c/n/p/s/v/w (q to go to previous menu):  "
  958. X        if *l <= lines
  959. X        then rsp:= snarf_input("Press !/a/" || prompt) | next
  960. X        else rsp :=    snarf_input("Press !/a/b/" || prompt) | next
  961. X        case map(rsp) of {
  962. X        "!"    : push_shell()
  963. X        "/"    : lst_rec.pos := search_list(lst_rec,rsp,lines)
  964. X        "?"    : lst_rec.pos := search_list(lst_rec,rsp,lines)
  965. X        "a"    : write_list(l,"append")
  966. X        "b"    : lst_rec.pos := (0 < lst_rec.pos-lines+1) | 0
  967. X        "c"|"" : next
  968. X        "l"    : lst_rec.long := { if /lst_rec.long then 1 else &null }
  969. X        "m"    : next    # no more to display; just stay were we are
  970. X        "n"    : {
  971. X            n := \lst_rec.old_n+1 | {
  972. X            err_message("No passage viewed yet from this list.")
  973. X            next
  974. X            }
  975. X            if 0 < n <= *l then {
  976. X            if not (lst_rec.pos < n < lst_rec.pos+lines)
  977. X            then lst_rec.pos := (0 < n-2) | n-1
  978. X            lst_rec.old_n := n & (return l[n])
  979. X            } else err_message("Out of range.")
  980. X        }            
  981. X        "p"    : {
  982. X            n := \lst_rec.old_n-1 | {
  983. X            err_message("No passage viewed yet from this list.")
  984. X            next
  985. X            }
  986. X            if 0 < n <= *l then {
  987. X            if not (lst_rec.pos < n < lst_rec.pos+lines)
  988. X            then lst_rec.pos := (0 < n-2) | n-1
  989. X            lst_rec.old_n := n & (return l[n])
  990. X            } else err_message("Out of range.")
  991. X        }            
  992. X        "q"    : break
  993. X        "s"    : {
  994. X            l := (lst_rec.l := sort(lst_rec.l))
  995. X            lst_rec.old_n := &null
  996. X        }
  997. X        "v"    : {
  998. X            rsp2 := snarf_input("View which passage:  ")
  999. X            rsp2 == "q" & next
  1000. X            rsp2 == ""  & rsp2 := lst_rec.old_n
  1001. X            if n := integer(rsp2) then {
  1002. X            if 0 < n <= *l then {
  1003. X                if not (lst_rec.pos < n < lst_rec.pos+lines)
  1004. X                then lst_rec.pos := (0 < n-2) | n-1
  1005. X                lst_rec.old_n := n
  1006. X                return l[n]
  1007. X            } else err_message("Out of range.")
  1008. X            } else err_message("Invalid passage number.")
  1009. X        }
  1010. X        "w"    : write_list(l)
  1011. X        default : {    
  1012. X            if rsp ? {
  1013. X            lst_rec.pos :=
  1014. X                search_list(lst_rec,tab(any('?/')),lines)
  1015. X            }
  1016. X            then next
  1017. X            else {
  1018. X            if n := integer(rsp)-1 then {
  1019. X                if 0 <= n < *l
  1020. X                then lst_rec.pos := n
  1021. X                else err_message("Out of range.")
  1022. X            } else {
  1023. X                err_message("Invalid command.")
  1024. X            }
  1025. X            }
  1026. X        }
  1027. X        }
  1028. X    }
  1029. X    }
  1030. X    return
  1031. X
  1032. Xend
  1033. X
  1034. X
  1035. X
  1036. Xprocedure write_list(l, switch)
  1037. X
  1038. X    #
  1039. X    # Used for writing the contents of a displayed list to a file.
  1040. X    #
  1041. X    local fname, outtext, i, firstchar
  1042. X
  1043. X    # Get straight whether we are appending or clobbering.
  1044. X    (\switch := "a") | (switch := "w")
  1045. X
  1046. X    until \outtext do {
  1047. X    fname := snarf_input("Enter filename (! for shell; q to quit):  ")
  1048. X    fname ? {
  1049. X        firstchar := move(1) | ""
  1050. X        case firstchar of {
  1051. X        ""   : fail
  1052. X        "!"  : push_shell() & initialize_screen()
  1053. X        "q"  : pos(0) & fail
  1054. X        default : {
  1055. X            outtext := open(fname, switch) | {
  1056. X            case switch of {
  1057. X                "a" : err_message("Can't append to "|| fname ||".")
  1058. X                "w" : err_message("Can't write to "|| fname ||".")
  1059. X                default : quit("write_passage","internal error",80)
  1060. X            }
  1061. X            }
  1062. X        }
  1063. X        }
  1064. X    }
  1065. X    }
  1066. X    message("Writing...")
  1067. X    every i := 1 to *l do
  1068. X    write(outtext, " ", left(i||".",7), convertb(l[i], kjv_filename))
  1069. X    close(outtext)
  1070. X    message("Done.")
  1071. X    return
  1072. X
  1073. Xend
  1074. X
  1075. X
  1076. X
  1077. Xprocedure show_lists()
  1078. X
  1079. X    #
  1080. X    # Display stats for all generated lists.  So far the only routine
  1081. X    # that can generate lists is search_database().  Every time it
  1082. X    # generates a list, it inserts that list into the global list,
  1083. X    # lists (declared and initialized in bibleref.icn).
  1084. X    #
  1085. X    local expanded_list, i, result
  1086. X    
  1087. X    #
  1088. X    # We're in the midst of a scanning expression in the main
  1089. X    # command loop.  If the "l" command was given with no arguments,
  1090. X    # then default to the last list retrieved.
  1091. X    #
  1092. X    if not pos(0) then {
  1093. X    err_message("Garbage characters after \"l\" command.")
  1094. X    fail
  1095. X    }
  1096. X    *lists = 0 & {
  1097. X    err_message("No lists in memory.")
  1098. X    fail
  1099. X    }
  1100. X
  1101. X    repeat {
  1102. X    result :=
  1103. X        listlistS(lists, "list of viewable lists", getval("co")-10) | fail
  1104. X    if /result
  1105. X    then return
  1106. X    else result ? display_list()
  1107. X    }
  1108. Xend
  1109. X
  1110. X
  1111. X
  1112. Xprocedure listlistS(all_lists, msg, width)
  1113. X
  1114. X    local l, offset, i, ss, j, prompt, rsp, rsp2
  1115. X    static lines, last_viewed
  1116. X    initial lines := getval("li")-3
  1117. X
  1118. X    # "all_lists" is a list of records of type lst
  1119. X    # "msg" is the message to put on the status line
  1120. X    # "width" gives the length to which lines in l are truncated
  1121. X
  1122. X    l := all_lists
  1123. X
  1124. X    offset := 0
  1125. X    repeat {
  1126. X    i := 0
  1127. X    while *l >= (ss := offset + (lines > (i +:= 1))) do {
  1128. X        iputs(igoto(getval("cm"), 1, i))
  1129. X        normal(); iputs(getval("ce"))
  1130. X        writes(" ", left(ss||".",5))
  1131. X        writes("length = " || *l[i].l || ", search pattern = " || l[i].s)
  1132. X    }
  1133. X
  1134. X    # If we haven't reached the end of the displayable screen,
  1135. SHAR_EOF
  1136. true || echo 'restore of listutil.icn failed'
  1137. fi
  1138. echo 'End of  part 1'
  1139. echo 'File listutil.icn is continued in part 2'
  1140. echo 2 > _shar_seq_.tmp
  1141. exit 0
  1142.  
  1143. exit 0 # Just in case...
  1144. -- 
  1145. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1146. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1147. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1148. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1149.