home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / epmmac.zip / EPMLEX.E < prev    next >
Text File  |  1996-03-27  |  68KB  |  1,720 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. */
  26. ; Customizing information:  Any of the following customizing constants can
  27. ; be overridden by including the appropriate definition after a CONST statement
  28. ; in your MYCNF.E.
  29. ;
  30. ; Example of customizing:  include the following lines in your MYCNF.E
  31. ; (with the ';' deleted from the beginning of each line).
  32. ;
  33. ;    const                               -- Customizations for EPMLEX:
  34. ;       RESPECT_case_for_addenda = 0     -- Ignore case of addenda words.
  35. ;       my_ADDENDA_FILENAME= 'd:\doc\margoli.adf'     -- I keep these in my
  36. ;       my_DICTIONARY_FILENAME= 'd:\doc\us.dct'       -- d:\doc directory.
  37. ; Can also have multiple dictionaries, separated by spaces - all will be loaded:
  38. ;       my_DICTIONARY_FILENAME= 'd:\doc\us.dct d:\doc\medical.dct d:\doc\legal.dct'
  39.  
  40. compile if not defined(SMALL)  -- If SMALL not defined, then being separately compiled
  41. include 'stdconst.e'
  42.  define INCLUDING_FILE = 'EPMLEX.E'
  43.    tryinclude 'MYCNF.E'        -- Include the user's configuration customizations.
  44.  compile if not defined(SITE_CONFIG)
  45.     const SITE_CONFIG = 'SITECNF.E'
  46.  compile endif
  47.  compile if SITE_CONFIG
  48.     tryinclude SITE_CONFIG
  49.  compile endif
  50. const
  51.  compile if not defined(SPELL_SUPPORT)  -- Must set here, since set to 0 in ENGLISH.E
  52.    SPELL_SUPPORT = 'DYNALINK'          -- New default
  53.  compile endif
  54.  compile if not defined(NLS_LANGUAGE)
  55.    NLS_LANGUAGE = 'ENGLISH'
  56.  compile endif
  57. include NLS_LANGUAGE'.e'
  58.  compile if EVERSION >= 6
  59.    EA_comment 'This contains the spell-checking code.  It can be linked explicitly, or will be linked automatically if the base .ex file is configured for it.'
  60.  compile endif
  61. compile endif
  62.  
  63. const
  64. compile if not defined(PROOF_DIALOG_FIXED)
  65.    PROOF_DIALOG_FIXED = 0               -- 1 if dialog should stay in one spot
  66. compile endif
  67.  
  68. compile if not defined(ADDENDASUPPORT)
  69.    ADDENDASUPPORT =  1                  -- 1 if addenda support
  70. compile endif
  71.  
  72. compile if ADDENDASUPPORT
  73.  compile if not defined(RESPECT_case_for_addenda)
  74. RESPECT_case_for_addenda     = 1        /* If addenda entries are to be     */
  75.  compile endif                          /* placed in the addenda without    */
  76.                                         /* modifying their case, then       */
  77.                                         /* this variable should be 1        */
  78.                                         /* Otherwise, it should be 0        */
  79. compile endif -- ADDENDASUPPORT
  80.  
  81. compile if not defined(PROOF_CIRCLE_STYLE)
  82.    PROOF_CIRCLE_STYLE = 2
  83. compile endif
  84. compile if not defined(PROOF_CIRCLE_COLOR1)
  85.    PROOF_CIRCLE_COLOR1 = 16777220
  86. compile endif
  87. compile if not defined(PROOF_CIRCLE_COLOR2)
  88.    PROOF_CIRCLE_COLOR2 = 16777218
  89. compile endif
  90. compile if not defined(DYNASPELL_BEEP)
  91.    DYNASPELL_BEEP = 'ALARM'
  92. compile endif
  93. compile if not defined(PROOF_NEXT_DEFAULT)
  94.    PROOF_NEXT_DEFAULT = 0
  95. compile endif
  96.  
  97. const
  98. ; Functions
  99. compile if EVERSION >= 5.50     -- Use the new function numbers
  100. LXFINIT   = 0     /* Initialize                   */
  101. LXFTERM   = 1     /* Terminate                    */
  102. LXFGDIC   = 2     /* Pickup Dictionary            */
  103. LXFFDIC   = 3     /* Drop Dictionary              */
  104. LXFSETADD = 4     /* Set Addenda Language Type    */
  105. LXFAD2TRS = 5     /* Add to Transient Addenda     */
  106. LXFREDTRS = 6     /* Read from Transient Addenda  */
  107. LXFSAVTRS = 7     /* Save Transient Addenda       */
  108. LXFVERFY  = 8     /* Verification                 */
  109. LXFSPAID  = 9     /* Spelling Aid                 */
  110. LXFHYPH   =10     /* Hyphenation                  */
  111. LXFDHYPH  =11     /* Dehyphenation                */
  112. LXFSYN    =12     /* Synonym                      */
  113. LXFAMUGDIC=255    /* Addenda Pickup Dictionary    */
  114.          /* (Pseudo-op; calls LXFGDIC internally) */
  115. LXFQLIB    = -1    /* Query Lexam library          */   /* √ */
  116. LXFFINIS   = -2    /* Drop all dicts & terminate   */   /* √ */
  117. LXFPRFLINE = -3    /* Proof an entire line in file */   /*   */
  118. LXFSETPUNCT= -4    /* Set punctuation for ProofLine*/
  119. compile else                    -- The old way; uses strings
  120. LXFINIT   = 'I'    -- Initialize
  121. LXFTERM   = 'T'    -- Terminate
  122. LXFGDIC   = 'PI'   -- Pickup Dictionary
  123. LXFFDIC   = 'DR'   -- Drop Dictionary
  124. LXFAD2TRS = 'ADDI' -- Add(ition) to Transient Addenda
  125. LXFVERFY  = 'V'    -- Verification
  126. LXFSPAID  = 'SP'   -- Spelling Aid
  127. LXFSYN    = 'SY'   -- Synonym
  128. LXFAMUGDIC= 'ADDE' -- Addenda Pickup Dictionary
  129. compile endif
  130.  
  131. ; Return codes
  132. LXRFGOOD = 0000   /* Function Successful:  Good Return Code                */
  133. LXRFUPDC = 0005   /* Function Successful:  Updateable dictionary created   */
  134. LXRFNFND = 0100   /* Function Unsuccessful: Word Not Found                 */
  135. LXRFDUPD = 0107   /* Function Unsuccessful: Duplicate Dictionary           */
  136. LXRFINIT = 0200   /* PC LEXAM Not Initialized: Control Block/Parameter Err */
  137. LXRFIFCN = 0201   /* Invalid Function                                      */
  138.  
  139. compile if EVERSION >= 6.01
  140.    DEFAULT_LEXAM_PUNCTUATION ='~!@#$¢£¥%^&*()_+|`1234567890-=\{}[]:";''<>?,./¬─═╔╗╚╝┌┐└┘║╦╠╣╩╬┬├┤┴┼│'
  141. compile else               -- Keep these two strings the same.
  142.    LEXAM_PUNCTUATION         ='~!@#$¢£¥%^&*()_+|`1234567890-=\{}[]:";''<>?,./¬─═╔╗╚╝┌┐└┘║╦╠╣╩╬┬├┤┴┼│'
  143. compile endif
  144.  
  145. compile if (EVERSION >= '5.60c' & EVERSION < 6) | EVERSION >= '6.00c'
  146.    USE_CUSTOM_PROOF_DIALOG = 1
  147. compile else
  148.    USE_CUSTOM_PROOF_DIALOG = 0
  149. compile endif
  150.  
  151. definit
  152.    universal  addenda_has_been_modified
  153.    universal  ADDENDA_FILENAME
  154.    universal  DICTIONARY_FILENAME
  155.    universal  Dictionary_loaded
  156. compile if EVERSION >= 6.01
  157.    universal  LEXAM_PUNCTUATION
  158.  
  159.    LEXAM_PUNCTUATION = DEFAULT_LEXAM_PUNCTUATION
  160.  compile if defined(my_LEXAM_PUNCTUATION)
  161.    'proof_punctuation' my_LEXAM_PUNCTUATION
  162.  compile endif
  163. compile endif
  164.  
  165. ; Note:  don't initialize the universals here for EPM if SPELL_SUPPORT =
  166. ; 'DYNALINK'; it will be done in STDCNF so that this won't override the
  167. ; config info read from the .INI file.
  168. compile if EVERSION < 5 or SPELL_SUPPORT <> 'DYNALINK'
  169.  compile if defined(my_ADDENDA_FILENAME)
  170.    ADDENDA_FILENAME= my_ADDENDA_FILENAME
  171.  compile else
  172.    ADDENDA_FILENAME= 'c:\lexam\lexam.adl'
  173.  compile endif
  174.  
  175.  compile if defined(my_DICTIONARY_FILENAME)
  176.    DICTIONARY_FILENAME= my_DICTIONARY_FILENAME
  177.  compile else
  178.    DICTIONARY_FILENAME= 'us.dct'
  179.  compile endif
  180. compile endif
  181.  
  182.    addenda_has_been_modified=0
  183.    Dictionary_loaded = 0
  184.  
  185. /*
  186. ╔════════════════════════════════════════════════════════════════════════════╗
  187. ║ Synonym Support                                                            ║
  188. ╚════════════════════════════════════════════════════════════════════════════╝
  189. */
  190. /*
  191. ┌────────────────────────────────────────────────────────────────────────────┐
  192. │ What's it called: syn                                                      │
  193. │                                                                            │
  194. │ What does it do : The syn command uses E's lexam support to retrieve       │
  195. │                   possible synonyms for a specified word.                  │
  196. │                   If synonyms are found a                                  │
  197. │                   PM list box is shown containing the possible new words.  │
  198. │                                                                            │
  199. └────────────────────────────────────────────────────────────────────────────┘
  200. */
  201. defc syn =
  202.    if load_lexam() then
  203.      return
  204.    endif
  205.    call pbegin_word()
  206.    call synonym()
  207.    call drop_dictionary()
  208.  
  209.  
  210. /*
  211. ┌────────────────────────────────────────────────────────────────────────────┐
  212. │ What's it called: synonym()                                                │
  213. │                                                                            │
  214. │ What does it do : checks the next word on a line for its possible synonyms.│
  215. │                   possible synonyms for a specified word.                  │
  216. │                   If synonyms are found a                                  │
  217. │                   PM list box is shown containing the possible new words.  │
  218. │                                                                            │
  219. └────────────────────────────────────────────────────────────────────────────┘
  220. */
  221. defproc synonym()
  222.    getline line                           /* get the current line          */
  223. compile if EVERSION >= '5.21'
  224.    line = translate(line, ' ', \9)  -- Convert tabs to spaces
  225. compile endif
  226.    if line<>'' then                       /* if it is NOT blank            */
  227.       i=.col                              /* get the current column number */
  228.       l=pos(' ',line,.col)                /* get possible word             */
  229.       if l=0 then                         /* could this be a word???       */
  230.          l=length(line)+1
  231.          if l<i then l=i endif
  232.       endif
  233.       wrd=strip(substr(line,i,l-i))       /* extract word candidate        */
  234.       oldwordlen=length(wrd)              /* save the length of the word   */
  235.       result=lexam(LXFVERFY,wrd)          /* authenticate word using lexam */
  236.       if result and wrd<>'' then          /* was it a success???             */
  237.          call strippunct(wrd,l,i)
  238.         .col=.col+i-1
  239.          result = lexam(LXFVERFY,wrd)
  240.       endif
  241.       if(result <> LXRFGOOD) then         /* was it a success ???          */
  242.          sayerror NO_MATCH__MSG '<'wrd'>' /* NO                      */
  243.          return ''                        /* exit function                 */
  244.       endif
  245.       /* It's a word!!!     */
  246.                                           /* get list of synonyms using lex*/
  247.       parse value lexam(LXFSYN,wrd) with 2 '/' result
  248.       if result='' then
  249.          sayerror NO_SYN__MSG '<'wrd'>'
  250.          return ''
  251.       endif
  252.  
  253. compile if EVERSION < 5.21  -- The old way
  254.       do forever
  255.          newword = listbox(SYNONYMS__MSG,'/'result,'/'REPLACE__MSG'/'CANCEL__MSG'/'HELP__MSG'/')
  256.          if newword<>3 then leave; endif
  257.          -- help was pressed
  258.          'helpmenu 14002'
  259.          return ''
  260.       enddo
  261. compile else
  262.       parse value listbox(SYNONYMS__MSG,'/'result,'/'REPLACE__MSG'/'CANCEL__MSG'/'HELP__MSG'/',0,0,0,0,
  263.  compile if EVERSION >= 5.60
  264.                           gethwndc(APP_HANDLE) || atoi(1) || atoi(1) || atoi(14002) || \26 wrd) with button 2 newword \0
  265.  compile else
  266.                           atoi(1) || atoi(1) || atoi(14002) || gethwndc(APP_HANDLE) || \26 wrd) with button 2 newword \0
  267.  compile endif
  268.       if button<>\1 then
  269.          newword = ''
  270.       endif
  271. compile endif -- EVERSION < 5.21
  272.       if newword<>'' then
  273. compile if EVERSION < 5.50  -- Don't have to worry about losing attributes...
  274.          getline line                           /* get the current line          */
  275.          replaceline leftstr(line,.col-1)||newword||substr(line,l)
  276. compile else
  277.          getsearch oldsearch
  278.          'xcom c '\1 || wrd || \1 || newword || \1
  279.          setsearch oldsearch
  280. compile endif
  281.          return length(newword)-oldwordlen
  282.       endif
  283.    endif
  284.  
  285. /*
  286. ╔════════════════════════════════════════════════════════════════════════════╗
  287. ║ Spell Checking Support                                                     ║
  288. ╚════════════════════════════════════════════════════════════════════════════╝
  289. */
  290.  
  291. compile if PROOF_DIALOG_FIXED
  292.    define DIALOG_POSN = ', -2, .windowwidth'
  293. compile elseif EVERSION < 5.21
  294.    define DIALOG_POSN = ' '
  295. compile else
  296.    define DIALOG_POSN = ', 0, 0 '
  297. compile endif
  298.  
  299. /*
  300. ┌────────────────────────────────────────────────────────────────────────────┐
  301. │ What's it called: proof()                                                  │
  302. │                                                                            │
  303. │ What does it do : The proof command uses E's lexam support to spell check  │
  304. │                   either the next word or a given word.  If a misspelled   │
  305. │                   word is encountered, a PM list box is shown containing   │
  306. │                   the possible corrections.                                │
  307. │                   syntax:   proof  [word]                                  │
  308. │                          - if 'word' is not specified, proof searchs for   │
  309. │                            the next word (after the cursor) and checks it. │
  310. └────────────────────────────────────────────────────────────────────────────┘
  311. */
  312. compile if not USE_CUSTOM_PROOF_DIALOG  --****************************************
  313. defc proof
  314.    universal ADDENDA_FILENAME
  315.    if load_lexam() then
  316.      return
  317.    endif
  318.    if arg(1)<>'' then
  319.       call proof1(arg(1))
  320.    else
  321.       call proof2()
  322.    endif
  323. compile if ADDENDASUPPORT
  324.    if addenda_filename<>'' then
  325.       call maybe_save_addenda()
  326.    endif
  327. compile endif
  328.    call drop_dictionary()
  329.    if arg(1)='' then
  330.       sayerror DONE__MSG
  331.    endif
  332.  
  333. /*
  334. ┌────────────────────────────────────────────────────────────────────────────┐
  335. │ What's it called: proof2()                                                 │
  336. │                                                                            │
  337. │ What does it do : Start at the current cursor position,  locate the next   │
  338. │                   word, and check the spelling of that word.   The spelling│
  339. │                   of each word is done by calling the lexam function.      │
  340. │                   The 'lexam' fuction is a internal                        │
  341. │                   opcode that uses the dynalink feature to access the      │
  342. │                   LEXAM.DLL                                                │
  343. │                                                                            │
  344. └────────────────────────────────────────────────────────────────────────────┘
  345. */
  346. defproc proof2
  347. compile if EVERSION >= 6.01
  348.    universal LEXAM_PUNCTUATION
  349. compile endif
  350.    script_file_type=AMU_script_verification()
  351. compile if defined(TEX_FILETYPES)
  352.    tex_file_type = wordpos(filetype(),TEX_FILETYPES)
  353. compile else
  354.    tex_file_type = (filetype() = 'TEX')
  355. compile endif
  356.  
  357.  --@@ If there's a line-marked area in the current file, proof only in there.
  358.  firstline=max(.line,1); lastline=.last; what = FILE__MSG
  359.  if marktype() then  /* if no mark, default to entire file */
  360.     getfileid curfileid
  361.     getmark fl,ll,fc,lc,markfileid
  362.     if markfileid = curfileid then
  363.        firstline=fl; lastline=ll
  364.        what = MARKED_AREA__MSG
  365.     endif
  366.  endif
  367.  partial_lines = marktype()='BLOCK' | marktype()='CHAR'
  368.  
  369.  /* start checking at next word...*/
  370. ;getline line
  371. ;.col=1
  372. ;if leftstr(line,1)==' 'then
  373. ;   tabword
  374. ;endif
  375.  if partial_lines then .col=fc; else .col=1; endif
  376.  firstline
  377.  
  378.  for zz= firstline to lastline --@@
  379.    zz                                 /* advance to next (new) line         */
  380.    getline line
  381. compile if EVERSION >= '5.21'
  382.    line = translate(line, ' ', \9)  -- Convert tabs to spaces
  383. compile endif
  384. compile if EVERSION >= '5.21'
  385.    display -8
  386. compile endif
  387. ;  sayerror 'Spell Checking 'what'...'
  388.    sayerror CHECKING__MSG what '(line' zz'; last='lastline')...'
  389. compile if EVERSION >= '5.21'
  390.    display 8
  391. compile endif
  392.  
  393.    loop
  394.  
  395.      if substr(line, .col, 1)=' ' & substr(line, .col)<>' ' then
  396.         tabword
  397.      endif
  398.      if partial_lines then
  399.         if .col>lc & (zz=lastline | marktype()='BLOCK') then
  400.            if marktype()='BLOCK' then .col=fc; endif
  401.            leave
  402.         endif
  403.      endif
  404.      l=pos(' ',line,.col)                /* find first word                 */
  405.      if not l then                       /* no more words on this line...   */
  406.         l=length(line)+1                 /* or there is only one word on    */
  407.         if l<=.col then                  /* the line...                     */
  408.            if marktype()='BLOCK' then .col=fc; else .col=1; endif
  409.            leave
  410.         endif
  411.      endif
  412.      wrd=substr(line,.col,l-.col)        /* extract word from line          */
  413.      if not verify(wrd, LEXAM_PUNCTUATION) then  -- No letters in "word"; skip it.
  414.         result = 0
  415.      else
  416.         result = lexam(LXFVERFY,wrd)        /* verify word using lexam         */
  417.      endif
  418.      if result and wrd<>'' then          /* was it a success???             */
  419.                                          /* YES, ignore script tags         */
  420.         if script_file_type then  -- Do just the cheap test first.
  421.            if (pos(leftstr(wrd,1),':&.') or pos(substr(line,max(.col-1,1),1),':&')) then
  422.               result=0
  423.               if leftstr(wrd,1)=':' then
  424.                  newl=pos('.',line,.col)
  425.                  if newl then
  426.                     l=newl
  427.                  endif
  428.               endif
  429.            endif
  430.         elseif tex_file_type & pos('\', wrd) then
  431.            result=0
  432.         endif
  433.         if result then                 /* strip punctuation and try again */
  434.            call strippunct(wrd,l,i)
  435.           .col=.col+i-1
  436.            result = lexam(LXFVERFY,wrd)
  437.         endif
  438.      endif
  439.      if result and wrd<>'' then
  440. ;;      result = lexam(LXFVERFY,wrd)  -- Redundant???
  441. ;;      if result and wrd<>'' then
  442. compile if EVERSION < 5.21  -- Help is now handled by the dialog box
  443.            -- t=-3 means help was requested, so call spellword again.
  444.            t=-3
  445.            do while t=-3
  446. compile endif
  447. compile if ADDENDASUPPORT
  448.               t=spellword2(wrd, l, '/~Next/~Temp. Add')    -- spell check the word
  449. compile else
  450.               t=spellword2(wrd, l, '/~Next')               -- spell check the word
  451. compile endif
  452. compile if EVERSION < 5.21  -- Help is now handled by the dialog box
  453.            enddo
  454. compile endif
  455.            if t=0 then                         -- error occured
  456.               return 0
  457.            endif
  458.            if t>0 then
  459.               l=l + t - 100
  460.            elseif t=-4 then   -- Edit was selected.
  461.               l = .col -1     -- (so .col won't change; recheck from current point)
  462.            endif
  463.            getline line
  464. compile if EVERSION >= '5.21'
  465.            line = translate(line, ' ', \9)  -- Convert tabs to spaces
  466. compile endif
  467. ;;      endif
  468.      endif
  469.      .col=l+1
  470.    endloop
  471.  endfor
  472.  
  473. /*
  474. ┌────────────────────────────────────────────────────────────────────────────┐
  475. │ What's it called: spellword()                                              │
  476. │                                                                            │
  477. │ What does it do : Check the word at the cursor position, removing          │
  478. │                   punctuation characters.  It is assumed that the cursor   │
  479. │                   is positioned at the beginning of the word.  (Used by    │
  480. │                   proof2 and proofword.)  If it's a valid word then check  │
  481. │                   the spelling of the word using the lexam opcode.  If a   │
  482. │                   valid result is returned place it in a PM list box using │
  483. │                   the 'listbox' procedure.  Returns the length of the word │
  484. │                   found.  The optional argument is a string containing a   │
  485. │                   button name.  E.g., '/Next'                              │
  486. └────────────────────────────────────────────────────────────────────────────┘
  487. */
  488. defproc spellword
  489.    getline line                              /* ignore script tags           */
  490. compile if EVERSION >= '5.21'
  491.    line = translate(line, ' ', \9)  -- Convert tabs to spaces
  492. compile endif
  493.    if line<>'' then                          /* if the line is not empty...  */
  494.       i=.col                                 /* save the cursor column       */
  495.       l=pos(' ',line,.col)                   /* get next word after cursor   */
  496.       if l=0 then                            /* is it a word???              */
  497.          l=max(length(line)+1, i)
  498.       endif
  499.       wrd=strip(substr(line,i,l-i))          /* extract word from line       */
  500.       result = lexam(LXFVERFY,wrd)           /* verify word                  */
  501.       if result and wrd<>'' then             /* was it a success             */
  502.          start_l = l
  503.          do forever
  504.             call strippunct(wrd,l,i)            /* strip punctuation/ try again */
  505.             .col=.col+i-1                       /* move to next column          */
  506.             if l>=arg(2) | wrd='' then  -- Will always be true if arg(2) omitted.
  507.                leave
  508.             endif
  509.             .col = l
  510.             l = start_l
  511.             wrd=strip(substr(line,.col,l-.col))    /* extract word from line       */
  512.          enddo
  513.          result = lexam(LXFVERFY,wrd)        /* try word  verification again */
  514.       endif
  515.       if (result or abbrev('FORCE', upcase(arg(3)), 1)) and wrd<>'' then             /* was it a success             */
  516.           return spellword2(wrd, l, arg(1))
  517.       else
  518.          --.messageline='word is spelled correctly'
  519.          return -2
  520.       endif
  521.    endif
  522.    return 0
  523.  
  524. defproc spellword2(wrd, l)
  525.          oldwordlen=length(wrd)              /* yes it's a word.....         */
  526.                                              /* use lexam to spell check word*/
  527.          refresh
  528.          parse value lexam(LXFSPAID,wrd) with 2 '/' result
  529.          if rc>=LXRFINIT then
  530.             sayerror LOOKUP_FAILED__MSG '<' wrd '> RC='rc
  531.             return -1  -- next word
  532.          else
  533.             if result='' then
  534.                result='*Nothing Found*'
  535.             endif
  536.             oldcol = .col; .col = .col + oldwordlen; .col = oldcol;
  537. compile if EVERSION < '5.50'
  538.             refresh
  539.             sayat wrd, .cursory, .cursorx,
  540.                   .textcolor%16+(.textcolor // 16)*16, oldwordlen
  541. compile elseif EVERSION >= 5.60
  542.             circleit PROOF_CIRCLE_STYLE, .line, .col, .col+oldwordlen-1, PROOF_CIRCLE_COLOR1, PROOF_CIRCLE_COLOR2
  543.             refresh  -- Refresh required to display circle, because control isn't being returned to the user
  544. compile else
  545.             circleit PROOF_CIRCLE_STYLE, .line, .col, .col+oldwordlen-1, 1 -- color irrelevant now
  546.             refresh  -- Refresh required to display circle, because control isn't being returned to the user
  547. compile endif
  548. compile if ADDENDASUPPORT
  549.  compile if EVERSION < 5.21  -- The old way
  550.             newword=listbox(PROOF__MSG '<'wrd'>', '/'result,
  551.                             '/'REPLACE__MSG'/'CANCEL__MSG||arg(3)'/'ADD__MSG'/'EDIT__MSG'.../'HELP__MSG $DIALOG_POSN)   -- put result in PM list box
  552.  compile else
  553.             parse value listbox(PROOF__MSG '<'wrd'>', '/'result,
  554.                                 '/'REPLACE__MSG'/'CANCEL__MSG||arg(3)'/'ADD__MSG'/'EDIT__MSG'.../'HELP__MSG $DIALOG_POSN ,0,0,
  555.   compile if EVERSION >= 5.60
  556.                                 gethwndc(APP_HANDLE) || atoi(1) || atoi(1) || atoi(14000)) with button 2 newword \0
  557.   compile else
  558.                                 atoi(1) || atoi(1) || atoi(14000) || gethwndc(APP_HANDLE)) with button 2 newword \0
  559.   compile endif
  560.             if button=\0 | button=\2 then  -- Close or Cancel
  561.                newword = ''
  562.             endif
  563.  compile endif -- EVERSION < 5.21
  564.             if arg(3)='' then
  565.                butlist='7 7 3 4 5'  -- Next; Temp. Add; Add; Edit; Help
  566.             else
  567.                butlist='3 4 5 6 7'  -- Next; Temp. Add; Add; Edit; Help
  568.             endif
  569. compile else
  570.  compile if EVERSION < 5.21  -- The old way
  571.             newword=listbox(PROOF__MSG '<'wrd'>','/'result,'/'REPLACE__MSG'/'CANCEL__MSG ||arg(3)'/'EDIT__MSG'.../'HELP__MSG $DIALOG_POSN)  -- put result in PM list box
  572.  compile else
  573.             parse value listbox(PROOF__MSG '<'wrd'>', '/'result,
  574.                                 '/'REPLACE__MSG'/'CANCEL__MSG||arg(3)'/'EDIT__MSG'.../'HELP__MSG $DIALOG_POSN ,0,0,
  575.   compile if EVERSION >= 5.60
  576.                                 gethwndc(APP_HANDLE) || atoi(1) || atoi(1) || atoi(14000)) with button 2 newword \0
  577.   compile else
  578.                                 atoi(1) || atoi(1) || atoi(14000) || gethwndc(APP_HANDLE)) with button 2 newword \0
  579.   compile endif
  580.             if button=\0 | button=\2 then  -- Close or Cancel
  581.                newword = ''
  582.             endif
  583.  compile endif -- EVERSION < 5.21
  584.             if arg(3)='' then
  585.                butlist='7 7 7 3 4'  -- Next; Temp. Add; Add; Edit; Help
  586.             else
  587.                butlist='3 7 7 4 5'  -- Next; Temp. Add; Add; Edit; Help
  588.             endif
  589. compile endif
  590.             parse value butlist with but_next but_temp_add but_add but_edit but_help
  591. compile if EVERSION < 5.21  -- Help is now handled by the dialog box
  592.             if newword=but_help then
  593.                'helpmenu 14000'
  594.                return -3     -- do line over again
  595.             endif
  596.             if newword=but_edit then
  597. compile else
  598.             if button=chr(but_edit) then
  599. compile endif
  600.                newword=entrybox(REPLACEMENT__MSG '<'wrd'>','/'REPLACE__MSG'/'CANCEL__MSG,wrd)
  601.                if newword='' then
  602.                   return -1  -- next word
  603.                endif
  604. compile if EVERSION < 5.50  -- Don't have to worry about losing attributes...
  605.                getline line
  606.                replaceline leftstr(line,.col-1)||newword||substr(line,l)
  607. compile else
  608.                getsearch oldsearch
  609.                'xcom c '\1 || wrd || \1 || newword || \1
  610.                setsearch oldsearch
  611. compile endif
  612.                refresh
  613. ;;             return -100 - (length(newword)-oldwordlen)    -- Don't care about new len.
  614.                return -4    -- re-check line
  615.             endif
  616. compile if EVERSION < '5.50'
  617.             sayat wrd, .cursory, .cursorx, .textcolor, oldwordlen
  618. compile else
  619. ;           refresh  -- maybe can leave out...
  620. compile endif
  621. compile if EVERSION < 5.21
  622.             if newword=but_next then   -- goto next word
  623. compile else
  624.             if button=chr(but_next) then   -- goto next word
  625. compile endif
  626.                return -1
  627.             endif
  628. compile if ADDENDASUPPORT
  629.  compile if EVERSION < 5.21
  630.             if newword=but_temp_add then   -- temporary addenda (just for this PROOF session)
  631.  compile else
  632.             if button=chr(but_temp_add) then   -- goto next word
  633.  compile endif
  634.  compile if RESPECT_CASE_FOR_ADDENDA
  635.                call lexam(LXFAD2TRS, wrd)
  636.  compile else
  637.                call lexam(LXFAD2TRS,lowcase(wrd))
  638.  compile endif
  639.                return -1
  640.             endif
  641.  compile if EVERSION < 5.21
  642.             if newword=but_add then   -- addenda
  643.  compile else
  644.             if button=chr(but_add) then   -- goto next word
  645.  compile endif
  646.                call AMU_addenda_addition_processing(wrd)
  647.                return -1
  648.             endif
  649. compile endif
  650.             if newword='*Nothing Found*' then
  651.                return -1
  652.             endif
  653.             if newword<>'' then              /* was it a valid result ???    */
  654.                                              /* replace word in line         */
  655. compile if EVERSION < 5.50  -- Don't have to worry about losing attributes...
  656.                getline line
  657.                replaceline leftstr(line,.col-1)||newword||substr(line,l)
  658.                refresh
  659. compile else
  660.                getsearch oldsearch
  661.                'xcom c '\1 || wrd || \1 || newword || \1
  662.                setsearch oldsearch
  663. compile endif
  664.                return 100 + length(newword)-oldwordlen
  665. ;              return -1
  666.             endif
  667.           endif
  668.    return 0
  669.  
  670. /*
  671. ┌────────────────────────────────────────────────────────────────────────────┐
  672. │ What's it called: proof1()                                                 │
  673. │                                                                            │
  674. │ What does it do : Takes a word argument and looks it up in the lexam       │
  675. │                   dictionary using the 'lexam' opcode.                     │
  676. │                   If the word is found a list box is presented with the    │
  677. │                   possible correct word choices.                           │
  678. └────────────────────────────────────────────────────────────────────────────┘
  679. */
  680. defproc proof1( wrd )
  681.    result = lexam(LXFVERFY,wrd)            /* first off, is it a word?    */
  682.    if result then                          /* well is it???               */
  683.       result = lexam(LXFSPAID,wrd)         /* YES, now check it with lexam*/
  684.  
  685.       parse value result with .'/' result  /* remove first word           */
  686.       if rc>=LXRFINIT then
  687.          sayerror LOOKUP_FAILED__MSG '<' wrd '>'
  688.       else
  689.          if result='' then
  690.             result='*Nothing Found*'
  691.          endif
  692. compile if EVERSION < 5.21  -- The old way
  693.          do forever
  694.  compile if ADDENDASUPPORT
  695.             newword=listbox(PROOF_WORD__MSG,'/'result,'/'REPLACE__MSG'/'EXIT__MSG'/'ADD__MSG'/'HELP__MSG)     /* put result in PM list box   */
  696.             if newword='3' then   --  addenda
  697.                call AMU_addenda_addition_processing(wrd)
  698.                return -1
  699.             endif
  700.             if newword<>4 then leave; endif
  701.  compile else
  702.             newword=listbox(PROOF_WORD__MSG,'/'strip(result),'/'REPLACE__MSG'/'EXIT__MSG'/'HELP__MSG)     /* put result in PM list box   */
  703.             if newword<>3 then leave; endif
  704.  compile endif
  705.             'helpmenu 14001'
  706.          enddo
  707. compile else
  708.          parse value listbox(PROOF_WORD__MSG, '/'result,
  709.  compile if ADDENDASUPPORT
  710.                              '/'REPLACE__MSG'/'EXIT__MSG'/'ADD__MSG'/'HELP__MSG,
  711.  compile else
  712.                              '/'REPLACE__MSG'/'EXIT__MSG'/'HELP__MSG
  713.  compile endif
  714.  compile if EVERSION >= 5.60
  715.                              gethwndc(APP_HANDLE) || atoi(1) || atoi(1) || atoi(14001)) with button 2 newword \0
  716.  compile else
  717.                              atoi(1) || atoi(1) || atoi(14001) || gethwndc(APP_HANDLE)) with button 2 newword \0
  718.  compile endif
  719.          if button=\0 | button=\2 then  -- Close or Cancel
  720.             newword = ''
  721.  compile if ADDENDASUPPORT
  722.          elseif button=\3 then   --  addenda
  723.             call AMU_addenda_addition_processing(wrd)
  724.             return -1
  725.  compile endif
  726.          endif
  727. compile endif -- EVERSION < 5.21
  728.          if newword='*Nothing Found*' then
  729.             return
  730.          endif
  731.          return newword
  732.       endif
  733.    endif
  734.  
  735. compile endif  -- not USE_CUSTOM_PROOF_DIALOG  *************************************
  736.  
  737. /*
  738. ╔════════════════════════════════════════════════════════════════════════════╗
  739. ║ Addenda Support                                                            ║
  740. ╚════════════════════════════════════════════════════════════════════════════╝
  741. */
  742. compile if ADDENDASUPPORT
  743. /*
  744. ┌────────────────────────────────────────────────────────────────────────────┐
  745. │ What's it called: maybe_save_addenda                                       │
  746. │                                                                            │
  747. │ What does it do :                                                          │
  748. │                                                                            │
  749. └────────────────────────────────────────────────────────────────────────────┘
  750. */
  751. ; Addenda support commands
  752.  
  753. defproc maybe_save_addenda
  754.    universal  addenda_has_been_modified
  755.    universal  AMU_addenda_file_identification
  756.    universal  ADDENDA_FILENAME
  757.    universal Dictionary_loaded
  758.  
  759.    if Dictionary_loaded < 2 then
  760. ;   if addenda_has_been_modified then
  761.      -- sayatbox 'saving addenda 'ADDENDA_FILENAME
  762.       if AMU_addenda_file_identification<>''  then
  763.        getfileid AMU_current_file_identification
  764.        rc = 0
  765.        activatefile AMU_addenda_file_identification
  766.        if not rc then
  767.           if .modify then 'xcom save'; endif
  768. ;;        'xcom quit'
  769.        endif
  770.        -- sayerror 'addenda file filed'
  771.        activatefile AMU_current_file_identification
  772.       endif
  773.       addenda_has_been_modified=0
  774.       -- sayerror 0
  775.   endif
  776.  
  777. ;defc AMU_addenda_pickup
  778. ;   universal  ADDENDA_FILENAME
  779. ;   call lexam(LXFAMUGDIC,ADDENDA_FILENAME)
  780.  
  781. ;defc AMU_addenda_addition
  782. ;   call lexam(LXFAD2TRS,arg(1))
  783.  
  784. defproc AMU_addenda_processing
  785.    universal AMU_addenda_file_identification
  786.    universal  ADDENDA_FILENAME
  787.    getfileid AMU_current_file_identification
  788.    'xcom e' ADDENDA_FILENAME
  789.    -- sayerror 'addenda file loaded'
  790.    if not rc or rc = sayerror('New file') then
  791.       getfileid AMU_addenda_file_identification
  792.    else
  793.       AMU_addenda_file_identification =''
  794.       sayerror BAD_ADDENDA__MSG ADDENDA_FILENAME 'rc=' rc
  795.       return rc  -- was STOP; made non-fatal
  796.    endif
  797.    .visible=0 -- hidden file
  798.    activatefile AMU_current_file_identification
  799.    if AMU_addenda_file_identification <>'' then
  800.       for i = 1 to AMU_addenda_file_identification.last
  801.          getline line,i,AMU_addenda_file_identification
  802.          if upcase(leftstr(line, 8))='.DU ADD ' then
  803.             line=substr(line,9)
  804.          endif
  805.          do while line <> ''
  806.             parse value line with wrd line
  807.  compile if RESPECT_CASE_FOR_ADDENDA
  808.             call lexam(LXFAD2TRS,wrd)
  809.  compile else
  810.             call lexam(LXFAD2TRS,lowcase(wrd))
  811.  compile endif
  812.          enddo
  813.       endfor
  814.    endif
  815.  
  816. defproc AMU_addenda_addition_processing(AMU_addenda_entry)
  817.    universal  addenda_has_been_modified
  818.    universal AMU_addenda_file_identification, ADDENDA_FILENAME
  819.    addenda_has_been_modified=1
  820.  compile if not RESPECT_CASE_FOR_ADDENDA
  821.    AMU_addenda_entry=lowcase(AMU_addenda_entry)
  822.  compile endif
  823.    call lexam(LXFAD2TRS,AMU_addenda_entry)
  824.    if ADDENDA_FILENAME<>'' & AMU_addenda_file_identification<>'' then
  825.       insertline AMU_addenda_entry,AMU_addenda_file_identification.last+1,AMU_addenda_file_identification
  826.    endif
  827.  
  828.  
  829. compile endif -- ADDENDASUPPORT
  830.  
  831. ; The following is a script file type verification algorithm
  832. ; suggested by Larry Margolis. (Thanks, Larry)
  833. defproc AMU_script_verification()
  834. compile if EVERSION >= 5.50
  835.  compile if defined(my_SCRIPT_FILE_TYPE)
  836.    return (wordpos(filetype(), 'SCR SCT SCRIPT IPF' my_SCRIPT_FILE_TYPE)>0)
  837.  compile else
  838.    return (wordpos(filetype(), 'SCR SCT SCRIPT IPF')>0)
  839.  compile endif
  840. compile else
  841.    ext=filetype()
  842.  compile if defined(my_SCRIPT_FILE_TYPE)
  843.    return ext='SCR' or ext='SCT' or ext='SCRIPT' or ext='IPF' or ext=my_SCRIPT_FILE_TYPE
  844.  compile else
  845.    return ext='SCR' or ext='SCT' or ext='SCRIPT' or ext='IPF'
  846.  compile endif
  847. compile endif
  848.  
  849.  
  850. /*
  851. ╔════════════════════════════════════════════════════════════════════════════╗
  852. ║ General Lexam Support                                                      ║
  853. ╚════════════════════════════════════════════════════════════════════════════╝
  854. */
  855. defproc load_lexam
  856.    universal DICTIONARY_FILENAME
  857.    universal ADDENDA_FILENAME
  858.    universal Dictionary_loaded
  859.    if not dictionary_loaded then
  860.       rc = 0
  861.       result = lexam(LXFINIT)
  862.       if (result<>LXRFGOOD and result<>LXRFIFCN) or rc=-322 then
  863.          if result='febe' or rc=-322 then  -- x'febe' = -322 = sayerror('Dynalink: unrecognized library name')
  864. compile if EVERSION < '5.60a'  -- 5.60a and above give the message internally
  865.             sayerror sayerrortext(-322) LEXAM_DLL'.DLL'
  866. compile endif
  867.          else
  868.             sayerror INIT_ERROR__MSG '('rc')'
  869.          endif
  870.          return 1
  871.       endif
  872.       dictlist=DICTIONARY_FILENAME
  873.       do while dictlist <> ''
  874.          parse value dictlist with dictionary dictlist
  875.          if not(verify(dictionary,'\:','M')) then
  876.             if not exist(dictionary) then
  877.                findfile destfilename, dictionary, '','D'
  878.                if not rc then dictionary = destfilename; endif
  879.             endif
  880.          endif
  881.          result=lexam(LXFGDIC, dictionary)
  882.          if result>=LXRFNFND & result<>LXRFDUPD then  -- Duplicate Dictionary; didn't unload?
  883.             if exist(dictionary) then
  884.                sayerror BAD_DICT__MSG '"'dictionary'";' ERROR__MSG result
  885.             else
  886.                call winmessagebox(PROOF__MSG, NO_DICT__MSG\10'"'dictionary'"'\10\10 || DICT_PTR__MSG, MB_CANCEL + MB_ERROR + MB_MOVEABLE)
  887. ;              sayerror NO_DICT__MSG '"'dictionary'"'  DICT_PTR__MSG
  888.             endif
  889.             return 1
  890.          endif
  891.       enddo
  892. compile if ADDENDASUPPORT
  893.       if ADDENDA_FILENAME<>'' then
  894.          result = lexam(LXFAMUGDIC,ADDENDA_FILENAME)
  895.          if result & result<>LXRFUPDC then
  896.             sayerror BAD_ADDENDA__MSG '"'ADDENDA_FILENAME'";' ERROR__MSG result
  897.          else
  898.             call AMU_addenda_processing()
  899.          endif
  900.       endif
  901. compile endif
  902.    endif
  903.    dictionary_loaded = dictionary_loaded + 1
  904.    return 0
  905.  
  906. defproc drop_dictionary
  907.    universal DICTIONARY_FILENAME
  908.    universal  ADDENDA_FILENAME
  909.    universal  Dictionary_loaded
  910.    if dictionary_loaded then
  911.       dictionary_loaded = dictionary_loaded - 1
  912.    endif
  913.    if not dictionary_loaded then  -- Only unload if use-count now 0.
  914.       dictlist=DICTIONARY_FILENAME
  915.       do while dictlist <> ''
  916.          parse value dictlist with dictionary dictlist
  917.          call lexam(LXFFDIC, dictionary);
  918.       enddo
  919. compile if ADDENDASUPPORT
  920.       if ADDENDA_FILENAME<>'' then
  921.          call lexam(LXFFDIC,ADDENDA_FILENAME);
  922.       endif
  923. compile endif
  924.       call lexam(LXFTERM)
  925.    endif
  926.  
  927. defproc strippunct(var wrd,var l,var i)
  928. compile if EVERSION >= 6.01
  929.    universal LEXAM_PUNCTUATION
  930. compile endif
  931.    /* strip leading and trailing punctuation and try again*/
  932.    i=verify(wrd, LEXAM_PUNCTUATION)
  933.    if i then
  934.       j = length(wrd)
  935.       do while pos(substr(wrd, j, 1), '.?!,:;')  -- Extra check, to accept "didn't."
  936.          j = j - 1
  937.       enddo
  938.       if j<length(wrd) then
  939.          if not lexam(LXFVERFY, leftstr(wrd, j)) then  -- If result is 0, word is good.
  940.             i = 1
  941. ;;          l = l - length(wrd) + j
  942.             wrd = leftstr(wrd, j)
  943.             return
  944.          endif
  945.       endif
  946.       l=l-length(wrd)
  947.       wrd=substr(wrd,i)
  948.       j=verify(wrd, LEXAM_PUNCTUATION,'m')
  949.       if j then
  950.          wrd=leftstr(wrd,j-1)
  951.       else
  952.          j=length(wrd)+1
  953.       endif
  954.       l=l+j+i-2
  955.    else
  956.       i=length(wrd)+1
  957.    endif
  958.  
  959. compile if not USE_CUSTOM_PROOF_DIALOG
  960. defc proofword,verify
  961.    universal ADDENDA_FILENAME
  962.    if load_lexam() then
  963.      return
  964.    endif
  965.    orig_col = .col
  966.    call pbegin_word()
  967.    if substr(textline(.line), orig_col, 1)=' ' & .col < orig_col then
  968.       tmp = .col
  969.       call pend_word()
  970.       orig_col = .col
  971.       .col = tmp
  972.    endif
  973.    spellrc = spellword('', orig_col, arg(1))
  974. compile if ADDENDASUPPORT
  975.    if addenda_filename<>'' then
  976.       call maybe_save_addenda()
  977.    endif
  978. compile endif
  979.    call drop_dictionary()
  980.    if -2 = spellrc then
  981.       sayerror SPELLED_OK__MSG
  982.    endif
  983. compile endif -- not USE_CUSTOM_PROOF_DIALOG
  984.  
  985. defc dict
  986.    universal DICTIONARY_FILENAME
  987.    dictlist = arg(1)
  988.    if dictlist='' then
  989.       sayerror DICTLIST_IS__MSG DICTIONARY_FILENAME
  990.       return
  991.    endif
  992.    do while dictlist <> ''
  993.       parse value dictlist with dictionary dictlist
  994.       if not exist(dictionary) then
  995.          sayerror FILE_NOT_FOUND__MSG '"'dictionary'"; 'DICT_REMAINS__MSG DICTIONARY_FILENAME
  996.          return
  997.       endif
  998.    enddo
  999.    DICTIONARY_FILENAME = arg(1)
  1000.  
  1001. compile if 0 -- EVERSION >= 5.60
  1002. defc newproof
  1003.    universal ADDENDA_FILENAME
  1004.    if load_lexam() then
  1005.      return
  1006.    endif
  1007.    script_file_type=AMU_script_verification()
  1008. compile if defined(TEX_FILETYPES)
  1009.    tex_file_type = wordpos(filetype(),TEX_FILETYPES)
  1010. compile else
  1011.    tex_file_type = (filetype() = 'TEX')
  1012. compile endif
  1013.  
  1014.  --@@ If there's a line-marked area in the current file, proof only in there.
  1015.    firstline=max(.line,1); lastline=.last; what = FILE__MSG
  1016.    if marktype() then  /* if no mark, default to entire file */
  1017.       getfileid curfileid
  1018.       getmark fl,ll,fc,lc,markfileid
  1019.       if markfileid = curfileid then
  1020.          firstline=fl; lastline=ll
  1021.          what = MARKED_AREA__MSG
  1022.       endif
  1023.    endif
  1024.    partial_lines = marktype()='BLOCK' | marktype()='CHAR'
  1025.  
  1026. ;; if partial_lines then .col=fc; else .col=1; endif
  1027.  
  1028.    while firstline<=lastline do
  1029.  compile if EVERSION >= '5.21'
  1030.       display -8
  1031.  compile endif
  1032.       sayerror CHECKING__MSG what'...'
  1033. ;;    sayerror 'Spell Checking 'what '(line' zz'; last='lastline')...'
  1034.  compile if EVERSION >= '5.21'
  1035.       display 8
  1036.  compile endif
  1037.       .col = 1
  1038.  rc = '[not set]'
  1039.       result = lexam(LXFPRFLINE, firstline, lastline)
  1040.       if length(result) then
  1041.  sayerror 'rc=' rc'; result =' c2x(result)
  1042.          firstline = ltoa(leftstr(result, 4), 10)
  1043.          if length(result)=4 then sayerror 'Unexpected error on line' firstline'; aborting.'; stop; endif
  1044.          firstline
  1045.          offst = 0
  1046.          oldlen = length(textline(firstline))
  1047.          do i = 5 to length(result) by 2
  1048.             .col = itoa(substr(result, i, 2), 10) + offst
  1049.  compile if ADDENDASUPPORT
  1050.             t=spellword('/~Next/~Temp. Add')    -- spell check the word
  1051.  compile else
  1052.             t=spellword('/~Next')               -- spell check the word
  1053.  compile endif
  1054.             if t=0 then                         -- error occured
  1055.                return 0
  1056.             endif
  1057.             if t>0 then
  1058.                offst = offst + t - 100
  1059.             elseif t=-4 then   -- Edit was selected.
  1060.                i = i - 2  -- Repeat at this position.  (???)
  1061.                newlen = length(textline(firstline))
  1062.                offst = offst + newlen - oldlen
  1063.                oldlen = newlen
  1064.             endif
  1065.          enddo
  1066.          firstline = firstline + 1
  1067.       else  -- proofed the entire block successfully
  1068.          leave
  1069.       endif
  1070.    endwhile
  1071.  
  1072.  compile if ADDENDASUPPORT
  1073.    if addenda_filename<>'' then
  1074.       call maybe_save_addenda()
  1075.    endif
  1076.  compile endif
  1077.    call drop_dictionary()
  1078.    if arg(1)='' then
  1079.       sayerror DONE__MSG
  1080.    endif
  1081.  
  1082. compile endif  -- >= 5.60
  1083.  
  1084. compile if EVERSION >= 6.01
  1085. defc proof_punctuation
  1086.    universal LEXAM_PUNCTUATION
  1087.    if arg(1)<>'' then
  1088.       newpunct = DEFAULT_LEXAM_PUNCTUATION
  1089.    else
  1090.       newpunct = arg(1)
  1091.    endif
  1092.    result = lexam(LXFSETPUNCT, newpunct)        /* Set punctuation */
  1093.    if result then
  1094.       sayerror result
  1095.    else
  1096.       LEXAM_PUNCTUATION = newpunct
  1097.    endif
  1098. compile endif  -- >= 6.01
  1099.  
  1100. compile if USE_CUSTOM_PROOF_DIALOG
  1101. ; New commands for use with custom Proof dialog.
  1102.  
  1103. ; Proof - proofs the document or marked area.
  1104. ;    It uses the new Lexam subop that proofs lines and doesn't stop
  1105. ;    until it hits an error or finishes the last line.
  1106. ; ProofWord - proofs the current word.
  1107.  
  1108. ; Both set up state information, then call SpellWordD (like SpellWord) to check
  1109. ; an individual word.  If SpellWordD decides the word is bad, then if the dialog
  1110. ; has been started, it tells it to display the word, otherwise it starts the
  1111. ; dialog and relies on the Init message coming from the dialog to tell the dialog
  1112. ; to show the word.
  1113.  
  1114. ; State information:
  1115. ;  proofdlg_hwnd      Proof Dialog's window handle
  1116. ;  proofdlg_whatflag  What we're proofing - 1 = file, 2 = mark, 3 = word in file, 4 = word as PROOF argument
  1117. ;  proof_curline      Current line we're checking
  1118. ;  proof_lastline     Last line to be checked
  1119. ;  proof_lexresult    Result from Lexam(proofline)
  1120. ;  proof_resultofs    Current offset in proof_lexresult we're checking
  1121. ;  proof_offst        offset from the columns in proof_lexresult we should use
  1122. ;                     (changes from 0 if we replace an earlier word in that line
  1123. ;                     with one of a different length)
  1124. ;  proof_prev_col     Saves the previous column (to be used after replacing
  1125. ;                     a word with a user-entered word; we need to use the old offset,
  1126. ;                     not the new one).
  1127.  
  1128. defc proof
  1129.    universal proofdlg_hwnd, proofdlg_whatflag, proof_curline, proof_lastline, proof_lexresult, proofdlg_filetypeflags, proof_word
  1130.    if load_lexam() then
  1131.       return
  1132.    endif
  1133.  
  1134.    if arg(1)<>'' then  -- A word to be proofed was given as an argument.
  1135.       proofdlg_whatflag = 4
  1136.       result = lexam(LXFVERFY,arg(1))           /* verify word                  */
  1137.       if not result then    -- was it a success
  1138.          call drop_dictionary()
  1139.          sayerror SPELLED_OK__MSG
  1140.          return
  1141.       endif
  1142.       proof_word = arg(1)
  1143.       if proofdlg_hwnd then  -- Dialog started
  1144.          'proofdlg' proofdlg_hwnd 'newword'
  1145.       else
  1146.          sayerror 0        -- (Clear a "Spell checking..." message, if one was up.)
  1147.          'proofdlg pop'    -- Start the dialog; it will do the rest
  1148.       endif
  1149.       return
  1150.    endif
  1151.  
  1152. ;  script_file_type=AMU_script_verification()
  1153. ;compile if defined(TEX_FILETYPES)
  1154. ;   tex_file_type = wordpos(filetype(),TEX_FILETYPES)
  1155. ;compile else
  1156. ;   tex_file_type = (filetype() = 'TEX')
  1157. ;compile endif
  1158. compile if defined(TEX_FILETYPES)
  1159.    proofdlg_filetypeflags = AMU_script_verification() + 2*(wordpos(filetype(),TEX_FILETYPES)>0) + 4*abbrev('HTML', filetype(), 3)
  1160. compile else
  1161.    proofdlg_filetypeflags = AMU_script_verification() + 2*(filetype() = 'TEX') + 4*abbrev('HTML', filetype(), 3)
  1162. compile endif
  1163.  
  1164.  --@@ If there's a line-marked area in the current file, proof only in there.
  1165.    proof_curline=max(.line,1); proof_lastline=.last; /* what = FILE__MSG;*/ proofdlg_whatflag = 1
  1166.    if marktype() then  /* if no mark, default to entire file */
  1167.       getfileid curfileid
  1168.       getmark fl,ll,fc,lc,markfileid
  1169.       if markfileid = curfileid then
  1170.          proof_curline=fl; proof_lastline=ll
  1171.          /* what = MARKED_AREA__MSG */
  1172.          proofdlg_whatflag = 2
  1173.       endif
  1174.    endif
  1175.    partial_lines = marktype()='BLOCK' | marktype()='CHAR'
  1176.  
  1177. ;; if partial_lines then .col=fc; else .col=1; endif
  1178.    proof_lexresult = ''
  1179.    'keep_on_prufin'
  1180.  
  1181. defc keep_on_prufin
  1182.    universal ADDENDA_FILENAME
  1183.    universal proofdlg_hwnd, proofdlg_whatflag, proof_curline, proof_lastline, proof_lexresult, proof_resultofs, proof_offst, proof_prev_col, proofdlg_filetypeflags
  1184.    while proof_curline<=proof_lastline do
  1185.       if not proofdlg_hwnd then
  1186.          display -8
  1187. ;;       sayerror 'Spell Checking 'subword('file marked area', proofdlg_whatflag, proofdlg_whatflag)'...'
  1188.          if proofdlg_whatflag=1 then
  1189.             sayerror CHECKING__MSG FILE__MSG
  1190.          elseif proofdlg_whatflag=1 then
  1191.             sayerror CHECKING__MSG MARKED_AREA__MSG
  1192.          endif
  1193.          display 8
  1194. ;;    else
  1195. ;;       msg = 'Checking spelling...'\0
  1196. ;;       call windowmessage(1,  proofdlg_hwnd,   -- send message back to dialog
  1197. ;;                          32,               -- WM_COMMAND - 0x0020
  1198. ;;                          9190,             -- Set dialog prompt
  1199. ;;                          ltoa(offset(msg) || selector(msg), 10) )
  1200.       endif
  1201.       if proof_lexresult='' then
  1202.          .col = 1
  1203.          proof_lexresult = lexam(LXFPRFLINE, proof_curline, proof_lastline, proofdlg_filetypeflags)
  1204. ;sayerror 'proof_lexresult('proof_curline',' proof_lastline') =' c2x(leftstr(proof_lexresult,4)) c2x(substr(proof_lexresult, 5))
  1205.          proof_resultofs = 5
  1206.          proof_offst = 0
  1207.          proof_prev_col = ''
  1208.       endif
  1209.       if length(proof_lexresult) then
  1210. ;sayerror 'rc=' rc'; proof_lexresult =' c2x(proof_lexresult)
  1211.          proof_curline = ltoa(leftstr(proof_lexresult, 4), 10)
  1212.          if length(proof_lexresult)=4 then
  1213.             sayerror PROOF_ERROR1__MSG proof_curline PROOF_ERROR2__MSG
  1214.             proof_curline = proof_curline + 1
  1215.             proof_lexresult=''
  1216.             iterate
  1217.          endif
  1218.          proof_curline
  1219.          oldlen = length(textline(proof_curline))
  1220.          do i = proof_resultofs to length(proof_lexresult) by 2
  1221.             if proof_prev_col then
  1222.                .col = proof_prev_col
  1223.             else
  1224.                .col = itoa(substr(proof_lexresult, i, 2), 10) + proof_offst
  1225.             endif
  1226.             t=spellwordd('')    -- spell check the word
  1227. ;sayerror 'i='i'; .col =' .col '=' itoa(substr(proof_lexresult, i, 2), 10) + proof_offst'; proof_offst='proof_offst 't='t
  1228.             if t = -3 then  -- Dialog will continue
  1229.                proof_resultofs = i + 2
  1230.                return
  1231.             endif
  1232.             proof_prev_col=''
  1233.             if not t then                         -- error occured
  1234.                leave
  1235.             endif
  1236.          enddo
  1237.          proof_curline = proof_curline + 1
  1238.          proof_lexresult = ''
  1239.       else  -- proofed the entire block successfully
  1240.          leave
  1241.       endif
  1242.    endwhile
  1243.  
  1244.  compile if ADDENDASUPPORT
  1245.    if addenda_filename<>'' then
  1246.       call maybe_save_addenda()
  1247.    endif
  1248.  compile endif
  1249.    call drop_dictionary()
  1250.    if proofdlg_hwnd then
  1251.       call windowmessage(0,  proofdlg_hwnd,   -- send message to dialog
  1252.                          41,                  -- WM_CLOSE - 0x0029
  1253.                          0,
  1254.                          0)
  1255.    endif
  1256.    if arg(1)='' then
  1257.       sayerror DONE__MSG
  1258.    endif
  1259.  
  1260.  
  1261. defc proofword, verify
  1262.    universal ADDENDA_FILENAME
  1263.    universal proofdlg_hwnd, proofdlg_whatflag
  1264.    if load_lexam() then
  1265.      return
  1266.    endif
  1267.    orig_col = .col
  1268.    call pbegin_word()
  1269.    if substr(textline(.line), orig_col, 1)=' ' & .col < orig_col then
  1270.       tmp = .col
  1271.       call pend_word()
  1272.       orig_col = .col
  1273.       .col = tmp
  1274.    endif
  1275.    proofdlg_whatflag = 3
  1276.    spellrc = spellwordd('', orig_col, arg(1))
  1277.    if -2 = spellrc then
  1278.       sayerror SPELLED_OK__MSG
  1279.       call drop_dictionary()
  1280.               -- Otherwise, closing the dialog will unload lexam.
  1281.    endif
  1282.  
  1283. ; return codes:  0 = unexpected error (line blank)
  1284. ;       X       >0 = 100 + length(newword)-length(oldword)
  1285. ;       X       -1 = Lookup failed or user selected Next or (Temp)Add; go on to next word.
  1286. ;               -2 = Word was spelled correctly
  1287. ;               -3 = Dialog invoked
  1288. ;       X       -4 = User selected Edit; recheck line.
  1289. ;      (X means not returned by this version of the routine.)
  1290. defproc spellwordd
  1291. compile if EVERSION >= 6.01
  1292.    universal LEXAM_PUNCTUATION
  1293. compile endif
  1294.    universal proofdlg_hwnd, proof_word, proofdlg_filetypeflags, proofdlg_whatflag
  1295.    getline line
  1296.    line = translate(line, ' ', \9)  -- Convert tabs to spaces
  1297.    if line='' then                        /* if the line is empty...     */
  1298.       return 0
  1299.    endif
  1300.    i=.col                                 /* save the cursor column       */
  1301.    l=pos(' ',line,.col)                   /* get next word after cursor   */
  1302.    if l=0 then                            /* is it a word???              */
  1303.       l=max(length(line)+1, i)
  1304.    endif
  1305.    wrd=strip(substr(line,i,l-i))          /* extract word from line       */
  1306.    if wrd='' then
  1307.       return -2
  1308.    endif
  1309.    if not verify(wrd, LEXAM_PUNCTUATION) then  -- No letters in "word"; skip it.
  1310.       return -2
  1311.    endif
  1312.    if proofdlg_whatflag = 3 then
  1313.       script_file_type=AMU_script_verification()
  1314.  compile if defined(TEX_FILETYPES)
  1315.       tex_file_type = wordpos(filetype(),TEX_FILETYPES)
  1316.  compile else
  1317.       tex_file_type = (filetype() = 'TEX')
  1318.  compile endif
  1319.    else
  1320.       script_file_type=proofdlg_filetypeflags // 2
  1321.  compile if EVERSION >= '6.01b'
  1322.       tex_file_type = proofdlg_filetypeflags bitand 2
  1323.  compile else
  1324.       tex_file_type = proofdlg_filetypeflags%2 - 2 * (proofdlg_filetypeflags % 4)
  1325.  compile endif
  1326.    endif
  1327.    result = 1
  1328.    if script_file_type then  -- Do just the cheap test first.
  1329.       tmp = substr(line,max(.col-1,1),1)
  1330.       if (pos(leftstr(wrd,1),':&.') or pos(tmp,':&')) then
  1331.          result=0
  1332.          if leftstr(wrd,1)=':' | tmp=':' then
  1333.             tmp=pos('.',line,.col)
  1334.             if tmp then
  1335.                result = 1
  1336.                .col = tmp+1
  1337.                wrd = substr(wrd, .col)
  1338. ;              l=tmp
  1339.             endif
  1340.          endif
  1341.       endif
  1342.    elseif tex_file_type & pos('\', wrd) then
  1343.       result=0
  1344.    endif
  1345.    if result then  -- If not set to 0 by SCRIPT or TeX
  1346.       result = lexam(LXFVERFY,wrd)           /* verify word                  */
  1347.    endif
  1348.    start_l = l
  1349.    if result then                         /* was it a success             */
  1350.       do forever
  1351.          call strippunct(wrd,l,i)            /* strip punctuation/ try again */
  1352.          .col=.col+i-1                       /* move to next column          */
  1353.          if wrd='' then
  1354.             return -2
  1355.          endif
  1356.          if l>=arg(2) then  -- Will always be true if arg(2) omitted.
  1357.             leave
  1358.          endif
  1359.          .col = l
  1360.          l = start_l
  1361.          wrd=strip(substr(line,.col,l-.col))    /* extract word from line       */
  1362.       enddo
  1363.       result = lexam(LXFVERFY,wrd)        /* try word  verification again */
  1364.    endif
  1365.    if not (result or abbrev('FORCE', upcase(arg(3)), 1)) then    -- was it a success
  1366.       --.messageline='word is spelled correctly'
  1367.       if l<start_l & arg(2)='' then
  1368.          .col = l
  1369.          return spellwordd(arg(1))
  1370.       endif
  1371.       return -2
  1372.    endif
  1373.    proof_word = wrd
  1374.    if proofdlg_hwnd then  -- Dialog started
  1375.       'proofdlg' proofdlg_hwnd 'newword'
  1376.    else
  1377.       sayerror 0        -- (Clear a "Spell checking..." message, if one was up.)
  1378.       'proofdlg pop'    -- Start the dialog; it will do the rest
  1379.    endif
  1380.    return -3
  1381.  
  1382. #define PRFDLG_REPLACE     9103    -- Proof dialog buttons
  1383. #define PRFDLG_NEXT        9105
  1384. #define PRFDLG_TEMPADD     9106
  1385. #define PRFDLG_ADD         9107
  1386. #define PRFDLG_HELP        9108
  1387. #define PRFDLG_EDIT        9111
  1388. #define DID_CANCEL            2
  1389.  
  1390. defc proofdlg
  1391.    universal ADDENDA_FILENAME
  1392.    universal proofdlg_hwnd, proof_word, proofdlg_whatflag, proof_offst, proof_resultofs, proof_prev_col, dynaspel_closecmd
  1393. ;; universal proof_nextcol  -- temp
  1394.    parse arg hndle opt rest
  1395.    continue = 0
  1396.    if arg(1)='pop' then
  1397.  compile if E_DLL = 'UTKE600'
  1398.       call windowmessage(0,  getpminfo(EPMINFO_OWNERCLIENT),
  1399.                          5549,    --WM_USER + 0x0500 + 0x00AD = OBJEPM_PROOFDLG
  1400.                          0,
  1401.                          0)
  1402.  compile else
  1403.       call windowmessage(0,  getpminfo(APP_HANDLE),
  1404.                         5150,               -- EPM_POPPROOFDLG
  1405.                         0,
  1406.                         0)
  1407.  compile endif -- E_DLL = 'UTKE600'
  1408.    elseif opt='init' then
  1409.       if proofdlg_whatflag = 1 then
  1410.          msg = CHECKING__MSG FILE__MSG\0
  1411.       elseif proofdlg_whatflag = 2 then
  1412.          msg = CHECKING__MSG MARKED_AREA__MSG\0
  1413.       elseif proofdlg_whatflag = 3 | proofdlg_whatflag = 4 then
  1414.          msg = PROOF_WORD__MSG\0
  1415.       else
  1416.          return
  1417.       endif
  1418.       call windowmessage(1,  hndle,   -- send message back to dialog
  1419.                          32,               -- WM_COMMAND - 0x0020
  1420.                          9193,             -- Set dialog title
  1421.                          ltoa(offset(msg) || selector(msg), 10) )
  1422.       proofdlg_hwnd = hndle
  1423.       if proof_word<>'' then
  1424.          'proofdlg' proofdlg_hwnd 'newword'
  1425.       endif
  1426.    elseif opt='newword' then
  1427.       if proof_word<>'' then
  1428.          oldwordlen=length(proof_word)
  1429.          oldcol = .col; .col = .col + oldwordlen; .col = oldcol;
  1430.          circleit PROOF_CIRCLE_STYLE, .line, .col, .col+oldwordlen-1, PROOF_CIRCLE_COLOR1, PROOF_CIRCLE_COLOR2
  1431. ;;       refresh  -- Refresh required to display circle, because control isn't being returned to the user
  1432.          msg = \26 proof_word\0  -- \26 is right arrow (also, EOF character!)
  1433.          call windowmessage(1,  proofdlg_hwnd,   -- send message back to dialog
  1434.                             32,               -- WM_COMMAND - 0x0020
  1435.                             9191,             -- Set current word being proofed
  1436.                             ltoa(offset(msg) || selector(msg), 10) )
  1437.       endif
  1438.       -- The following must be here, because 9191 re-enables the buttons.
  1439.       if proofdlg_whatflag = 3 | proofdlg_whatflag = 4 then
  1440.          call windowmessage(1,  proofdlg_hwnd,   -- send message back to dialog
  1441.                             32,               -- WM_COMMAND - 0x0020
  1442.                             9195,             -- Disable buttons
  1443.                             2+8+(64+1)*(proofdlg_whatflag=4) )  -- Temp. Add, Next, and for whatflg=4, Edit & Replace
  1444. compile if PROOF_NEXT_DEFAULT
  1445.       else
  1446.          call windowmessage(1,  proofdlg_hwnd,   -- send message back to dialog
  1447.                             32,               -- WM_COMMAND - 0x0020
  1448.                             9196,             -- Set default button
  1449.                             PRFDLG_NEXT)
  1450. compile endif
  1451.       endif
  1452.    elseif opt='suggest' then
  1453.        oldwordlen=length(proof_word)
  1454.        circleit PROOF_CIRCLE_STYLE, .line, .col, .col+oldwordlen-1, PROOF_CIRCLE_COLOR1, PROOF_CIRCLE_COLOR2
  1455.        parse value lexam(LXFSPAID, proof_word) with 2 '/' result
  1456.        if rc>=LXRFINIT then
  1457.           msg = LOOKUP_FAILED__MSG '<' proof_word '> RC='rc\0
  1458.           call windowmessage(1,  hndle,   -- send message back to dialog
  1459.                              32,               -- WM_COMMAND - 0x0020
  1460.                              9190,             -- Set dialog prompt
  1461.                              ltoa(offset(msg) || selector(msg), 10) )
  1462.        elseif result='' then
  1463.           msg = WORD_NOT_FOUND__MSG '<' proof_word '>'\0
  1464.           call windowmessage(1,  hndle,   -- send message back to dialog
  1465.                              32,               -- WM_COMMAND - 0x0020
  1466.                              9190,             -- Set dialog prompt
  1467.                              ltoa(offset(msg) || selector(msg), 10) )
  1468.        else
  1469.           msg = result\0
  1470. compile if PROOF_NEXT_DEFAULT
  1471.           call windowmessage(1,  proofdlg_hwnd,   -- send message back to dialog
  1472.                              32,               -- WM_COMMAND - 0x0020
  1473.                              9196,             -- Set default button
  1474.                              PRFDLG_REPLACE)
  1475. compile endif
  1476.           call windowmessage(1,  hndle,   -- send message back to dialog
  1477.                              32,               -- WM_COMMAND - 0x0020
  1478.                              9192,             -- Fill listbox
  1479.                              ltoa(offset(msg) || selector(msg), 10) )
  1480.        endif
  1481.    elseif opt='edit' then
  1482.       msg = proof_word\0
  1483.       call windowmessage(1,  hndle,   -- send message back to dialog
  1484.                          32,               -- WM_COMMAND - 0x0020
  1485.                          9197,             -- Set entry field
  1486.                          ltoa(offset(msg) || selector(msg), 10) )
  1487.    elseif opt='rep_l' | opt='rep_n' then  -- Replace from list / Replace with new word
  1488.       if proofdlg_whatflag <> 4 then  -- Shouldn't be, since we disable the button...
  1489. compile if 0  -- The following loses attributes.
  1490.          getline line
  1491.          replaceline leftstr(line,.col-1) || rest || substr(line,.col+length(proof_word))
  1492. compile else  -- A Change command will preserve them.
  1493.          getsearch oldsearch
  1494.          'xcom c '\1 || proof_word || \1 || rest || \1
  1495.          setsearch oldsearch
  1496. compile endif
  1497.       endif
  1498.       continue = 1
  1499.       if proofdlg_whatflag < 3 then
  1500.          proof_offst = proof_offst + length(rest) - length(proof_word)
  1501.          if opt='rep_n' then  -- Replace from list / Replace with new word
  1502.             proof_resultofs = proof_resultofs - 2  -- back up one word (recheck replaced word)
  1503.             proof_prev_col = .col
  1504. ;; proof_nextcol = .col
  1505.          endif
  1506.       endif
  1507.    elseif opt='add' then
  1508.       call AMU_addenda_addition_processing(proof_word)
  1509.       continue = 1
  1510.    elseif opt='tempadd' then
  1511.  compile if RESPECT_CASE_FOR_ADDENDA
  1512.       call lexam(LXFAD2TRS, proof_word)
  1513.  compile else
  1514.       call lexam(LXFAD2TRS,lowcase(proof_word))
  1515.  compile endif
  1516.       continue = 1
  1517.    elseif opt='next' then
  1518.       continue = 1
  1519.    elseif opt='close' then
  1520.  compile if ADDENDASUPPORT
  1521.       if addenda_filename<>'' then
  1522.          call maybe_save_addenda()
  1523.       endif
  1524.  compile endif
  1525.       call drop_dictionary()
  1526.       proofdlg_hwnd = ''
  1527.       if dynaspel_closecmd then
  1528.          dynaspel_closecmd
  1529.          dynaspel_closecmd = ''
  1530.       endif
  1531.    else
  1532.       sayerror 'ProofDlg' arg(1)
  1533.    endif
  1534. ;sayerror 'proofdlg "'arg(1)'", continue =' continue
  1535.    if continue then  -- Continue to next word
  1536. ;;    .col = proof_nextcol
  1537.       if proofdlg_whatflag >= 3 then  -- We were proofing a single word; all done!
  1538.          call windowmessage(0,  hndle,           -- send message to dialog
  1539.                             41,                  -- WM_CLOSE - 0x0029
  1540.                             0,
  1541.                             0)
  1542.       else  -- really have to keep going
  1543.           call windowmessage(1,  hndle,   -- send message back to dialog
  1544.                              32,               -- WM_COMMAND - 0x0020
  1545.                              9194,             -- Disable everything
  1546.                              0)
  1547.          if opt<>'rep_n' then
  1548.             proof_prev_col = ''
  1549.          endif
  1550.          'keep_on_prufin'
  1551.       endif
  1552.    endif
  1553. compile endif  -- USE_CUSTOM_PROOF_DIALOG
  1554.  
  1555. const SPELL_DEBUG = 0
  1556.  
  1557. defkeys spell_keys overlay  -- For dynamic spell-checking
  1558.  
  1559. def space, enter =
  1560. compile if EVERSION >= 6.01
  1561.    universal LEXAM_PUNCTUATION
  1562. compile endif
  1563.    universal EPM_utility_array_ID
  1564.    universal dynaspel_line, dynaspel_col
  1565.    saveline = .line
  1566.    savecol = .col - 1
  1567.    getfileid fid
  1568.    do_array 3, EPM_utility_array_ID, 'dspl.'fid, xkeyset  -- Restore original keyset for this fileid.
  1569.    .keyset = xkeyset
  1570.    executekey lastkey()
  1571.    keys spell_keys
  1572.    getline line, saveline
  1573.    if not savecol or line = '' then
  1574. compile if SPELL_DEBUG
  1575.       sayerror '[Line was blank]'
  1576. compile endif -- DEBUG
  1577.       return
  1578.    endif
  1579.    if substr(line, savecol, 1) = ' ' then
  1580. compile if SPELL_DEBUG
  1581.       sayerror '[Prev. char was blank]'
  1582. compile endif -- DEBUG
  1583.       return
  1584.    endif
  1585. ;  newcol = .col
  1586.    start = lastpos(' ', line, savecol)
  1587. ;  wrd = substr(line, start+1, savecol - start)
  1588.    parse value substr(line, start+1) with wrd .
  1589.    if not verify(wrd, LEXAM_PUNCTUATION) then  -- No letters in "word"; skip it.
  1590. compile if SPELL_DEBUG
  1591.       sayerror '[Only punctuation in word 'wrd']'
  1592. compile endif -- DEBUG
  1593.       return
  1594.    endif
  1595.    firstchar = leftstr(wrd, 1)
  1596.    if firstchar='\' then  -- Do the cheap test first
  1597. compile if defined(TEX_FILETYPES)
  1598.       if wordpos(filetype(),TEX_FILETYPES) then
  1599. compile else
  1600.       if filetype() = 'TEX' then
  1601. compile endif
  1602. compile if SPELL_DEBUG
  1603.          sayerror '[TEX token: 'wrd']'
  1604. compile endif -- DEBUG
  1605.          return
  1606.       endif
  1607.    elseif pos(firstchar, ':&') then  -- (Do the cheap test first)  Script markup or variable?
  1608.       if AMU_script_verification() then
  1609.          p=pos('.', wrd)
  1610.          if p & p<length(wrd) then
  1611.             wrd = substr(wrd, p+1)
  1612.          else
  1613. compile if SPELL_DEBUG
  1614.             if firstchar='&' then
  1615.                sayerror '[SCRIPT variable: 'wrd']'
  1616.             else
  1617.                sayerror '[SCRIPT markup: 'wrd']'
  1618.             endif
  1619. compile endif -- DEBUG
  1620.             return
  1621.          endif
  1622.       endif
  1623.    elseif firstchar='.' & not start then  -- (Do the cheap test first)  SCRIPT control word?
  1624.       if AMU_script_verification() then
  1625. compile if SPELL_DEBUG
  1626.          sayerror '[SCRIPT control word: 'wrd']'
  1627. compile endif -- DEBUG
  1628.          return
  1629.       endif
  1630.    endif
  1631.    result=lexam(LXFVERFY,wrd)          /* authenticate word using lexam */
  1632.    if result then
  1633.       call strippunct(wrd,savecol,tmp)
  1634.       result = lexam(LXFVERFY,wrd)
  1635.    endif
  1636.    if(result <> LXRFGOOD) then         /* was it a success ???          */
  1637. compile if DYNASPELL_BEEP = 'ALARM'
  1638.  compile if EPM32
  1639.       call dynalink32('PMWIN',
  1640.                       '#701',      -- ORD_WIN32ALARM
  1641.                       atol(1)  ||  -- HWND_DESKTOP
  1642.                       atol(0) )    -- WA_WARNING
  1643.  compile else
  1644.       call dynalink('PMWIN',
  1645.                     'WINALARM',
  1646.                     atoi(0) ||   -- atol_swap(
  1647.                     atoi(1) ||   --    HWND_DESKTOP)
  1648.                     atoi(0) )    -- WA_WARNING
  1649.  compile endif
  1650. compile elseif DYNASPELL_BEEP
  1651.       call beep(1000, 100)
  1652. compile endif
  1653.       dynaspel_line = saveline
  1654.       dynaspel_col = savecol
  1655.       sayerror DYNASPEL_PROMPT1__MSG || wrd || DYNASPEL_PROMPT2__MSG
  1656. compile if SPELL_DEBUG
  1657.    else
  1658.       sayerror '[Word was 'wrd' - OK]'
  1659. compile endif -- DEBUG
  1660.    endif
  1661.  
  1662. compile if not defined(DYNASPELL_KEY)
  1663. define DYNASPELL_KEY = 'c_A'
  1664. compile endif
  1665.  
  1666. def $DYNASPELL_KEY =
  1667.    universal dynaspel_line, dynaspel_col, dynaspel_closecmd
  1668.    if not dynaspel_line then
  1669.       sayerror DYNASPEL_NORECALL__MSG
  1670.       return
  1671.    endif
  1672.    if .line=dynaspel_line then
  1673.       oldlen = length(textline(dynaspel_line))
  1674.    endif
  1675.    call psave_pos(save_pos)
  1676.    dynaspel_line; .col = dynaspel_col
  1677. compile if USE_CUSTOM_PROOF_DIALOG
  1678.    dynaspel_closecmd = 'dynaspell_restorepos' oldlen save_pos
  1679. compile endif
  1680.    'proofword'
  1681. compile if USE_CUSTOM_PROOF_DIALOG
  1682. defc dynaspell_restorepos
  1683.    universal dynaspel_line, dynaspel_col
  1684.    parse arg oldlen save_pos
  1685. compile endif
  1686.    call prestore_pos(save_pos)
  1687.    if .line=dynaspel_line then
  1688.       diff = length(textline(dynaspel_line)) - oldlen
  1689.       if diff>0 then
  1690.          right diff
  1691.       elseif diff<0 then
  1692.          left -diff
  1693.       endif
  1694.    endif
  1695.  
  1696.  
  1697. defc dynaspell =  -- Takes no arguments; just toggles setting.
  1698.    universal EPM_utility_array_ID
  1699.    universal ADDENDA_FILENAME
  1700.    getfileid fid
  1701.    if .keyset<>'SPELL_KEYS' then  -- Dynamic spell-checking off for this file
  1702.       if load_lexam() then
  1703.          return
  1704.       endif
  1705.       tmp_keyset = .keyset
  1706.       do_array 2, EPM_utility_array_ID, 'dspl.'fid, tmp_keyset  -- Remember original keyset for this fileid.
  1707.       keys spell_keys
  1708.    else  -- Dynamic spell-checking is on; now being turned off.
  1709. compile if ADDENDASUPPORT
  1710.       if addenda_filename<>'' then
  1711.          call maybe_save_addenda()
  1712.       endif
  1713. compile endif
  1714.       call drop_dictionary()
  1715.       do_array 3, EPM_utility_array_ID, 'dspl.'fid, tmp_keyset  -- Retrieve original keyset for this fileid.
  1716.       .keyset = tmp_keyset
  1717.       empty = ''
  1718.       do_array 2, EPM_utility_array_ID, 'dspl.'fid, empty
  1719.    endif
  1720.