1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include "modest-text-utils.h"
42 #endif /*HAVE_CONFIG_H */
45 static GString *get_next_line (const char *b, const gsize blen, const gchar * iter);
46 static int get_indent_level (const char *l);
47 static void unquote_line (GString * l);
48 static void append_quoted (GString * buf, const int indent,
49 const GString * str, const int cutpoint);
50 static int get_breakpoint_utf8 (const gchar * s, const gint indent,
52 static int get_breakpoint_ascii (const gchar * s, const gint indent,
54 static int get_breakpoint (const gchar * s, const gint indent,
58 get_next_line (const gchar * b, const gsize blen, const gchar * iter)
64 return g_string_new("");
72 gs = g_string_new_len (i0, iter - i0);
76 get_indent_level (const char *l)
93 /* if we hit the signature marker "-- ", we return -(indent + 1). This
96 if (strcmp (l, "-- ") == 0) {
104 unquote_line (GString * l)
119 g_string_erase (l, 0, p - l->str);
123 append_quoted (GString * buf, int indent, const GString * str,
128 indent = indent < 0 ? abs (indent) - 1 : indent;
129 for (i = 0; i <= indent; i++) {
130 g_string_append (buf, "> ");
133 g_string_append_len (buf, str->str, cutpoint);
135 g_string_append (buf, str->str);
137 g_string_append (buf, "\n");
141 get_breakpoint_utf8 (const gchar * s, gint indent, const gint limit)
144 const gchar *pos, *last;
147 indent = indent < 0 ? abs (indent) - 1 : indent;
151 uni = g_utf8_to_ucs4_fast (s, -1, NULL);
153 if ((index + 2 * indent > limit) && last) {
157 if (g_unichar_isspace (uni[index])) {
160 pos = g_utf8_next_char (pos);
168 get_breakpoint_ascii (const gchar * s, const gint indent, const gint limit)
173 if (last + 2 * indent < limit)
176 for (i = strlen (s); i > 0; i--) {
178 if (i + 2 * indent <= limit) {
189 get_breakpoint (const gchar * s, const gint indent, const gint limit)
192 if (g_utf8_validate (s, -1, NULL)) {
193 return get_breakpoint_utf8 (s, indent, limit);
194 } else { /* assume ASCII */
195 //g_warning("invalid UTF-8 in msg");
196 return get_breakpoint_ascii (s, indent, limit);
202 /* just to prevent warnings:
203 * warning: `%x' yields only last 2 digits of year in some locales
206 my_strftime(char *s, size_t max, const char *fmt, const
208 return strftime(s, max, fmt, tm);
213 modest_text_utils_quote (const gchar * to_quote, const gchar * from,
214 const time_t sent_date, const int limit)
217 gint indent, breakpoint, rem_indent = 0;
219 GString *q, *l, *remaining;
222 /* format sent_date */
223 my_strftime (sent_str, 100, "%c", localtime (&sent_date));
224 q = g_string_new ("");
225 g_string_printf (q, "On %s, %s wrote:\n", sent_str, from);
227 /* remaining will store the rest of the line if we have to break it */
228 remaining = g_string_new ("");
231 len = strlen(to_quote);
233 l = get_next_line (to_quote, len, iter);
234 iter = iter + l->len + 1;
235 indent = get_indent_level (l->str);
238 if (remaining->len) {
239 if (l->len && indent == rem_indent) {
240 g_string_prepend (l, " ");
241 g_string_prepend (l, remaining->str);
245 get_breakpoint (remaining-> str,
248 append_quoted (q, rem_indent,
249 remaining, breakpoint);
250 g_string_erase (remaining, 0,
252 if (remaining->str[0] == ' ') {
253 g_string_erase (remaining, 0,
256 } while (remaining->len);
259 g_string_free (remaining, TRUE);
260 breakpoint = get_breakpoint (l->str, indent, limit);
261 remaining = g_string_new (l->str + breakpoint);
262 if (remaining->str[0] == ' ') {
263 g_string_erase (remaining, 0, 1);
266 append_quoted (q, indent, l, breakpoint);
267 g_string_free (l, TRUE);
268 } while ((iter < to_quote + len) || (remaining->str[0]));
270 return g_string_free (q, FALSE);