changeset 857:aaedbc351b38

Add %zero ABC% exceptions.
author Ben Schmidt
date Wed, 29 Feb 2012 01:04:11 +1100
parents ffd9a5c36d46
children cefb04b9f9bc
files ChangeLog README.listtexts src/prepstdreply.c
diffstat 3 files changed, 40 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Feb 29 15:55:32 2012 +1100
+++ b/ChangeLog	Wed Feb 29 01:04:11 2012 +1100
@@ -1,3 +1,5 @@
+ o Add ability to except characters from width reckoning (and be zero-width)
+   to facilitate wrapping even more languages well
  o Add different width-reckoning modes to facilitate wrapping many languages
  o Add different wrapping modes to facilitate wrapping many languages
  o Fix backslash escaping mechanism so double backslash can't effectively
--- a/README.listtexts	Wed Feb 29 15:55:32 2012 +1100
+++ b/README.listtexts	Wed Feb 29 01:04:11 2012 +1100
@@ -294,6 +294,13 @@
   as ASCII characters) when reckoning the width for wrapping (good for Chinese,
   Japanese, Korean)
 
+- %zero ABC%
+  (ABC represents a sequence of non-ASCII characters)
+  treat the listed characters as having zero-width when reckoning the width for
+  wrapping (useful for ignoring combining characters such as accents so they
+  don't affect the width calculation); usefully, the listed characters can be
+  represented as unicode escapes (\uNNNN)
+
 If a line with any of the directives in this section, after processing,
 contains only whitespace, the line does not appear at all in the output (the
 newline and any whitespace is omitted).
--- a/src/prepstdreply.c	Wed Feb 29 15:55:32 2012 +1100
+++ b/src/prepstdreply.c	Wed Feb 29 01:04:11 2012 +1100
@@ -127,6 +127,7 @@
 	int wrapwidth;
 	enum wrap_mode wrapmode;
 	enum width_reckoning widthreckoning;
+	char *zerowidth;
 	conditional *cond;
 	conditional *skip;
 };
@@ -492,6 +493,7 @@
 	txt->wrapwidth = 0;
 	txt->wrapmode = WRAP_WORD;
 	txt->widthreckoning = WIDTH_THIN;
+	txt->zerowidth = NULL;
 	txt->cond = NULL;
 	txt->skip = NULL;
 
@@ -995,6 +997,15 @@
 		myfree(*line_p);
 		*line_p = line;
 		return 0;
+	} else if(strncmp(token, "zero ", 5) == 0) {
+		token += 5;
+		if (txt->zerowidth != NULL) myfree(txt->zerowidth);
+		txt->zerowidth = mystrdup(token);
+		line = concatstr(2, line, endpos + 1);
+		*pos_p = line + (*pos_p - *line_p);
+		myfree(*line_p);
+		*line_p = line;
+		return 0;
 	} else if(strncmp(token, "control ", 8) == 0) {
 		token = filename_token(token + 8);
 		if (token != NULL) {
@@ -1080,6 +1091,7 @@
 	int peeking = 0; /* for a failed conditional without an else */
 	int skipwhite; /* skip whitespace after a conditional directive */
 	int swallow;
+	char utf8char[5] = {0, 0, 0, 0, 0};
 
 	for (;;) {
 		line = NULL;
@@ -1390,11 +1402,30 @@
 					width++;
 				} else if ((unsigned char)*pos > 0xbf) {
 					/* Not a UTF-8 continuation byte. */
+					if (txt->zerowidth != NULL) {
+					    tmp = pos;
+					    utf8char[0] = *tmp++;
+					    for (i = 1; i < 4; i++, tmp++) {
+						if ((unsigned char)*tmp<0x80 ||
+						      (unsigned char)*tmp>0xbf)
+						      break;
+						utf8char[i] = *tmp;
+					    }
+					    utf8char[i] = '\0';
+					    if (strstr(txt->zerowidth, utf8char)
+						    == NULL) {
 					    width++;
 					    if (txt->widthreckoning ==
 						    WIDTH_WIDE)
 						    width++;
 				}
+					} else {
+					    width++;
+					    if (txt->widthreckoning ==
+						    WIDTH_WIDE)
+						    width++;
+					}
+				}
 			}
 			pos++;
 			skipwhite = 0;