diff --git a/cfgs/config/advanced.cfg b/cfgs/config/advanced.cfg index 9677497..ca1fc17 100644 --- a/cfgs/config/advanced.cfg +++ b/cfgs/config/advanced.cfg @@ -650,6 +650,9 @@ QUOTESTRING " FL> " // effectively disables the automatically named quotebuffers, as // described in the chapter about the QUOTEBUFMODE keyword. +// +;QuoteUseNewAI No/Yes + ---------------------------------------------------------------------- -- REPLYLINKING diff --git a/cfgs/config/advanced.rus b/cfgs/config/advanced.rus index 67ef825..181fe4c 100644 --- a/cfgs/config/advanced.rus +++ b/cfgs/config/advanced.rus @@ -722,6 +722,11 @@ QuoteBufMode Ask ; ;QuoteBufMode Append ; Дописать. ;QuoteBufMode Overwrite ; Переписать. +// Использовать дополнительный AI для квотинга (по умолчанию: Yes) +// Пробует найти ложные цитирования, связанные с использованием в тексте +// цитат обрамленные символами '<' и '>' и показывать их без подсветки. +;QuoteUseNewAI No/Yes + ---------------------------------------------------------------------- -- ПОСТРОЕНИЕ ЦЕПОЧЕК ОТВЕТОВ (REPLYLINKING) diff --git a/docs/notework.txt b/docs/notework.txt index 88d4f93..d419366 100644 --- a/docs/notework.txt +++ b/docs/notework.txt @@ -10,6 +10,9 @@ ______________________________________________________________________ Notes for GoldED+ 1.1.5, /snapshot/ ______________________________________________________________________ ++ New config file token: QuoteUseNewAI No/Yes. It will try to solve + false quoting when '<' and '>' characters is used. + - Fixed buffer overflow bug in LocationAlias matching. - Fixed PgUp/PgDn keys in help window (bugreport from Semen Panevin). diff --git a/golded3/gccfgg.cpp b/golded3/gccfgg.cpp index 6626e03..c536828 100644 --- a/golded3/gccfgg.cpp +++ b/golded3/gccfgg.cpp @@ -756,6 +756,7 @@ CfgGed::CfgGed() { quotectrl = CI_TEAR|CI_ORIG; quotemargin = 70; quotewraphard = false; + quoteusenewai = true; ra2usersbbs = 0; replylink = REPLYLINK_DIRECT; replylinkfloat = true; diff --git a/golded3/gccfgg.h b/golded3/gccfgg.h index 2b6cbc6..d0e269e 100644 --- a/golded3/gccfgg.h +++ b/golded3/gccfgg.h @@ -300,6 +300,7 @@ const word CRC_QUOTESPACING = 0xB403; const word CRC_QUOTESTRING = 0xE44F; const word CRC_QUOTESTOPS = 0xD2E4; const word CRC_QUOTEWRAPHARD = 0x6BD4; +const word CRC_QUOTEUSENEWAI = 0xCFF0; const word CRC_QWKBADMSGS = 0x0C2D; const word CRC_QWKCONFMAP = 0xEAE1; const word CRC_QWKEXPORTPATH = 0xB3AB; diff --git a/golded3/gccfgg0.cpp b/golded3/gccfgg0.cpp index ef157ac..080fecd 100644 --- a/golded3/gccfgg0.cpp +++ b/golded3/gccfgg0.cpp @@ -488,6 +488,7 @@ SwitchQ: case CRC_QUOTESTRING : CfgQuotestring (); break; case CRC_QUOTESTOPS : CfgQuotestops (); break; case CRC_QUOTEWRAPHARD : CfgQuotewraphard (); break; + case CRC_QUOTEUSENEWAI : CfgQuoteusenewai (); break; case CRC_QWKBADMSGS : CfgQwkbadmsgs (); break; case CRC_QWKCONFMAP : CfgQwkconfmap (); break; case CRC_QWKEXPORTPATH : CfgQwkexportpath (); break; diff --git a/golded3/gccfgg7.cpp b/golded3/gccfgg7.cpp index 5602faf..87df9d7 100644 --- a/golded3/gccfgg7.cpp +++ b/golded3/gccfgg7.cpp @@ -82,6 +82,13 @@ void CfgQuotewraphard() { // ------------------------------------------------------------------ +void CfgQuoteusenewai() +{ + CFG->quoteusenewai = 0 != GetYesno(val); +} + +// ------------------------------------------------------------------ + void CfgQwkbadmsgs() { QWK->BadMsgs(val); diff --git a/golded3/gcprot.h b/golded3/gcprot.h index 43e1d0b..2adb5bd 100644 --- a/golded3/gcprot.h +++ b/golded3/gcprot.h @@ -289,6 +289,7 @@ void CfgQuotespacing (); void CfgQuotestring (); void CfgQuotestops (); void CfgQuotewraphard (); +void CfgQuoteusenewai (); void CfgQwkbadmsgs (); void CfgQwkconfmap (); void CfgQwkexportpath (); diff --git a/golded3/gecfgg.h b/golded3/gecfgg.h index f5bf2bb..be60021 100644 --- a/golded3/gecfgg.h +++ b/golded3/gecfgg.h @@ -298,6 +298,7 @@ public: char quotestring[10]; char quotestops[41]; bool quotewraphard; + bool quoteusenewai; int ra2usersbbs; // RA2; int replylink; bool replylinkfloat; diff --git a/golded3/geedit.cpp b/golded3/geedit.cpp index 9dfcc61..5fe2b7e 100644 --- a/golded3/geedit.cpp +++ b/golded3/geedit.cpp @@ -101,7 +101,16 @@ void IEclass::setlinetype(Line* __line) { _test_halt(__line == NULL); __line->type &= ~(GLINE_ALL|GLINE_TEAR|GLINE_ORIG|GLINE_TAGL); - __line->type |= is_quote(__line->txt.c_str()) ? GLINE_QUOT : (__line->txt[0] == CTRL_A) ? GLINE_HIDD : 0; + + if (is_quote(__line->txt.c_str()) && + is_quote2(__line, __line->txt.c_str())) + { + __line->type |= GLINE_QUOT; + } + else if (__line->txt[0] == CTRL_A) + { + __line->type |= GLINE_HIDD; + } } @@ -660,6 +669,7 @@ Line* IEclass::wrapit(Line** __currline, uint* __curr_col, uint* __curr_row, boo // Length of this line uint _thislen = _thisline->txt.length(); + setlinetype(_thisline); uint _wrapmargin = (_thisline->type & GLINE_QUOT) ? marginquotes : margintext; // Does this line need wrapping? diff --git a/golded3/geline.cpp b/golded3/geline.cpp index 709aa3e..d53f080 100644 --- a/golded3/geline.cpp +++ b/golded3/geline.cpp @@ -2212,7 +2212,8 @@ void MakeLineIndex(GMsg* msg, int margin, bool getvalue, bool header_recode) { ptr = tptr; } } - else if(is_quote(ptr)) { + else if(is_quote(ptr) && is_quote2(line, ptr)) + { para = GLINE_QUOT; line->type |= GLINE_QUOT|GLINE_HARD; GetQuotestr(ptr, qbuf, &qlen); diff --git a/golded3/geprot.h b/golded3/geprot.h index aef650d..a1f573c 100644 --- a/golded3/geprot.h +++ b/golded3/geprot.h @@ -393,6 +393,7 @@ int GetAkaNo(const ftn_addr& __aka); int GetQuotestr(const char* ptr, char* qbuf, uint* qlen); int cmp_quotes(char* q1, char* q2); int is_quote(const char* ptr); +bool is_quote2(const Line* line, const char* ptr); int IsQuoteChar(const char* s); void maketitle(); int maketitle_and_status(char *); diff --git a/golded3/geutil.cpp b/golded3/geutil.cpp index 4d9f95a..4c4ac94 100644 --- a/golded3/geutil.cpp +++ b/golded3/geutil.cpp @@ -371,6 +371,82 @@ int is_quote(const char* ptr) { } +// ------------------------------------------------------------------ + +bool is_quote2(const Line* line, const char* ptr) +{ + if (!CFG->quoteusenewai) return true; + + char *head = (char *)ptr; + + // search first '>' before CR, NUL or any other quote character + for (bool found = false; !found; ptr++) + { + if (*ptr == '>') + found = true; + else + { + if (IsQuoteChar(ptr) || (*ptr == CR) || !*ptr) + return true; + } + } + + // line is double quoted? + if (is_quote(ptr)) + return true; + + // if "SPACE*[a-zA-Z]{0, 3}>" + for (ptr--; isspace(*head); head++); + + int nr = 0; + for (char *tmp = head; tmp < ptr; tmp++) + { + char ch = toupper(*tmp); + if ((ch >= 'A') && (ch <= 'Z')) + nr++; + } + + if ((nr < 4) && (nr == (ptr-head))) + return true; + + // take a look at previous lines + for (Line *ln = line->prev; ln; ln = ln->prev) + { + // previous line is quoted? + if (ln->isquote()) + return true; + // or begin of paragraph? + if ((ln->txt.length() == 0) || + (ln->txt[0] == LF) || + (ln->txt[0] == CR)) + return true; + // or kludge? + if (ln->txt[0] == CTRL_A) + return true; + + // found begin of citation? + char *begin = strrchr(ln->txt.c_str(), '<'); + if (begin) + { + // found both '<' and '>'? + if (strchr(begin, '>')) + return true; + + for (Line *ln2 = ln->next; ln2 != line; ln2 = ln2->next) + { + // found both '<' and '>'? + if (strchr(ln2->txt.c_str(), '>')) + return true; + } + + return false; // don't quote current line + } + } + + return true; +} + + // ------------------------------------------------------------------ int quotecolor(const char* line) {