home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / e / epmtex12.zip / EPMLEX.TEX next >
Text File  |  1993-01-27  |  32KB  |  777 lines

  1. /*
  2. ╔════════════════════════════════════════════════════════════════════════════╗
  3. ║ What's it called: EPMLEX.E                                                 ║
  4. ║                                                                            ║
  5. ║ What does it do : Spell checking and Synonym support for the EPM editor.   ║
  6. ║                                                                            ║
  7. ║                   There are two major components to spell and synonym      ║
  8. ║                   checking in EPM.  The first and most important is the    ║
  9. ║                   actual word verification and word/dictionary lookup.     ║
  10. ║                   This is done by the internal EPM opcode, "lexam".        ║
  11. ║                   This opcode can take on the variations indicated by      ║
  12. ║                   the LXF constants defined below.                         ║
  13. ║                                                                            ║
  14. ║                   The second most important part to word checking is the   ║
  15. ║                   presentation of the results.  This is neatly done in     ║
  16. ║                   EPM using a PM list box.  E has an internal list dialog  ║
  17. ║                   accessible through the 'listbox' function.  See          ║
  18. ║                   STDCTRL.E for details on the 'listbox' function.         ║
  19. ║                                                                            ║
  20. ║ Who and When    : Larry Margolis, 11/91                                    ║
  21. ║ Updated from the original                                                  ║
  22. ║ EPMLEX.E done by: C.Maurer,  R.Yozzo,  Gennaro Cuomo, and Larry Margolis   ║
  23. ║                   1/89 - 10/90                                             ║
  24. ║                                                                            ║
  25. ║ Modified by Jon Hacker 1/93 (search for JBH to find mods)                  ║
  26. ╚════════════════════════════════════════════════════════════════════════════╝
  27. */
  28. ; Customizing information:  Any of the following customizing constants can
  29. ; be overridden by including the appropriate definition after a CONST statement
  30. ; in your MYCNF.E.
  31. ;
  32. ; Example of customizing:  include the following lines in your MYCNF.E
  33. ; (with the ';' deleted from the beginning of each line).
  34. ;
  35. ;    const                               -- Customizations for EPMLEX:
  36. ;       RESPECT_case_for_addenda = 0     -- Ignore case of addenda words.
  37. ;       my_ADDENDA_FILENAME= 'd:\doc\margoli.adf'     -- I keep these in my
  38. ;       my_DICTIONARY_FILENAME= 'd:\doc\us.dct'       -- d:\doc directory.
  39. ; Can also have multiple dictionaries, separated by spaces - all will be loaded:
  40. ;       my_DICTIONARY_FILENAME= 'd:\doc\us.dct d:\doc\medical.dct d:\doc\legal.dct'
  41.  
  42. compile if not defined(SMALL)  -- If SMALL not defined, then being separately compiled
  43. include 'stdconst.e'
  44.  define INCLUDING_FILE = 'EPMLEX.E'
  45.    tryinclude 'MYCNF.E'        -- Include the user's configuration customizations.
  46.  compile if not defined(SITE_CONFIG)
  47.     const SITE_CONFIG = 'SITECNF.E'
  48.  compile endif
  49.  compile if SITE_CONFIG
  50.     tryinclude SITE_CONFIG
  51.  compile endif
  52. const
  53.  compile if not defined(SPELL_SUPPORT)  -- Must set here, since set to 0 in ENGLISH.E
  54.   compile if EVERSION >= 5
  55.  SPELL_SUPPORT = 'DYNALINK'          -- New default
  56.   compile else
  57.  SPELL_SUPPORT = 0
  58.   compile endif
  59.  compile endif
  60.  compile if not defined(NLS_LANGUAGE)
  61.   const NLS_LANGUAGE = 'ENGLISH'
  62.  compile endif
  63. include NLS_LANGUAGE'.e'
  64. compile endif
  65.  
  66. const
  67. compile if not defined(PROOF_DIALOG_FIXED)
  68.    PROOF_DIALOG_FIXED = 0               -- 1 if dialog should stay in one spot
  69. compile endif
  70.  
  71. compile if not defined(ADDENDASUPPORT)
  72.    ADDENDASUPPORT =  1                  -- 1 if addenda support
  73. compile endif
  74.  
  75. compile if ADDENDASUPPORT
  76.  compile if not defined(RESPECT_case_for_addenda)
  77. RESPECT_case_for_addenda     = 1        /* If addenda entries are to be     */
  78.  compile endif                          /* placed in the addenda without    */
  79.                                         /* modifying their case, then       */
  80.                                         /* this variable should be 1        */
  81.                                         /* Otherwise, it should be 0        */
  82. compile endif -- ADDENDASUPPORT
  83.  
  84.  
  85. const
  86. ; Functions
  87. compile if EVERSION >= 5.50     -- Use the new function numbers
  88. LXFINIT   = 0     /* Initialize                   */
  89. LXFTERM   = 1     /* Terminate                    */
  90. LXFGDIC   = 2     /* Pickup Dictionary            */
  91. LXFFDIC   = 3     /* Drop Dictionary              */
  92. LXFSETADD = 4     /* Set Addenda Language Type    */
  93. LXFAD2TRS = 5     /* Add to Transient Addenda     */
  94. LXFREDTRS = 6     /* Read from Transient Addenda  */
  95. LXFSAVTRS = 7     /* Save Transient Addenda       */
  96. LXFVERFY  = 8     /* Verification                 */
  97. LXFSPAID  = 9     /* Spelling Aid                 */
  98. LXFHYPH   =10     /* Hyphenation                  */
  99. LXFDHYPH  =11     /* Dehyphenation                */
  100. LXFSYN    =12     /* Synonym                      */
  101. LXFAMUGDIC=255    /* Addenda Pickup Dictionary    */
  102.          /* (Pseudo-op; calls LXFGDIC internally) */
  103. compile else                    -- The old way; uses strings
  104. LXFINIT   = 'I'    -- Initialize
  105. LXFTERM   = 'T'    -- Terminate
  106. LXFGDIC   = 'PI'   -- Pickup Dictionary
  107. LXFFDIC   = 'DR'   -- Drop Dictionary
  108. LXFAD2TRS = 'ADDI' -- Add(ition) to Transient Addenda
  109. LXFVERFY  = 'V'    -- Verification
  110. LXFSPAID  = 'SP'   -- Spelling Aid
  111. LXFSYN    = 'SY'   -- Synonym
  112. LXFAMUGDIC= 'ADDE' -- Addenda Pickup Dictionary
  113. compile endif
  114.  
  115. ; Return codes
  116. LXRFGOOD = 0000   /* Function Successful:  Good Return Code                */
  117. LXRFNFND = 0100   /* Function Unsuccessful: Word Not Found                 */
  118. LXRFDUPD = 0107   /* Function Unsuccessful: Duplicate Dictionary           */
  119. LXRFINIT = 0200   /* PC LEXAM Not Initialized: Control Block/Parameter Err */
  120. LXRFIFCN = 0201   /* Invalid Function                                      */
  121.  
  122. definit
  123.    universal  addenda_has_been_modified
  124.    universal  ADDENDA_FILENAME
  125.    universal  DICTIONARY_FILENAME
  126.    universal  Dictionary_loaded
  127.  
  128. ; Note:  don't initialize the universals here for EPM if SPELL_SUPPORT =
  129. ; 'DYNALINK'; it will be done in STDCNF so that this won't override the
  130. ; config info read from the .INI file.
  131. compile if EVERSION < 5 or SPELL_SUPPORT <> 'DYNALINK'
  132.  compile if defined(my_ADDENDA_FILENAME)
  133.    ADDENDA_FILENAME= my_ADDENDA_FILENAME
  134.  compile else
  135.    ADDENDA_FILENAME= 'c:\lexam\lexam.adl'
  136.  compile endif
  137.  
  138.  compile if defined(my_DICTIONARY_FILENAME)
  139.    DICTIONARY_FILENAME= my_DICTIONARY_FILENAME
  140.  compile else
  141.    DICTIONARY_FILENAME= 'c:\lexam\us.dct'
  142.  compile endif
  143. compile endif
  144.  
  145.    addenda_has_been_modified=0
  146.    Dictionary_loaded = 0
  147.  
  148. /*
  149. ╔════════════════════════════════════════════════════════════════════════════╗
  150. ║ Synonym Support                                                            ║
  151. ╚════════════════════════════════════════════════════════════════════════════╝
  152. */
  153. /*
  154. ┌────────────────────────────────────────────────────────────────────────────┐
  155. │ What's it called: syn                                                      │
  156. │                                                                            │
  157. │ What does it do : The syn command uses E's lexam support to retrieve       │
  158. │                   possible synonyms for a specified word.                  │
  159. │                   If synonyms are found a                                  │
  160. │                   PM list box is shown containing the possible new words.  │
  161. │                                                                            │
  162. └────────────────────────────────────────────────────────────────────────────┘
  163. */
  164. defc syn =
  165.    if load_lexam() then
  166.      return
  167.    endif
  168.    call pbegin_word()
  169.    call synonym()
  170.    call drop_dictionary()
  171.  
  172.  
  173. /*
  174. ┌────────────────────────────────────────────────────────────────────────────┐
  175. │ What's it called: synonym()                                                │
  176. │                                                                            │
  177. │ What does it do : checks the next word on a line for its possible synonyms.│
  178. │                   possible synonyms for a specified word.                  │
  179. │                   If synonyms are found a                                  │
  180. │                   PM list box is shown containing the possible new words.  │
  181. │                                                                            │
  182. └────────────────────────────────────────────────────────────────────────────┘
  183. */
  184. defproc synonym()
  185.    getline line                           /* get the current line          */
  186.    if line<>'' then                       /* if it is NOT blank            */
  187.       i=.col                              /* get the current column number */
  188.       l=pos(' ',line,.col)                /* get possible word             */
  189.       if l=0 then                         /* could this be a word???       */
  190.          l=length(line)+1
  191.          if l<i then l=i endif
  192.       endif
  193.       wrd=strip(substr(line,i,l-i))       /* extract word candidate        */
  194.       oldwordlen=length(wrd)              /* save the length of the word   */
  195.       result=lexam(LXFVERFY,wrd)          /* authenticate word using lexam */
  196.       if result and wrd<>'' then          /* was it a success???             */
  197.          call strippunct(wrd,l,i)
  198.         .col=.col+i-1
  199.          result = lexam(LXFVERFY,wrd)
  200.       endif
  201.       if(result <> LXRFGOOD) then         /* was it a success ???          */
  202.          sayerror NO_MATCH__MSG '<'wrd'>' /* NO                      */
  203.          return ''                        /* exit function                 */
  204.       endif
  205.       /* It's a word!!!     */
  206.                                           /* get list of synonyms using lex*/
  207.       parse value lexam(LXFSYN,wrd) with 2 '/' result
  208.       if result='' then
  209.          sayerror NO_SYN__MSG '<'wrd'>'
  210.          return ''
  211.       endif
  212.  
  213.       do forever
  214.          newword = listbox(SYNONYMS__MSG,'/'result,'/'REPLACE__MSG'/'CANCEL__MSG'/'HELP__MSG'/')
  215.          if newword<>3 then leave; endif
  216.          -- help was pressed
  217.          'helpmenu 14002'
  218.          return ''
  219.       enddo
  220.       if newword<>'' then
  221.          replaceline leftstr(line,.col-1)||newword||substr(line,l)
  222.          return length(newword)-oldwordlen
  223.       endif
  224.    endif
  225.  
  226. /*
  227. ╔════════════════════════════════════════════════════════════════════════════╗
  228. ║ Spell Checking Support                                                     ║
  229. ╚════════════════════════════════════════════════════════════════════════════╝
  230. */
  231.  
  232. /*
  233. ┌────────────────────────────────────────────────────────────────────────────┐
  234. │ What's it called: proof()                                                  │
  235. │                                                                            │
  236. │ What does it do : The proof command uses E's lexam support to spell check  │
  237. │                   either the next word or a given word.     If a misspelled│
  238. │                   word is encountered, a                                   │
  239. │                   PM list box is shown containing the possible corrections.│
  240. │                   syntax:   proof  [word]                                  │
  241. │                          - if 'word' is not specified, proof searchs for   │
  242. │                            the next word (after the cursor) and checks it. │
  243. └────────────────────────────────────────────────────────────────────────────┘
  244. */
  245. defc proof
  246.    universal ADDENDA_FILENAME
  247.    if load_lexam() then
  248.      return
  249.    endif
  250.    if arg(1)<>'' then
  251.       call proof1(arg(1))
  252.    else
  253.       call proof2()
  254.    endif
  255. compile if ADDENDASUPPORT
  256.    if addenda_filename<>'' then
  257.       call maybe_save_addenda()
  258.    endif
  259. compile endif
  260.    call drop_dictionary()
  261.    if arg(1)='' then
  262. /* JBH  -- added beep to signal completion */
  263.       beep(1000,80)
  264.       sayerror DONE__MSG
  265. /* JBH  -- end mod  */
  266.    endif
  267.  
  268. /*
  269. ┌────────────────────────────────────────────────────────────────────────────┐
  270. │ What's it called: proof2()                                                 │
  271. │                                                                            │
  272. │ What does it do : Start at the current cursor position,  locate the next   │
  273. │                   word, and check the spelling of that word.   The spelling│
  274. │                   of each word is done by calling the lexam function.      │
  275. │                   The 'lexam' fuction is a internal                        │
  276. │                   opcode that uses the dynalink feature to access the      │
  277. │                   LEXAM.DLL                                                │
  278. │                                                                            │
  279. └────────────────────────────────────────────────────────────────────────────┘
  280. */
  281. defproc proof2
  282.  
  283. /* JBH  -- deleted script_file support and added TeX file support */
  284. ; script_file_type=AMU_script_verification()
  285.  tex_file_type=AMU_tex_verification()
  286. /* JBH  -- end mod */
  287.  
  288.  --@@ If there's a line-marked area in the current file, proof only in there.
  289.  firstline=max(.line,1); lastline=.last; what = 'file'
  290.  if marktype() then  /* if no mark, default to entire file */
  291.     getfileid curfileid
  292.     getmark fl,ll,fc,lc,markfileid
  293.     if markfileid = curfileid then
  294.        firstline=fl; lastline=ll
  295.        what = 'marked area'
  296.     endif
  297.  endif
  298.  partial_lines = marktype()='BLOCK' | marktype()='CHAR'
  299.  
  300.  /* start checking at next word...*/
  301. ;getline line
  302. ;.col=1
  303. ;if leftstr(line,1)==' 'then
  304. ;   tabword
  305. ;endif
  306.  if partial_lines then .col=fc; else .col=1; endif
  307.  firstline
  308.  if substr(textline(firstline), .col, 1)=' ' then tabword; endif
  309.  
  310.  for zz= firstline to lastline --@@
  311.    zz                                 /* advance to next (new) line         */
  312.    getline line
  313.    sayerror 'Spell Checking 'what'...'
  314.  
  315.    loop
  316.  
  317.      if partial_lines then
  318.         if .col>lc & (zz=lastline | marktype()='BLOCK') then
  319.            if marktype()='BLOCK' then .col=fc; endif
  320.            leave
  321.         endif
  322.      endif
  323.      l=pos(' ',line,.col)                /* find first word                 */
  324.      if not l then                       /* no more words on this line...   */
  325.         l=length(line)+1                 /* or there is only one word on    */
  326.         if l<=.col then                  /* the line...                     */
  327.            if marktype()='BLOCK' then .col=fc; else .col=1; endif
  328.            leave
  329.         endif
  330.      endif
  331.      wrd=substr(line,.col,l-.col)        /* extract word from line          */
  332.  
  333.      result = lexam(LXFVERFY,wrd)        /* verify word using lexam         */
  334.      if result and wrd<>'' then          /* was it a success???             */
  335.                                          /* YES, ignore script tags         */
  336.  
  337. /* JBH - delete script file stuff and replace with TeX stuff    */
  338. ;                                         /* then, ignore script tags         */
  339. ;        if script_file_type and
  340. ;              (pos(leftstr(wrd,1),':&.') or pos(substr(line,max(.col-1,1),1),':&')) then
  341. ;           result=0
  342. ;           if leftstr(wrd,1)=':' then
  343. ;              newl=pos('.',line,.col)
  344. ;              if newl then
  345. ;                 l=newl
  346. ;              endif
  347. ;           endif
  348.         if tex_file_type and pos(leftstr(wrd,1),'\') then  /* if tex file and wrd starts */
  349.             result = 0                                     /* with '\' then skip word    */
  350.             sayerror'TeX command ' wrd ' ignored'
  351. /* JBH  -- end mod */
  352.         else                           /* strip punctuation and try again */
  353.            call strippunct(wrd,l,i)
  354.           .col=.col+i-1
  355.            result = lexam(LXFVERFY,wrd)
  356.         endif
  357.      endif
  358.      if result and wrd<>'' then
  359.         result = lexam(LXFVERFY,wrd)
  360.         if result and wrd<>'' then
  361.            -- t=-3 means help was requested, so call spellword again.
  362.            t=-3
  363.            do while t=-3
  364. compile if ADDENDASUPPORT
  365.               t=spellword('/~Next/~Temp. Add')    -- spell check the word
  366. compile else
  367.               t=spellword('/~Next')               -- spell check the word
  368. compile endif
  369.            enddo
  370.            if t=0 then                         -- error occured
  371.               return 0
  372.            endif
  373.            if t>0 then
  374.               l=l + t - 100
  375.            endif
  376.            if t=-4 then     -- Edit was selected.
  377.               l=-1          -- so .col won't change; recheck from current point
  378.            endif
  379.            getline line
  380.         endif
  381.      endif
  382.      .col=l+1
  383.    endloop
  384.  endfor
  385.  
  386. compile if PROOF_DIALOG_FIXED
  387.    define DIALOG_POSN = ', -2, .windowwidth'
  388. compile else
  389.    define DIALOG_POSN = ' '
  390. compile endif
  391. /*
  392. ┌────────────────────────────────────────────────────────────────────────────┐
  393. │ What's it called: spellword()                                              │
  394. │                                                                            │
  395. │ What does it do : Check the word at the cursor position, removing          │
  396. │                   punctuation characters.  It is assumed that the cursor   │
  397. │                   is positioned at the beginning of the word.  (Used by    │
  398. │                   proof2 and proofword.)  If it's a valid word then check  │
  399. │                   the spelling of the word using the lexam opcode.  If a   │
  400. │                   valid result is returned place it in a PM list box using │
  401. │                   the 'listbox' procedure.  Returns the length of the word │
  402. │                   found.  The optional argument is a string containing a   │
  403. │                   button name.  E.g., '/Next'                              │
  404. └────────────────────────────────────────────────────────────────────────────┘
  405. */
  406. defproc spellword
  407.    getline line                              /* ignore script tags           */
  408.    if line<>'' then                          /* if the line is not empty...  */
  409.       i=.col                                 /* save the cursor column       */
  410.       l=pos(' ',line,.col)                   /* get next word after cursor   */
  411.       if l=0 then                            /* is it a word???              */
  412.          l=length(line)+1
  413.          if l<i then l=i endif
  414.       endif
  415.       wrd=strip(substr(line,i,l-i))          /* extract word from line       */
  416.       result = lexam(LXFVERFY,wrd)           /* verify word                  */
  417.       if result and wrd<>'' then             /* was it a success             */
  418.          call strippunct(wrd,l,i)            /* strip punctuation/ try again */
  419.          .col=.col+i-1                       /* move to next column          */
  420.          result = lexam(LXFVERFY,wrd)        /* try word  verification again */
  421.       endif
  422.       if result and wrd<>'' then             /* was it a success             */
  423.          oldwordlen=length(wrd)              /* yes it's a word.....         */
  424.                                              /* use lexam to spell check word*/
  425.          refresh
  426.          parse value lexam(LXFSPAID,wrd) with 2 '/' result
  427.          if rc>=LXRFINIT then
  428.             sayerror LOOKUP_FAILED__MSG '<' wrd '>'
  429.             return -1  -- next word
  430.          else
  431.             if result='' then
  432.                result='*Nothing Found*'
  433.             endif
  434.             oldcol = .col; .col = .col + oldwordlen; .col = oldcol;
  435. compile if EVERSION < '5.50'
  436.             refresh
  437.             sayat wrd, .cursory, .cursorx,
  438.                   .textcolor%16+(.textcolor // 16)*16, oldwordlen
  439. compile else
  440.             circleit 2, .line, .col, .col+oldwordlen-1, 1 -- color irrelevant now
  441.             refresh  -- Refresh required to display circle
  442. compile endif
  443. compile if ADDENDASUPPORT
  444.             newword=listbox(PROOF__MSG '<'wrd'>', '/'result,
  445.                             '/'REPLACE__MSG'/'CANCEL__MSG||arg(1)'/'ADD__MSG'/'EDIT__MSG'.../'HELP__MSG $DIALOG_POSN)   -- put result in PM list box
  446.             if arg(1)='' then
  447.                butlist='7 7 3 4 5'  -- Next; Temp. Add; Add; Edit; Help
  448.             else
  449.                butlist='3 4 5 6 7'  -- Next; Temp. Add; Add; Edit; Help
  450.             endif
  451. compile else
  452.             newword=listbox(PROOF__MSG '<'wrd'>','/'result,'/'REPLACE__MSG'/'CANCEL__MSG ||arg(1)'/'EDIT__MSG'.../'HELP__MSG $DIALOG_POSN)  -- put result in PM list box
  453.             if arg(1)='' then
  454.                butlist='7 7 7 3 4'  -- Next; Temp. Add; Add; Edit; Help
  455.             else
  456.                butlist='3 7 7 4 5'  -- Next; Temp. Add; Add; Edit; Help
  457.             endif
  458. compile endif
  459.             parse value butlist with but_next but_temp_add but_add but_edit but_help
  460.             if newword=but_help then
  461.                'helpmenu 14000'
  462.                return -3     -- do line over again
  463.             endif
  464.             if newword=but_edit then
  465.                newword=entrybox(REPLACEMENT__MSG '<'wrd'>','/'REPLACE__MSG'/'CANCEL__MSG,wrd)
  466.                if newword='' then
  467.                   return -1  -- next word
  468.                endif
  469.                replaceline leftstr(line,.col-1)||newword||substr(line,l)
  470.                refresh
  471. ;;             return -100 - (length(newword)-oldwordlen)    -- Don't care about new len.
  472.                return -4    -- re-check line
  473.             endif
  474.             if newword='*Nothing Found*' then
  475.                return -1
  476.             endif
  477. compile if EVERSION < '5.50'
  478.             sayat wrd, .cursory, .cursorx, .textcolor, oldwordlen
  479. compile else
  480. ;           refresh  -- maybe can leave out...
  481. compile endif
  482.             if newword=but_next then   -- goto next word
  483.                return -1
  484.             endif
  485. compile if ADDENDASUPPORT
  486.             if newword=but_temp_add then   -- temporary addenda (just for this PROOF session)
  487.  compile if RESPECT_CASE_FOR_ADDENDA
  488.                call lexam(LXFAD2TRS, wrd)
  489.  compile else
  490.                call lexam(LXFAD2TRS,lowcase(wrd))
  491.  compile endif
  492.                return -1
  493.             endif
  494.             if newword=but_add then   -- addenda
  495.                call AMU_addenda_addition_processing(wrd)
  496.                return -1
  497.             endif
  498. compile endif
  499.             if newword<>'' then              /* was it a valid result ???    */
  500.                                              /* replace word in line         */
  501.                replaceline leftstr(line,.col-1)||newword||substr(line,l)
  502. compile if EVERSION < 5.50
  503.                refresh
  504. compile endif
  505.                return 100 + length(newword)-oldwordlen
  506. ;              return -1
  507.             endif
  508.           endif
  509.       else
  510.          --.messageline='word is spelled correctly'
  511.          return -2
  512.       endif
  513.    endif
  514.    return 0
  515.  
  516. /*
  517. ┌────────────────────────────────────────────────────────────────────────────┐
  518. │ What's it called: proof1()                                                 │
  519. │                                                                            │
  520. │ What does it do : Takes a word argument and looks it up in the lexam       │
  521. │                   dictionary using the 'lexam' opcode.                     │
  522. │                   If the word is found a list box is presented with the    │
  523. │                   possible correct word choices.                           │
  524. └────────────────────────────────────────────────────────────────────────────┘
  525. */
  526. defproc proof1( wrd )
  527.    result = lexam(LXFVERFY,wrd)            /* first off, is it a word?    */
  528.    if result then                          /* well is it???               */
  529.       result = lexam(LXFSPAID,wrd)         /* YES, now check it with lexam*/
  530.  
  531.       parse value result with .'/' result  /* remove first word           */
  532.       if rc>=LXRFINIT then
  533.          sayerror LOOKUP_FAILED__MSG '<' wrd '>'
  534.       else
  535.          if result='' then
  536.             result='*Nothing Found*'
  537.          endif
  538.          do forever
  539. compile if ADDENDASUPPORT
  540.             newword=listbox(PROOF_WORD__MSG,'/'result,'/'REPLACE__MSG'/'EXIT__MSG'/'ADD__MSG'/'HELP__MSG)     /* put result in PM list box   */
  541.             if newword='3' then   --  addenda
  542.                call AMU_addenda_addition_processing(wrd)
  543.                return -1
  544.             endif
  545.             if newword<>4 then leave; endif
  546. compile else
  547.             newword=listbox(PROOF_WORD__MSG,'/'strip(result),'/'REPLACE__MSG'/'EXIT__MSG'/'HELP__MSG)     /* put result in PM list box   */
  548.             if newword<>3 then leave; endif
  549. compile endif
  550.             'helpmenu 14001'
  551.          enddo
  552.          if newword='*Nothing Found*' then
  553.             return
  554.          endif
  555.          return newword
  556.       endif
  557.    endif
  558.  
  559. /*
  560. ╔════════════════════════════════════════════════════════════════════════════╗
  561. ║ Addenda Support                                                            ║
  562. ╚════════════════════════════════════════════════════════════════════════════╝
  563. */
  564. compile if ADDENDASUPPORT
  565. /*
  566. ┌────────────────────────────────────────────────────────────────────────────┐
  567. │ What's it called: maybe_save_addenda                                       │
  568. │                                                                            │
  569. │ What does it do :                                                          │
  570. │                                                                            │
  571. └────────────────────────────────────────────────────────────────────────────┘
  572. */
  573. ; Addenda support commands
  574.  
  575. defproc maybe_save_addenda
  576.    universal  addenda_has_been_modified
  577.    universal  AMU_addenda_file_identification
  578.    universal  ADDENDA_FILENAME
  579.  
  580. ;   if addenda_has_been_modified then
  581.      -- sayatbox 'saving addenda 'ADDENDA_FILENAME
  582.       if AMU_addenda_file_identification<>''  then
  583.        getfileid AMU_current_file_identification
  584.        rc = 0
  585.        activatefile AMU_addenda_file_identification
  586.        if not rc then
  587.           if .modify then 'xcom save'; endif
  588. ;;        'xcom quit'
  589.        endif
  590.        -- sayerror 'addenda file filed'
  591.        activatefile AMU_current_file_identification
  592.       endif
  593.       addenda_has_been_modified=0
  594.       -- sayerror 0
  595. ;  endif
  596.  
  597. ;defc AMU_addenda_pickup
  598. ;   universal  ADDENDA_FILENAME
  599. ;   call lexam(LXFAMUGDIC,ADDENDA_FILENAME)
  600.  
  601. ;defc AMU_addenda_addition
  602. ;   call lexam(LXFAD2TRS,arg(1))
  603.  
  604. defproc AMU_addenda_processing
  605.    universal AMU_addenda_file_identification
  606.    universal  ADDENDA_FILENAME
  607.    getfileid AMU_current_file_identification
  608.    'xcom e' ADDENDA_FILENAME
  609.    -- sayerror 'addenda file loaded'
  610.    if not rc or rc = sayerror('New file') then
  611.       getfileid AMU_addenda_file_identification
  612.    else
  613.       AMU_addenda_file_identification =''
  614.       sayerror BAD_ADDENDA__MSG ADDENDA_FILENAME 'rc=' rc
  615.       stop
  616.    endif
  617.    .visible=0 -- hidden file
  618.    activatefile AMU_current_file_identification
  619.    if AMU_addenda_file_identification <>'' then
  620.       for i = 1 to AMU_addenda_file_identification.last
  621.          getline line,i,AMU_addenda_file_identification
  622.          if upcase(leftstr(line, 8))='.DU ADD ' then
  623.             line=substr(line,9)
  624.          endif
  625.          do while line <> ''
  626.             parse value line with wrd line
  627.  compile if RESPECT_CASE_FOR_ADDENDA
  628.             call lexam(LXFAD2TRS,wrd)
  629.  compile else
  630.             call lexam(LXFAD2TRS,lowcase(wrd))
  631.  compile endif
  632.          enddo
  633.       endfor
  634.    endif
  635.  
  636. defproc AMU_addenda_addition_processing(AMU_addenda_entry)
  637.    universal  addenda_has_been_modified
  638.    universal AMU_addenda_file_identification, ADDENDA_FILENAME
  639.    addenda_has_been_modified=1
  640.  compile if not RESPECT_CASE_FOR_ADDENDA
  641.    AMU_addenda_entry=lowcase(AMU_addenda_entry)
  642.  compile endif
  643.    call lexam(LXFAD2TRS,AMU_addenda_entry)
  644.    if ADDENDA_FILENAME<>'' & AMU_addenda_file_identification<>'' then
  645.       insertline AMU_addenda_entry,AMU_addenda_file_identification.last+1,AMU_addenda_file_identification
  646.    endif
  647.  
  648.  
  649. compile endif -- ADDENDASUPPORT
  650.  
  651. ; The following is a script file type verification algorithm
  652. ; suggested by Larry Margolis. (Thanks, Larry)
  653. defproc AMU_script_verification()
  654.    ext=filetype()
  655. compile if defined(my_SCRIPT_FILE_TYPE)
  656.    return ext='SCR' or ext='SCT' or ext='SCRIPT' or ext='IPF' or ext=my_SCRIPT_FILE_TYPE
  657. compile else
  658.    return ext='SCR' or ext='SCT' or ext='SCRIPT' or ext='IPF'
  659. compile endif
  660.  
  661.  
  662. /* JBH add TeX file support */
  663. ; The following is a TeX file type verification algorithm
  664. defproc AMU_tex_verification()
  665.    ext=filetype()
  666.    return ext='TEX'
  667. /* JBH  -- end mod */
  668.  
  669. /*
  670. ╔════════════════════════════════════════════════════════════════════════════╗
  671. ║ General Lexam Support                                                      ║
  672. ╚════════════════════════════════════════════════════════════════════════════╝
  673. */
  674. defproc load_lexam
  675.    universal DICTIONARY_FILENAME
  676.    universal ADDENDA_FILENAME
  677.    universal Dictionary_loaded
  678.    result = lexam(LXFINIT)
  679.    if result<>LXRFGOOD and result<>LXRFIFCN  then
  680.       if result='febe' then  -- x'febe' = -322 = sayerror('Dynalink: unrecognized library name')
  681.          sayerror sayerrortext(-322) LEXAM_DLL'.DLL'
  682.          return 1
  683.       endif
  684.       sayerror INIT_ERROR__MSG
  685.    endif
  686.    dictlist=DICTIONARY_FILENAME
  687.    do while dictlist <> ''
  688.       parse value dictlist with dictionary dictlist
  689.       result=lexam(LXFGDIC, dictionary)
  690.       if result>=LXRFNFND & result<>LXRFDUPD then  -- Duplicate Dictionary; didn't unload?
  691.          if exist(dictionary) then
  692.             sayerror BAD_DICT__MSG '"'dictionary'";' ERROR__MSG result
  693.          else
  694.             sayerror NO_DICT__MSG '"'dictionary'"'
  695.          endif
  696.          return 1
  697.       endif
  698.    enddo
  699.    Dictionary_loaded = 1
  700. compile if ADDENDASUPPORT
  701.    if ADDENDA_FILENAME<>'' then
  702.       call lexam(LXFAMUGDIC,ADDENDA_FILENAME)
  703.       call AMU_addenda_processing()
  704.    endif
  705. compile endif
  706.    return 0
  707.  
  708. defproc drop_dictionary
  709.    universal DICTIONARY_FILENAME
  710.    universal  ADDENDA_FILENAME
  711.    universal  Dictionary_loaded
  712.    dictlist=DICTIONARY_FILENAME
  713.    do while dictlist <> ''
  714.       parse value dictlist with dictionary dictlist
  715.       call lexam(LXFFDIC, dictionary);
  716.    enddo
  717. compile if ADDENDASUPPORT
  718.    if ADDENDA_FILENAME<>'' then
  719.       call lexam(LXFFDIC,ADDENDA_FILENAME);
  720.    endif
  721. compile endif
  722.    call lexam(LXFTERM)
  723.    Dictionary_loaded = 0
  724.  
  725. defproc strippunct(var wrd,var l,var i)
  726.    -- Make this a variable, not a constant. to save space.
  727.    punctuation ='~!@#$¢£¥%^&*()_+|`1234567890-=\{}[]:";''<>?,./¬─═╔╗╚╝┌┐└┘║╦╠╣╩╬┬├┤┴┼│'
  728.    /* strip leading and trailing punctuation and try again*/
  729.    i=verify(wrd,punctuation)
  730.    if i then
  731.       l=l-length(wrd)
  732.       wrd=substr(wrd,i)
  733.       j=verify(wrd,punctuation,'m')
  734.       if j then
  735.          wrd=leftstr(wrd,j-1)
  736.       else
  737.          j=length(wrd)+1
  738.       endif
  739.       l=l+j+i-2
  740.    else
  741.       i=length(wrd)+1
  742.    endif
  743.  
  744. defc proofword,verify
  745.    universal ADDENDA_FILENAME
  746.    if load_lexam() then
  747.      return
  748.    endif
  749.    call pbegin_word()
  750.    spellrc = spellword('')
  751. compile if ADDENDASUPPORT
  752.    if addenda_filename<>'' then
  753.       call maybe_save_addenda()
  754.    endif
  755. compile endif
  756.    call drop_dictionary()
  757.    if -2 = spellrc then
  758.       sayerror SPELLED_OK__MSG
  759.    endif
  760.  
  761. defc dict
  762.    universal DICTIONARY_FILENAME
  763.    dictlist = arg(1)
  764.    if dictlist='' then
  765.       sayerror DICTLIST_IS__MSG DICTIONARY_FILENAME
  766.       return
  767.    endif
  768.    do while dictlist <> ''
  769.       parse value dictlist with dictionary dictlist
  770.       if not exist(dictionary) then
  771.          sayerror FILE_NOT_FOUND__MSG '"'dictionary'"; 'DICT_REMAINS__MSG DICTIONARY_FILENAME
  772.          return
  773.       endif
  774.    enddo
  775.    DICTIONARY_FILENAME = arg(1)
  776.  
  777.