patch: tweak for smart quotes near breaks


Subject: patch: tweak for smart quotes near breaks
From: WJCarpenter (bill-abisource@carpenter.ORG)
Date: Fri Aug 25 2000 - 21:29:55 CDT


This patch (against 082400 sources) fixes a bug where the smart quote
algorithm wasn't properly applied just after a line, column, or page
break. (In a nutshell, I was underinformed about the internal
representation of breaks.)

It also wraps most of the smart quote promotion in a PASTE operation
into a big UNDO atomic glob. So, a brute force way to get your whole
document smart quote converted is to CUT the whole thing to the
clipboard and then paste it back (that part's not new). If you want
to undo the smart quote-edness of that, it's just one or two UNDOs.

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

diff -ru abi-082400-ORIG/src/af/util/xp/ut_string.h abi-082400/src/af/util/xp/ut_string.h --- abi-082400-ORIG/src/af/util/xp/ut_string.h Tue Aug 22 19:14:21 2000 +++ abi-082400/src/af/util/xp/ut_string.h Fri Aug 25 17:48:36 2000 @@ -102,7 +102,7 @@ #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 -#define UT_UCS_isspace(x) (((x)==' ' || ((x)=='\t') || ((x)=='\f'))) // HACK: not UNICODE safe +#define UT_UCS_isspace(x) (((x)==' '||((x)=='\r')||((x)=='\n')||((x)=='\t')||((x)=='\f'))) // HACK: not UNICODE safe #define UT_UCS_ispunct(x) ((!UT_UCS_isspace(x) && !UT_UCS_isalnum(x) && (x)>' ')) // HACK: not UNICODE safe #ifdef WIN32 diff -ru abi-082400-ORIG/src/text/fmt/xp/fl_BlockLayout.cpp abi-082400/src/text/fmt/xp/fl_BlockLayout.cpp --- abi-082400-ORIG/src/text/fmt/xp/fl_BlockLayout.cpp Tue Aug 22 19:14:21 2000 +++ abi-082400/src/text/fmt/xp/fl_BlockLayout.cpp Fri Aug 25 19:13:20 2000 @@ -2252,6 +2252,7 @@ { switch (pChars[i]) { + // see similar control characters in fl_DocLayout.cpp case UCS_FF: // form feed, forced page break case UCS_VTAB: // vertical tab, forced column break case UCS_LF: // newline @@ -2729,9 +2730,14 @@ { m_pLayout->considerSmartQuoteCandidateAt(sq_bl, sq_of); } - for (unsigned int sdex=0; sdex<sqcount; ++sdex) + if (sqcount) { - m_pLayout->considerSmartQuoteCandidateAt(this, sqlist[sdex]); + m_pDoc->beginUserAtomicGlob(); + for (unsigned int sdex=0; sdex<sqcount; ++sdex) + { + m_pLayout->considerSmartQuoteCandidateAt(this, sqlist[sdex]); + } + m_pDoc->endUserAtomicGlob(); } if (UT_isSmartQuotableCharacter(pChars[len - 1])) { diff -ru abi-082400-ORIG/src/text/fmt/xp/fl_DocLayout.cpp abi-082400/src/text/fmt/xp/fl_DocLayout.cpp --- abi-082400-ORIG/src/text/fmt/xp/fl_DocLayout.cpp Tue Aug 22 19:14:21 2000 +++ abi-082400/src/text/fmt/xp/fl_DocLayout.cpp Fri Aug 25 19:21:49 2000 @@ -1197,14 +1197,24 @@ // doesn't matter what occurs in that position. enum sqThingAt { - sqDONTCARE, - sqQUOTEls, sqQUOTErs, sqQUOTEld, sqQUOTErd, // the smart quotes, left/right single/double - sqBREAK, sqFOLLOWPUNCT, sqOPENPUNCT, sqCLOSEPUNCT, sqOTHERPUNCT, sqALPHA, sqWHITE + sqDONTCARE = 1, + sqQUOTEls = 2, + sqQUOTErs = 3, + sqQUOTEld = 4, + sqQUOTErd = 5,// the smart quotes, left/right single/double + sqBREAK = 6, + sqFOLLOWPUNCT = 7, + sqOPENPUNCT = 8, + sqCLOSEPUNCT = 9, + sqOTHERPUNCT =10, + sqALPHA =11, + sqWHITE =12 }; // TODO: This function probably needs tuning for non-Anglo locales. static enum sqThingAt whatKindOfChar(UT_UCSChar thing) { + xxx_UT_DEBUGMSG(("what sort of character is %d 0x%x |%c|\n", thing, thing, thing)); switch (thing) { case UCS_LQUOTE: return sqQUOTEls; @@ -1217,12 +1227,18 @@ case '.': case ',': case ';': case ':': case '!': case '?': return sqFOLLOWPUNCT; + // see similar control characters in fl_BlockLayout.cpp + case UCS_FF: // form feed, forced page break + case UCS_VTAB: // vertical tab, forced column break + case UCS_LF: // newline + case UCS_TAB: // tab + return sqBREAK; } if (UT_UCS_isalpha(thing)) return sqALPHA; if (UT_UCS_ispunct(thing)) return sqOTHERPUNCT; if (UT_UCS_isspace(thing)) return sqWHITE; - return sqDONTCARE; + return sqBREAK; // supposed to be a character, but...! } struct sqTable @@ -1348,7 +1364,7 @@ // something other than '?' if '?' ever shows up as UT_isSmartQuotableCharacter() UT_UCSChar c = '?'; if (pgb.getLength() > offset) c = *pgb.getPointer(offset); - xxx_UT_DEBUGMSG(("FL_DocLayout::considerSmartQuoteCandidateAt(%x, %d) |%c|\n", block, offset, c)); + UT_DEBUGMSG(("FL_DocLayout::considerSmartQuoteCandidateAt(%x, %d) |%c|\n", block, offset, c)); // there are some operations that leave a dangling pending // smart quote, so just double check before plunging onward @@ -1374,15 +1390,21 @@ { last = r; } while ((r = r->getNext())); // assignment - if (last && (FPRUN_TEXT == last->getType())) + if (last && (FPRUN_TEXT == last->getType()) && last->getLength() > 0) { - // last run of previous block was a text run, - // so find out what the final character was - UT_GrowBuf pgb_b(1024); - ob->getBlockBuf(&pgb_b); - if (pgb_b.getLength()) + fp_Line *blocks_line, *lasts_line; + blocks_line = block->getFirstRun()->getLine(); + lasts_line = last->getLine(); + if (blocks_line == lasts_line) { - before = whatKindOfChar(*pgb_b.getPointer(pgb.getLength()-1)); + // last run of previous block was a text run on the same line + // so find out what the final character was + UT_GrowBuf pgb_b(1024); + ob->getBlockBuf(&pgb_b); + if (pgb_b.getLength()) + { + before = whatKindOfChar(*pgb_b.getPointer(pgb_b.getLength()-1)); + } } } } @@ -1436,17 +1458,20 @@ } } } + UT_DEBUGMSG(("before %d, after %d, replace %x\n", before, after, replacement)); if (replacement != UCS_UNKPUNK) { // your basic emacs (save-excursion...) :-) PT_DocPosition saved_pos, quotable_at; saved_pos = m_pView->getPoint(); quotable_at = block->getPosition(UT_FALSE) + offset; + m_pView->moveInsPtTo(quotable_at); // delete/insert create change records for UNDO m_pView->cmdCharDelete(UT_TRUE, 1); m_pView->cmdCharInsert(&replacement, 1); m_pView->moveInsPtTo(saved_pos); + // Alas, Abi undo moves the insertion point, so you can't // just UNDO right after a smart quote pops up to force // an ASCII quote. For an open quote, you could type



This archive was generated by hypermail 2b25 : Fri Aug 25 2000 - 21:30:09 CDT