1 # Copyright (C) 2016-2018 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
4 # used for displaying help texts and other non-mail content
5 package PublicInbox::WwwText;
8 use PublicInbox::Linkify;
9 use PublicInbox::WwwStream;
10 use PublicInbox::Hval qw(ascii_html);
11 our $QP_URL = 'https://xapian.org/docs/queryparser.html';
12 our $WIKI_URL = 'https://en.wikipedia.org/wiki';
14 # /$INBOX/_/text/$KEY/ # KEY may contain slashes
15 # For now, "help" is the only supported $KEY
20 $key = 'help' if !defined $key; # this 302s to _/text/help/
22 # get the raw text the same way we get mboxrds
23 my $raw = ($key =~ s!/raw\z!!);
24 my $have_tslash = ($key =~ s!/\z!!) if !$raw;
27 if (!_default_text($ctx, $key, \$txt)) {
29 $txt = "404 Not Found ($key)\n";
32 return [ $code, [ 'Content-Type', 'text/plain',
33 'Content-Length', bytes::length($txt) ],
37 # enforce trailing slash for "wget -r" compatibility
38 if (!$have_tslash && $code == 200) {
39 my $url = $ctx->{-inbox}->base_url($ctx->{env});
40 $url .= "_/text/$key/";
42 return [ 302, [ 'Content-Type', 'text/plain',
44 [ "Redirecting to $url\n" ] ];
47 # Follow git commit message conventions,
48 # first line is the Subject/title
49 my ($title) = ($txt =~ /\A([^\n]*)/s);
51 $ctx->{-title_html} = ascii_html($title);
53 my $nslash = ($key =~ tr!/!/!);
54 $ctx->{-upfx} = '../../../' . ('../' x $nslash);
56 PublicInbox::WwwStream->response($ctx, $code, sub {
58 $nr == 1 ? '<pre>'.$txt.'</pre>' : undef
63 my $l = PublicInbox::Linkify->new;
64 $_[0] = $l->linkify_2(ascii_html($l->linkify_1($_[0])));
67 sub _srch_prefix ($$) {
68 my ($srch, $txt) = @_;
71 my $help = $srch->help;
73 for ($i = 0; $i < @$help; $i += 2) {
74 my $pfx = $help->[$i];
76 $pad = $n if $n > $pad;
78 $htxt .= $help->[$i + 1];
82 my $padding = ' ' x ($pad + 8);
83 $htxt =~ s/^/$padding/gms;
84 $htxt =~ s/^$padding(\S+)\0/" $1".
85 (' ' x ($pad - length($1)))/egms;
86 $htxt =~ s/\f\n/\n/gs;
92 sub _default_text ($$$) {
93 my ($ctx, $key, $txt) = @_;
94 return if $key ne 'help'; # TODO more keys?
96 my $ibx = $ctx->{-inbox};
97 my $base_url = $ibx->base_url($ctx->{env});
98 $$txt .= "public-inbox help for $base_url\n";
104 public-inbox uses Message-ID identifiers in URLs.
105 One may look up messages by substituting Message-IDs
106 (without the leading '<' or trailing '>') into the URL.
107 Forward slash ('/') characters in the Message-IDs
108 need to be escaped as "%2F" (without quotes).
110 Thus, it is possible to retrieve any message by its
111 Message-ID by going to:
113 $base_url<Message-ID>/
115 (without the '<' or '>')
117 Message-IDs are described at:
123 # n.b. we use the Xapian DB for any regeneratable,
124 # order-of-arrival-independent data.
125 my $srch = $ibx->search;
131 This public-inbox has search functionality provided by Xapian.
133 It supports typical AND, OR, NOT, '+', '-' queries present
134 in other search engines.
136 We also support search prefixes to limit the scope of the
137 search to certain fields.
139 Prefixes supported in this installation include:
142 _srch_prefix($srch, $txt);
146 Most prefixes are probabilistic, meaning they support stemming
147 and wildcards ('*'). Ranges (such as 'd:') and boolean prefixes
148 do not support stemming or wildcards.
149 The upstream Xapian query parser documentation fully explains
157 Message threading is enabled for this public-inbox,
158 additional endpoints for message threads are available:
160 * $base_url<Message-ID>/T/#u
162 Loads the thread belonging to the given <Message-ID>
163 in flat chronological order. The "#u" anchor
164 focuses the browser on the given <Message-ID>.
166 * $base_url<Message-ID>/t/#u
168 Loads the thread belonging to the given <Message-ID>
169 in threaded order with nesting. For deep threads,
170 this requires a wide display or horizontal scrolling.
172 Both of these HTML endpoints are suitable for offline reading
173 using the thread overview at the bottom of each page.
175 Users of feed readers may follow a particular thread using:
177 * $base_url<Message-ID>/t.atom
179 Which loads the thread in Atom Syndication Standard
180 described at Wikipedia and RFC4287:
182 $WIKI_URL/Atom_(standard)
183 https://tools.ietf.org/html/rfc4287
185 Atom Threading Extensions (RFC4685) is supported:
187 https://tools.ietf.org/html/rfc4685
189 Finally, the gzipped mbox for a thread is available for
190 downloading and importing into your favorite mail client:
192 * $base_url<Message-ID>/t.mbox.gz
194 We use the mboxrd variant of the mbox format described
202 This help text is maintained by public-inbox developers
203 reachable via plain-text email at: meta\@public-inbox.org
206 # TODO: support admin contact info in ~/.public-inbox/config