/* * ----------------------------------------------------------------- * Execution of this macro requires a license for uni-XEDIT Extended * for each concurrent user of the macro. * ----------------------------------------------------------------- * * * * SPELL.XEDIT * * The SPELL.XEDIT macro supplies several functions related to spell * checking uni-XEDIT ring files and uses the Unix 'spell' command. * The functions provided through this macro are specified as * command line parameters or as PF key assignments. * * The functions provided are: * * check This is the default action and spell checks the ring file. * * clear Removes spell check markup from the ring file. * * correct Removes the current word's markup. This should be * assigned to a PF key. * * add Removes the current word's markup and adds the * current word to the spelling list for this directory. * This should be assigned to a PF key. * * find Puts the cursor on the first/next misspelled word. * Note that check, correct and add all perform the * find function as their last act. * * Each of the major functions is documented separately below. * * The two functions designed to work more efficiently when they are * assigned to PF keys are correct and add. This can be accomplished * by including the appropriate 'set' options in your uni-XEDIT * profile macro. For example, * * 'set pf2 only macro spell correct' * 'set pf4 only macro spell add' * * This macro uses the editor's truncation setting in drawing markup * lines. Currently, the truncation must be less than 247. If you * have a truncation setting in your profile, make sure it is less than * 247. Alternatively, 'set trunc 247' prior to issuing the spell macro. * The default truncation setting of 256 causes double markup lines to * be drawn resulting in incorrect operation of the CORRECT and CLEAR * actions. * ******************************************************************* * Possible enhancements: * * ---correct/add could remove marks throughout, or maybe another * function that will remove the last correct/add word throughout * (may have to save it in a temp file). * ******************************************************************* * * HOW TO USE THE SPELL.XEDIT MACRO * * During an edit session you may execute the spell macro by * typing on the command line * * spell * or spell check * * and pressing . The file will be spell checked and the * message "Press ENTER to return to the editor" appears. Press * to return to the edit session. * * The mispelled words will be marked in the form of the following * example and the cursor is placed on the first misspelled word. * * This is a tst with mispeled wods. * ----------^^^------^^^^^^^^-^^^^-------------------------------- * * Correct a misspelled word using regular editor facilities such as * delete and insert. * * You may do any of the following: * * -- Make the appropriate corrections to the word and then * press the PF key that you assigned to the CORRECT action * to clear the word's markup. If the cursor is not in the * misspelled word, pressing the PF key simply moves the * the cursor to the first character of the word. You will * need to press the PF key a second time to clear the markup. * Correct the next word, press the CORRECT PF key and so forth * throughout the file. * * -- Make corrections to all misspelled words, deferring * the clearing of markup until you are finished. To clear * all markup, type on the command line 'spell clear' and * press . * -- Make corrections to a misspelled word and then ADD it * to the dictionary by pressing the PF key that you assigned * to this action. * */ /***********************************************************************/ /* LOCAL DICTIONARY * * Set up local dictionary. * */ 'set wrap off' localdict="spell.list" /* file name for a local dictionary, which might be found in the same directory where the document being checked lives. */ "extract /fname /trunc" fn=fname.1 x=lastpos("/",fn) if x>0 /* if file being edited is not in the current directory */ then localdict=left(fn,x)||localdict /* then use that directory's dict. */ /************************************************************************/ /* * ACTION * * This section determines which action to perform. * */ arg action select when action="CHECK" | action="" then call check when action="CLEAR" then call clear when action="CORRECT" | action="ADD" then call correct when action="FIND" then call find otherwise say action "is an invalid spell action." end exit /************************************************************************/ /* * CHECK * * The check action runs the current document through the spell * command and marks every misspelled word in the document by * adding a line to the document showing the misspelled word. * The lines added take the form of * * blah blah blah blah mispelled blah blah blah blah * --------------------^^^^^^^^^-------------------- */ check: a="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" tempfile="sp.out" address unix "touch" tempfile address unix "rm" tempfile "save" if chars(localdict)=0 /* use local dictionary if one exists */ then address unix "spell" fname.1 ">" tempfile else address unix "spell +"localdict fname.1 ">" tempfile do while lines(tempfile) > 0 word=linein(tempfile) "top" "msgmode off" "cl/"||word /* find first occurrence of the misspelled word */ do while rc=0 /* process all such occurrences */ "msgmode on" "extract /column /curline" /* * The following section of code determines whether occurrences of the * found string are really part of a larger word. */ whole="y" if column.1>1 then if index(a,substr(curline.3,column.1-1,1))>0 then whole="n" /* char before word is an alphanumeric! */ if column.1+length(word)<=trunc.1 then if index(a,substr(curline.3,column.1+length(word),1))>0 then whole="n" /* char after word is an alphanumeric! */ /* * The variable 'whole' indicates whether the found string is part of a * larger word or not. */ if whole="y" /* only mark whole words, not part of larger words */ then do "down" /* see if next line is a markup line */ "extract /curline" if translate(curline.3,,"-^")="" & curline.3<>"" then do /* combine new markup with old */ "replace", overlay("^",curline.3,column.1,length(word),'^') up end else do /* make a new markup line */ up header=copies("-",column.1-1) pointer=copies("^",length(word)) trailer=copies("-",trunc.1-length(header)-length(pointer)) line=header||pointer||trailer "input" line end end "msgmode off" "cl/"||word /* look for next occurence */ end "msgmode on" end address unix "rm" tempfile "top" call find return /************************************************************************/ /* * CLEAR * * The clear action removes all spell markup lines. * */ clear: "top" "msgmode off" "cl/^" /* find the first line that might be a markup line */ do while rc=0 "msgmode on" "extract /curline" /* get the possible markup line */ if translate(curline.3,,"^-")="" & curline.3<>"" then do /* if it's really a markup line, */ "msgmode off" "delete" /* delete it */ "msgmode on" end "msgmode off" "cl/^" /* find the next markup line */ end "msgmode on" "top" return /************************************************************************/ /* * CORRECT and ADD * * The correct action is used after you have corrected the spelling * of a word to remove the markup for that word. This action is * intended to be assigned to a PF key. * * After correcting the word, press the PF key for this macro without * moving the cursor. The markup for the word is removed, as is the * markup line if it was the last markup for this line. * * Spell ADD is also implemented here. It is similar to correct, * except that it adds the marked up word to the local directory's * spelling list. Note that the marked up word will have been taken * directly from the markup columns indicated by the markup line, so * they must be spelled correctly! They might be misspelled because * * 1. An earlier error on this line was corrected using insert/delete * * 2. This word itself was modified using insert/delete before you * decided to add it to the local dictionary. * * Make sure to check the spelling before pressing the PF key * assigned to the ADD action. * */ correct: "extract /cursor /trunc /curline" delta=curline.2-cursor.1 /* for repositioning at end */ c=cursor.4 /* column where cursor ended up */ ":"||cursor.3 /* make cursor line current */ "down" /* move down to markup line */ "extract /curline" l=curline.3 if translate(l,,"^-")="" & l<>"" /* make sure it's a markup line */ then do if substr(l,c,1)<>"^" /* allow for just beyond markup area */ then c=c-1 if substr(l,c,1)="^" /* make sure within markup area */ then do do while substr(l,c,1)="^" /* look for start of markup area */ c=c-1 if c=0 then leave end c=c+1 /* start of markup area */ end=trunc.1+1 /* default end of markup area */ stop=index(l,"-",c) /* explicit end of markup area or 0 */ if stop>0 then end=stop /* reset end of markup area if necc.*/ l=overlay('-',l,c,end-c,'-') /* make new markup line */ if translate(l,,"-")="" /* if new markup line is empty */ then do "msgmode off" "delete" /* then get rid of it */ "msgmode on" end else "replace" l /* else replace it */ end end "up" /* back to cursor line */ if action="ADD" then do "extract /curline" text=curline.3 word=substr(text,c,end-c) /* bogus word! */ "x" localdict /* get this directory's local dictionary */ found="no" "msgmode off" "cl/"word /* see if this word is here */ do while rc=0 "msgmode on" "extract /curline" /* get line containing string */ if curline.3=word /* if whole word only */ then do found="yes" /* remember that */ leave /* and stop looking */ end "msgmode off" "cl/"word /* else, try again */ end "msgmode on" if found="no" then do /* add if not already there */ "input" word "sort * 1" trunc.1-1 "file" end else "qq" end delta /* restore screen position */ call find return /************************************************************************/ /* * FIND * * The find action finds the next marked up word and returns to the top * of the file when done. * */ find: do forever "msgmode off" "cl/^" /* find a possible markup */ saverc=rc "msgmode on" if saverc<>0 /* if none found, */ then do "top" "cursor home" /* done */ leave end "extract /curline" /* possible markup line */ if translate(curline.3,,"^-")="" & curline.3<>"" /* if really so, */ then do "-1" /* move up to misspelled word */ "cursor column" /* leave cursor there */ leave end end return /************************************************************************/