---
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.10
Received 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