--- text-motions.c | 153 +++++++++++++++++++++++---------------------------------- 1 file changed, 62 insertions(+), 91 deletions(-) diff --git a/text-motions.c b/text-motions.c index f406da3..cc98dee 100644 --- a/text-motions.c +++ b/text-motions.c _AT_@ -357,119 +357,90 @@ 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; + Iterator it = text_iterator_get(txt, pos); + + while (text_iterator_byte_get(&it, &c) && (c == '\n' || c == '\r')) + text_iterator_byte_next(&it, NULL); + return text_line_empty_next(txt, it.pos); } size_t text_paragraph_prev(Text *txt, size_t pos) { - return text_paragraph_sentence_prev(txt, pos, false); + char c; + Iterator it = text_iterator_get(txt, pos); + + /* c == \0 catches starting the search at EOF */ + while (text_iterator_byte_get(&it, &c) && (c == '\n' || c == '\r' || c == '\0')) + text_iterator_byte_prev(&it, NULL); + return text_line_empty_prev(txt, it.pos); } size_t text_line_empty_next(Text *txt, size_t pos) { - // TODO refactor search \n\n - char c; + char c, prev = 'X', dos; Iterator it = text_iterator_get(txt, pos); while (text_iterator_byte_get(&it, &c)) { - if (c == '\n' && text_iterator_byte_next(&it, &c)) { - size_t match = it.pos; - if (c == '\r') - text_iterator_byte_next(&it, &c); - if (c == '\n') - return match; - } + if ((dos = c == '\r')) /* dos is 1 when we have a \r\n line break */ + text_iterator_byte_next(&it, &c); + if (prev == '\n' && c == '\n') + return it.pos - dos; + prev = c; text_iterator_byte_next(&it, NULL); } - return pos; + return it.pos; } size_t text_line_empty_prev(Text *txt, size_t pos) { - // TODO refactor search \n\n - char c; + char c, prev = 'X'; Iterator it = text_iterator_get(txt, pos); while (text_iterator_byte_prev(&it, &c)) { - if (c == '\n' && text_iterator_byte_prev(&it, &c)) { - if (c == '\r') - text_iterator_byte_prev(&it, &c); - if (c == '\n') - return it.pos + 1; - } + if (c == '\r') + text_iterator_byte_prev(&it, &c); + if (prev == '\n' && c == '\n') + return it.pos + 1; + prev = c; } return pos; } -- 2.4.10Received on Wed Feb 03 2016 - 13:07:00 CET
This archive was generated by hypermail 2.3.0 : Wed Feb 03 2016 - 13:12:12 CET