home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume23 / quranref / part08 < prev    next >
Encoding:
Text File  |  1991-10-19  |  26.4 KB  |  630 lines

  1. Newsgroups: comp.sources.misc
  2. From: goer@midway.uchicago.edu (Richard L. Goerwitz)
  3. Subject:  v23i074:  quranref - Holy Qur'an word and passage based retrievals, Part08/08
  4. Message-ID: <1991Oct19.022406.13196@sparky.imd.sterling.com>
  5. X-Md4-Signature: 5bad0c869b381ab6b4b5f8e598b14f45
  6. Date: Sat, 19 Oct 1991 02:24:06 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 74
  11. Archive-name: quranref/part08
  12. Environment: Icon
  13.  
  14. ---- Cut Here and feed the following to sh ----
  15. #!/bin/sh
  16. # this is quranref.08 (part 8 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file README continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 8; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping README'
  34. else
  35. echo 'x - continuing file README'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'README' &&
  37. X"and").  This tells Quranref that you want to perform an intersection
  38. Xwith respect to another set of passages.  After typing "a" and hitting
  39. Xreturn, Quranref asks you for a unit (c = chapter, v = verse).
  40. XNormally you would press "v."  You are then asked for a range
  41. X(normally 0).  After entering a unit and range, you would enter a new
  42. Xword or pattern to look for, and then press "f" to tell Quranref you
  43. Xare finished.  What Quranref would retrieve in this instance is a list
  44. Xof all Biblical verses which contain both of the words, or
  45. Xword-patterns, that you specified.  Note that if you had entered 1 as
  46. Xyour range, you would have gotten a list of all passages containing
  47. Xword(s) matching the first pattern and which either contain, *or are
  48. Xadjacent to another passage containing*, a word matching the next
  49. Xpattern you specified.
  50. X    In addition to "a" ("and"), Quranref also accepts "o" ("or")
  51. Xand "n" (and-not) directives.  Also, words and patterns preceded by an
  52. Xexclamation point and a space ("! ") are inverted (a la egrep -v).  I
  53. Xwould not recommend using the "! " much, though.  It is slow, and
  54. Xusually brings about massive hit lists.  If you want, say, all
  55. Xoccurrences of the word "woman" that don't contain the word "child,"
  56. Xthen formalize your search as "woman" and-not "child," rather than as
  57. X"woman" and "! child."  The only thing slower than a search for
  58. X"woman" and "! child" would be to look for "woman" together with the
  59. Xwords "the" and "child."  There are about 4100 passages containing
  60. X"the," and although I've used a cute trick to reduce the number that
  61. Xhave to be stored, retrieving them all is still a mess (takes almost
  62. X30 seconds on my machine).
  63. X
  64. X
  65. X--------
  66. X
  67. X
  68. XAdditional Notes:
  69. X
  70. X    As mentioned above, this package is really just a wrapper
  71. Xaround a more general set of indexing and retrieval utilities I'm
  72. Xusing for personal research.  Despite the way they are used here,
  73. Xthese utilities are *not* geared solely for the Quran.  In fact, they
  74. Xare set up so that they can be used with just about any text broken up
  75. Xinto hierarchically arranged divisions.  As noted above, this
  76. Xdistribution is actually built on top of a similar package geared for
  77. XChristian and Jewish Bible research.  If you need help integrating a
  78. Xnew text into the retrieve package, drop me a line (i.e. new Quran
  79. Xtranslations, 'ahadith, biblical texts, etc.).  If I'm not busy, and
  80. Xthe job looks to be one I can help you out with, I'll be glad to do
  81. Xso.  If nothing else, I can at least get you started, and offer
  82. Xpointers on how to proceed.  Please, though, if you don't have M. H.
  83. XShakir's Quran translation, and can't ftp from the location specified
  84. Xearlier on in this document (i.e. princeton.edu), please *DON'T* write
  85. Xto me asking me to e-mail you the files, or to package them up on
  86. Xdisks.  I've been flooded with requests for biblical texts already,
  87. Xand can't reasonably oblige them all.
  88. X    It is with some reservation that I mention here several
  89. Xfeatures Quranref possesses that I haven't fully documented.  Most are
  90. Xones 1) that I'm not likely to continue supporting, 2) that haven't
  91. Xbeen tested, 3) that are too slow to be practical, or 4) that are
  92. Xlikely to change.  First of all, the "d" command can take a number
  93. Xargument, which causes it to display the list whose position in the
  94. Xglobal list of lists corresponds to that number).  On the top level
  95. X(and in some other places), the "!" command can also pass arguments to
  96. Xa shell (/bin/sh, or the value of your SHELL environment variable).
  97. XAlso, if you type "f lord god" at the main prompt, and press return,
  98. Xyou'll get a list of verses containing the words "lord" and "god"
  99. X(i.e. Quranref will, in other words, perform a verse-based, range 0
  100. X"and" on the respective hit lists for these two words).  Finally, when
  101. Xbrowsing search lists, you can look at the first line of each verse by
  102. Xtyping "l" and return (typing l+return again turns this feature off).
  103. X    While I don't want to hide the existence of these marginal
  104. Xfeatures, I don't want to encourage anyone to expect their presence in
  105. Xlater versions, or to suggest that they will work properly in the
  106. Xcurrent one.  I'm particularly worried about the "l" and "f lord god"
  107. Xexamples above.  The "l" listing option is very slow.  Also, telling
  108. Xpeople that "f lord god" is okay also might lead them to think that
  109. XQuranref has a concept of word order within verses.  In fact, this is
  110. Xjust an alternate way of performing a set intersection on the hit
  111. Xlists for "lord" and "god."  If you use "undocumented" features such
  112. Xas these, be aware that there may be difficulties inherent in their
  113. Xuse, and that, in general, I've avoided mentioning them until now
  114. Xprecisely because I'm not quite sure they are worthy of mention in the
  115. Xfirst place.
  116. X
  117. X
  118. X--------
  119. X
  120. X
  121. XProblems:
  122. X
  123. X    Doubtless you will find problems, more options not discussed
  124. Xin the documentation, and just general indications that this program
  125. Xwas written late at night after I was done all my serious work for the
  126. Xday :-).  If - no, when - this happens, I encourage you to drop me a
  127. Xline.  I'd like to know about any flaws you run into, especially
  128. Xmajor, systemic ones.
  129. X    Generally, I really hope that the bugs will not prove too
  130. Xannoying, and that the package will prove generally useful to you the
  131. Xuser, and, if you place it in a public directory, to anyone else who
  132. Xmight happen to try it out.
  133. X
  134. X
  135. X   -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  136. X   goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  137. SHAR_EOF
  138. echo 'File README is complete' &&
  139. true || echo 'restore of README failed'
  140. rm -f _shar_wnt_.tmp
  141. fi
  142. # ============= README.rtv ==============
  143. if test -f 'README.rtv' -a X"$1" != X"-c"; then
  144.     echo 'x - skipping README.rtv (File already exists)'
  145.     rm -f _shar_wnt_.tmp
  146. else
  147. > _shar_wnt_.tmp
  148. echo 'x - extracting README.rtv (Text)'
  149. sed 's/^X//' << 'SHAR_EOF' > 'README.rtv' &&
  150. X--------
  151. X
  152. X
  153. XName: retrieve
  154. XLanguage: Icon
  155. XContents: tools for word-based, indexed access to text files
  156. XRequires: up-to-date Icon Program Library, up-to-date iconc/icont, UNIX
  157. XFiles: binsrch.icn bmp2text.icn gettokens.icn indexutl.icn initfile.icn
  158. X       makeind.icn retrieve.icn retrops.icn searchb.icn whatnext.icn
  159. X       huffcode.icn huffadj.icn
  160. X
  161. X
  162. X--------
  163. X
  164. X
  165. XOverview:
  166. X
  167. X    Scholars have traditionally split so-called "Classics" - the
  168. XQuran, the Bible, and generally any closely studied literary or
  169. Xreligious text - into hierarchically arranged divisions (in the case
  170. Xof the Bible, these are books, chapters, and verses).  Such divisions
  171. Xdrastically simplify the process of citation and reference.
  172. XFortunately for those of us who need electronic access to these files,
  173. Xthis hierarchical system of divisions permits easy representation
  174. Xusing bit-fields, i.e. fixed-width series' of binary digits.  Such
  175. Xrepresentations are compact, and allow the programmer to implement
  176. Xhigh-level boolean operations and range-based searches using simple
  177. Xshifts, additions, and subtractions.
  178. X    The package with which this README file is packed - "retrieve"
  179. X- offers a naive, but generalized and fairly high-level, tool for
  180. Xindexing texts which are divided up in the manner just described, and
  181. Xfor performing word-based searches on them.  These word-based searches
  182. Xoffer wildcard-based access to word patterns (e.g. "give me every
  183. Xpassage containing a word with the letters 'NIX'").  The search
  184. Xfacilities also permit boolean and range-based specifications (e.g.
  185. X"give me every instance of word X occurring within eleven sections of
  186. Xthe word Y").  One can also access passages by both absolute (e.g.
  187. X"give me book 1, chapter 3, verse 4"), and relative, location (e.g.
  188. X"give me the passage occurring before/after the one I just looked
  189. Xat").
  190. X    Retrieve performs only superficial compression, and is written
  191. Xentirely in Icon.  As a result it is something of a disk hog, and
  192. Xtakes a long time to index files.  Surprisingly, though, once set up,
  193. Xfiles incorporated into the retrieve package can be accessed quite
  194. Xrapidly.  After a brief initialization process (takes 2-4 seconds on a
  195. XSun4), absolute locations can be retrieved with no perceptible delay.
  196. XThe same is true of relative locations (again, after a lag on first
  197. Xinvocation).  Regular expression based searches appear instantaneous
  198. Xon a fast machine (there is a just perceptible delay on a Sun4 for a
  199. Xfour megabyte indexed file, five to ten seconds on a Xenix/386 box
  200. Xwith a relatively slow disk).  Boolean and range-based searches take
  201. Xthe longest, varying widely according to their complexity and the
  202. Xnumber of "hits."
  203. X
  204. X
  205. X--------
  206. X
  207. X
  208. XInstallation:
  209. X
  210. X    Retrieve is really not a program as such.  It is a set of
  211. Xtools for indexing, and accessing indexed, files.  Installation
  212. Xconsists of four basic steps:
  213. X
  214. X    1) creating an indexable file
  215. X    2) indexing that file
  216. X    3) writing a program using the retrieve interface
  217. X    4) compiling and running what you wrote in (3)
  218. X
  219. XThese steps are discussed in detail in the following sections.
  220. X
  221. X
  222. X--------
  223. X
  224. X
  225. XStep 1:  Creating an Indexable File
  226. X
  227. X    The format for indexable files must conform to a simple, but
  228. Xstrict, set of guidelines.  Basically, they must interleave series' of
  229. Xlocation designators (internally represented by so-called "bitmaps")
  230. Xwith actual text:
  231. X
  232. X    ::001:001:001
  233. X    This is text.
  234. X    ::001:001:002
  235. X    This is more text.
  236. X
  237. XThe initial :: (double colon) delimits lines containing the location
  238. Xdesignators.  These designators translate into integers divisible
  239. Xinternally into (in this case) three bit-fields of length 10 (enough
  240. Xto handle 999:999:999), which serve as a location markers for the text
  241. Xthat goes with them.  Note that the translation process is invisible.
  242. XAll you need to do is make sure,
  243. X
  244. X    a) that the location designators are correctly paired with
  245. X       blocks of text, and
  246. X    b) that the fields are numbered consistently, beginning with
  247. X       the same low value (usually 1 or 0), and continuing in
  248. X       ascending order until they roll over again to their low
  249. X       value
  250. X
  251. X    Rather than speak merely in the abstract about the format, let
  252. Xme offer a simple illustration taken from the King James Bible.  The
  253. Xfirst verse in the Bible is Genesis chapter 1 verse 1.  This passage
  254. Xmight be designated 1:1:1.  Verses in Genesis chapter 1 would continue
  255. Xin ascending order to verse 31 (1:1:31), after which chapter 2 would
  256. Xbegin (i.e. 1:2:1).  The resulting text would look like:
  257. X
  258. X    ::1:1:1
  259. X    In the beginning God created the heaven and the earth.
  260. X    ::1:1:2
  261. X    And the earth was without form, and void; and darkness was
  262. X    upon the face of the deep. And the Spirit of God moved upon
  263. X    the face of the waters.
  264. X    ::1:1:3
  265. X    And God said, Let there be light: and there was light.
  266. X    ::1:1:4
  267. X    And God saw the light, that it was good: and God divided the
  268. X    light from the darkness.
  269. X    ::1:1:5
  270. X    And God called the light Day, and the darkness he called
  271. X    Night. And the evening and the morning were the first day.
  272. X
  273. X    ...
  274. X
  275. X    ::1:2:1
  276. X    Thus the heavens and the earth were finished, and all the host
  277. X    of them.
  278. X
  279. XAlthough you can use any number of fields you want or need, and can
  280. Xuse any nonnumeric separator (e.g. 01-01-01-05-03), lines containing
  281. Xlocation designators *must* begin with "::," and must be ordered
  282. Xsequentially throughout the input file, paired with the correct text
  283. Xblock in each instance.
  284. X        
  285. X
  286. X--------
  287. X
  288. X
  289. XStep 2:  Indexing the File
  290. X
  291. X    Indexing the file created in step (1) entails compiling and
  292. Xinvoking a program called "makeind."  The compilation end of this
  293. Xprocess would typically be achieved by typing:
  294. X
  295. X    icont -o makeind makeind.icn gettokens.icn indexutl.icn
  296. X
  297. XOne of the files listed just above, gettokens.icn, is of particular
  298. Xinterest.  It contains the tokenizing routine to be used in creating
  299. Xthe main word index.  Should this routine prove unsatisfactory for one
  300. Xreason or another you are free to replace it with something more to
  301. Xyour liking.  Just comment out the old gettokens() routine, and insert
  302. Xthe new one in its place.  Then recompile.
  303. X    Once you have compiled makeind, you must invoke it for the
  304. Xtext file you created in step (1).  Invoking makeind involves
  305. Xspecifying a file to be indexed, the number of fields in location
  306. Xmarkers for that file, and the maximum value for fields.  If you plan
  307. Xon invoking passages by relative location, you must also use the -l
  308. Xoption, which tells makeind to build a .LIM file, which records the
  309. Xhigh values for a specific field throughout the file being indexed.
  310. XLet us say you have examined Genesis 1:31 in the Bible, and want to
  311. Xlook at the next verse.  The only easy way the procedure that handles
  312. Xthis particular chore can know the maximum verse value for Genesis
  313. Xchapter 1 (31) is to store this maximum value in a file.  By supplying
  314. Xmakeind with an -l argument, you are telling it to create a file to
  315. Xstore such values.
  316. X    Just for illustration's sake, let us suppose you want to index
  317. Xthe King James Version (KJV).  How might you invoke makeind to
  318. Xaccomplish this?  First you would need to determine the maximum field
  319. Xvalue for your text.  In the case of the Christian English Bible, this
  320. Xis 176.  The English Bible (including Apocrypha) contains 84 books (at
  321. Xleast in the RSV).  The Protestant KJV contains 66.  The maximum
  322. Xnumber of chapters in any book is 150 (Psalms; 151 for Catholics).
  323. XThe maximum number of verses in any one chapter in any one book is 176
  324. X(Psalm 119).  176 would therefore be the maximum value any field would
  325. Xhave to contain.  You would pass this information to makeind via the
  326. X-m option.  The total number of fields is three, naturally (book,
  327. Xchapter, and verse).  This value would be passed using the -n option.
  328. XAs noted above, in order to use relative locations you would need to
  329. Xtell makeind what field to record max values for.  In our hypothesized
  330. Xscenario, you would want makeind to store the max value for the verse
  331. Xfield for every chapter of every book in the Bible.  The verse field
  332. X(field #3), in other words, is your "rollover" field, and would be
  333. Xpassed to makeind using the -l option.  Assuming "kjv" to be the name
  334. Xof your indexable biblical text, this set of circumstances would imply
  335. Xthe following invocation for makeind:
  336. X
  337. X    makeind -f kjv -m 176 -n 3 -l 3
  338. X
  339. XIf you were to want a case-sensitive index (not a good idea), you
  340. Xwould add "-s" to the argument list above (the only disadvantage a
  341. Xcase-insensitive index would bring is that it would obscure the
  342. XLord/lord, and other similar, distinctions).
  343. X    Actual English Bible texts usually take up 4-5 megabytes.
  344. XIndexing one would require over three times that much core memory, and
  345. Xwould take at least several hours on a fast CPU.  The end result would
  346. Xbe a set of data files occupying about 2 megabytes plus the original
  347. Xfile (which Bibleref compresses down to about 3/4 its original size).
  348. XThe Bible is hardly a small book.  Once these data files were created,
  349. Xthey could be moved, along with the compressed original source file,
  350. Xto any platform you desired.  The old input file is saved with a .BAK
  351. Xextension in case you would like to save it.
  352. X    Having indexed, and having moved the files to wherever you
  353. Xwanted them, you would then be ready for step 3.
  354. X
  355. X
  356. X--------
  357. X
  358. X
  359. XStep 3:  Writing a Program to Access Indexed Files
  360. X
  361. X    When accessing text files such as the Bible, the most useful
  362. Xunit for searches is normally the word.  Let us suppose you are a
  363. Xzealous lay-speaker preparing a talk on fire imagery and divine wrath
  364. Xin the Bible.  You would probably want to look for every passage in
  365. Xthe text that contained words like
  366. X
  367. X    fire, fiery
  368. X    burn
  369. X    furnace
  370. X    etc.
  371. X
  372. XTo refine the search, let us say that you want every instance of one
  373. Xof these fire words that occurs within one verse of a biblical title
  374. Xfor God:
  375. X
  376. X    God
  377. X    LORD
  378. X    etc.
  379. X
  380. XThe searches for fire, fiery, burn, etc. would be accomplished by
  381. Xcalling a routine called retrieve().  Retrieve takes three arguments:
  382. X
  383. X    retrieve(pattern, filename, invert_search)
  384. X
  385. XThe first argument should be a string containing a regular expression
  386. Xbased pattern, such as
  387. X
  388. X    fir(y|e|iness)|flam(e|ing)|burn.*?
  389. X
  390. XNote that the pattern must match words IN THEIR ENTIRETY.  So, for
  391. Xinstance, "fir[ie]" would not catch "fieriness," but rather only
  392. X"fire."  Likewise, if you want every string beginning with the
  393. Xsequence "burn," the string "burn" will not work.  Use "burn.*"
  394. Xinstead.  The filename argument supplies retrieve() with the name of
  395. Xthe original text file.  The last argument, if nonnull, inverts the
  396. Xsense of the search (a la egrep -v).  In the case of the fire words
  397. Xmentioned above, one would invoke retrieve() as follows:
  398. X
  399. X    hits1 := retrieve("fir(y|e|iness)|flam(e|ing)|burn.*?", "kjv")
  400. X
  401. XFor the divine names, one would do something along these lines:
  402. X
  403. X    hits2 := retrieve("god|lord", "kjv")
  404. X
  405. X    Having finished the basic word searches, one would then
  406. Xperform a set intersection on them.  If we are looking for fire words
  407. Xwhich occur at most one verse away from a divine name, then we would
  408. Xspecify 1 as our range (as opposed to, say, zero), and the verse as
  409. Xour unit.  The utility you would use to carry out the search is
  410. Xr_and().  R_and() would be invoked as follows:
  411. X
  412. X    hits3 := r_and(hits1, hits2, "kjv", 3, 1)
  413. X
  414. XThe last two arguments, 3 and 1, specify field three (the "verse"
  415. Xfield) and field 1 (the range).
  416. X    To display the text for your "hit list" (hits3 above), you
  417. Xwould call bitmap_2_text():
  418. X
  419. X    every write(!bitmap_2_text(hits3, "kjv"))
  420. X
  421. XBitmap_2_text converts the location designators contained in hits3
  422. Xinto actual text.
  423. X    The three basic functions mentioned above - retrieve(),
  424. Xr_and(), and bitmap_2_text() - are contained in the three distinct
  425. Xfiles (retrieve.icn, retrops.icn, and bmp2text.icn, respectively).
  426. XOther useful routines are included in these files, and also in
  427. Xwhatnext.icn.  If you are planning on writing a retrieval engine for
  428. Xserious work of some kind, you would probably want to construct a mini
  429. Xinterpreter, which would convert strings typed in by the user at
  430. Xrun-time into internal search and retrieval operations.
  431. X    Note that I have included no routine to parse or expand
  432. Xhuman-readable input (the nature of which will naturally vary from
  433. Xtext to text).  Again, using the Bible as our hypothetical case, it
  434. Xwould be very useful to be able to ask for every passage in, say,
  435. XGenesis chapters 2 through 4, and to be able to print these to the
  436. Xscreen.  Doing this would require a parsing routine to break down the
  437. Xreferences, and map them to retrieve-internal format.  The routine
  438. Xwould then have to generate all valid locations from the minimum value
  439. Xin chapter 2 above to the max in chapter 4.  See the file whatnext.icn
  440. Xfor some aids in accomplishing this sort of task.
  441. X
  442. X
  443. X--------
  444. X
  445. X
  446. XStep 4:  Compiling and Running Your Program
  447. X
  448. X    Assuming you have written a search/retrieval program using the
  449. Xroutines contained in retrieve.icn, retrops.icn, bmp2text.icn, and
  450. Xwhatnext.icn, you would now be ready to compile it.  In order to
  451. Xfunction properly, these routines would need to be linked with
  452. Xinitfile.icn and indexutl.icn.  Specific dependencies are noted in the
  453. Xindividual files in case there is any confusion.
  454. X    If you have made significant use of this package, you probably
  455. Xshould not worry about the exact dependencies, though.  Just link
  456. Xeverything in together, and worry about what isn't needed after you
  457. Xhave fully tested your program:
  458. X
  459. X    icont -o yourprog yourprog.icn initfile.icn indexutl.icn \
  460. X        retrieve.icn retrops.icn bmp2text.icn binsrch.icn
  461. X
  462. X
  463. X--------
  464. X
  465. X
  466. XProblems, bugs:
  467. X
  468. X    This is really an early test release of the retrieve package.
  469. XI use it for various things.  For instance, I recently retrieved a
  470. Xtext file containing informal reviews of a number of science fiction
  471. Xworks.  My father likes SciFi, and it was close to Fathers' Day, so I
  472. Xindexed the file, and performed cross-referenced searches for words
  473. Xlike "very good," "brilliant," and "excellent," omitting authors my
  474. Xfather has certainly read (e.g. Herbert, Azimov, etc.).  I also had
  475. Xoccasion to write a retrieval engine for the King James Bible (hence
  476. Xthe many examples from this text), and to construct a retrieval
  477. Xpackage for the Hebrew Bible, which I am now using to gather data for
  478. Xvarious chapters of my dissertation.  I'm happy, incidentally, to hand
  479. Xout copies of my KJV retrieval program.  It's a clean little program
  480. Xthat doubtless many would find useful.  The Hebrew Bible retrieval
  481. Xpackage I'll hand out as well, but only to fully competent Icon
  482. Xprogrammers who feel comfortable with Hebrew and Aramaic.  This latter
  483. Xretrieval package a much less finished product, and would almost
  484. Xcertainly need to be hacked to work on platforms other than what I
  485. Xhave here at home (a Xenix/386 setup with a VGA).
  486. X    In general, I hope that someone out there will find these
  487. Xroutines useful, if for no other reason than that it will mean that I
  488. Xget some offsite testing.  Obviously, the whole package could have
  489. Xbeen written/maintained in C or something that might offer much better
  490. Xperformance.  Doing so would, however, have entailed a considerable
  491. Xloss of flexibility, and would have required a lot more time on my
  492. Xpart.  Right now, the retrieve package occupies about 70k of basic
  493. Xsource files, probably half of which consists of comments.  When
  494. Xcompiled together with a moderate-size user interface, the total
  495. Xpackage typically comes to about 150k.  In-core size typically runs
  496. Xabout 300k on my home machine here (a Xenix/386 box), with the basic
  497. Xrun-time interpreter taking up a good chunk of that space all on its
  498. Xown.  It's not a small package, but I've found it a nice base for
  499. Xrapid prototyping and development of small to medium-size search and
  500. Xretrieval engines.
  501. X
  502. X   -Richard L. Goerwitz              goer%sophist@uchicago.bitnet
  503. X   goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer
  504. SHAR_EOF
  505. true || echo 'restore of README.rtv failed'
  506. rm -f _shar_wnt_.tmp
  507. fi
  508. # ============= outbits.icn ==============
  509. if test -f 'outbits.icn' -a X"$1" != X"-c"; then
  510.     echo 'x - skipping outbits.icn (File already exists)'
  511.     rm -f _shar_wnt_.tmp
  512. else
  513. > _shar_wnt_.tmp
  514. echo 'x - extracting outbits.icn (Text)'
  515. sed 's/^X//' << 'SHAR_EOF' > 'outbits.icn' &&
  516. X############################################################################
  517. X#
  518. X#    Name:     outbits.icn
  519. X#
  520. X#    Title:     output variable-length characters in byte-size chunks
  521. X#
  522. X#    Author:     Richard L. Goerwitz
  523. X#
  524. X#    Version: 1.5
  525. X#
  526. X############################################################################
  527. X#
  528. X#  In any number of instances (e.g. when outputting variable-length
  529. X#  characters or fixed-length encoded strings), the programmer must
  530. X#  fit variable and/or non-byte-sized blocks into standard 8-bit
  531. X#  bytes.  Outbits() performs this task.
  532. X#
  533. X#  Pass to outbits(i, len) an integer i, and a length parameter (len),
  534. X#  and outbits will suspend byte-sized chunks of i converted to
  535. X#  characters (most significant bits first) until there is not enough
  536. X#  left of i to fill up an 8-bit character.  The remaining portion is
  537. X#  stored in a buffer until outbits() is called again, at which point
  538. X#  the buffer is combined with the new i and then output in the same
  539. X#  manner as before.  The buffer is flushed by calling outbits() with
  540. X#  a null i argument.  Note that len gives the number of bits there
  541. X#  are in i (or at least the number of bits you want preserved; those
  542. X#  that are discarded are the most significant ones). 
  543. X#
  544. X#  A trivial example of how outbits() might be used:
  545. X#
  546. X#      outtext := open("some.file.name","w")
  547. X#      l := [1,2,3,4]
  548. X#      every writes(outtext, outbits(!l,3))
  549. X#      writes(outtext, outbits(&null,3))           # flush buffer
  550. X#
  551. X#  List l may be reconstructed with inbits() (see inbits.icn):
  552. X#
  553. X#      intext := open("some.file.name")
  554. X#      l := []
  555. X#      while put(l, inbits(intext, 3))
  556. X#
  557. X#  Note that outbits() is a generator, while inbits() is not.
  558. X#
  559. X############################################################################
  560. X#
  561. X#  Links: none
  562. X#  See also: inbits.icn
  563. X#
  564. X############################################################################
  565. X
  566. X
  567. Xprocedure outbits(i, len)
  568. X
  569. X    local old_part, new_part, window, old_byte_mask
  570. X    static old_i, old_len, byte_length, byte_mask
  571. X    initial {
  572. X    old_i := old_len := 0
  573. X    byte_length := 8
  574. X    byte_mask := (2^byte_length)-1
  575. X    }
  576. X
  577. X    old_byte_mask := (0 < 2^old_len - 1) | 0
  578. X    window := byte_length - old_len
  579. X    old_part := ishift(iand(old_i, old_byte_mask), window)
  580. X
  581. X    # If we have a no-arg invocation, then flush buffer (old_i).
  582. X    if /i then {
  583. X    if old_len > 0 then {
  584. X        old_i := old_len := 0
  585. X        return char(old_part)
  586. X    } else {
  587. X        old_i := old_len := 0
  588. X        fail
  589. X    }
  590. X    } else {
  591. X    new_part := ishift(i, window-len)
  592. X    len -:= (len >= window) | {
  593. X        old_len +:= len
  594. X        old_i := ior(ishift(old_part, len-window), i)
  595. X        fail
  596. X    }
  597. X#    For debugging purposes.
  598. X#    write("old_byte_mask = ", old_byte_mask)
  599. X#    write("window = ", image(window))
  600. X#    write("old_part = ", image(old_part))
  601. X#    write("new_part = ", image(new_part))
  602. X#    write("outputting ", image(ior(old_part, new_part)))
  603. X    suspend char(ior(old_part, new_part))
  604. X    }
  605. X
  606. X    until len < byte_length do {
  607. X    suspend char(iand(ishift(i, byte_length-len), byte_mask))
  608. X    len -:= byte_length
  609. X    }
  610. X
  611. X    old_len := len
  612. X    old_i := i
  613. X    fail
  614. X
  615. Xend
  616. SHAR_EOF
  617. true || echo 'restore of outbits.icn failed'
  618. rm -f _shar_wnt_.tmp
  619. fi
  620. rm -f _shar_seq_.tmp
  621. echo You have unpacked the last part
  622. exit 0
  623.  
  624. exit 0 # Just in case...
  625. -- 
  626. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  627. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  628. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  629. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  630.