home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol094 / indexer.doc < prev    next >
Text File  |  1984-04-29  |  13KB  |  281 lines

  1.               The INDEXER Program
  2.  
  3. The Indexing Problem
  4.  
  5. An index is a table that lists the important topics of a book in
  6. alphabetical order, showing for each the numbers of the pages on
  7. which that topic is mentioned.    An index is an indispensable
  8. part of any non-fiction book.  Even a poor index can give better
  9. access to a book than a table of contents can, while a good
  10. index increases the utility of a book many times.
  11.  
  12. Indexing a book is a skilled job.  The indexer must understand
  13. the subject of the book well, so as to know what the important
  14. topics are.  The indexer must read the book and comprehend it,
  15. so as to know when a reference to a topic is important enough
  16. to merit an index entry.  The indexer must understand the
  17. intended use, and users, of the book well, so as to know the
  18. terms that they will expect to find in the index.
  19.  
  20. An index of sorts can be built automatically by sorting the
  21. words of a document file, eliminating duplicates, and appending
  22. the page numbers on which the words appeared.  The indexes of
  23. the Pascal/Z manuals appear to have been made by such a process,
  24. and they demonstrate the failings of the method.  It only
  25. indexes words, it does not index topics.  It works only to the
  26. extent that the topics of the book are fully expressed in single
  27. words (and to the extent that the words were used consistently).
  28. It is completely unselective, showing every reference no matter
  29. how trivial.  There can be no provision for sub-entries under a
  30. major topic, nor for multiple entries for a topic under
  31. different terms.
  32.  
  33. A good index can be built automatically by some word processing
  34. programs.  The writer embeds indexing commands within the text
  35. of a document.    When the program formats the document for
  36. printing, it writes each embedded index term to a disk file with
  37. the page number on which it appeared.  This method can work
  38. well, since the entries are topical terms chosen by the writer,
  39. who embeds them only at the relevant points.  I have developed
  40. and used such a system for documents formatted by Magic Wand.
  41.  
  42. Both automatic methods fail if the book is to be typeset.  They
  43. rely on page numbers as they exist in the machine-printed form
  44. of the work.  The page numbers of the typeset work will be
  45. different, so the machine-made index will have to be heavily
  46. edited or completely remade.
  47.  
  48. And of course, the automatic methods can't work when the book to
  49. be indexed is not available in machine-readable form.  In these
  50. cases, the index must be made by hand.    In the traditional
  51. method, the indexer sets up a file of 4x5 (index!) cards, one
  52. for each topic to be indexed.  Then he/she reads the book and,
  53. wherever a topic appears, writes the page number on its card.
  54. The sorted cards provide the material for typing the index.
  55.  
  56. The INDEXER program is a machine aid for a human indexer.  It
  57. does the job of the pile of index cards, and it makes the
  58. finished index automatically, as a disk file that can be edited
  59. or printed.
  60.  
  61.  
  62. INDEXER's Operations
  63.  
  64.  
  65. The INDEXER program works as follows.  When invoked as a CP/M
  66. command, it looks for a file containing a saved index in
  67. internal form.    If there is such a file (one named INDEXER.TRE
  68. on the default drive), the program loads it, and work can
  69. continue from where you left off before.
  70.  
  71. Once initialized, INDEXER prompts for a "term."  You may type an
  72. index term of up to 64 characters.  Spaces, commas, and indeed
  73. any printable characters are allowed.  You may use the backspace
  74. key to correct typing errors.  The end of the term is signalled
  75. with the Return key.
  76.  
  77. INDEXER files the term in storage and prompts for a "page."  It
  78. expects the page number of a reference to the term just entered,
  79. an integer from 1 to 32767.  It will accept a negative integer
  80. and store it.  It will also accept a zero, but for reasons of
  81. its own it will store a page number of zero as -32767.    The
  82. program stores any term or subterm only once.  It collects all
  83. the page references for that term and stores them in a list with
  84. the term.
  85.  
  86. You may go on entering terms and pages as long as you like.
  87. When you want to stop work, enter a term of length zero; that
  88. is, press Return at the "term" prompt.    Then INDEXER writes the
  89. index to disk in two forms.  It writes its collection of terms
  90. and pages in internal form as INDEXER.TRE, so that it will be
  91. able to reload them and pick up work where it left off.  It also
  92. writes a finished index file as INDEXER.OUT.  This file can be
  93. edited with any word processor for final printing.
  94.  
  95.  
  96. Using Sub-terms
  97.  
  98.  
  99. INDEXER allows any term to have sub-terms and sub-sub-terms to a
  100. depth of nine.    Subterms are very useful in indexes; they allow
  101. you to group subtopics under a main topic entry.  Some readers
  102. will look for a topic under its general term; others will look
  103. for it under a very specific term.  For example, a good index
  104. for the Pascal/Z manual might index the CASE statement two or
  105. even three ways:
  106.        ...
  107.       CASE statement 27
  108.      ELSE allowed 4, 69
  109.      option J 41
  110.      speed of vs. IF 43
  111.       ...
  112.       ELSE clause 27
  113.      with CASE 4, 69
  114.       ...
  115.       statement types
  116.      assignment 25
  117.      BEGIN 32
  118.      CASE 27
  119.       ...
  120.  
  121. To INDEXER, each group of subterms is a little index of its own.
  122. Its terms are stored and sorted, and their page numbers are
  123. collected, just as is done for the main terms.    When it prepares
  124. the output file, INDEXER indents once for each sub-term level.
  125.  
  126. To enter a subterm, you first enter its main term.  But instead
  127. of ending the main term by pressing Return, you end it by
  128. pressing LineFeed (or control-J if your terminal lacks a
  129. LineFeed key).    INDEXER then prompts for a " . .term," indenting
  130. one level on the screen.  Enter the subterm just as you would a
  131. main term.  End it, too, with LineFeed if you are entering a
  132. sub-subterm.  When you eventually end a term with Return, you
  133. will be prompted for a page number as usual.  That page number
  134. will be associated with the subterm, not with its superior
  135. term(s).
  136.  
  137.  
  138. Term Recall
  139.  
  140.  
  141. Typing all these terms is tedious, but INDEXER has a feature
  142. which can save a lot of the labor.  The feature is called Term
  143. Recall, and it serves two purposes.
  144.  
  145. You recall a term by typing some of its initial letters, then
  146. pressing the Escape key.  INDEXER searches its list of terms for
  147. the alphabetically-lowest one that matches the initial letters
  148. you have typed to that point.  It then completes the term on the
  149. screen by typing the remaining letters of that term.  If that is
  150. the term you wanted to recall, you may then press Return or
  151. LineFeed just as if you had typed the whole term yourself.  Or
  152. you can modify the term as it appears then by backspacing and
  153. retyping part of it.
  154.  
  155. If the term is not the one you want, just press Escape again.
  156. INDEXER will wipe out the letters it supplied, find the next
  157. term in alphabetic order, and show its final letters.  If you
  158. keep pressing Escape, you will be shown all the terms that match
  159. the initial letters you typed.    When there are no more, INDEXER
  160. beeps the console alarm.
  161.  
  162. If you decide that you don't want any of the recalled terms,
  163. press the Delete key.  INDEXER will restore the line to just the
  164. characters you had typed initially.
  165.  
  166. Term Recall can save a lot of typing.  It also provides a way to
  167. review the terms you have defined so far.  Press Escape without
  168. typing any initial letters at all; INDEXER will complete your
  169. non-existent entry by showing you the first of all the terms it
  170. has, and will step through all the terms as you press Escape.
  171.  
  172.  
  173. How To Index With INDEXER
  174.  
  175.  
  176. Start by marking up a copy of the book.  Read through it
  177. carefully with a pencil and a highlighting pen in hand.  Mark
  178. every term to be indexed, and note in the margins where a topic
  179. should be entered under more than one term.
  180.  
  181. Then, book in lap, start up INDEXER using the INDEXER.SUB submit
  182. file:
  183.  
  184.       SUBMIT INDEXER bookname
  185.  
  186. This submit file contains CP/M commands that will keep INDEXER's
  187. two output files as bookname.TRE and bookname.INX, so you can
  188. have index work in progress for several different books at once.
  189.  
  190. When INDEXER starts up, begin entering terms and pages in the
  191. order they occur in the book. When you have finished the book,
  192. or when you want to stop, just hit Return at the "term" prompt.
  193. INDEXER will write its files, and the submit file will rename
  194. them.  If you are not finished, come back to the index later
  195. with the same submit command; you will be able to pick up where
  196. you left off.
  197.  
  198. You may print bookname.INX, or edit it with your favorite word
  199. processor to insert print-formatting commands.    One reason for
  200. editing the file is to delete errors.  There is no way to get
  201. INDEXER to forget a term once you have entered it.  If you enter
  202. a term incorrectly, give it a page number of zero.  That will
  203. show up in the output file as page 32767.  You can find such
  204. lines with your editor and delete them.
  205.  
  206.  
  207. INDEXER's Limitations
  208.  
  209.  
  210. Please do not enter many index terms in alphabetical order.  The
  211. scheme for term storage (a binary tree) assumes that terms will
  212. be entered in approximately random sequence.  If they are all
  213. given in alphabetic order, the program will fail.
  214.  
  215. INDEXER's storage is large, but not too large.  To put it as a
  216. formula, INDEXER uses 15+(2*termlength) bytes for every unique
  217. term or subterm, and four bytes for every page number.    If terms
  218. average about 20 bytes each, and if there are about two page
  219. numbers per term, INDEXER can handle about 500 terms in a 64KB
  220. machine.  If the program runs out of storage, it will crash with
  221. a run-time error message.  So if your index is approaching 500
  222. terms (about nine pages as printed), save your work often.
  223.  
  224.  
  225. Programmer Details
  226.  
  227.  
  228. INDEXER stores terms as character strings.  I chose to do my own
  229. strings rather than using the Pascal/Z string type, so that the
  230. program could be ported to other compilers.  Since most terms
  231. are shorter than the 64 bytes allowed, keeping every term as an
  232. independent string would waste storage.  Except when they are
  233. being entered or written, terms are stored compactly in blocks
  234. of 2048 bytes, and referenced by a block number and an offset
  235. index.    I've allowed for up to 16 blocks (32Kb).  The code is
  236. about 18Kb, so what with Pascal stack space and the binary tree
  237. nodes, the full 16 blocks will probably never be allocated.
  238.  
  239. Terms are stored in a binary tree, and subterms under a term are
  240. stored in a tree dangling from the superior term's node.  Page
  241. references are stored in an ordered chain anchored in the term's
  242. node.  In some cases, the trees are processed with recursive
  243. algorithms, as traditional (see J and W program 11.5).    But more
  244. often, recursion was inconvenient and would have eaten up too
  245. much stack space.  Where a tree is to be "walked" in lexical
  246. (in-) order, it is done by setting up a tree-walk record which
  247. is processed by a "treestep" function.    That figures out the
  248. next node and returns a pointer to it, saving the state of the
  249. walk in the tree-walk record.  I played a lot of games with the
  250. trees, some of which are (I think) quite clever.  The Term
  251. Recall feature is based on tree-walking, and it turned out to be
  252. a really slick user interface.
  253.  
  254. An index has to be in true alphabetical, not ASCII, order.  The
  255. only way to make "Apple" come after "anteater" is to do all
  256. comparisons in upper case.  To keep the speed up, I stored every
  257. term two ways: as entered, and in all-caps.  The all-caps form
  258. is used for all comparisons; the as-entered form is used for all
  259. output.  This has the side effect that the terms "Apple" and
  260. "apple" are identical, and only the first one entered will
  261. appear in the output.  If storage was critical, it would be
  262. possible to store only the original form of a term, and convert
  263. it to all-caps prior to any comparison.
  264.  
  265. There is no provision for odd page number systems.  The program
  266. can't handle hyphenated or alphabetical page numbers.  It can be
  267. done, but it requires making a page number into a string, not an
  268. integer.  It also introduces complications in keeping page
  269. numbers in order (getting page "7-2" to collate before page
  270. "7-10") and in eliding sequential page numbers (compressing page
  271. numbers 7-1, 7-2, and 7-3 into a single reference).  Since the
  272. program is designed for use on real books, integers are fine.
  273.  
  274. At 800+ lines, INDEXER is one big program.  I wouldn't be at all
  275. surprised if it still contained a bug or two, so be alert.  It
  276. compiles, assembles, and links in less than 10 minutes on a 4
  277. MHZ system with double density drives.    I tried applying the
  278. PASOPT program to it, with unimpressive results.  PASOPT read
  279. that immense source file and managed to save 108 bytes of
  280. machine code, or less than one percent.  Wowee.
  281.