* mdocml: Full support for ie/el.
@ 2010-05-17 2:01 kristaps
0 siblings, 0 replies; only message in thread
From: kristaps @ 2010-05-17 2:01 UTC (permalink / raw)
To: source
Log Message:
-----------
Full support for ie/el. This completes the initial roff support.
Added test files for ie/el.
Using `if 0' as a baseline for "false" roff instructions instead of `if t'.
Modified Files:
--------------
mdocml:
roff.7
roff.c
mdocml/regress/roff/if:
line-nest.in
multiline-free0.in
multiline-free1.in
multiline0.in
multiline1.in
multiline2.in
multiline3.in
simple0.in
simple1.in
simple2.in
mdocml/regress/roff/ig:
cond0.in
redef0.in
simple0.in
simple2.in
Added Files:
-----------
mdocml/regress/roff/ie:
simple0.in
simple1.in
simple2.in
with-el0.in
with-el1.in
with-el2.in
with-el3.in
with-el4.in
with-el5.in
Revision Data
-------------
--- /dev/null
+++ regress/roff/ie/simple1.in
@@ -0,0 +1,11 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \
+1
+fdsa
--- /dev/null
+++ regress/roff/ie/with-el0.in
@@ -0,0 +1,13 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \
+1
+.el \
+2
+fdsa
--- /dev/null
+++ regress/roff/ie/with-el1.in
@@ -0,0 +1,15 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+2
+.\}
+.el \
+3
+fdsa
--- /dev/null
+++ regress/roff/ie/with-el3.in
@@ -0,0 +1,23 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
--- /dev/null
+++ regress/roff/ie/simple0.in
@@ -0,0 +1,12 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.\}
+fdsa
--- /dev/null
+++ regress/roff/ie/simple2.in
@@ -0,0 +1,11 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0
+1
+fdsa
--- /dev/null
+++ regress/roff/ie/with-el2.in
@@ -0,0 +1,16 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
--- /dev/null
+++ regress/roff/ie/with-el4.in
@@ -0,0 +1,29 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
+.el \
+3
+fdsa
+.el \
+3
+fdsa
--- /dev/null
+++ regress/roff/ie/with-el5.in
@@ -0,0 +1,51 @@
+.Dd $Mdocdate: May 17 2010 $
+.Dt FOO 1
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+asdf
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+.ie 0 \{\
+1
+.de garglepants
+2
+.\}
+foobar
+.ie 0 \{\
+1
+.de actuallygarglepantsisadouche
+2
+.\}
+xyzzy
+.el \
+3
+fdsa
+.el \
+3
+fdsa
+.el \
+3
+fdsa
Index: simple1.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/simple1.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/simple1.in -Lregress/roff/if/simple1.in -u -p -r1.1 -r1.2
--- regress/roff/if/simple1.in
+++ regress/roff/if/simple1.in
@@ -7,5 +7,5 @@
.Sh DESCRIPTION
123
.\" Note this has no whitespace...
-.if t
+.if 0
asdf
Index: multiline-free1.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/multiline-free1.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/multiline-free1.in -Lregress/roff/if/multiline-free1.in -u -p -r1.1 -r1.2
--- regress/roff/if/multiline-free1.in
+++ regress/roff/if/multiline-free1.in
@@ -5,7 +5,7 @@
.Nm foo
.Nd bar
.Sh DESCRIPTION
-.if t \{\
+.if 0 \{\
there \\} dude
.\}
fdsa
Index: multiline-free0.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/multiline-free0.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/multiline-free0.in -Lregress/roff/if/multiline-free0.in -u -p -r1.1 -r1.2
--- regress/roff/if/multiline-free0.in
+++ regress/roff/if/multiline-free0.in
@@ -5,6 +5,6 @@
.Nm foo
.Nd bar
.Sh DESCRIPTION
-.if t \{\
+.if 0 \{\
there \} dude
fdsa
Index: line-nest.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/line-nest.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/line-nest.in -Lregress/roff/if/line-nest.in -u -p -r1.1 -r1.2
--- regress/roff/if/line-nest.in
+++ regress/roff/if/line-nest.in
@@ -6,6 +6,6 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t .if t \
+.if 0 .if 0 \
fdsa
asdf
Index: multiline3.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/multiline3.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/multiline3.in -Lregress/roff/if/multiline3.in -u -p -r1.1 -r1.2
--- regress/roff/if/multiline3.in
+++ regress/roff/if/multiline3.in
@@ -6,9 +6,9 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \{ .if t
+.if 0 \{ .if 0
asdf
-. if t \{\
+. if 0 \{\
shmoop moop
. \}
.\}
Index: multiline2.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/multiline2.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/multiline2.in -Lregress/roff/if/multiline2.in -u -p -r1.1 -r1.2
--- regress/roff/if/multiline2.in
+++ regress/roff/if/multiline2.in
@@ -6,9 +6,9 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \{\
+.if 0 \{\
asdf
-. if t \{\
+. if 0 \{\
shmoop moop
. \}
.\}
Index: multiline0.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/multiline0.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/multiline0.in -Lregress/roff/if/multiline0.in -u -p -r1.1 -r1.2
--- regress/roff/if/multiline0.in
+++ regress/roff/if/multiline0.in
@@ -6,7 +6,7 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \{\
+.if 0 \{\
asdf
.\}
fdsa
Index: multiline1.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/multiline1.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/multiline1.in -Lregress/roff/if/multiline1.in -u -p -r1.1 -r1.2
--- regress/roff/if/multiline1.in
+++ regress/roff/if/multiline1.in
@@ -6,7 +6,7 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \
+.if 0 \
\{\
asdf
.\}
Index: simple0.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/simple0.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/simple0.in -Lregress/roff/if/simple0.in -u -p -r1.1 -r1.2
--- regress/roff/if/simple0.in
+++ regress/roff/if/simple0.in
@@ -6,5 +6,5 @@
.Nd bar
.Sh DESCRIPTION
123
-.if t \
+.if 0 \
asdf
Index: simple2.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/if/simple2.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/if/simple2.in -Lregress/roff/if/simple2.in -u -p -r1.1 -r1.2
--- regress/roff/if/simple2.in
+++ regress/roff/if/simple2.in
@@ -7,5 +7,5 @@
.Sh DESCRIPTION
123
.\" Note that this has whitespace...
-.if t
+.if 0
asdf
Index: roff.7
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.7,v
retrieving revision 1.3
retrieving revision 1.4
diff -Lroff.7 -Lroff.7 -u -p -r1.3 -r1.4
--- roff.7
+++ roff.7
@@ -228,6 +228,11 @@ Historic groff did not accept white-spac
for the
.Sx \&ig
macro.
+.It
+The
+.Sx \&if
+and family would print funny white-spaces with historic groff when
+depending on next-line syntax.
.El
.Sh AUTHORS
The
Index: roff.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -Lroff.c -Lroff.c -u -p -r1.81 -r1.82
--- roff.c
+++ roff.c
@@ -26,6 +26,8 @@
#include "mandoc.h"
#include "roff.h"
+#define RSTACK_MAX 128
+
#define ROFF_CTL(c) \
('.' == (c) || '\'' == (c))
@@ -36,26 +38,26 @@ enum rofft {
ROFF_de,
ROFF_dei,
ROFF_de1,
+ ROFF_el,
+ ROFF_ie,
ROFF_if,
ROFF_ig,
ROFF_cblock,
ROFF_ccond,
-#if 0
- ROFF_ie,
- ROFF_el,
-#endif
ROFF_MAX
};
+enum roffrule {
+ ROFFRULE_ALLOW,
+ ROFFRULE_DENY
+};
+
struct roff {
struct roffnode *last; /* leaf of stack */
mandocmsg msg; /* err/warn/fatal messages */
void *data; /* privdata for messages */
-};
-
-enum roffrule {
- ROFFRULE_ALLOW,
- ROFFRULE_DENY
+ enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */
+ int rstackpos; /* position in rstack */
};
struct roffnode {
@@ -65,7 +67,7 @@ struct roffnode {
int col; /* parse col */
char *end; /* end-rules: custom token */
int endspan; /* end-rules: next-line or infty */
- enum roffrule rule;
+ enum roffrule rule; /* current evaluation rule */
};
#define ROFF_ARGS struct roff *r, /* parse ctx */ \
@@ -93,9 +95,9 @@ static enum rofferr roff_block_text(ROF
static enum rofferr roff_block_sub(ROFF_ARGS);
static enum rofferr roff_cblock(ROFF_ARGS);
static enum rofferr roff_ccond(ROFF_ARGS);
-static enum rofferr roff_if(ROFF_ARGS);
-static enum rofferr roff_if_text(ROFF_ARGS);
-static enum rofferr roff_if_sub(ROFF_ARGS);
+static enum rofferr roff_cond(ROFF_ARGS);
+static enum rofferr roff_cond_text(ROFF_ARGS);
+static enum rofferr roff_cond_sub(ROFF_ARGS);
const struct roffmac roffs[ROFF_MAX] = {
{ "am", roff_block, roff_block_text, roff_block_sub, 0 },
@@ -104,7 +106,9 @@ const struct roffmac roffs[ROFF_MAX] =
{ "de", roff_block, roff_block_text, roff_block_sub, 0 },
{ "dei", roff_block, roff_block_text, roff_block_sub, 0 },
{ "de1", roff_block, roff_block_text, roff_block_sub, 0 },
- { "if", roff_if, roff_if_text, roff_if_sub, ROFFMAC_STRUCT },
+ { "el", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT },
+ { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT },
+ { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT },
{ "ig", roff_block, roff_block_text, roff_block_sub, 0 },
{ ".", roff_cblock, NULL, NULL, 0 },
{ "\\}", roff_ccond, NULL, NULL, 0 },
@@ -149,6 +153,11 @@ roffnode_pop(struct roff *r)
assert(r->last);
p = r->last;
+
+ if (ROFF_el == p->tok)
+ if (r->rstackpos > -1)
+ r->rstackpos--;
+
r->last = r->last->parent;
if (p->end)
free(p->end);
@@ -219,6 +228,7 @@ roff_alloc(const mandocmsg msg, void *da
r->msg = msg;
r->data = data;
+ r->rstackpos = -1;
return(r);
}
@@ -306,7 +316,7 @@ roff_parse(const char *buf, int *pos)
for (j = 0; j < 4; j++, (*pos)++)
if ('\0' == (mac[j] = buf[*pos]))
break;
- else if (' ' == buf[*pos])
+ else if (' ' == buf[*pos] || (j && '\\' == buf[*pos]))
break;
if (j == 4 || j < 1)
@@ -395,7 +405,14 @@ roff_ccond(ROFF_ARGS)
return(ROFF_IGN);
}
- if (ROFF_if != r->last->tok) {
+ switch (r->last->tok) {
+ case (ROFF_el):
+ /* FALLTHROUGH */
+ case (ROFF_ie):
+ /* FALLTHROUGH */
+ case (ROFF_if):
+ break;
+ default:
if ( ! (*r->msg)(MANDOCERR_NOSCOPE, r->data, ln, ppos, NULL))
return(ROFF_ERR);
return(ROFF_IGN);
@@ -478,36 +495,6 @@ roff_block(ROFF_ARGS)
/* ARGSUSED */
static enum rofferr
-roff_if_sub(ROFF_ARGS)
-{
- enum rofft t;
- enum roffrule rr;
-
- ppos = pos;
- rr = r->last->rule;
- roffnode_cleanscope(r);
-
- if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
- return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
-
- /*
- * A denied conditional must evaluate its children if and only
- * if they're either structurally required (such as loops and
- * conditionals) or a closing macro.
- */
- if (ROFFRULE_DENY == rr)
- if ( ! (ROFFMAC_STRUCT & roffs[t].flags))
- if (ROFF_ccond != t)
- return(ROFF_IGN);
-
- assert(roffs[t].proc);
- return((*roffs[t].proc)
- (r, t, bufp, szp, ln, ppos, pos, offs));
-}
-
-
-/* ARGSUSED */
-static enum rofferr
roff_block_sub(ROFF_ARGS)
{
enum rofft t;
@@ -573,39 +560,86 @@ roff_block_text(ROFF_ARGS)
/* ARGSUSED */
static enum rofferr
-roff_if_text(ROFF_ARGS)
+roff_cond_sub(ROFF_ARGS)
+{
+ enum rofft t;
+ enum roffrule rr;
+
+ ppos = pos;
+ rr = r->last->rule;
+
+ roffnode_cleanscope(r);
+
+ if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
+
+ /*
+ * A denied conditional must evaluate its children if and only
+ * if they're either structurally required (such as loops and
+ * conditionals) or a closing macro.
+ */
+ if (ROFFRULE_DENY == rr)
+ if ( ! (ROFFMAC_STRUCT & roffs[t].flags))
+ if (ROFF_ccond != t)
+ return(ROFF_IGN);
+
+ assert(roffs[t].proc);
+ return((*roffs[t].proc)
+ (r, t, bufp, szp, ln, ppos, pos, offs));
+}
+
+
+/* ARGSUSED */
+static enum rofferr
+roff_cond_text(ROFF_ARGS)
{
char *ep, *st;
+ enum roffrule rr;
+
+ rr = r->last->rule;
+
+ /*
+ * We display the value of the text if out current evaluation
+ * scope permits us to do so.
+ */
st = &(*bufp)[pos];
if (NULL == (ep = strstr(st, "\\}"))) {
roffnode_cleanscope(r);
- return(ROFF_IGN);
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
}
if (ep > st && '\\' != *(ep - 1))
roffnode_pop(r);
roffnode_cleanscope(r);
- return(ROFF_IGN);
+ return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
}
/* ARGSUSED */
static enum rofferr
-roff_if(ROFF_ARGS)
+roff_cond(ROFF_ARGS)
{
int sv;
- /*
- * Read ahead past the conditional.
- * FIXME: this does not work, as conditionals don't end on
- * whitespace, but are parsed according to a formal grammar.
- * It's good enough for now, however.
- */
+ /* Stack overflow! */
- while ((*bufp)[pos] && ' ' != (*bufp)[pos])
- pos++;
+ if (ROFF_ie == tok && r->rstackpos == RSTACK_MAX - 1) {
+ (*r->msg)(MANDOCERR_MEM, r->data, ln, ppos, NULL);
+ return(ROFF_ERR);
+ }
+
+ if (ROFF_if == tok || ROFF_ie == tok) {
+ /*
+ * Read ahead past the conditional. FIXME: this does
+ * not work, as conditionals don't end on whitespace,
+ * but are parsed according to a formal grammar. It's
+ * good enough for now, however.
+ */
+ while ((*bufp)[pos] && ' ' != (*bufp)[pos])
+ pos++;
+ }
sv = pos;
while (' ' == (*bufp)[pos])
@@ -617,7 +651,6 @@ roff_if(ROFF_ARGS)
* really doing anything. Warn about this. It's probably
* wrong.
*/
-
if ('\0' == (*bufp)[pos] && sv != pos) {
if ( ! (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL))
return(ROFF_ERR);
@@ -627,7 +660,28 @@ roff_if(ROFF_ARGS)
if ( ! roffnode_push(r, tok, ln, ppos))
return(ROFF_ERR);
- /* Don't evaluate: just assume NO. */
+ /* TODO: here we would evaluate the conditional. */
+
+ if (ROFF_el == tok) {
+ /*
+ * An `.el' will get the value of the current rstack
+ * entry set in prior `ie' calls or defaults to DENY.
+ */
+ if (r->rstackpos < 0)
+ r->last->rule = ROFFRULE_DENY;
+ else
+ r->last->rule = r->rstack[r->rstackpos];
+ } else if (ROFF_ie == tok) {
+ /*
+ * An if-else will put the NEGATION of the current
+ * evaluated conditional into the stack.
+ */
+ r->rstackpos++;
+ if (ROFFRULE_DENY == r->last->rule)
+ r->rstack[r->rstackpos] = ROFFRULE_ALLOW;
+ else
+ r->rstack[r->rstackpos] = ROFFRULE_DENY;
+ }
r->last->endspan = 1;
Index: redef0.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/ig/redef0.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/ig/redef0.in -Lregress/roff/ig/redef0.in -u -p -r1.1 -r1.2
--- regress/roff/ig/redef0.in
+++ regress/roff/ig/redef0.in
@@ -8,6 +8,6 @@
a
.ig if
asdf
-.if t \
+.if 0 \
b
c
Index: cond0.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/ig/cond0.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/ig/cond0.in -Lregress/roff/ig/cond0.in -u -p -r1.1 -r1.2
--- regress/roff/ig/cond0.in
+++ regress/roff/ig/cond0.in
@@ -10,7 +10,7 @@
.Nd bar
.Sh DESCRIPTION
garglebats!
-.if t \
+.if 0 \
.ig .
foo
..
Index: simple0.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/ig/simple0.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/ig/simple0.in -Lregress/roff/ig/simple0.in -u -p -r1.1 -r1.2
--- regress/roff/ig/simple0.in
+++ regress/roff/ig/simple0.in
@@ -8,5 +8,5 @@
123
.ig
hello
-..
+.0
12124
Index: simple2.in
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/regress/roff/ig/simple2.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/roff/ig/simple2.in -Lregress/roff/ig/simple2.in -u -p -r1.1 -r1.2
--- regress/roff/ig/simple2.in
+++ regress/roff/ig/simple2.in
@@ -8,7 +8,7 @@
123
.ig
hello
-.if t \{\
+.if 0 \{\
hello
.\}
..
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-05-17 2:01 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-17 2:01 mdocml: Full support for ie/el kristaps
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).