--- text-motions.c | 141 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 68 insertions(+), 73 deletions(-) diff --git a/text-motions.c b/text-motions.c index f406da3..6f8d0b4 100644 --- a/text-motions.c +++ b/text-motions.c _AT_@ -357,89 +357,84 @@ size_t text_word_start_prev(Text *txt, size_t pos) { return text_customword_start_prev(txt, pos, is_word_boundry); } -static size_t text_paragraph_sentence_next(Text *txt, size_t pos, bool sentence) { - char c; - bool content = false, paragraph = false; - Iterator it = text_iterator_get(txt, pos); - while (text_iterator_byte_next(&it, &c)) { - content |= !isspace((unsigned char)c); - if (sentence && (c == '.' || c == '?' || c == '!') && text_iterator_byte_next(&it, &c) && isspace((unsigned char)c)) { - if (c == '\n' && text_iterator_byte_next(&it, &c)) { - if (c == '\r') - text_iterator_byte_next(&it, &c); - } else { - while (text_iterator_byte_get(&it, &c) && c == ' ') - text_iterator_byte_next(&it, NULL); - } - break; - } - if (c == '\n' && text_iterator_byte_next(&it, &c)) { - if (c == '\r') - text_iterator_byte_next(&it, &c); - content |= !isspace((unsigned char)c); - if (c == '\n') - paragraph = true; - } - if (content && paragraph) - break; - } - return it.pos; -} - -static size_t text_paragraph_sentence_prev(Text *txt, size_t pos, bool sentence) { - char prev, c; - bool content = false, paragraph = false; - - Iterator it = text_iterator_get(txt, pos); - if (!text_iterator_byte_get(&it, &prev)) - return pos; - - while (text_iterator_byte_prev(&it, &c)) { - content |= !isspace((unsigned char)c) && c != '.' && c != '?' && c != '!'; - if (sentence && content && (c == '.' || c == '?' || c == '!') && isspace((unsigned char)prev)) { - do text_iterator_byte_next(&it, NULL); - while (text_iterator_byte_get(&it, &c) && isspace((unsigned char)c)); - break; - } - if (c == '\r') - text_iterator_byte_prev(&it, &c); - if (c == '\n' && text_iterator_byte_prev(&it, &c)) { - content |= !isspace((unsigned char)c); - if (c == '\r') - text_iterator_byte_prev(&it, &c); - if (c == '\n') { - paragraph = true; - if (content) { - do text_iterator_byte_next(&it, NULL); - while (text_iterator_byte_get(&it, &c) && isspace((unsigned char)c)); - break; - } - } - } - if (content && paragraph) { - do text_iterator_byte_next(&it, NULL); - while (text_iterator_byte_get(&it, &c) && !isspace((unsigned char)c)); - break; - } - prev = c; - } - return it.pos; -} - size_t text_sentence_next(Text *txt, size_t pos) { - return text_paragraph_sentence_next(txt, pos, true); + char c, prev = 'X'; + Iterator it = text_iterator_get(txt, pos), rev = text_iterator_get(txt, pos); + + if (!text_iterator_byte_get(&it, &c)) + return pos; + + while (text_iterator_byte_get(&rev, &prev) && isspace((unsigned char)prev)) + text_iterator_byte_prev(&rev, NULL); + prev = rev.pos == 0 ? '.' : prev; /* simulate punctuation at BOF */ + + do { + if ((prev == '.' || prev == '?' || prev == '!') && isspace((unsigned char)c)) { + do text_iterator_byte_next(&it, NULL); + while (text_iterator_byte_get(&it, &c) && isspace((unsigned char)c)); + return it.pos; + } + prev = c; + } while (text_iterator_byte_next(&it, &c)); + return it.pos; } size_t text_sentence_prev(Text *txt, size_t pos) { - return text_paragraph_sentence_prev(txt, pos, true); + char c, prev = 'X'; + bool content = false; + Iterator it = text_iterator_get(txt, pos); + + while (it.pos != 0 && text_iterator_byte_prev(&it, &c)) { + if (content && isspace((unsigned char)prev) && (c == '.' || c == '?' || c == '!')) { + do text_iterator_byte_next(&it, NULL); + while (text_iterator_byte_get(&it, &c) && isspace((unsigned char)c)); + return it.pos; + } + content |= !isspace((unsigned char)c); + prev = c; + } /* The loop only ends on hitting BOF or error */ + if (content) /* starting pos was after first sentence in file => find that sentences start */ + while (text_iterator_byte_get(&it, &c) && isspace((unsigned char)c)) + text_iterator_byte_next(&it, NULL); + return it.pos; } size_t text_paragraph_next(Text *txt, size_t pos) { - return text_paragraph_sentence_next(txt, pos, false); + char c, dos, prev = 'X'; + bool content = false; + Iterator it = text_iterator_get(txt, pos); + + if (!text_iterator_byte_get(&it, &c)) + return pos; + + do { + content |= c != '\n' && c != '\r'; + if ((dos = c == '\r')) /* dos is 1 when we have a \r\n line break */ + text_iterator_byte_next(&it, &c); + if (content && prev == '\n' && c == '\n') + return it.pos - dos; + prev = c; + } while (text_iterator_byte_next(&it, &c)); + return it.pos; } size_t text_paragraph_prev(Text *txt, size_t pos) { - return text_paragraph_sentence_prev(txt, pos, false); + char c, prev = 'X'; + bool content = false; + Iterator it = text_iterator_get(txt, pos); + + if (!text_iterator_byte_get(&it, &c)) + return pos; + + do { + content |= c != '\n' && c != '\r' && c != '\0'; /* \0 checks for EOF */ + if (c == '\r') + text_iterator_byte_prev(&it, &c); + if (content && prev == '\n' && c == '\n') + return it.pos + 1; + prev = c; + } while (text_iterator_byte_prev(&it, &c)); + return it.pos; } size_t text_line_empty_next(Text *txt, size_t pos) { -- 2.4.10Received on Tue Feb 02 2016 - 22:14:52 CET
This archive was generated by hypermail 2.3.0 : Tue Feb 02 2016 - 22:24:06 CET