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 modest_text_utils_quote (const gchar * to_quote, const gchar * from,
203 const time_t sent_date, const int limit)
206 gint indent, breakpoint, rem_indent = 0;
208 GString *q, *l, *remaining;
211 /* format sent_date */
212 strftime (sent_str, 100, "%c", localtime (&sent_date));
213 q = g_string_new ("");
214 g_string_printf (q, "On %s, %s wrote:\n", sent_str, from);
216 /* remaining will store the rest of the line if we have to break it */
217 remaining = g_string_new ("");
220 len = strlen(to_quote);
222 l = get_next_line (to_quote, len, iter);
223 iter = iter + l->len + 1;
224 indent = get_indent_level (l->str);
227 if (remaining->len) {
228 if (l->len && indent == rem_indent) {
229 g_string_prepend (l, " ");
230 g_string_prepend (l, remaining->str);
234 get_breakpoint (remaining-> str,
237 append_quoted (q, rem_indent,
238 remaining, breakpoint);
239 g_string_erase (remaining, 0,
241 if (remaining->str[0] == ' ') {
242 g_string_erase (remaining, 0,
245 } while (remaining->len);
248 g_string_free (remaining, TRUE);
249 breakpoint = get_breakpoint (l->str, indent, limit);
250 remaining = g_string_new (l->str + breakpoint);
251 if (remaining->str[0] == ' ') {
252 g_string_erase (remaining, 0, 1);
255 append_quoted (q, indent, l, breakpoint);
256 g_string_free (l, TRUE);
257 } while ((iter < to_quote + len) || (remaining->str[0]));
259 return g_string_free (q, FALSE);