--- /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 674EE429E31\r
+ for <notmuch@notmuchmail.org>; Tue, 14 Feb 2012 09:34:02 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+ tests=[RCVD_IN_DNSWL_LOW=-0.7] 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 xUeE7P45OOid for <notmuch@notmuchmail.org>;\r
+ Tue, 14 Feb 2012 09:33:59 -0800 (PST)\r
+Received: from dmz-mailsec-scanner-8.mit.edu (DMZ-MAILSEC-SCANNER-8.MIT.EDU\r
+ [18.7.68.37])\r
+ by olra.theworths.org (Postfix) with ESMTP id 9BEAB431FBC\r
+ for <notmuch@notmuchmail.org>; Tue, 14 Feb 2012 09:33:56 -0800 (PST)\r
+X-AuditID: 12074425-b7f4a6d0000008e0-a0-4f3a9b038ca9\r
+Received: from mailhub-auth-4.mit.edu ( [18.7.62.39])\r
+ by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP\r
+ id D0.E3.02272.30B9A3F4; Tue, 14 Feb 2012 12:33:55 -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 q1EHXtRI019622; \r
+ Tue, 14 Feb 2012 12:33:55 -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 q1EHXr3j016486\r
+ (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
+ Tue, 14 Feb 2012 12:33:54 -0500 (EST)\r
+Received: from amthrax by drake.mit.edu with local (Exim 4.77)\r
+ (envelope-from <amthrax@drake.mit.edu>)\r
+ id 1RxMGH-000271-7w; Tue, 14 Feb 2012 12:33:53 -0500\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 1/8] Document the JSON schemata used by show and search\r
+Date: Tue, 14 Feb 2012 12:33:36 -0500\r
+Message-Id: <1329240823-7856-2-git-send-email-amdragon@mit.edu>\r
+X-Mailer: git-send-email 1.7.7.3\r
+In-Reply-To: <1329240823-7856-1-git-send-email-amdragon@mit.edu>\r
+References: <1329240823-7856-1-git-send-email-amdragon@mit.edu>\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFjrOIsWRmVeSWpSXmKPExsUixG6nrss828rfoHutlcWRPbPYLa5u7We3\r
+ uH5zJrMDs8fOWXfZPZ6tusXs0fRjMWsAcxSXTUpqTmZZapG+XQJXRvuqC4wFP9UrenZfYGtg\r
+ nCXbxcjJISFgInGudR0jhC0mceHeerYuRi4OIYF9jBJXTr1ghHA2MEoc/bCTBcK5zyTx8eId\r
+ qLL5jBJ3vzwC62cT0JDYtn85mC0iIC2x8+5sVhCbWSBe4kjberC4sIC7xKT/E1lAbBYBVYkf\r
+ bZfYuxg5OHgF7CVWvGSGOENB4tzqc+wgNqeAg8T+ff/BxggBlVy6u5VlAiP/AkaGVYyyKblV\r
+ urmJmTnFqcm6xcmJeXmpRboWermZJXqpKaWbGMHh5aK6g3HCIaVDjAIcjEo8vAYWlv5CrIll\r
+ xZW5hxglOZiURHmFZ1j5C/El5adUZiQWZ8QXleakFh9ilOBgVhLh3TQdKMebklhZlVqUD5OS\r
+ 5mBREufV1HrnJySQnliSmp2aWpBaBJOV4eBQkuBlmwXUKFiUmp5akZaZU4KQZuLgBBnOAzT8\r
+ y0yQ4cUFibnFmekQ+VOMilLivG9BEgIgiYzSPLheWPy/YhQHekWYVw5kBQ8wdcB1vwIazAQ0\r
+ ePtpC5DBJYkIKakGRmN185uzsuS+b+SpP8Cknf/lUAO/V4bQrjMTP+WtSvz5RX3ZRRWhFxed\r
+ XppVV62WM7jf8nuaPFfZAsfy7Ol/PKa9+3pV6rHgP8aMHTVOU3ztZ63bI+G96ky/s80jW921\r
+ R1MsPiQ7up1fVa29p7TiwMGdsnlP51Wv/RH1d7m1XMP1s/wzslNvpymxFGckGmoxFxUnAgDD\r
+ EjOe2gIAAA==\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: Tue, 14 Feb 2012 17:34:03 -0000\r
+\r
+---\r
+ devel/schemata | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ notmuch-search.c | 3 +\r
+ notmuch-show.c | 2 +\r
+ 3 files changed, 140 insertions(+), 0 deletions(-)\r
+ create mode 100644 devel/schemata\r
+\r
+diff --git a/devel/schemata b/devel/schemata\r
+new file mode 100644\r
+index 0000000..d90d4c6\r
+--- /dev/null\r
++++ b/devel/schemata\r
+@@ -0,0 +1,135 @@\r
++This file describes the schemata used for notmuch's structured output\r
++format (currently JSON).\r
++\r
++[]'s indicate lists. List items can be marked with a '?', meaning\r
++they are optional; or a '*', meaning there can be zero or more of that\r
++item. {}'s indicate an object that maps from field identifiers to\r
++values. An object field marked '?' is optional. |'s indicate\r
++alternates (e.g., int|string means something can be an int or a\r
++string).\r
++\r
++Common non-terminals\r
++--------------------\r
++\r
++# Number of seconds since the Epoch\r
++unix_time = int\r
++\r
++# Thread ID, sans "thread:"\r
++threadid = string\r
++\r
++# Message ID, sans "id:"\r
++messageid = string\r
++\r
++notmuch show schema\r
++-------------------\r
++\r
++# A top-level set of threads (do_show)\r
++# Returned by notmuch show without a --part argument\r
++thread_set = [thread*]\r
++\r
++# Top-level messages in a thread (show_messages)\r
++thread = [thread_node*]\r
++\r
++# A message and its replies (show_messages)\r
++thread_node = [\r
++ message?, # present if --entire-thread or matched\r
++ [thread_node*] # children of message\r
++]\r
++\r
++# A message (show_message)\r
++message = {\r
++ # (format_message_json)\r
++ id: messageid,\r
++ match: bool,\r
++ filename: string,\r
++ timestamp: unix_time, # date header as unix time\r
++ date_relative: string, # user-friendly timestamp\r
++ tags: [string*],\r
++\r
++ headers: headers,\r
++ body: [part]\r
++}\r
++\r
++# A MIME part (show_message_body)\r
++part = {\r
++ # format_part_start_json\r
++ id: int|string, # part id (currently DFS part number)\r
++\r
++ # format_part_encstatus_json\r
++ encstatus?: encstatus,\r
++\r
++ # format_part_sigstatus_json\r
++ sigstatus?: sigstatus,\r
++\r
++ # format_part_content_json\r
++ content-type: string,\r
++ content-id?: string,\r
++ # if content-type starts with "multipart/":\r
++ content: [part*],\r
++ # if content-type is "message/rfc822":\r
++ content: [{headers: headers, body: [part]}],\r
++ # otherwise (leaf parts):\r
++ filename?: string,\r
++ content-charset?: string,\r
++ content?: string # pre-fetched body content\r
++}\r
++\r
++# The headers of a message (format_headers_json with raw headers) or\r
++# a part (format_headers_message_part_json with pretty-printed headers)\r
++headers = {\r
++ Subject: string,\r
++ From: string,\r
++ To?: string,\r
++ Cc?: string,\r
++ Bcc?: string,\r
++ Date: string\r
++}\r
++\r
++# Encryption status (format_part_encstatus_json)\r
++encstatus = [{status: "good"|"bad"}]\r
++\r
++# Signature status (format_part_sigstatus_json)\r
++sigstatus = [signature*]\r
++\r
++signature = {\r
++ # signature_status_to_string\r
++ status: "none"|"good"|"bad"|"error"|"unknown",\r
++ # if status is "good":\r
++ fingerprint?: string,\r
++ created?: unix_time,\r
++ expires?: unix_time,\r
++ userid?: string\r
++ # if status is not "good":\r
++ keyid?: string\r
++ # if the signature has errors: \r
++ errors?: int\r
++}\r
++\r
++notmuch search schema\r
++---------------------\r
++\r
++# --output=summary\r
++summary = [thread*]\r
++\r
++# --output=threads\r
++threads = [threadid*]\r
++\r
++# --output=messages\r
++messages = [messageid*]\r
++\r
++# --output=files\r
++files = [string*]\r
++\r
++# --output=tags\r
++tags = [string*]\r
++\r
++thread = {\r
++ thread: threadid,\r
++ timestamp: unix_time,\r
++ date_relative: string, # user-friendly timestamp\r
++ matched: int, # number of matched messages\r
++ total: int, # total messages in thread\r
++ authors: string, # comma-separated names with | between \r
++ # matched and unmatched\r
++ subject: string\r
++}\r
+diff --git a/notmuch-search.c b/notmuch-search.c\r
+index d504051..92ce38a 100644\r
+--- a/notmuch-search.c\r
++++ b/notmuch-search.c\r
+@@ -90,6 +90,9 @@ format_thread_json (const void *ctx,\r
+ const int total,\r
+ const char *authors,\r
+ const char *subject);\r
++\r
++/* Any changes to the JSON format should be reflected in the file\r
++ * devel/schemata. */\r
+ static const search_format_t format_json = {\r
+ "[",\r
+ "{",\r
+diff --git a/notmuch-show.c b/notmuch-show.c\r
+index d930f94..93fb16f 100644\r
+--- a/notmuch-show.c\r
++++ b/notmuch-show.c\r
+@@ -65,6 +65,8 @@ format_part_content_json (GMimeObject *part);\r
+ static void\r
+ format_part_end_json (GMimeObject *part);\r
+ \r
++/* Any changes to the JSON format should be reflected in the file\r
++ * devel/schemata. */\r
+ static const notmuch_show_format_t format_json = {\r
+ "[", NULL,\r
+ "{", format_message_json,\r
+-- \r
+1.7.7.3\r
+\r