--- /dev/null
+Return-Path: <amthrax@drake.mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 784AA431FAF\r
+ for <notmuch@notmuchmail.org>; Sun, 5 Feb 2012 09:22:18 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0.104\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0.104 tagged_above=-999 required=5\r
+ tests=[DATE_IN_PAST_12_24=0.804, RCVD_IN_DNSWL_LOW=-0.7]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id 3yrKOQ1NBmVq for <notmuch@notmuchmail.org>;\r
+ Sun, 5 Feb 2012 09:22:16 -0800 (PST)\r
+Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU\r
+ [18.9.25.15])\r
+ by olra.theworths.org (Postfix) with ESMTP id 69983431FB6\r
+ for <notmuch@notmuchmail.org>; Sun, 5 Feb 2012 09:22:16 -0800 (PST)\r
+X-AuditID: 1209190f-b7f8a6d000000914-18-4f2ebac706af\r
+Received: from mailhub-auth-4.mit.edu ( [18.7.62.39])\r
+ by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP\r
+ id CD.16.02324.7CABE2F4; Sun, 5 Feb 2012 12:22:15 -0500 (EST)\r
+Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
+ by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id q15HMFPN018060; \r
+ Sun, 5 Feb 2012 12:22:15 -0500\r
+Received: from drake.mit.edu\r
+ (209-6-116-242.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com\r
+ [209.6.116.242]) (authenticated bits=0)\r
+ (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+ by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q15HMDeN027733\r
+ (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
+ Sun, 5 Feb 2012 12:22:14 -0500 (EST)\r
+Received: from amthrax by drake.mit.edu with local (Exim 4.77)\r
+ (envelope-from <amthrax@drake.mit.edu>)\r
+ id 1Ru5n3-0000sm-TY; Sun, 05 Feb 2012 12:22:13 -0500\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH v2 1/2] show: Convert text format to the new self-recursive\r
+ style\r
+Date: Sat, 4 Feb 2012 16:24:25 -0500\r
+Message-Id: <1328390666-22435-2-git-send-email-amdragon@mit.edu>\r
+X-Mailer: git-send-email 1.7.7.3\r
+In-Reply-To: <1328390666-22435-1-git-send-email-amdragon@mit.edu>\r
+References: <1327560926-22401-1-git-send-email-amdragon@mit.edu>\r
+ <1328390666-22435-1-git-send-email-amdragon@mit.edu>\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFtrNIsWRmVeSWpSXmKPExsUixG6nrnt8l56/wbdWG4urW/vZLa7fnMns\r
+ wOSxc9Zddo9nq24xBzBFcdmkpOZklqUW6dslcGX8XGdWcN+34uvP+4wNjBvtuhg5OSQETCQu\r
+ /L7DBmGLSVy4tx7I5uIQEtjHKDHr0AsWCGc9o8STe3NZIZx7TBJneiZDOfMZJVZvmQHWzyag\r
+ IbFt/3JGEFtEQFpi593ZrCA2s4CTxOK/i5hBbGGBQImuhllg9SwCqhJ/fr8FWsHBwSvgINE/\r
+ TQfiDAWJc6vPsYOEOQUcJTb+LQQJCwmUS2z6dYt1AiP/AkaGVYyyKblVurmJmTnFqcm6xcmJ\r
+ eXmpRbomermZJXqpKaWbGEFhxCnJv4Px20GlQ4wCHIxKPLzM5nr+QqyJZcWVuYcYJTmYlER5\r
+ M7cDhfiS8lMqMxKLM+KLSnNSiw8xSnAwK4nwyh7V9RfiTUmsrEotyodJSXOwKInzqmm98xMS\r
+ SE8sSc1OTS1ILYLJynBwKEnw8gLjRUiwKDU9tSItM6cEIc3EwQkynAdouABIDW9xQWJucWY6\r
+ RP4Uo6KUOC8DSEIAJJFRmgfXC4vzV4ziQK8I8/KDVPEAUwRc9yugwUxAg/exgVxdXJKIkJJq\r
+ YFTof5LC/vOpqJ4d59llwTN/6c+Z/fGuutExxkSfJX+9Slav3OITwjM53uZneqx0mKfa25sT\r
+ ef7tjpD0/7XW30JJ9+ShaoPu0ODCKS8rqnj0y2+a+Vg9miv5lfPT598PPny+cT7Ewv7i1f0O\r
+ 3/InJhQrvzDb8XWxxbH7GW84rs2eH7Bg70kD5lIlluKMREMt5qLiRABBxPV8zgIAAA==\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 05 Feb 2012 17:22:18 -0000\r
+\r
+This is all code movement and a smidgen of glue. This moves the\r
+existing text formatter code into one self-recursive function, but\r
+doesn't change any of the logic. The next patch will actually take\r
+advantage of what the new structure has to offer.\r
+\r
+Note that this patch retains format_headers_message_part_text because\r
+it is also used by the raw format.\r
+---\r
+ notmuch-show.c | 270 +++++++++++++++++++++++++++++---------------------------\r
+ 1 files changed, 139 insertions(+), 131 deletions(-)\r
+\r
+diff --git a/notmuch-show.c b/notmuch-show.c\r
+index dec799c..6a890b2 100644\r
+--- a/notmuch-show.c\r
++++ b/notmuch-show.c\r
+@@ -21,40 +21,17 @@\r
+ #include "notmuch-client.h"\r
+ \r
+ static void\r
+-format_message_text (unused (const void *ctx),\r
+- notmuch_message_t *message,\r
+- int indent);\r
+-static void\r
+-format_headers_text (const void *ctx,\r
+- notmuch_message_t *message);\r
+-\r
+-static void\r
+ format_headers_message_part_text (GMimeMessage *message);\r
+ \r
+ static void\r
+-format_part_start_text (GMimeObject *part,\r
+- int *part_count);\r
+-\r
+-static void\r
+-format_part_content_text (GMimeObject *part);\r
+-\r
+-static void\r
+-format_part_end_text (GMimeObject *part);\r
++format_part_text (const void *ctx, mime_node_t *node,\r
++ int indent, const notmuch_show_params_t *params);\r
+ \r
+ static const notmuch_show_format_t format_text = {\r
+- "", NULL,\r
+- "\fmessage{ ", format_message_text,\r
+- "\fheader{\n", format_headers_text, format_headers_message_part_text, "\fheader}\n",\r
+- "\fbody{\n",\r
+- format_part_start_text,\r
+- NULL,\r
+- NULL,\r
+- format_part_content_text,\r
+- format_part_end_text,\r
+- "",\r
+- "\fbody}\n",\r
+- "\fmessage}\n", "",\r
+- ""\r
++ .message_set_start = "",\r
++ .part = format_part_text,\r
++ .message_set_sep = "",\r
++ .message_set_end = ""\r
+ };\r
+ \r
+ static void\r
+@@ -191,16 +168,6 @@ _get_one_line_summary (const void *ctx, notmuch_message_t *message)\r
+ }\r
+ \r
+ static void\r
+-format_message_text (unused (const void *ctx), notmuch_message_t *message, int indent)\r
+-{\r
+- printf ("id:%s depth:%d match:%d filename:%s\n",\r
+- notmuch_message_get_message_id (message),\r
+- indent,\r
+- notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),\r
+- notmuch_message_get_filename (message));\r
+-}\r
+-\r
+-static void\r
+ format_message_json (const void *ctx, notmuch_message_t *message, unused (int indent))\r
+ {\r
+ notmuch_tags_t *tags;\r
+@@ -338,26 +305,6 @@ format_message_mbox (const void *ctx,\r
+ fclose (file);\r
+ }\r
+ \r
+-\r
+-static void\r
+-format_headers_text (const void *ctx, notmuch_message_t *message)\r
+-{\r
+- const char *headers[] = {\r
+- "Subject", "From", "To", "Cc", "Bcc", "Date"\r
+- };\r
+- const char *name, *value;\r
+- unsigned int i;\r
+-\r
+- printf ("%s\n", _get_one_line_summary (ctx, message));\r
+-\r
+- for (i = 0; i < ARRAY_SIZE (headers); i++) {\r
+- name = headers[i];\r
+- value = notmuch_message_get_header (message, name);\r
+- if (value && strlen (value))\r
+- printf ("%s: %s\n", name, value);\r
+- }\r
+-}\r
+-\r
+ static void\r
+ format_headers_message_part_text (GMimeMessage *message)\r
+ {\r
+@@ -523,78 +470,6 @@ signer_status_to_string (GMimeSignerStatus x)\r
+ #endif\r
+ \r
+ static void\r
+-format_part_start_text (GMimeObject *part, int *part_count)\r
+-{\r
+- GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part);\r
+-\r
+- if (disposition &&\r
+- strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)\r
+- {\r
+- printf ("\fattachment{ ID: %d", *part_count);\r
+-\r
+- } else {\r
+-\r
+- printf ("\fpart{ ID: %d", *part_count);\r
+- }\r
+-}\r
+-\r
+-static void\r
+-format_part_content_text (GMimeObject *part)\r
+-{\r
+- const char *cid = g_mime_object_get_content_id (part);\r
+- GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));\r
+-\r
+- if (GMIME_IS_PART (part))\r
+- {\r
+- const char *filename = g_mime_part_get_filename (GMIME_PART (part));\r
+- if (filename)\r
+- printf (", Filename: %s", filename);\r
+- }\r
+-\r
+- if (cid)\r
+- printf (", Content-id: %s", cid);\r
+-\r
+- printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));\r
+-\r
+- if (g_mime_content_type_is_type (content_type, "text", "*") &&\r
+- !g_mime_content_type_is_type (content_type, "text", "html"))\r
+- {\r
+- GMimeStream *stream_stdout = g_mime_stream_file_new (stdout);\r
+- g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);\r
+- show_text_part_content (part, stream_stdout);\r
+- g_object_unref(stream_stdout);\r
+- }\r
+- else if (g_mime_content_type_is_type (content_type, "multipart", "*") ||\r
+- g_mime_content_type_is_type (content_type, "message", "rfc822"))\r
+- {\r
+- /* Do nothing for multipart since its content will be printed\r
+- * when recursing. */\r
+- }\r
+- else\r
+- {\r
+- printf ("Non-text part: %s\n",\r
+- g_mime_content_type_to_string (content_type));\r
+- }\r
+-}\r
+-\r
+-static void\r
+-format_part_end_text (GMimeObject *part)\r
+-{\r
+- GMimeContentDisposition *disposition;\r
+-\r
+- disposition = g_mime_object_get_content_disposition (part);\r
+- if (disposition &&\r
+- strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)\r
+- {\r
+- printf ("\fattachment}\n");\r
+- }\r
+- else\r
+- {\r
+- printf ("\fpart}\n");\r
+- }\r
+-}\r
+-\r
+-static void\r
+ format_part_start_json (unused (GMimeObject *part), int *part_count)\r
+ {\r
+ printf ("{\"id\": %d", *part_count);\r
+@@ -844,6 +719,139 @@ format_part_content_raw (GMimeObject *part)\r
+ }\r
+ \r
+ static void\r
++format_part_text (const void *ctx, mime_node_t *node,\r
++ int indent, const notmuch_show_params_t *params)\r
++{\r
++ /* The disposition and content-type metadata are associated with\r
++ * the envelope for message parts */\r
++ GMimeObject *meta = node->envelope_part ?\r
++ GMIME_OBJECT (node->envelope_part) : node->part;\r
++ GMimeContentType *content_type = g_mime_object_get_content_type (meta);\r
++ int i;\r
++\r
++ if (node->envelope_file) {\r
++ notmuch_message_t *message = node->envelope_file;\r
++ const char *headers[] = {\r
++ "Subject", "From", "To", "Cc", "Bcc", "Date"\r
++ };\r
++ const char *name, *value;\r
++ unsigned int i;\r
++\r
++ printf ("\fmessage{ ");\r
++ printf ("id:%s depth:%d match:%d filename:%s\n",\r
++ notmuch_message_get_message_id (message),\r
++ indent,\r
++ notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),\r
++ notmuch_message_get_filename (message));\r
++\r
++ printf ("\fheader{\n");\r
++\r
++ printf ("%s\n", _get_one_line_summary (ctx, message));\r
++\r
++ for (i = 0; i < ARRAY_SIZE (headers); i++) {\r
++ name = headers[i];\r
++ value = notmuch_message_get_header (message, name);\r
++ if (value && strlen (value))\r
++ printf ("%s: %s\n", name, value);\r
++ }\r
++ printf ("\fheader}\n");\r
++ } else {\r
++ GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (meta);\r
++ const char *cid = g_mime_object_get_content_id (meta);\r
++\r
++ if (disposition &&\r
++ strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)\r
++ {\r
++ printf ("\fattachment{ ID: %d", node->part_num);\r
++\r
++ } else {\r
++\r
++ printf ("\fpart{ ID: %d", node->part_num);\r
++ }\r
++\r
++ if (GMIME_IS_PART (node->part))\r
++ {\r
++ const char *filename = g_mime_part_get_filename (GMIME_PART (node->part));\r
++ if (filename)\r
++ printf (", Filename: %s", filename);\r
++ }\r
++\r
++ if (cid)\r
++ printf (", Content-id: %s", cid);\r
++\r
++ printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));\r
++ }\r
++\r
++ if (node->envelope_part) {\r
++ GMimeMessage *message = GMIME_MESSAGE (node->part);\r
++ InternetAddressList *recipients;\r
++ const char *recipients_string;\r
++\r
++ printf ("\fheader{\n");\r
++ printf ("Subject: %s\n", g_mime_message_get_subject (message));\r
++ printf ("From: %s\n", g_mime_message_get_sender (message));\r
++ recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);\r
++ recipients_string = internet_address_list_to_string (recipients, 0);\r
++ if (recipients_string)\r
++ printf ("To: %s\n", recipients_string);\r
++ recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);\r
++ recipients_string = internet_address_list_to_string (recipients, 0);\r
++ if (recipients_string)\r
++ printf ("Cc: %s\n", recipients_string);\r
++ printf ("Date: %s\n", g_mime_message_get_date_as_string (message));\r
++ printf ("\fheader}\n");\r
++ }\r
++\r
++ if (!node->envelope_file) {\r
++ if (g_mime_content_type_is_type (content_type, "text", "*") &&\r
++ !g_mime_content_type_is_type (content_type, "text", "html"))\r
++ {\r
++ GMimeStream *stream_stdout = g_mime_stream_file_new (stdout);\r
++ g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);\r
++ show_text_part_content (node->part, stream_stdout);\r
++ g_object_unref(stream_stdout);\r
++ }\r
++ else if (g_mime_content_type_is_type (content_type, "multipart", "*") ||\r
++ g_mime_content_type_is_type (content_type, "message", "rfc822"))\r
++ {\r
++ /* Do nothing for multipart since its content will be printed\r
++ * when recursing. */\r
++ }\r
++ else\r
++ {\r
++ printf ("Non-text part: %s\n",\r
++ g_mime_content_type_to_string (content_type));\r
++ }\r
++ }\r
++\r
++ if (GMIME_IS_MESSAGE (node->part))\r
++ printf ("\fbody{\n");\r
++\r
++ for (i = 0; i < node->nchildren; i++)\r
++ format_part_text (ctx, mime_node_child (node, i), indent, params);\r
++\r
++ if (GMIME_IS_MESSAGE (node->part))\r
++ printf ("\fbody}\n");\r
++\r
++ if (node->envelope_file) {\r
++ printf ("\fmessage}\n");\r
++ } else {\r
++ GMimeContentDisposition *disposition;\r
++\r
++ disposition = g_mime_object_get_content_disposition (meta);\r
++ if (disposition &&\r
++ strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)\r
++ {\r
++ printf ("\fattachment}\n");\r
++ }\r
++ else\r
++ {\r
++ printf ("\fpart}\n");\r
++ }\r
++ }\r
++}\r
++\r
++static void\r
+ show_message (void *ctx,\r
+ const notmuch_show_format_t *format,\r
+ notmuch_message_t *message,\r
+-- \r
+1.7.7.3\r
+\r