]> git.notmuchmail.org Git - notmuch/blob - devel/schemata
schemata: Disambiguate non-terminal names
[notmuch] / devel / schemata
1 This file describes the schemata used for notmuch's structured output
2 format (currently JSON and S-Expressions).
3
4 []'s indicate lists.  List items can be marked with a '?', meaning
5 they are optional; or a '*', meaning there can be zero or more of that
6 item.  {}'s indicate an object that maps from field identifiers to
7 values.  An object field marked '?' is optional.  |'s indicate
8 alternates (e.g., int|string means something can be an int or a
9 string).
10
11 For S-Expression output, lists are printed delimited by () instead of
12 []. Objects are printed as p-lists, i.e. lists where the keys and values
13 are interleaved. Keys are printed as keywords (symbols preceded by a
14 colon), e.g. (:id "123" :time 54321 :from "foobar"). Null is printed as
15 nil, true as t and false as nil.
16
17 This is version 1 of the structured output format.
18
19 Common non-terminals
20 --------------------
21
22 # Number of seconds since the Epoch
23 unix_time = int
24
25 # Thread ID, sans "thread:"
26 threadid = string
27
28 # Message ID, sans "id:"
29 messageid = string
30
31 notmuch show schema
32 -------------------
33
34 # A top-level set of threads (do_show)
35 # Returned by notmuch show without a --part argument
36 thread_set = [thread*]
37
38 # Top-level messages in a thread (show_messages)
39 thread = [thread_node*]
40
41 # A message and its replies (show_messages)
42 thread_node = [
43     message|null,             # null if not matched and not --entire-thread
44     [thread_node*]            # children of message
45 ]
46
47 # A message (format_part_sprinter)
48 message = {
49     # (format_message_sprinter)
50     id:             messageid,
51     match:          bool,
52     filename:       string,
53     timestamp:      unix_time, # date header as unix time
54     date_relative:  string,   # user-friendly timestamp
55     tags:           [string*],
56
57     headers:        headers,
58     body?:          [part]    # omitted if --body=false
59 }
60
61 # A MIME part (format_part_sprinter)
62 part = {
63     id:             int|string, # part id (currently DFS part number)
64
65     encstatus?:     encstatus,
66     sigstatus?:     sigstatus,
67
68     content-type:   string,
69     content-id?:    string,
70     # if content-type starts with "multipart/":
71     content:        [part*],
72     # if content-type is "message/rfc822":
73     content:        [{headers: headers, body: [part]}],
74     # otherwise (leaf parts):
75     filename?:      string,
76     content-charset?: string,
77     # A leaf part's body content is optional, but may be included if
78     # it can be correctly encoded as a string.  Consumers should use
79     # this in preference to fetching the part content separately.
80     content?:       string,
81     # If a leaf part's body content is not included, the length of
82     # the encoded content (in bytes) may be given instead.
83     content-length?: int,
84     # If a leaf part's body content is not included, its transfer encoding
85     # may be given.  Using this and the encoded content length, it is
86     # possible for the consumer to estimate the decoded content length.
87     content-transfer-encoding?: string
88 }
89
90 # The headers of a message or part (format_headers_sprinter with reply = FALSE)
91 headers = {
92     Subject:        string,
93     From:           string,
94     To?:            string,
95     Cc?:            string,
96     Bcc?:           string,
97     Reply-To?:      string,
98     Date:           string
99 }
100
101 # Encryption status (format_part_sprinter)
102 encstatus = [{status: "good"|"bad"}]
103
104 # Signature status (format_part_sigstatus_sprinter)
105 sigstatus = [signature*]
106
107 signature = {
108     # (signature_status_to_string)
109     status:         "none"|"good"|"bad"|"error"|"unknown",
110     # if status is "good":
111     fingerprint?:   string,
112     created?:       unix_time,
113     expires?:       unix_time,
114     userid?:        string
115     # if status is not "good":
116     keyid?:         string
117     # if the signature has errors:
118     errors?:        int
119 }
120
121 notmuch search schema
122 ---------------------
123
124 # --output=summary
125 search_summary = [thread_summary*]
126
127 # --output=threads
128 search_threads = [threadid*]
129
130 # --output=messages
131 search_messages = [messageid*]
132
133 # --output=files
134 search_files = [string*]
135
136 # --output=tags
137 search_tags = [string*]
138
139 thread_summary = {
140     thread:         threadid,
141     timestamp:      unix_time,
142     date_relative:  string,   # user-friendly timestamp
143     matched:        int,      # number of matched messages
144     total:          int,      # total messages in thread
145     authors:        string,   # comma-separated names with | between
146                               # matched and unmatched
147     subject:        string,
148     tags:           [string*]
149 }
150
151 notmuch reply schema
152 --------------------
153
154 reply = {
155     # The headers of the constructed reply
156     reply-headers: reply_headers,
157
158     # As in the show format (format_part_sprinter)
159     original: message
160 }
161
162 # Reply headers (format_headers_sprinter with reply = TRUE)
163 reply_headers = {
164     Subject:        string,
165     From:           string,
166     To?:            string,
167     Cc?:            string,
168     Bcc?:           string,
169     In-reply-to:    string,
170     References:     string
171 }