patch: various spellcheck problems


Subject: patch: various spellcheck problems
From: WJCarpenter (bill-abisource@carpenter.ORG)
Date: Mon Jun 26 2000 - 11:04:02 CDT


The attached context diff patch (against 0.7.10 release code) attacks
several spellcheck related problems of various types. Most are
interactions with smart quotes (which are invisible on UNIX and
perhaps other places), and some are just problems I tripped over while
looking into that. All in all, the changes aren't conceptually that
big, but there is a lot of spelling stuff scattered around, so the
patch is a big list of little things. The changes are all to XP
files, and there isn't any "tricky" stuff, but I can only conveniently
test this on Linux.

-- Smart quotes were being included as character parts of words, so
   smart quoted words always failed spell check. Smart quote
   characters are now word delimiter characters for spellcheck
   purposes. THIS FIXES BUG #757 (except for the part about the
   on-screen representation of smart quotes). [[If you want to test
   this and don't have easy access to something that creates smart
   quotes, you can easily hand insert them into a saved *.abw file.
   Open single quote ‘, close single quote ’, open
   double quote “, and close double quote ”, e.g.,

        ‘smart single’
        “smart double”

-- There is a punctuation exception in spellcheck for the right single
   quote character, since it can occur in contractions.
   Unfortunately, that exception was being applied in some places and
   not in others, the result being that squiggles could appear and
   disappear under a word depending on what operations you were doing.
   The special treatment of right single quote is now centralized in
   the function UT_isWordDelimiter(). This caused by far the greatest
   number of individual code changes since I changed the signature of
   that function and had to update code surrounding each call to it.

-- Smart quote's apostrophe (0x2019) is now given the same treatment
   as ASCII right single quote for spellcheck purposes. For words
   that get spellchecked, smart quote apostrophe is mapped to ASCII
   single quote first. IgnoreAll lists and local dictionary entries
   have smart quote apostrophe mapped to ASCII right single quote.

-- There is an obscure spellcheck case which failed in 0.7.10 and
   still fails after this patch. To reproduce, type a line with a
   misspelled word in the middle. As usual, it gets a squiggle.
   Position the cursor immediately after the word (before the space)
   and hit enter. The squiggle disappears. This is probably related
   to the FASTSQUIGGLE code in src/text/fmt/fl_BlockLayout.cpp (at
   least the problem goes away if that is turned off). This condition
   is also reported in bug #860.

I looked at all the bugs in bugzilla with "spell" in the summary or
description, and I don't think any of them come into play except as
mentioned above.

I went after this spelling stuff while looking into the general
treatment of smart quotes because it's pretty easy to know what is The
Right Thing for the spelling stuff. As I mentioned before, I have a
brute force thing which makes smart quotes visible on UNIX, but the
real solution is not yet at hand.

-- 
bill@carpenter.ORG (WJCarpenter)    PGP 0x91865119
38 95 1B 69 C9 C6 3D 25    73 46 32 04 69 D6 ED F3

diff -r -c abi-0.7.10-ORIG/src/af/util/xp/ut_misc.cpp abi-0.7.10/src/af/util/xp/ut_misc.cpp *** abi-0.7.10-ORIG/src/af/util/xp/ut_misc.cpp Mon Jul 26 07:42:44 1999 --- abi-0.7.10/src/af/util/xp/ut_misc.cpp Sun Jun 25 16:11:31 2000 *************** *** 220,233 **** ! UT_Bool UT_isWordDelimiter(UT_UCSChar ch) { /* TODO we need a more systematic way to handle this, instead TODO of just randomly adding more whitespace & punctuation TODO on an as-discovered basis */ ! switch (ch) { case ' ': case ',': --- 220,241 ---- ! UT_Bool UT_isWordDelimiter(UT_UCSChar currentChar, UT_UCSChar followChar) { + #if 1 + /* wjc ... these UT_UCS_isXXX() functions aren't really right for UCS */ + if (UT_UCS_isalnum(currentChar)) return UT_FALSE; + // the following case is for embedded apostrophe in a contraction + if ((currentChar == '\'' || currentChar == UCS_RQUOTE) && UT_UCS_isalnum(followChar)) return UT_FALSE; + return UT_TRUE; + + #else /* TODO we need a more systematic way to handle this, instead TODO of just randomly adding more whitespace & punctuation TODO on an as-discovered basis */ ! switch (currentChar) { case ' ': case ',': *************** *** 235,241 **** case '"': case '-': case '_': - // case '\'': // we want quotes inside words for contractions case '(': case ')': case '[': --- 243,248 ---- *************** *** 256,265 **** --- 263,286 ---- case UCS_LF: // line break case UCS_VTAB: // column break case UCS_FF: // page break + case UCS_LDBLQUOTE: // smart quote, open double /* wjc */ + case UCS_RDBLQUOTE: // smart quote, close double /* wjc */ + case UCS_LQUOTE: // smart quote, open single /* wjc */ return UT_TRUE; + case '\'': // we want quotes inside words for contractions + case UCS_RQUOTE: // we want quotes inside words for contractions + if (UT_UCS_isalpha(followChar)) + { + return UT_FALSE; + } + else + { + return UT_TRUE; + } default: return UT_FALSE; } + #endif } const XML_Char* UT_getAttribute(const XML_Char* name, const XML_Char** atts) diff -r -c abi-0.7.10-ORIG/src/af/util/xp/ut_misc.h abi-0.7.10/src/af/util/xp/ut_misc.h *** abi-0.7.10-ORIG/src/af/util/xp/ut_misc.h Thu Apr 8 11:25:56 1999 --- abi-0.7.10/src/af/util/xp/ut_misc.h Sat Jun 24 22:02:02 2000 *************** *** 75,81 **** #define UT_ABS(A) ( ((A) < 0) ? (-(A)) : (A) ) const char * UT_pathSuffix(const char * path); ! UT_Bool UT_isWordDelimiter(UT_UCSChar); const XML_Char* UT_getAttribute(const XML_Char* name, const XML_Char** atts); UT_sint32 signedHiWord(UT_uint32 dw); --- 75,81 ---- #define UT_ABS(A) ( ((A) < 0) ? (-(A)) : (A) ) const char * UT_pathSuffix(const char * path); ! UT_Bool UT_isWordDelimiter(UT_UCSChar currentChar, UT_UCSChar followChar); const XML_Char* UT_getAttribute(const XML_Char* name, const XML_Char** atts); UT_sint32 signedHiWord(UT_uint32 dw); diff -r -c abi-0.7.10-ORIG/src/af/util/xp/ut_string.h abi-0.7.10/src/af/util/xp/ut_string.h *** abi-0.7.10-ORIG/src/af/util/xp/ut_string.h Fri Apr 14 04:01:04 2000 --- abi-0.7.10/src/af/util/xp/ut_string.h Sun Jun 25 16:03:32 2000 *************** *** 85,90 **** --- 85,93 ---- #define UT_UCS_isdigit(x) (((x) >= '0') && ((x) <= '9')) #define UT_UCS_isupper(x) (((x) >= 'A') && ((x) <= 'Z')) // HACK: not UNICODE-safe + #define UT_UCS_islower(x) (((x) >= 'a') && ((x) <= 'z')) // HACK: not UNICODE-safe + #define UT_UCS_isalpha(x) (UT_UCS_isupper(x) || UT_UCS_islower(x)) // HACK: not UNICODE-safe + #define UT_UCS_isalnum(x) (UT_UCS_isalpha(x) || UT_UCS_isdigit(x)) // HACK: not UNICODE-safe #ifdef WIN32 #define snprintf _snprintf diff -r -c abi-0.7.10-ORIG/src/af/util/xp/ut_types.h abi-0.7.10/src/af/util/xp/ut_types.h *** abi-0.7.10-ORIG/src/af/util/xp/ut_types.h Tue Feb 29 13:46:51 2000 --- abi-0.7.10/src/af/util/xp/ut_types.h Sun Jun 25 21:31:07 2000 *************** *** 123,128 **** --- 123,129 ---- #define UCS_RQUOTE ((UT_UCSChar)0x2019) #define UCS_LDBLQUOTE ((UT_UCSChar)0x201c) #define UCS_RDBLQUOTE ((UT_UCSChar)0x201d) + #define UCS_UNKPUNK ((UT_UCSChar)0xFFFF) /* "unknown punctuation" used with UT_isWordDelimiter() */ #else /* see bug 512 */ *************** *** 135,140 **** --- 136,142 ---- #define UCS_RQUOTE ((UT_UCSChar)0x0027) #define UCS_LDBLQUOTE ((UT_UCSChar)0x0022) #define UCS_RDBLQUOTE ((UT_UCSChar)0x0022) + #define UCS_UNKPUNK ((UT_UCSChar)0x00FF) #endif diff -r -c abi-0.7.10-ORIG/src/af/xap/xp/xad_Document.cpp abi-0.7.10/src/af/xap/xp/xad_Document.cpp *** abi-0.7.10-ORIG/src/af/xap/xp/xad_Document.cpp Wed May 10 21:57:52 2000 --- abi-0.7.10/src/af/xap/xp/xad_Document.cpp Sun Jun 25 21:46:43 2000 *************** *** 91,98 **** for (UT_uint32 i = 0; i < len; i++) { ! key[i] = (char) pWord[i]; ! copy[i] = (UT_UCSChar) pWord[i]; } UT_sint32 iRes = m_pIgnoreList->addEntry(key, NULL, (void*) copy); --- 91,102 ---- for (UT_uint32 i = 0; i < len; i++) { ! UT_UCSChar currentChar; ! currentChar = pWord[i]; ! // convert smart quote apostrophe to ASCII single quote ! if (currentChar == UCS_RQUOTE) currentChar = '\''; ! key[i] = (char) currentChar; ! copy[i] = currentChar; } UT_sint32 iRes = m_pIgnoreList->addEntry(key, NULL, (void*) copy); diff -r -c abi-0.7.10-ORIG/src/af/xap/xp/xap_Dictionary.cpp abi-0.7.10/src/af/xap/xp/xap_Dictionary.cpp *** abi-0.7.10-ORIG/src/af/xap/xp/xap_Dictionary.cpp Mon Oct 18 07:00:57 1999 --- abi-0.7.10/src/af/xap/xp/xap_Dictionary.cpp Sun Jun 25 22:20:53 2000 *************** *** 336,343 **** for (UT_uint32 i = 0; i < len; i++) { ! key[i] = (char) pWord[i]; ! copy[i] = (UT_UCSChar) pWord[i]; } UT_sint32 iRes = m_hashWords.addEntry(key, NULL, (void*) copy); --- 336,347 ---- for (UT_uint32 i = 0; i < len; i++) { ! UT_UCSChar currentChar; ! currentChar = pWord[i]; ! // map smart quote apostrophe to ASCII right single quote ! if (currentChar == UCS_RQUOTE) currentChar = '\''; ! key[i] = (char) currentChar; ! copy[i] = currentChar; } UT_sint32 iRes = m_hashWords.addEntry(key, NULL, (void*) copy); diff -r -c abi-0.7.10-ORIG/src/text/fmt/xp/fl_BlockLayout.cpp abi-0.7.10/src/text/fmt/xp/fl_BlockLayout.cpp *** abi-0.7.10-ORIG/src/text/fmt/xp/fl_BlockLayout.cpp Thu Jun 15 00:07:15 2000 --- abi-0.7.10/src/text/fmt/xp/fl_BlockLayout.cpp Sun Jun 25 23:16:09 2000 *************** *** 1614,1620 **** first, we expand this region outward until we get a word delimiter on each side */ ! while ((iFirst > 0) && !UT_isWordDelimiter(pBlockText[iFirst-1])) { iFirst--; } --- 1614,1620 ---- first, we expand this region outward until we get a word delimiter on each side */ ! while ((iFirst > 0) && !UT_isWordDelimiter(pBlockText[iFirst-1], pBlockText[iFirst])) { iFirst--; } *************** *** 1623,1630 **** iLen += (iOffset-iFirst); UT_uint32 iBlockSize = pgb.getLength(); ! while ((iFirst + iLen < iBlockSize) && !UT_isWordDelimiter(pBlockText[iFirst + iLen])) { iLen++; } --- 1623,1633 ---- iLen += (iOffset-iFirst); UT_uint32 iBlockSize = pgb.getLength(); ! while ((iFirst + iLen < iBlockSize)) { + UT_UCSChar followChar; + followChar = ((iFirst + iLen + 1) < iBlockSize) ? pBlockText[iFirst + iLen + 1] : UCS_UNKPUNK; + if (UT_isWordDelimiter(pBlockText[iFirst + iLen], followChar)) break; iLen++; } *************** *** 1635,1642 **** { // insert UT_uint32 iLast = iOffset + chg; ! while ((iLast > iFirst) && !UT_isWordDelimiter(pBlockText[iLast-1])) { iLast--; } --- 1638,1646 ---- { // insert UT_uint32 iLast = iOffset + chg; ! while (iLast > iFirst) { + if (UT_isWordDelimiter(pBlockText[iLast-1], pBlockText[iLast])) break; iLast--; } *************** *** 1802,1816 **** while (wordBeginning < eor) { // skip delimiters... ! while ((wordBeginning < eor) && (UT_isWordDelimiter(pBlockText[wordBeginning]))) { wordBeginning++; } - // ignore initial quote - if (pBlockText[wordBeginning] == '\'') - wordBeginning++; - if (wordBeginning < eor) { // we're at the start of a word. find end of word --- 1806,1817 ---- while (wordBeginning < eor) { // skip delimiters... ! while (wordBeginning < eor) { + if (!UT_isWordDelimiter(pBlockText[wordBeginning], UCS_UNKPUNK)) break; wordBeginning++; } if (wordBeginning < eor) { // we're at the start of a word. find end of word *************** *** 1820,1826 **** wordLength = 0; while ((!bFound) && ((wordBeginning + wordLength) < eor)) { ! if ( UT_TRUE == UT_isWordDelimiter(pBlockText[wordBeginning + wordLength] )) { bFound = UT_TRUE; } --- 1821,1829 ---- wordLength = 0; while ((!bFound) && ((wordBeginning + wordLength) < eor)) { ! UT_UCSChar followChar; ! followChar = ((wordBeginning + wordLength + 1) < eor) ? pBlockText[wordBeginning + wordLength + 1] : UCS_UNKPUNK; ! if ( UT_TRUE == UT_isWordDelimiter(pBlockText[wordBeginning + wordLength], followChar)) { bFound = UT_TRUE; } *************** *** 1836,1844 **** } } - // ignore terminal quote - if (pBlockText[wordBeginning + wordLength - 1] == '\'') - wordLength--; // for some reason, the spell checker fails on all 1-char words & really big ones if ((wordLength > 1) && --- 1839,1844 ---- *************** *** 1850,1859 **** PD_Document * pDoc = m_pLayout->getDocument(); XAP_App * pApp = m_pLayout->getView()->getApp(); ! if (!SpellCheckNWord16( &(pBlockText[wordBeginning]), wordLength) && ! !pApp->isWordInDict(&(pBlockText[wordBeginning]), wordLength)) { ! UT_Bool bIsIgnored = pDoc->isIgnore(&(pBlockText[wordBeginning]), wordLength); // unknown word... if (bToggleIP && !bUpdateScreen) --- 1850,1869 ---- PD_Document * pDoc = m_pLayout->getDocument(); XAP_App * pApp = m_pLayout->getView()->getApp(); ! UT_UCSChar theWord[101]; ! // convert smart quote apostrophe to ASCII single quote to be compatible with ispell ! for (int ldex=0; ldex<wordLength; ++ldex) ! { ! UT_UCSChar currentChar; ! currentChar = pBlockText[wordBeginning + ldex]; ! if (currentChar == UCS_RQUOTE) currentChar = '\''; ! theWord[ldex] = currentChar; ! } ! ! if (!SpellCheckNWord16(theWord, wordLength) && ! !pApp->isWordInDict(theWord, wordLength)) { ! UT_Bool bIsIgnored = pDoc->isIgnore(theWord, wordLength); // unknown word... if (bToggleIP && !bUpdateScreen) *************** *** 1908,1914 **** while (!bAllUpperCase && ((wordBeginning + wordLength) < eor)) { ! UT_ASSERT(!UT_isWordDelimiter( pBlockText[wordBeginning + wordLength] )); if (bAllUpperCase) bAllUpperCase = UT_UCS_isupper(pBlockText[wordBeginning + wordLength]); --- 1918,1924 ---- while (!bAllUpperCase && ((wordBeginning + wordLength) < eor)) { ! UT_ASSERT(!UT_isWordDelimiter( pBlockText[wordBeginning + wordLength], 'a')); if (bAllUpperCase) bAllUpperCase = UT_UCS_isupper(pBlockText[wordBeginning + wordLength]); *************** *** 1931,1942 **** PD_Document * pDoc = m_pLayout->getDocument(); XAP_App * pApp = m_pLayout->getView()->getApp(); ! if (!SpellCheckNWord16( &(pBlockText[wordBeginning]), wordLength) && ! !pApp->isWordInDict(&(pBlockText[wordBeginning]), wordLength)) { // squiggle it m_vecSquiggles.addItem(pPOB); ! pPOB->bIsIgnored = pDoc->isIgnore( &(pBlockText[wordBeginning]), wordLength); _updateSquiggle(pPOB); --- 1941,1962 ---- PD_Document * pDoc = m_pLayout->getDocument(); XAP_App * pApp = m_pLayout->getView()->getApp(); ! UT_UCSChar theWord[101]; ! // convert smart quote apostrophe to ASCII single quote to be compatible with ispell ! for (int ldex=0; ldex<wordLength; ++ldex) ! { ! UT_UCSChar currentChar; ! currentChar = pBlockText[wordBeginning + ldex]; ! if (currentChar == UCS_RQUOTE) currentChar = '\''; ! theWord[ldex] = currentChar; ! } ! ! if (!SpellCheckNWord16(theWord, wordLength) && ! !pApp->isWordInDict(theWord, wordLength)) { // squiggle it m_vecSquiggles.addItem(pPOB); ! pPOB->bIsIgnored = pDoc->isIgnore(theWord, wordLength); _updateSquiggle(pPOB); *************** *** 3716,3722 **** while (!bAllUpperCase && ((wordBeginning + wordLength) < eor)) { ! UT_ASSERT(!UT_isWordDelimiter( pBlockText[wordBeginning + wordLength] )); if (bAllUpperCase) bAllUpperCase = UT_UCS_isupper(pBlockText[wordBeginning + wordLength]); --- 3736,3742 ---- while (!bAllUpperCase && ((wordBeginning + wordLength) < eor)) { ! UT_ASSERT(!UT_isWordDelimiter( pBlockText[wordBeginning + wordLength], 'a')); if (bAllUpperCase) bAllUpperCase = UT_UCS_isupper(pBlockText[wordBeginning + wordLength]); *************** *** 3729,3746 **** wordLength = pPOB->iLength; // for some reason, the spell checker fails on all 1-char words & really big ones if ((wordLength > 1) && (!m_pLayout->getSpellCheckCaps() || !bAllUpperCase) && ! (!UT_UCS_isdigit(pBlockText[wordBeginning])) && // still ignore first char==num words (!bHasNumeric || !m_pLayout->getSpellCheckNumbers()) && // can these two lines be simplified? (wordLength < 100) && ! (!SpellCheckNWord16( &(pBlockText[wordBeginning]), wordLength)) && ! (!pApp->isWordInDict(&(pBlockText[wordBeginning]), wordLength))) { // squiggle it ! pPOB->bIsIgnored = pDoc->isIgnore( &(pBlockText[wordBeginning]), wordLength); _updateSquiggle(pPOB); } else --- 3749,3778 ---- wordLength = pPOB->iLength; + UT_UCSChar theWord[101]; + if (wordLength < 100) + { + // convert smart quote apostrophe to ASCII single quote to be compatible with ispell + for (int ldex=0; ldex<wordLength; ++ldex) + { + UT_UCSChar currentChar; + currentChar = pBlockText[wordBeginning + ldex]; + if (currentChar == UCS_RQUOTE) currentChar = '\''; + theWord[ldex] = currentChar; + } + } // for some reason, the spell checker fails on all 1-char words & really big ones if ((wordLength > 1) && (!m_pLayout->getSpellCheckCaps() || !bAllUpperCase) && ! (!UT_UCS_isdigit(theWord[0])) && // still ignore first char==num words (!bHasNumeric || !m_pLayout->getSpellCheckNumbers()) && // can these two lines be simplified? (wordLength < 100) && ! (!SpellCheckNWord16(theWord, wordLength)) && ! (!pApp->isWordInDict(theWord, wordLength))) { // squiggle it ! pPOB->bIsIgnored = pDoc->isIgnore(theWord, wordLength); _updateSquiggle(pPOB); } else diff -r -c abi-0.7.10-ORIG/src/text/fmt/xp/fv_View.cpp abi-0.7.10/src/text/fmt/xp/fv_View.cpp *** abi-0.7.10-ORIG/src/text/fmt/xp/fv_View.cpp Sun Jun 11 07:56:12 2000 --- abi-0.7.10/src/text/fmt/xp/fv_View.cpp Sun Jun 25 21:35:58 2000 *************** *** 784,794 **** } } ! UT_Bool bInWord = !UT_isWordDelimiter(pSpan[bKeepLooking ? offset-1 : offset]); for (offset--; offset > 0; offset--) { ! if (UT_isWordDelimiter(pSpan[offset])) { if (bInWord) break; --- 784,794 ---- } } ! UT_Bool bInWord = !UT_isWordDelimiter(pSpan[bKeepLooking ? offset-1 : offset], UCS_UNKPUNK); for (offset--; offset > 0; offset--) { ! if (UT_isWordDelimiter(pSpan[offset], UCS_UNKPUNK)) { if (bInWord) break; *************** *** 843,849 **** } } ! UT_Bool bBetween = UT_isWordDelimiter(pSpan[offset]); // Needed so ctrl-right arrow will work // This is the code that was causing bug 10 --- 843,849 ---- } } ! UT_Bool bBetween = UT_isWordDelimiter(pSpan[offset], UCS_UNKPUNK); // Needed so ctrl-right arrow will work // This is the code that was causing bug 10 *************** *** 851,865 **** for (; offset < pgb.getLength(); offset++) { ! if (!UT_isWordDelimiter(pSpan[offset])) break; } for (; offset < pgb.getLength(); offset++) { ! if (!UT_isWordDelimiter(pSpan[offset])) { ! if (bBetween) break; } else if (pSpan[offset] != ' ') --- 851,869 ---- for (; offset < pgb.getLength(); offset++) { ! UT_UCSChar followChar; ! followChar = ((offset + 1) < pgb.getLength()) ? pSpan[offset+1] : UCS_UNKPUNK; ! if (!UT_isWordDelimiter(pSpan[offset], followChar)) break; } for (; offset < pgb.getLength(); offset++) { ! UT_UCSChar followChar; ! followChar = ((offset + 1) < pgb.getLength()) ? pSpan[offset+1] : UCS_UNKPUNK; ! if (!UT_isWordDelimiter(pSpan[offset], followChar)) { ! if (bBetween) break; } else if (pSpan[offset] != ' ') *************** *** 911,917 **** } } ! UT_Bool bBetween = UT_isWordDelimiter(pSpan[offset]); // Needed so ctrl-right arrow will work // This is the code that was causing bug 10 --- 915,921 ---- } } ! UT_Bool bBetween = UT_isWordDelimiter(pSpan[offset], UCS_UNKPUNK); // Needed so ctrl-right arrow will work // This is the code that was causing bug 10 *************** *** 925,931 **** */ for (; offset < pgb.getLength(); offset++) { ! if (UT_isWordDelimiter(pSpan[offset])) { if (bBetween) break; --- 929,937 ---- */ for (; offset < pgb.getLength(); offset++) { ! UT_UCSChar followChar; ! followChar = ((offset + 1) < pgb.getLength()) ? pSpan[offset+1] : UCS_UNKPUNK; ! if (UT_isWordDelimiter(pSpan[offset], followChar)) { if (bBetween) break; *************** *** 5193,5199 **** sp_suggestions sg; memset(&sg, 0, sizeof(sg)); ! SpellCheckSuggestNWord16(pWord, pPOB->iLength,&sg); // we currently return all requested suggestions // TODO: prune lower-weighted ones?? --- 5199,5215 ---- sp_suggestions sg; memset(&sg, 0, sizeof(sg)); ! UT_UCSChar theWord[101]; ! // convert smart quote apostrophe to ASCII single quote to be compatible with ispell ! for (int ldex=0; ldex<pPOB->iLength && ldex<100; ++ldex) ! { ! UT_UCSChar currentChar; ! currentChar = *(pWord + ldex); ! if (currentChar == UCS_RQUOTE) currentChar = '\''; ! theWord[ldex] = currentChar; ! } ! ! SpellCheckSuggestNWord16(theWord, pPOB->iLength, &sg); // we currently return all requested suggestions // TODO: prune lower-weighted ones?? *************** *** 5396,5404 **** wCount.ch_no++; } } ! newWord = (delim && !UT_isWordDelimiter(pSpan[i])); ! delim = UT_isWordDelimiter(pSpan[i]); if (newWord) wCount.word++; --- 5412,5422 ---- wCount.ch_no++; } } ! UT_UCSChar followChar; ! followChar = (i+1 < len) ? pSpan[i+1] : UCS_UNKPUNK; ! newWord = (delim && !UT_isWordDelimiter(pSpan[i], followChar)); ! delim = UT_isWordDelimiter(pSpan[i], followChar); if (newWord) wCount.word++; diff -r -c abi-0.7.10-ORIG/src/wp/ap/xp/ap_Dialog_Spell.cpp abi-0.7.10/src/wp/ap/xp/ap_Dialog_Spell.cpp *** abi-0.7.10-ORIG/src/wp/ap/xp/ap_Dialog_Spell.cpp Sat Nov 6 18:01:31 1999 --- abi-0.7.10/src/wp/ap/xp/ap_Dialog_Spell.cpp Sun Jun 25 21:36:29 2000 *************** *** 163,171 **** while (m_iWordOffset < iBlockLength) { // skip delimiters... ! while ((m_iWordOffset < iBlockLength) && ! (UT_isWordDelimiter( pBlockText[m_iWordOffset]))) ! m_iWordOffset++; // ignore initial quote if (pBlockText[m_iWordOffset] == '\'') --- 163,175 ---- while (m_iWordOffset < iBlockLength) { // skip delimiters... ! while (m_iWordOffset < iBlockLength) ! { ! UT_UCSChar followChar; ! followChar = ((m_iWordOffset + 1) < iBlockLength) ? pBlockText[m_iWordOffset+1] : UCS_UNKPUNK; ! if (!UT_isWordDelimiter( pBlockText[m_iWordOffset], followChar)) break; ! m_iWordOffset++; ! } // ignore initial quote if (pBlockText[m_iWordOffset] == '\'') *************** *** 179,185 **** m_iWordLength = 0; while ((!bFound) && (m_iWordOffset + m_iWordLength) < iBlockLength) { ! if ( UT_TRUE == UT_isWordDelimiter( pBlockText[m_iWordOffset + m_iWordLength] )) { bFound = UT_TRUE; --- 183,191 ---- m_iWordLength = 0; while ((!bFound) && (m_iWordOffset + m_iWordLength) < iBlockLength) { ! UT_UCSChar followChar; ! followChar = ((m_iWordOffset + m_iWordLength + 1) < iBlockLength) ? pBlockText[m_iWordOffset + m_iWordLength + 1] : UCS_UNKPUNK; ! if ( UT_TRUE == UT_isWordDelimiter( pBlockText[m_iWordOffset + m_iWordLength], followChar)) { bFound = UT_TRUE; *************** *** 210,222 **** // try ignore all list and user dictionaries here, too XAP_App * pApp = m_pFrame->getApp(); ! if (!SpellCheckNWord16( &(pBlockText[m_iWordOffset]), m_iWordLength) && ! !m_pDoc->isIgnore( &(pBlockText[m_iWordOffset]), m_iWordLength) && ! !pApp->isWordInDict(&(pBlockText[m_iWordOffset]), m_iWordLength)) { // unknown word... // prepare list of possibilities ! SpellCheckSuggestNWord16( &(pBlockText[m_iWordOffset]), m_iWordLength, &m_Suggestions); // update sentence boundaries (so we can display --- 216,238 ---- // try ignore all list and user dictionaries here, too XAP_App * pApp = m_pFrame->getApp(); ! UT_UCSChar theWord[101]; ! // convert smart quote apostrophe to ASCII single quote to be compatible with ispell ! for (int ldex=0; ldex<m_iWordLength; ++ldex) ! { ! UT_UCSChar currentChar; ! currentChar = pBlockText[m_iWordOffset + ldex]; ! if (currentChar == UCS_RQUOTE) currentChar = '\''; ! theWord[ldex] = currentChar; ! } ! ! if (!SpellCheckNWord16( theWord, m_iWordLength) && ! !m_pDoc->isIgnore( theWord, m_iWordLength) && ! !pApp->isWordInDict(theWord, m_iWordLength)) { // unknown word... // prepare list of possibilities ! SpellCheckSuggestNWord16(theWord, m_iWordLength, &m_Suggestions); // update sentence boundaries (so we can display



This archive was generated by hypermail 2b25 : Mon Jun 26 2000 - 15:40:08 CDT