[pan2: 13/23] Teach text-massager about format=flowed.
- From: Petr Kovář <pmkovar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2: 13/23] Teach text-massager about format=flowed.
- Date: Sun, 29 May 2011 13:04:38 +0000 (UTC)
commit d0b4dba36ecd2358458f81616aec4c43fce123d7
Author: K. Haley <haleykd users sf net>
Date: Wed Apr 7 15:02:40 2010 -0600
Teach text-massager about format=flowed.
pan/gui/body-pane.cc | 4 +-
pan/usenet-utils/text-massager-test.cc | 6 ++
pan/usenet-utils/text-massager.cc | 147 +++++++++++++++++++++-----------
pan/usenet-utils/text-massager.h | 2 +-
4 files changed, 108 insertions(+), 51 deletions(-)
---
diff --git a/pan/gui/body-pane.cc b/pan/gui/body-pane.cc
index 42070a6..f4eb451 100644
--- a/pan/gui/body-pane.cc
+++ b/pan/gui/body-pane.cc
@@ -940,10 +940,12 @@ BodyPane :: append_part (GMimeObject * obj, GtkAllocation * widget_size)
else if (g_mime_content_type_is_type (type, "text", "*"))
{
const char * fallback_charset (_charset.c_str());
+ const char * p_flowed (g_mime_object_get_content_type_parameter(obj,"format"));
+ const bool flowed (g_strcmp0 (p_flowed, "flowed") == 0);
std::string str = mime_part_to_utf8 (part, fallback_charset);
if (!str.empty() && _prefs.get_flag ("wrap-article-body", false))
- str = _tm.fill (str);
+ str = _tm.fill (str, flowed);
const bool do_mute (_prefs.get_flag ("mute-quoted-text", false));
const bool do_smilies (_prefs.get_flag ("show-smilies-as-graphics", true));
diff --git a/pan/usenet-utils/text-massager-test.cc b/pan/usenet-utils/text-massager-test.cc
index 796ecf9..3013e95 100644
--- a/pan/usenet-utils/text-massager-test.cc
+++ b/pan/usenet-utils/text-massager-test.cc
@@ -34,6 +34,12 @@ int main (void)
expected_out = "> a\n> b\n> c";
check (out == expected_out);
+ /* flowed test */
+ in = "This is \na test of \nflowed text.\n\nA\n";
+ out = tm.fill (in, true);
+ expected_out = "This is a test of flowed text.\n\nA";
+ check (out == expected_out);
+
/* wrap real-world 1 */
in =
"Cybe R. Wizard wrote:\n"
diff --git a/pan/usenet-utils/text-massager.cc b/pan/usenet-utils/text-massager.cc
index cee9d2e..d34d808 100644
--- a/pan/usenet-utils/text-massager.cc
+++ b/pan/usenet-utils/text-massager.cc
@@ -108,8 +108,99 @@ namespace
typedef std::vector<Paragraph> paragraphs_t;
typedef paragraphs_t::iterator p_it;
+ void merge_fixed (paragraphs_t ¶graphs, lines_t &lines, int wrap_col)
+ {
+ int prev_content_len = 0;
+ StringView cur_leader;
+ std::string cur_content;
+
+ for (lines_cit it=lines.begin(), end=lines.end(); it!=end; ++it)
+ {
+ const Line& line (*it);
+ bool paragraph_end = true;
+ bool hard_break = false;
+
+ if (cur_content.empty() || line.leader==cur_leader)
+ paragraph_end = false;
+
+ if (line.content.empty()) {
+ hard_break = prev_content_len!=0;
+ paragraph_end = true;
+ }
+
+ // we usually don't want to wrap really short lines
+ if (prev_content_len && prev_content_len<(wrap_col/2))
+ paragraph_end = true;
+
+ if (paragraph_end) // the new line is a new paragraph, so save old
+ {
+ paragraphs.push_back (Paragraph (
+ cur_leader.str, cur_leader.len,
+ cur_content.c_str(), cur_content.size()));
+ cur_leader = line.leader;
+ cur_content = line.content.to_string();
+ if (hard_break) {
+ paragraphs.push_back (Paragraph (
+ cur_leader.str, cur_leader.len, "", 0));
+ }
+ }
+ else // append to the content
+ {
+ if (!cur_content.empty())
+ cur_content += ' ';
+ cur_leader = line.leader;
+ cur_content.insert (cur_content.end(),
+ line.content.begin(),
+ line.content.end());
+ }
+
+ prev_content_len = line.content.len;
+ }
+ }
+
+ void merge_flowed (paragraphs_t ¶graphs, lines_t &lines)
+ {
+ StringView cur_leader;
+ std::string cur_content;
+ bool prev_flowed=true;
+
+ for (lines_cit it=lines.begin(), end=lines.end(); it!=end; ++it)
+ {
+ const Line& line (*it);
+
+ if (line.leader != cur_leader)
+ prev_flowed = false;
+
+ if (!prev_flowed) // the new line is a new paragraph, so save old
+ {
+ paragraphs.push_back (Paragraph (
+ cur_leader.str, cur_leader.len,
+ cur_content.c_str(), cur_content.size()));
+ cur_leader = line.leader;
+ cur_content = line.content.to_string();
+ }
+ else // append to the content
+ {
+ if (!cur_content.empty())
+ cur_content += ' ';
+ cur_leader = line.leader;
+ cur_content.insert (cur_content.end(),
+ line.content.begin(),
+ line.content.end());
+ }
+ // flowed text ends with a space
+ if (line.content.len && line.content.str[line.content.len] == ' ')
+ prev_flowed = true;
+ else
+ prev_flowed = false;
+ }
+ //add final content
+ paragraphs.push_back (Paragraph (cur_leader.str, cur_leader.len,
+ cur_content.c_str(), cur_content.size()));
+ }
+
std::vector<Paragraph>
- get_paragraphs (const TextMassager& tm, const StringView& body)
+ get_paragraphs (const TextMassager& tm, const StringView& body, bool flowed)
{
StringView mybody (body);
StringView line;
@@ -141,52 +232,10 @@ namespace
std::vector<Paragraph> paragraphs;
if (!lines.empty())
{
- int prev_content_len = 0;
- StringView cur_leader;
- std::string cur_content;
-
- for (lines_cit it=lines.begin(), end=lines.end(); it!=end; ++it)
- {
- const Line& line (*it);
- bool paragraph_end = true;
- bool hard_break = false;
-
- if (cur_content.empty() || line.leader==cur_leader)
- paragraph_end = false;
-
- if (line.content.empty()) {
- hard_break = prev_content_len!=0;
- paragraph_end = true;
- }
-
- // we usually don't want to wrap really short lines
- if (prev_content_len && prev_content_len<(tm.get_wrap_column()/2))
- paragraph_end = true;
-
- if (paragraph_end) // the new line is a new paragraph, so save old
- {
- paragraphs.push_back (Paragraph (
- cur_leader.str, cur_leader.len,
- cur_content.c_str(), cur_content.size()));
- cur_leader = line.leader;
- cur_content = line.content.to_string();
- if (hard_break) {
- paragraphs.push_back (Paragraph (
- cur_leader.str, cur_leader.len, "", 0));
- }
- }
- else // append to the content
- {
- if (!cur_content.empty())
- cur_content += ' ';
- cur_leader = line.leader;
- cur_content.insert (cur_content.end(),
- line.content.begin(),
- line.content.end());
- }
-
- prev_content_len = line.content.len;
- }
+ if (flowed)
+ merge_flowed(paragraphs, lines);
+ else
+ merge_fixed(paragraphs, lines, tm.get_wrap_column());
// Remember that empty line we added back up at the top?
// We remove it now
@@ -271,7 +320,7 @@ namespace
}
std::string
-TextMassager :: fill (const StringView& body) const
+TextMassager :: fill (const StringView& body, bool flowed) const
{
std::string retval;
@@ -291,7 +340,7 @@ TextMassager :: fill (const StringView& body) const
typedef std::vector<std::string> strings_t;
typedef strings_t::const_iterator strings_cit;
strings_t lines;
- paragraphs_t paragraphs (get_paragraphs (*this, tmp_body));
+ paragraphs_t paragraphs (get_paragraphs (*this, tmp_body, flowed));
for (p_it it=paragraphs.begin(), end=paragraphs.end(); it!=end; ++it)
fill_paragraph (*this, *it, lines);
diff --git a/pan/usenet-utils/text-massager.h b/pan/usenet-utils/text-massager.h
index 47e4977..68251db 100644
--- a/pan/usenet-utils/text-massager.h
+++ b/pan/usenet-utils/text-massager.h
@@ -44,7 +44,7 @@ namespace pan
public:
static char* rot13_inplace (char * text);
std::string mute_quotes (const StringView& text) const;
- std::string fill (const StringView& text) const;
+ std::string fill (const StringView& text, bool flowed = false) const;
int get_wrap_column () const { return _wrap_column; }
bool is_quote_character (unsigned int unichar) const;
std::set<char> get_quote_characters () const;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]