home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OL.LZH / PROCS.LZH / SENTENCE.ICN < prev    next >
Text File  |  1991-07-13  |  5KB  |  153 lines

  1. ############################################################################
  2. #
  3. #    Name:     sentence.icn
  4. #
  5. #    Title:     generate sentences in file
  6. #
  7. #    Author:     Richard L. Goerwitz
  8. #
  9. #    Date:     June 3, 1991
  10. #
  11. #    Version: 1.2
  12. #
  13. ############################################################################
  14. #  
  15. #  sentence(f)   - suspends sentences from file f
  16. #
  17. #  A lot of grammatical and stylistic analysis programs are predicated
  18. #  on the notion of a sentence.  For instance, some programs count the
  19. #  number of words in each sentence.  Other count the number and length
  20. #  of clauses.  Still others pedantically check for sentence-final par-
  21. #  ticles and prepositions.
  22. #
  23. #  This procedure, sentence(), is supposed to be used as a filter for
  24. #  ASCII text files, suspending everything that looks remotely like a
  25. #  sentence in them.
  26. #
  27. #  BUGS:  Cannot correctly parse sentences with constructs like "R. L.
  28. #  Goerwitz" in them.  The algorithm can be much improved simply by
  29. #  checking to see if the word after the period is in /usr/dict/words
  30. #  or whatever your system dictionary file is.  If it isn't, then it's
  31. #  likely not to be the beginning of a sentence (this also is not in-
  32. #  fallible, naturally).
  33. #
  34. ############################################################################
  35. #
  36. #  Requires:  co-expressions
  37. #
  38. ############################################################################
  39.  
  40.  
  41. procedure sentence(intext)
  42.  
  43.     local sentence, get_line, line, tmp_s, end_part, whole_thing
  44.     static inits, punct
  45.     initial {
  46.     inits := &ucase ++ &digits
  47.     punct := ".\"'!?)]"
  48.     }
  49.     sentence := ""
  50.     get_line := create read_line(intext)
  51.  
  52.     while line := @get_line do {
  53.  
  54.     # If we hit a blank line, it's a signal from read_line that we
  55.     # have encountered a change in the indentation level, and
  56.     # should call it a sentence break (though it could just be
  57.     # indentation for a quote, a section header, etc., it seems
  58.     # these all indicate major, sentence-like divisions in the
  59.     # text).
  60.     if line == "" then {
  61.         suspend sentence
  62.         sentence := ""
  63.         next
  64.     }
  65.  
  66.     # Go on until you can't find any more sentence-endings in line,
  67.     # then break and get another line.
  68.     repeat {
  69.  
  70.         # Scan for a sentence break somewhere in line.
  71.         line ? {
  72.  
  73.         # Ugly, but it works.  Look for sequences containing
  74.         # things like periods and question marks, followed by
  75.         # a space and another space or a word beginning with
  76.         # a capital letter.  If we don't have enough context,
  77.         # append the next line from intext to line & scan again.
  78.         if tmp_s := tab(upto(punct)) &
  79.             upto('!?.', end_part := tab(many(punct))) &
  80.             not (pos(-1), line ||:= @get_line, next) &
  81.             =" " & (=" " | (tab(many('\'"('))|&null,any(inits)))
  82.         # IF YOU WANT TO ADD A DICTIONARY CHECK, then read in
  83.         # a dictionary like /usr/dict/words, and then change
  84.         # any(inits) above to something like (any(inits),
  85.         # longstr(list_of_usrdictwords,map(&subject),&pos), =" ")
  86.         # where longstr() matches each string in list_of_usr-
  87.         # dictwords.
  88.         then {
  89.  
  90.             # Don't bother with little two-letter hunks.
  91.             whole_thing := sentence || tmp_s || end_part
  92.             if *whole_thing > 3 | find(" ",whole_thing)
  93.             then suspend whole_thing
  94.  
  95.             tab(many(' '))
  96.             line := tab(0)
  97.             sentence := ""
  98.             next
  99.         }
  100.         else break
  101.         }
  102.     }
  103.  
  104.     # Otherwise just tack line onto sentence & try again.
  105.     sentence ||:= line
  106.     }
  107.  
  108.     return sentence
  109.  
  110. end
  111.  
  112.  
  113.  
  114.  
  115. procedure read_line(intext)
  116.  
  117.     local new_line, ilevel, junk_count, space_count, line
  118.     static last_ilevel, blank_flag
  119.     last_ilevel := 0
  120.  
  121.     while line := trim(!intext,'\t ') do {
  122.  
  123.     # Check to see if line is blank; if so, set blank_flag.
  124.     if line == "" then
  125.         { blank_flag := 1; next }
  126.  
  127.     # Determine current indentation level.
  128.     detab(line) ? {
  129.         ilevel := *tab(many(' ')) | 0
  130.     }
  131.  
  132.     line ? {
  133.  
  134.         tab(many('\t '))
  135.  
  136.         # Signal the calling procedure if there is a change in the
  137.         # indentation level by suspending a blank line.
  138.         if (ilevel > last_ilevel) | (ilevel < last_ilevel, \blank_flag)
  139.         then suspend ""
  140.         last_ilevel := ilevel
  141.  
  142.         # Put a space on the end of line, unless it ends in a dash.
  143.         new_line := tab(-1) || (="-" | (move(1) || " "))
  144.         # Make sure the flag that indicates blank lines is unset.
  145.         blank_flag := &null
  146.     }
  147.  
  148.     # Suspend the newly reformatted, trimmed, space-terminated line.
  149.     suspend new_line
  150.     }
  151.  
  152. end
  153.