From ae0b27023018416c0bfe54823466dee67c20705a Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 11 Nov 2007 14:14:15 +0000 Subject: [PATCH 1/3] print_wrapped_text(): allow hard newlines print_wrapped_text() will insert its own newlines. Up until now, if the text passed to it contained newlines, they would not be handled properly (the wrapping got confused after that). The strategy is to replace a single new-line with a space, but keep double new-lines so that already-wrapped text with empty lines between paragraphs will be handled properly. However, single new-line characters are only handled this way if the character after it is an alphanumeric character, as per Linus' suggestion. Signed-off-by: Johannes Schindelin --- utf8.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/utf8.c b/utf8.c index db706ac4ed..2aace1d42c 100644 --- a/utf8.c +++ b/utf8.c @@ -310,6 +310,8 @@ int print_wrapped_text(const char *text, int indent, int indent2, int width) if (!c || isspace(c)) { if (w < width || !space) { const char *start = bol; + if (!c && text == start) + return w; if (space) start = space; else @@ -317,13 +319,25 @@ int print_wrapped_text(const char *text, int indent, int indent2, int width) fwrite(start, text - start, 1, stdout); if (!c) return w; - else if (c == '\t') - w |= 0x07; space = text; + if (c == '\t') + w |= 0x07; + else if (c == '\n') { + space++; + if (*space == '\n') { + putchar('\n'); + goto new_line; + } + else if (!isalnum(*space)) + goto new_line; + else + putchar(' '); + } w++; text++; } else { +new_line: putchar('\n'); text = bol = space + isspace(*space); space = NULL; From a94410c8134581f2f11a7db838da4d8725911a3c Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 10 Nov 2008 18:47:00 +0100 Subject: [PATCH 2/3] Add strbuf_add_wrapped_text() to utf8.[ch] The newly added function can rewrap text according to a given first-line indent, other-indent and text width. Signed-off-by: Johannes Schindelin --- utf8.c | 33 ++++++++++++++++++++++++--------- utf8.h | 2 ++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/utf8.c b/utf8.c index 2aace1d42c..da996695cc 100644 --- a/utf8.c +++ b/utf8.c @@ -1,4 +1,5 @@ #include "git-compat-util.h" +#include "strbuf.h" #include "utf8.h" /* This code is originally from http://www.cl.cam.ac.uk/~mgk25/ucs/ */ @@ -279,14 +280,22 @@ int is_utf8(const char *text) return 1; } -static void print_spaces(int count) +static inline void strbuf_write(struct strbuf *sb, const char *buf, int len) +{ + if (sb) + strbuf_insert(sb, sb->len, buf, len); + else + fwrite(buf, len, 1, stdout); +} + +static void print_spaces(struct strbuf *buf, int count) { static const char s[] = " "; while (count >= sizeof(s)) { - fwrite(s, sizeof(s) - 1, 1, stdout); + strbuf_write(buf, s, sizeof(s) - 1); count -= sizeof(s) - 1; } - fwrite(s, count, 1, stdout); + strbuf_write(buf, s, count); } /* @@ -295,7 +304,8 @@ static void print_spaces(int count) * If indent is negative, assume that already -indent columns have been * consumed (and no extra indent is necessary for the first line). */ -int print_wrapped_text(const char *text, int indent, int indent2, int width) +int strbuf_add_wrapped_text(struct strbuf *buf, + const char *text, int indent, int indent2, int width) { int w = indent, assume_utf8 = is_utf8(text); const char *bol = text, *space = NULL; @@ -315,8 +325,8 @@ int print_wrapped_text(const char *text, int indent, int indent2, int width) if (space) start = space; else - print_spaces(indent); - fwrite(start, text - start, 1, stdout); + print_spaces(buf, indent); + strbuf_write(buf, start, text - start); if (!c) return w; space = text; @@ -325,20 +335,20 @@ int print_wrapped_text(const char *text, int indent, int indent2, int width) else if (c == '\n') { space++; if (*space == '\n') { - putchar('\n'); + strbuf_write(buf, "\n", 1); goto new_line; } else if (!isalnum(*space)) goto new_line; else - putchar(' '); + strbuf_write(buf, " ", 1); } w++; text++; } else { new_line: - putchar('\n'); + strbuf_write(buf, "\n", 1); text = bol = space + isspace(*space); space = NULL; w = indent = indent2; @@ -354,6 +364,11 @@ new_line: } } +int print_wrapped_text(const char *text, int indent, int indent2, int width) +{ + return strbuf_add_wrapped_text(NULL, text, indent, indent2, width); +} + int is_encoding_utf8(const char *name) { if (!name) diff --git a/utf8.h b/utf8.h index 2f1b14ff49..ae30ae4c6e 100644 --- a/utf8.h +++ b/utf8.h @@ -10,6 +10,8 @@ int is_utf8(const char *text); int is_encoding_utf8(const char *name); int print_wrapped_text(const char *text, int indent, int indent2, int len); +int strbuf_add_wrapped_text(struct strbuf *buf, + const char *text, int indent, int indent2, int width); #ifndef NO_ICONV char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding); From 00d3947366a50a06da40989a1fd1e3f99885a4c3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 18 Oct 2009 23:40:35 -0700 Subject: [PATCH 3/3] Teach --wrap to only indent without wrapping When a zero or negative width is given to "shortlog -w,," and --format=%[wrap(w,in1,in2)...%], just indent the text by in1 without wrapping. Signed-off-by: Junio C Hamano --- utf8.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/utf8.c b/utf8.c index da996695cc..5c18f0c281 100644 --- a/utf8.c +++ b/utf8.c @@ -310,6 +310,19 @@ int strbuf_add_wrapped_text(struct strbuf *buf, int w = indent, assume_utf8 = is_utf8(text); const char *bol = text, *space = NULL; + if (width <= 0) { + /* just indent */ + while (*text) { + const char *eol = strchrnul(text, '\n'); + if (*eol == '\n') + eol++; + print_spaces(buf, indent); + strbuf_write(buf, text, eol-text); + text = eol; + } + return 1; + } + if (indent < 0) { w = -indent; space = text;