summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/mandoc/chars.c16
-rw-r--r--usr.bin/mandoc/chars.in3
-rw-r--r--usr.bin/mandoc/html.c132
-rw-r--r--usr.bin/mandoc/html.h12
-rw-r--r--usr.bin/mandoc/main.c11
-rw-r--r--usr.bin/mandoc/main.h3
-rw-r--r--usr.bin/mandoc/man.342
-rw-r--r--usr.bin/mandoc/man.724
-rw-r--r--usr.bin/mandoc/man.c39
-rw-r--r--usr.bin/mandoc/man_html.c4
-rw-r--r--usr.bin/mandoc/mandoc.153
-rw-r--r--usr.bin/mandoc/mandoc.c4
-rw-r--r--usr.bin/mandoc/mdoc.340
-rw-r--r--usr.bin/mandoc/mdoc.7106
-rw-r--r--usr.bin/mandoc/mdoc.c37
-rw-r--r--usr.bin/mandoc/mdoc_html.c11
-rw-r--r--usr.bin/mandoc/mdoc_macro.c50
-rw-r--r--usr.bin/mandoc/mdoc_term.c22
-rw-r--r--usr.bin/mandoc/mdoc_validate.c36
19 files changed, 477 insertions, 168 deletions
diff --git a/usr.bin/mandoc/chars.c b/usr.bin/mandoc/chars.c
index 7bd8bacf95c..edeec1abb30 100644
--- a/usr.bin/mandoc/chars.c
+++ b/usr.bin/mandoc/chars.c
@@ -1,4 +1,4 @@
-/* $Id: chars.c,v 1.4 2009/12/24 02:08:14 schwarze Exp $ */
+/* $Id: chars.c,v 1.5 2010/02/18 02:11:25 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -38,7 +38,7 @@ struct ln {
#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
};
-#define LINES_MAX 351
+#define LINES_MAX 350
#define CHAR(w, x, y, z, a, b) \
{ NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR },
@@ -162,18 +162,6 @@ find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
if (NULL == (pp = htab[hash]))
return(NULL);
- if (NULL == pp->next) {
- if ( ! match(pp, p, sz, type))
- return(NULL);
-
- if (CHARS_HTML == tab->type) {
- *rsz = pp->htmlsz;
- return(pp->html);
- }
- *rsz = pp->asciisz;
- return(pp->ascii);
- }
-
for (prev = NULL; pp; pp = pp->next) {
if ( ! match(pp, p, sz, type)) {
prev = pp;
diff --git a/usr.bin/mandoc/chars.in b/usr.bin/mandoc/chars.in
index 083c83ca41f..5129c8e43d3 100644
--- a/usr.bin/mandoc/chars.in
+++ b/usr.bin/mandoc/chars.in
@@ -1,4 +1,4 @@
-/* $Id: chars.in,v 1.3 2009/12/24 02:08:14 schwarze Exp $ */
+/* $Id: chars.in,v 1.4 2010/02/18 02:11:25 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -412,7 +412,6 @@ CHAR("r?", 2, "c", 1, "&#191;", 6)
CHAR("em", 2, "--", 2, "&#8212;", 7)
CHAR("en", 2, "-", 1, "&#8211;", 7)
CHAR("hy", 2, "-", 1, "&#8208;", 7)
-CHAR("\\", 1, "\\", 1, "\\", 1)
CHAR("e", 1, "\\", 1, "\\", 1)
/* Units. */
diff --git a/usr.bin/mandoc/html.c b/usr.bin/mandoc/html.c
index 262bb98dc84..c9429eb93fe 100644
--- a/usr.bin/mandoc/html.c
+++ b/usr.bin/mandoc/html.c
@@ -1,4 +1,4 @@
-/* $Id: html.c,v 1.5 2009/12/24 02:08:14 schwarze Exp $ */
+/* $Id: html.c,v 1.6 2010/02/18 02:11:25 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -32,38 +32,34 @@
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
-#define DOCTYPE "-//W3C//DTD HTML 4.01//EN"
-#define DTD "http://www.w3.org/TR/html4/strict.dtd"
-
struct htmldata {
const char *name;
int flags;
#define HTML_CLRLINE (1 << 0)
#define HTML_NOSTACK (1 << 1)
+#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */
};
static const struct htmldata htmltags[TAG_MAX] = {
{"html", HTML_CLRLINE}, /* TAG_HTML */
{"head", HTML_CLRLINE}, /* TAG_HEAD */
{"body", HTML_CLRLINE}, /* TAG_BODY */
- {"meta", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_META */
+ {"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */
{"title", HTML_CLRLINE}, /* TAG_TITLE */
{"div", HTML_CLRLINE}, /* TAG_DIV */
{"h1", 0}, /* TAG_H1 */
{"h2", 0}, /* TAG_H2 */
- {"p", HTML_CLRLINE}, /* TAG_P */
{"span", 0}, /* TAG_SPAN */
{"link", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
- {"br", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
+ {"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */
{"a", 0}, /* TAG_A */
{"table", HTML_CLRLINE}, /* TAG_TABLE */
- {"col", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_COL */
+ {"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */
{"tr", HTML_CLRLINE}, /* TAG_TR */
{"td", HTML_CLRLINE}, /* TAG_TD */
{"li", HTML_CLRLINE}, /* TAG_LI */
{"ul", HTML_CLRLINE}, /* TAG_UL */
{"ol", HTML_CLRLINE}, /* TAG_OL */
- {"base", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_BASE */
};
static const char *const htmlfonts[HTMLFONT_MAX] = {
@@ -93,12 +89,17 @@ static const char *const htmlattrs[ATTR_MAX] = {
static void print_spec(struct html *, const char *, size_t);
static void print_res(struct html *, const char *, size_t);
static void print_ctag(struct html *, enum htmltag);
+static void print_doctype(struct html *);
+static void print_xmltype(struct html *);
static int print_encode(struct html *, const char *, int);
static void print_metaf(struct html *, enum roffdeco);
+static void print_attr(struct html *,
+ const char *, const char *);
+static void *ml_alloc(char *, enum htmltype);
-void *
-html_alloc(char *outopts)
+static void *
+ml_alloc(char *outopts, enum htmltype type)
{
struct html *h;
const char *toks[4];
@@ -115,6 +116,7 @@ html_alloc(char *outopts)
exit(EXIT_FAILURE);
}
+ h->type = type;
h->tags.head = NULL;
h->ords.head = NULL;
h->symtab = chars_init(CHARS_HTML);
@@ -137,6 +139,21 @@ html_alloc(char *outopts)
return(h);
}
+void *
+html_alloc(char *outopts)
+{
+
+ return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
+}
+
+
+void *
+xhtml_alloc(char *outopts)
+{
+
+ return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
+}
+
void
html_free(void *p)
@@ -333,6 +350,15 @@ print_encode(struct html *h, const char *p, int norecurse)
}
+static void
+print_attr(struct html *h, const char *key, const char *val)
+{
+ printf(" %s=\"", key);
+ (void)print_encode(h, val, 1);
+ putchar('\"');
+}
+
+
struct tag *
print_otag(struct html *h, enum htmltag tag,
int sz, const struct htmlpair *p)
@@ -340,6 +366,8 @@ print_otag(struct html *h, enum htmltag tag,
int i;
struct tag *t;
+ /* Push this tags onto the stack of open scopes. */
+
if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
t = malloc(sizeof(struct tag));
if (NULL == t) {
@@ -356,13 +384,31 @@ print_otag(struct html *h, enum htmltag tag,
if ( ! (HTML_CLRLINE & htmltags[tag].flags))
putchar(' ');
+ /* Print out the tag name and attributes. */
+
printf("<%s", htmltags[tag].name);
- for (i = 0; i < sz; i++) {
- printf(" %s=\"", htmlattrs[p[i].key]);
- assert(p->val);
- (void)print_encode(h, p[i].val, 1);
- putchar('\"');
+ for (i = 0; i < sz; i++)
+ print_attr(h, htmlattrs[p[i].key], p[i].val);
+
+ /* Add non-overridable attributes. */
+
+ if (TAG_HTML == tag && HTML_XHTML_1_0_STRICT == h->type) {
+ print_attr(h, "xmlns", "http://www.w3.org/1999/xhtml");
+ print_attr(h, "xml:lang", "en");
+ print_attr(h, "lang", "en");
}
+
+ /* Accomodate for XML "well-formed" singleton escaping. */
+
+ if (HTML_AUTOCLOSE & htmltags[tag].flags)
+ switch (h->type) {
+ case (HTML_XHTML_1_0_STRICT):
+ putchar('/');
+ break;
+ default:
+ break;
+ }
+
putchar('>');
h->flags |= HTML_NOSPACE;
@@ -382,12 +428,58 @@ print_ctag(struct html *h, enum htmltag tag)
}
-/* ARGSUSED */
void
-print_gen_doctype(struct html *h)
+print_gen_decls(struct html *h)
{
-
- printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">", DOCTYPE, DTD);
+
+ print_xmltype(h);
+ print_doctype(h);
+}
+
+
+static void
+print_xmltype(struct html *h)
+{
+ const char *decl;
+
+ switch (h->type) {
+ case (HTML_XHTML_1_0_STRICT):
+ decl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ break;
+ default:
+ decl = NULL;
+ break;
+ }
+
+ if (NULL == decl)
+ return;
+
+ printf("%s\n", decl);
+}
+
+
+static void
+print_doctype(struct html *h)
+{
+ const char *doctype;
+ const char *dtd;
+ const char *name;
+
+ switch (h->type) {
+ case (HTML_HTML_4_01_STRICT):
+ name = "HTML";
+ doctype = "-//W3C//DTD HTML 4.01//EN";
+ dtd = "http://www.w3.org/TR/html4/strict.dtd";
+ break;
+ default:
+ name = "html";
+ doctype = "-//W3C//DTD XHTML 1.0 Strict//EN";
+ dtd = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
+ break;
+ }
+
+ printf("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n",
+ name, doctype, dtd);
}
diff --git a/usr.bin/mandoc/html.h b/usr.bin/mandoc/html.h
index a428248265e..2ac9402ef75 100644
--- a/usr.bin/mandoc/html.h
+++ b/usr.bin/mandoc/html.h
@@ -1,4 +1,4 @@
-/* $Id: html.h,v 1.4 2009/12/24 02:08:14 schwarze Exp $ */
+/* $Id: html.h,v 1.5 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -28,7 +28,6 @@ enum htmltag {
TAG_DIV,
TAG_H1,
TAG_H2,
- TAG_P,
TAG_SPAN,
TAG_LINK,
TAG_BR,
@@ -40,7 +39,6 @@ enum htmltag {
TAG_LI,
TAG_UL,
TAG_OL,
- TAG_BASE,
TAG_MAX
};
@@ -105,6 +103,11 @@ struct htmlpair {
do { (p)->key = ATTR_SUMMARY; \
(p)->val = (v); } while (/* CONSTCOND */ 0)
+enum htmltype {
+ HTML_HTML_4_01_STRICT,
+ HTML_XHTML_1_0_STRICT
+};
+
struct html {
int flags;
#define HTML_NOSPACE (1 << 0)
@@ -121,11 +124,12 @@ struct html {
struct tag *metaf;
enum htmlfont metal;
enum htmlfont metac;
+ enum htmltype type;
};
struct roffsu;
-void print_gen_doctype(struct html *);
+void print_gen_decls(struct html *);
void print_gen_head(struct html *);
struct tag *print_ofont(struct html *, enum htmlfont);
struct tag *print_otag(struct html *, enum htmltag,
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c
index f0f591d8e9d..5688ec04728 100644
--- a/usr.bin/mandoc/main.c
+++ b/usr.bin/mandoc/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.20 2009/12/23 22:30:17 schwarze Exp $ */
+/* $Id: main.c,v 1.21 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -49,6 +49,7 @@ enum outt {
OUTT_ASCII = 0,
OUTT_TREE,
OUTT_HTML,
+ OUTT_XHTML,
OUTT_LINT
};
@@ -416,6 +417,12 @@ fdesc(struct buf *blk, struct buf *ln, struct curparse *curp)
if ( ! (curp->outman && curp->outmdoc)) {
switch (curp->outtype) {
+ case (OUTT_XHTML):
+ curp->outdata = xhtml_alloc(curp->outopts);
+ curp->outman = html_man;
+ curp->outmdoc = html_mdoc;
+ curp->outfree = html_free;
+ break;
case (OUTT_HTML):
curp->outdata = html_alloc(curp->outopts);
curp->outman = html_man;
@@ -538,6 +545,8 @@ toptions(enum outt *tflags, char *arg)
*tflags = OUTT_TREE;
else if (0 == strcmp(arg, "html"))
*tflags = OUTT_HTML;
+ else if (0 == strcmp(arg, "xhtml"))
+ *tflags = OUTT_XHTML;
else {
fprintf(stderr, "%s: Bad argument\n", arg);
return(0);
diff --git a/usr.bin/mandoc/main.h b/usr.bin/mandoc/main.h
index 667e4fa9a3f..f29c8d57dc2 100644
--- a/usr.bin/mandoc/main.h
+++ b/usr.bin/mandoc/main.h
@@ -1,4 +1,4 @@
-/* $Id: main.h,v 1.1 2009/10/21 19:13:50 schwarze Exp $ */
+/* $Id: main.h,v 1.2 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -30,6 +30,7 @@ struct man;
*/
void *html_alloc(char *);
+void *xhtml_alloc(char *);
void html_mdoc(void *, const struct mdoc *);
void html_man(void *, const struct man *);
void html_free(void *);
diff --git a/usr.bin/mandoc/man.3 b/usr.bin/mandoc/man.3
index 79334e82966..2630278fad4 100644
--- a/usr.bin/mandoc/man.3
+++ b/usr.bin/mandoc/man.3
@@ -1,6 +1,6 @@
-.\" $Id: man.3,v 1.6 2009/10/20 10:15:04 schwarze Exp $
+.\" $Id: man.3,v 1.7 2010/02/18 02:11:26 schwarze Exp $
.\"
-.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 20 2009 $
+.Dd $Mdocdate: February 18 2010 $
.Dt MAN 3
.Os
.\" SECTION
@@ -91,7 +91,7 @@ Both functions (see
and variables (see
.Sx Variables )
may use the following types:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Vt struct man
An opaque type defined in
@@ -112,7 +112,7 @@ for details.
.\" SUBSECTION
.Ss Functions
Function descriptions follow:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Fn man_alloc
Allocates a parsing structure. The
@@ -166,7 +166,7 @@ return 0, the data will be incomplete.
.\" SUBSECTION
.Ss Variables
The following variables are also defined:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Va man_macronames
An array of string-ified token names.
@@ -215,7 +215,7 @@ fields) and some type-specific data.
The tree itself is arranged according to the following normal form,
where capitalised non-terminals represent nodes.
.Pp
-.Bl -tag -width "ELEMENTXX" -compact -offset "XXXX"
+.Bl -tag -width "ELEMENTXX" -compact
.\" LIST-ITEM
.It ROOT
\(<- mnode+
@@ -242,11 +242,8 @@ next-lint scope as documented in
The following example reads lines from stdin and parses them, operating
on the finished parse tree with
.Fn parsed .
-Note that, if the last line of the file isn't newline-terminated, this
-will truncate the file's last character (see
-.Xr fgetln 3 ) .
-Further, this example does not error-check nor free memory upon failure.
-.Bd -literal -offset "XXXX"
+This example does not error-check nor free memory upon failure.
+.Bd -literal -offset indent
struct man *man;
struct man_node *node;
char *buf;
@@ -255,18 +252,23 @@ int line;
line = 1;
man = man_alloc(NULL, 0, NULL);
+buf = NULL;
+alloc_len = 0;
-while ((buf = fgetln(fp, &len))) {
- buf[len - 1] = '\\0';
- if ( ! man_parseln(man, line, buf))
- errx(1, "man_parseln");
- line++;
+while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
+ if (len && buflen[len - 1] = '\en')
+ buf[len - 1] = '\e0';
+ if ( ! man_parseln(man, line, buf))
+ errx(1, "man_parseln");
+ line++;
}
+free(buf);
+
if ( ! man_endparse(man))
- errx(1, "man_endparse");
+ errx(1, "man_endparse");
if (NULL == (node = man_node(man)))
- errx(1, "man_node");
+ errx(1, "man_node");
parsed(man, node);
man_free(man);
@@ -280,4 +282,4 @@ man_free(man);
The
.Nm
utility was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
+.An Kristaps Dzonsons Aq kristaps@bsd.lv .
diff --git a/usr.bin/mandoc/man.7 b/usr.bin/mandoc/man.7
index 68ecffdd4ce..f68a0b6f2b3 100644
--- a/usr.bin/mandoc/man.7
+++ b/usr.bin/mandoc/man.7
@@ -1,4 +1,4 @@
-.\" $Id: man.7,v 1.15 2009/12/24 02:08:14 schwarze Exp $
+.\" $Id: man.7,v 1.16 2010/02/18 02:11:26 schwarze Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: December 24 2009 $
+.Dd $Mdocdate: February 18 2010 $
.Dt MAN 7
.Os
.
@@ -102,7 +102,7 @@ and
Terms may be text-decorated using the
.Sq \ef
escape followed by an indicator: B (bold), I, (italic), R (Roman), or P
-(revert to previous mode):
+(revert to previous mode):
.Pp
.D1 \efBbold\efR \efIitalic\efP
.Pp
@@ -295,7 +295,7 @@ the C library, this may be as follows:
.D1 Standard C Library (libc, -lc)
.It Em SYNOPSIS
Documents the utility invocation syntax, function call syntax, or device
-configuration.
+configuration.
.Pp
For the first, utilities (sections 1, 6, and 8), this is
generally structured as follows:
@@ -310,10 +310,10 @@ And for the third, configurations (section 4):
.Pp
.D1 \&.B name* at cardbus ? function ?
.Pp
-Manuals not in these sections generally don't need a
+Manuals not in these sections generally don't need a
.Em SYNOPSIS .
.It Em DESCRIPTION
-This expands upon the brief, one-line description in
+This expands upon the brief, one-line description in
.Em NAME .
It usually contains a break-down of the options (if documenting a
command).
@@ -361,7 +361,7 @@ Documents error handling in sections 2, 3, and 9.
.
.It Em SEE ALSO
References other manuals with related topics. This section should exist
-for most manuals.
+for most manuals.
.Pp
.D1 \&.BR bar \&( 1 \&),
.Pp
@@ -504,7 +504,7 @@ sub-section, closed by a section or
.Sx \&SS ;
part, closed by a section, sub-section, or
.Sx \&RE ;
-or paragraph, closed by a section, sub-section, part,
+or paragraph, closed by a section, sub-section, part,
.Sx \&HP ,
.Sx \&IP ,
.Sx \&LP ,
@@ -563,13 +563,13 @@ and
.
.
.Ss \&BI
-Text is rendered alternately in bold face and italic. Thus,
+Text is rendered alternately in bold face and italic. Thus,
.Sq .BI this word and that
causes
.Sq this
and
.Sq and
-to render in bold face, while
+to render in bold face, while
.Sq word
and
.Sq that
@@ -819,7 +819,7 @@ The
.Cm width
argument must conform to
.Sx Scaling Widths .
-If not specified, the saved or default width is used.
+If not specified, the saved or default width is used.
.
.
.Ss \&SB
@@ -960,7 +960,7 @@ Insert vertical spaces into output with the following syntax:
.Op Cm height
.Ed
.Pp
-Insert
+Insert
.Cm height
spaces, which must conform to
.Sx Scaling Widths .
diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c
index ebbf4ccdb35..d9a88f7b648 100644
--- a/usr.bin/mandoc/man.c
+++ b/usr.bin/mandoc/man.c
@@ -1,4 +1,4 @@
-/* $Id: man.c,v 1.17 2009/12/23 22:30:17 schwarze Exp $ */
+/* $Id: man.c,v 1.18 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -361,6 +361,7 @@ static int
man_ptext(struct man *m, int line, char *buf)
{
int i, j;
+ char sv;
/* Literal free-form text whitespace is preserved. */
@@ -374,7 +375,12 @@ man_ptext(struct man *m, int line, char *buf)
for (i = 0; ' ' == buf[i]; i++)
/* Skip leading whitespace. */ ;
- if (0 == buf[i]) {
+
+ if ('\0' == buf[i]) {
+ /* Trailing whitespace? */
+ if (i && ' ' == buf[i - 1])
+ if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+ return(0);
if ( ! pstring(m, line, 0, &buf[i], 0))
return(0);
goto descope;
@@ -388,15 +394,30 @@ man_ptext(struct man *m, int line, char *buf)
if (i && ' ' == buf[i] && '\\' == buf[i - 1])
continue;
- buf[i++] = 0;
+ sv = buf[i];
+ buf[i++] = '\0';
+
if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j)))
return(0);
+ /* Trailing whitespace? Check at overwritten byte. */
+
+ if (' ' == sv && '\0' == buf[i])
+ if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+ return(0);
+
for ( ; ' ' == buf[i]; i++)
/* Skip trailing whitespace. */ ;
j = i;
- if (0 == buf[i])
+
+ /* Trailing whitespace? */
+
+ if (' ' == buf[i - 1] && '\0' == buf[i])
+ if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+ return(0);
+
+ if ('\0' == buf[i])
break;
}
@@ -459,7 +480,7 @@ man_pmacro(struct man *m, int ln, char *buf)
i++;
while (buf[i] && ' ' == buf[i])
i++;
- if (0 == buf[i])
+ if ('\0' == buf[i])
goto out;
}
@@ -468,7 +489,7 @@ man_pmacro(struct man *m, int ln, char *buf)
/* Copy the first word into a nil-terminated buffer. */
for (j = 0; j < 4; j++, i++) {
- if (0 == (mac[j] = buf[i]))
+ if ('\0' == (mac[j] = buf[i]))
break;
else if (' ' == buf[i])
break;
@@ -503,6 +524,12 @@ man_pmacro(struct man *m, int ln, char *buf)
while (buf[i] && ' ' == buf[i])
i++;
+ /* Trailing whitespace? */
+
+ if ('\0' == buf[i] && ' ' == buf[i - 1])
+ if ( ! man_pwarn(m, ln, i - 1, WTSPACE))
+ goto err;
+
/* Remove prior ELINE macro, if applicable. */
if (m->flags & MAN_ELINE) {
diff --git a/usr.bin/mandoc/man_html.c b/usr.bin/mandoc/man_html.c
index 25163cce39c..0a4050f79a4 100644
--- a/usr.bin/mandoc/man_html.c
+++ b/usr.bin/mandoc/man_html.c
@@ -1,4 +1,4 @@
-/* $Id: man_html.c,v 1.4 2009/12/24 02:08:14 schwarze Exp $ */
+/* $Id: man_html.c,v 1.5 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -110,7 +110,7 @@ html_man(void *arg, const struct man *m)
h = (struct html *)arg;
- print_gen_doctype(h);
+ print_gen_decls(h);
t = print_otag(h, TAG_HTML, 0, NULL);
print_man(man_meta(m), man_node(m), h);
diff --git a/usr.bin/mandoc/mandoc.1 b/usr.bin/mandoc/mandoc.1
index 44ea8e50e8c..7dbf90bbb92 100644
--- a/usr.bin/mandoc/mandoc.1
+++ b/usr.bin/mandoc/mandoc.1
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.1,v 1.20 2009/12/24 02:08:14 schwarze Exp $
+.\" $Id: mandoc.1,v 1.21 2010/02/18 02:11:26 schwarze Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: December 24 2009 $
+.Dd $Mdocdate: February 18 2010 $
.Dt MANDOC 1
.Os
.
@@ -167,6 +167,10 @@ styles. This is the default. See
Produce strict HTML-4.01 output, with a sane default style. See
.Sx HTML Output .
.
+.It Fl T Ns Ar xhtml
+Produce strict XHTML-1.0 output, with a sane default style. See
+.Sx XHTML Output .
+.
.It Fl T Ns Ar tree
Produce an indented parse tree.
.
@@ -231,7 +235,7 @@ relative URI.
.It Fl O Ns Ar includes=fmt
The string
.Ar fmt ,
-for example,
+for example,
.Ar ../src/%I.html ,
is used as a template for linked header files (usually via the
.Sq \&In
@@ -242,7 +246,7 @@ hyperlink.
.It Fl O Ns Ar man=fmt
The string
.Ar fmt ,
-for example,
+for example,
.Ar ../html%S/%N.%S.html ,
is used as a template for linked manuals (usually via the
.Sq \&Xr
@@ -260,7 +264,7 @@ present a hyperlink.
This section documents output details of
.Nm .
In general, output conforms to the traditional manual style of a header,
-a body composed of sections and sub-sections, and a footer.
+a body composed of sections and sub-sections, and a footer.
.Pp
The text style of output characters (non-macro characters, punctuation,
and white-space) is dictated by context.
@@ -307,7 +311,7 @@ however, these rules are also applied to macro arguments when appropriate.
.
.
.Ss ASCII Output
-Output produced by
+Output produced by
.Fl T Ns Ar ascii ,
which is the default, is rendered in standard 7-bit ASCII documented in
.Xr ascii 7 .
@@ -333,7 +337,7 @@ exceed this limit.
.Ss HTML Output
Output produced by
.Fl T Ns Ar html
-comforms to HTML-4.01 strict.
+conforms to HTML-4.01 strict.
.Pp
Font styles and page structure are applied using CSS2. By default, no
font style is applied to any text, although CSS2 is hard-coded to format
@@ -348,6 +352,17 @@ cause rendered documents to appear as they do in
Special characters are rendered in decimal-encoded UTF-8.
.
.
+.Ss XHTML Output
+Output produced by
+.Fl T Ns Ar xhtml
+conforms to XHTML-1.0 strict.
+.Pp
+See
+.Sx HTML Output
+for details; beyond generating XHTML tags instead of HTML tags, these
+output modes are identical.
+.
+.
.Sh EXAMPLES
To page manuals to the terminal:
.
@@ -379,15 +394,15 @@ Each input and output format is separately noted.
.Ss ASCII Compatibility
.Bl -bullet -compact
.It
-The
+The
.Sq \e~
-special character doesn't produce expected behaviour in
+special character doesn't produce expected behaviour in
.Fl T Ns Ar ascii .
.
.It
-The
+The
.Sq \&Bd \-literal
-and
+and
.Sq \&Bd \-unfilled
macros of
.Xr mdoc 7
@@ -396,7 +411,7 @@ in
are synonyms, as are \-filled and \-ragged.
.
.It
-In
+In
.Xr groff 1 ,
the
.Sq \&Pa
@@ -437,7 +452,7 @@ Sentences are unilaterally monospaced.
.El
.
.
-.Ss HTML Compatibility
+.Ss HTML/XHTML Compatibility
.Bl -bullet -compact
.It
The
@@ -446,7 +461,7 @@ escape will revert the font to the previous
.Sq \ef
escape, not to the last rendered decoration, which is now dictated by
CSS instead of hard-coded. It also will not span past the current
-scope, for the same reason. Note that in
+scope, for the same reason. Note that in
.Sx ASCII Output
mode, this will work fine.
.It
@@ -483,13 +498,17 @@ utility was written by
.Sh CAVEATS
The
.Fl T Ns Ar html
+and
+.Fl T Ns Ar xhtml
CSS2 styling used for
.Fl m Ns Ar doc
input lists does not render properly in brain-dead browsers, such as
Internet Explorer 6 and earlier.
.Pp
In
-.Fl T Ns Ar html ,
+.Fl T Ns Ar html
+and
+.Fl T Ns Ar xhtml ,
the maximum size of an element attribute is determined by
.Dv BUFSIZ ,
which is usually 1024 bytes. Be aware of this when setting long link
@@ -498,7 +517,9 @@ formats, e.g.,
.Pp
The
.Fl T Ns Ar html
-output mode doesn't render the
+and
+.Fl T Ns Ar xhtml
+output modes don't render the
.Sq \es
font size escape documented in
.Xr mdoc 7
diff --git a/usr.bin/mandoc/mandoc.c b/usr.bin/mandoc/mandoc.c
index 06c73fc0662..85c16657383 100644
--- a/usr.bin/mandoc/mandoc.c
+++ b/usr.bin/mandoc/mandoc.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc.c,v 1.6 2009/12/24 02:08:14 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.7 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -39,8 +39,6 @@ mandoc_special(const char *p)
return(0);
switch (*p) {
- case ('\\'):
- /* FALLTHROUGH */
case ('\''):
/* FALLTHROUGH */
case ('`'):
diff --git a/usr.bin/mandoc/mdoc.3 b/usr.bin/mandoc/mdoc.3
index 156cbe841f0..de36d9519ea 100644
--- a/usr.bin/mandoc/mdoc.3
+++ b/usr.bin/mandoc/mdoc.3
@@ -1,6 +1,6 @@
-.\" $Id: mdoc.3,v 1.5 2009/10/20 10:15:04 schwarze Exp $
+.\" $Id: mdoc.3,v 1.6 2010/02/18 02:11:26 schwarze Exp $
.\"
-.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 20 2009 $
+.Dd $Mdocdate: February 18 2010 $
.Dt MDOC 3
.Os
.\" SECTION
@@ -92,7 +92,7 @@ Both functions (see
and variables (see
.Sx Variables )
may use the following types:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Vt struct mdoc
An opaque type defined in
@@ -113,7 +113,7 @@ for details.
.\" SUBSECTION
.Ss Functions
Function descriptions follow:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Fn mdoc_alloc
Allocates a parsing structure. The
@@ -168,7 +168,7 @@ return 0, the data will be incomplete.
.\" SUBSECTION
.Ss Variables
The following variables are also defined:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Va mdoc_macronames
An array of string-ified token names.
@@ -225,7 +225,7 @@ fields) and some type-specific data.
The tree itself is arranged according to the following normal form,
where capitalised non-terminals represent nodes.
.Pp
-.Bl -tag -width "ELEMENTXX" -compact -offset "XXXX"
+.Bl -tag -width "ELEMENTXX" -compact
.\" LIST-ITEM
.It ROOT
\(<- mnode+
@@ -259,11 +259,8 @@ an empty line will produce a zero-length string.
The following example reads lines from stdin and parses them, operating
on the finished parse tree with
.Fn parsed .
-Note that, if the last line of the file isn't newline-terminated, this
-will truncate the file's last character (see
-.Xr fgetln 3 ) .
-Further, this example does not error-check nor free memory upon failure.
-.Bd -literal -offset "XXXX"
+This example does not error-check nor free memory upon failure.
+.Bd -literal -offset indent
struct mdoc *mdoc;
const struct mdoc_node *node;
char *buf;
@@ -272,18 +269,21 @@ int line;
line = 1;
mdoc = mdoc_alloc(NULL, 0, NULL);
+buf = NULL;
+alloc_len = 0;
-while ((buf = fgetln(fp, &len))) {
- buf[len - 1] = '\\0';
- if ( ! mdoc_parseln(mdoc, line, buf))
- errx(1, "mdoc_parseln");
- line++;
+while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
+ if (len && buflen[len - 1] = '\en')
+ buf[len - 1] = '\e0';
+ if ( ! mdoc_parseln(mdoc, line, buf))
+ errx(1, "mdoc_parseln");
+ line++;
}
if ( ! mdoc_endparse(mdoc))
- errx(1, "mdoc_endparse");
+ errx(1, "mdoc_endparse");
if (NULL == (node = mdoc_node(mdoc)))
- errx(1, "mdoc_node");
+ errx(1, "mdoc_node");
parsed(mdoc, node);
mdoc_free(mdoc);
@@ -297,7 +297,7 @@ mdoc_free(mdoc);
The
.Nm
utility was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
+.An Kristaps Dzonsons Aq kristaps@bsd.lv .
.\" SECTION
.Sh CAVEATS
.Bl -dash -compact
diff --git a/usr.bin/mandoc/mdoc.7 b/usr.bin/mandoc/mdoc.7
index 0f3840f72a0..123cb113031 100644
--- a/usr.bin/mandoc/mdoc.7
+++ b/usr.bin/mandoc/mdoc.7
@@ -1,4 +1,4 @@
-.\" $Id: mdoc.7,v 1.21 2010/01/02 02:42:06 schwarze Exp $
+.\" $Id: mdoc.7,v 1.22 2010/02/18 02:11:26 schwarze Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: January 2 2010 $
+.Dd $Mdocdate: February 18 2010 $
.Dt MDOC 7
.Os
.
@@ -132,7 +132,7 @@ and
Terms may be text-decorated using the
.Sq \ef
escape followed by an indicator: B (bold), I, (italic), R (Roman), or P
-(revert to previous mode):
+(revert to previous mode):
.Pp
.D1 \efBbold\efR \efIitalic\efP
.Pp
@@ -170,19 +170,19 @@ for arbitrary-digit numerals:
.D1 \es+(10much bigger\es-(10
.D1 \es+'100'much much bigger\es-'100'
.Pp
-Note these forms are
+Note these forms are
.Em not
-recommended for
+recommended for
.Nm ,
which encourages semantic annotation.
.
.
.Ss Predefined Strings
-Historically,
+Historically,
.Xr groff 1
-also defined a set of package-specific
+also defined a set of package-specific
.Dq predefined strings ,
-which, like
+which, like
.Sx Special Characters ,
demark special output characters and strings by way of input codes.
Predefined strings are escaped with the slash-asterisk,
@@ -343,7 +343,7 @@ and
.Sx \&Os
macros, is required for every document.
.Pp
-The first section (sections are denoted by
+The first section (sections are denoted by
.Sx \&Sh )
must be the NAME section, consisting of at least one
.Sx \&Nm
@@ -420,7 +420,7 @@ macro(s) must precede the
.Sx \&Nd
macro.
.Pp
-See
+See
.Sx \&Nm
and
.Sx \&Nd .
@@ -438,7 +438,7 @@ See
.
.It Em SYNOPSIS
Documents the utility invocation syntax, function call syntax, or device
-configuration.
+configuration.
.Pp
For the first, utilities (sections 1, 6, and 8), this is
generally structured as follows:
@@ -469,10 +469,10 @@ And for the third, configurations (section 4):
\&.Cd \*qit* at isa? port 0x4e\*q
.Ed
.Pp
-Manuals not in these sections generally don't need a
+Manuals not in these sections generally don't need a
.Em SYNOPSIS .
.Pp
-See
+See
.Sx \&Op ,
.Sx \&Cd ,
.Sx \&Fn ,
@@ -481,7 +481,7 @@ and
.Sx \&Vt .
.
.It Em DESCRIPTION
-This expands upon the brief, one-line description in
+This expands upon the brief, one-line description in
.Em NAME .
It usually contains a break-down of the options (if documenting a
command), such as:
@@ -683,7 +683,7 @@ All macros have bodies; some
don't have heads; only one
.Po
.Sx \&It Fl column
-.Pc
+.Pc
has multiple heads.
.Bd -literal -offset indent
\&.Yo \(lB\-arg \(lBparm...\(rB\(rB \(lBhead... \(lBTa head...\(rB\(rB
@@ -770,7 +770,16 @@ or end of line.
.It Sx \&Ql Ta Yes Ta Yes
.It Sx \&Qq Ta Yes Ta Yes
.It Sx \&Sq Ta Yes Ta Yes
+.It Sx \&Vt Ta Yes Ta Yes
.El
+.Pp
+Note that the
+.Sx \&Vt
+macro is a
+.Sx Block partial-implicit
+only when invoked as the first macro
+in a SYNOPSIS section line, else it is
+.Sx In-line .
.
.
.Ss In-line
@@ -863,10 +872,10 @@ then the macro accepts an arbitrary number of arguments.
.It Sx \&Ux Ta Yes Ta Yes Ta n
.It Sx \&Va Ta Yes Ta Yes Ta n
.It Sx \&Vt Ta Yes Ta Yes Ta >0
-.It Sx \&Xr Ta Yes Ta Yes Ta >0, <3
+.It Sx \&Xr Ta Yes Ta Yes Ta >0
.It Sx \&br Ta \&No Ta \&No Ta 0
.It Sx \&sp Ta \&No Ta \&No Ta 1
-.El
+.El
.
.
.Sh REFERENCE
@@ -1026,7 +1035,7 @@ a function:
.Ed
.
.Ss \&Aq
-Encloses its arguments in angled brackets.
+Encloses its arguments in angled brackets.
.Pp
Examples:
.Bd -literal -offset indent
@@ -1073,7 +1082,7 @@ Note that these parameters do not begin with a hyphen.
.Pp
Examples:
.Bd -literal -offset indent
-\&.At
+\&.At
\&.At V.1
.Ed
.Pp
@@ -1242,7 +1251,7 @@ See also
.Sx \&Bq .
.
.Ss \&Bq
-Encloses its arguments in square brackets.
+Encloses its arguments in square brackets.
.Pp
Examples:
.Bd -literal -offset indent
@@ -1389,7 +1398,7 @@ manual. Its calling syntax is as follows:
.Pp
.D1 \. Ns Sx \&Dd Cm date
.Pp
-The
+The
.Cm date
field may be either
.Ar $\&Mdocdate$ ,
@@ -1438,7 +1447,7 @@ See also
.Sx \&Dq .
.
.Ss \&Dq
-Encloses its arguments in double quotes.
+Encloses its arguments in double quotes.
.Pp
Examples:
.Bd -literal -offset indent
@@ -1892,9 +1901,58 @@ and
.
.Ss \&Va
.Ss \&Vt
+A variable type. This is also used for indicating global variables in the
+SYNOPSIS section, in which case a variable name is also specified. Note that
+it accepts
+.Sx Block partial-implicit
+syntax when invoked as the first macro in the SYNOPSIS section, else it
+accepts ordinary
+.Sx In-line
+syntax.
+.Pp
+Note that this should not be confused with
+.Sx \&Ft ,
+which is used for function return types.
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Vt unsigned char
+\&.Vt extern const char * const sys_signame[] ;
+.Ed
+.Pp
+See also
+.Sx \&Ft
+and
+.Sx \&Va .
+.
.Ss \&Xc
.Ss \&Xo
.Ss \&Xr
+Link to another manual
+.Pq Qq cross-reference .
+Its calling syntax is
+.Pp
+.D1 \. Ns Sx \&Xr Cm name section
+.Pp
+The
+.Cm name
+and
+.Cm section
+are the name and section of the linked manual. If
+.Cm section
+is followed by non-punctuation, an
+.Sx \&Ns
+is inserted into the token stream. This behaviour is for compatibility
+with
+.Xr groff 1 .
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Xr mandoc 1
+\&.Xr mandoc 1 ;
+\&.Xr mandoc 1 s behaviour
+.Ed
+.
.Ss \&br
.Ss \&sp
.
@@ -1924,9 +1982,9 @@ the
macro does not format its arguments when used in the FILES section under
certain list types. This irregular behaviour has been discontinued.
.It
-Historic
+Historic
.Xr groff 1
-does not print a dash for empty
+does not print a dash for empty
.Sx \&Fl
arguments. This behaviour has been discontinued.
.It
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index e8eeed72a37..8d2cf52b80c 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc.c,v 1.33 2010/01/02 02:42:06 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.34 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -577,6 +577,7 @@ static int
parsetext(struct mdoc *m, int line, char *buf)
{
int i, j;
+ char sv;
if (SEC_NONE == m->lastnamed)
return(mdoc_perr(m, line, 0, ETEXTPROL));
@@ -593,7 +594,8 @@ parsetext(struct mdoc *m, int line, char *buf)
for (i = 0; ' ' == buf[i]; i++)
/* Skip leading whitespace. */ ;
- if (0 == buf[i])
+
+ if ('\0' == buf[i])
return(mdoc_perr(m, line, 0, ENOBLANK));
/*
@@ -609,15 +611,30 @@ parsetext(struct mdoc *m, int line, char *buf)
if (i && ' ' == buf[i] && '\\' == buf[i - 1])
continue;
- buf[i++] = 0;
+ sv = buf[i];
+ buf[i++] = '\0';
+
if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j)))
return(0);
+ /* Trailing whitespace? Check at overwritten byte. */
+
+ if (' ' == sv && '\0' == buf[i])
+ if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS))
+ return(0);
+
for ( ; ' ' == buf[i]; i++)
/* Skip trailing whitespace. */ ;
j = i;
- if (0 == buf[i])
+
+ /* Trailing whitespace? */
+
+ if (' ' == buf[i - 1] && '\0' == buf[i])
+ if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS))
+ return(0);
+
+ if ('\0' == buf[i])
break;
}
@@ -654,7 +671,7 @@ parsemacro(struct mdoc *m, int ln, char *buf)
/* Empty lines are ignored. */
- if (0 == buf[1])
+ if ('\0' == buf[1])
return(1);
i = 1;
@@ -665,14 +682,14 @@ parsemacro(struct mdoc *m, int ln, char *buf)
i++;
while (buf[i] && ' ' == buf[i])
i++;
- if (0 == buf[i])
+ if ('\0' == buf[i])
return(1);
}
/* Copy the first word into a nil-terminated buffer. */
for (j = 0; j < 4; j++, i++) {
- if (0 == (mac[j] = buf[i]))
+ if ('\0' == (mac[j] = buf[i]))
break;
else if (' ' == buf[i])
break;
@@ -703,6 +720,12 @@ parsemacro(struct mdoc *m, int ln, char *buf)
while (buf[i] && ' ' == buf[i])
i++;
+ /* Trailing whitespace? */
+
+ if ('\0' == buf[i] && ' ' == buf[i - 1])
+ if ( ! mdoc_pwarn(m, ln, i - 1, ETAILWS))
+ goto err;
+
/*
* Begin recursive parse sequence. Since we're at the start of
* the line, we don't need to do callable/parseable checks.
diff --git a/usr.bin/mandoc/mdoc_html.c b/usr.bin/mandoc/mdoc_html.c
index ca34fa46656..d3eefba017b 100644
--- a/usr.bin/mandoc/mdoc_html.c
+++ b/usr.bin/mandoc/mdoc_html.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_html.c,v 1.6 2010/01/02 02:42:06 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.7 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -262,7 +262,7 @@ html_mdoc(void *arg, const struct mdoc *m)
h = (struct html *)arg;
- print_gen_doctype(h);
+ print_gen_decls(h);
t = print_otag(h, TAG_HTML, 0, NULL);
print_mdoc(mdoc_meta(m), mdoc_node(m), h);
print_tagq(h, t);
@@ -1579,7 +1579,7 @@ mdoc_vt_pre(MDOC_ARGS)
struct htmlpair tag;
struct roffsu su;
- if (SEC_SYNOPSIS == n->sec) {
+ if (MDOC_BLOCK == n->type) {
if (n->prev && MDOC_Vt != n->prev->tok) {
SCALE_VS_INIT(&su, 1);
bufcat_su(h, "margin-top", &su);
@@ -1587,7 +1587,10 @@ mdoc_vt_pre(MDOC_ARGS)
print_otag(h, TAG_DIV, 1, &tag);
} else
print_otag(h, TAG_DIV, 0, NULL);
- }
+
+ return(1);
+ } else if (MDOC_HEAD == n->type)
+ return(0);
PAIR_CLASS_INIT(&tag, "type");
print_otag(h, TAG_SPAN, 1, &tag);
diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c
index 05b9d9d9ba3..c906c59a1bf 100644
--- a/usr.bin/mandoc/mdoc_macro.c
+++ b/usr.bin/mandoc/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.27 2010/01/01 19:24:07 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.28 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -27,6 +27,7 @@
#define REWIND_NOHALT (1 << 1)
#define REWIND_HALT (1 << 2)
+static int ctx_synopsis(MACRO_PROT_ARGS);
static int obsolete(MACRO_PROT_ARGS);
static int blk_part_exp(MACRO_PROT_ARGS);
static int in_line_eoln(MACRO_PROT_ARGS);
@@ -94,8 +95,8 @@ const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
{ in_line_eoln, 0 }, /* Rv */
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
- { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
- { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
+ { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
+ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
{ in_line_eoln, 0 }, /* %A */
{ in_line_eoln, 0 }, /* %B */
{ in_line_eoln, 0 }, /* %D */
@@ -394,6 +395,8 @@ rew_dohalt(int tok, enum mdoc_type type, const struct mdoc_node *p)
case (MDOC_Qq):
/* FALLTHROUGH */
case (MDOC_Sq):
+ /* FALLTHROUGH */
+ case (MDOC_Vt):
assert(MDOC_TAIL != type);
if (type == p->type && tok == p->tok)
return(REWIND_REWIND);
@@ -1173,6 +1176,9 @@ in_line_argn(MACRO_PROT_ARGS)
case (MDOC_Ux):
maxargs = 0;
break;
+ case (MDOC_Xr):
+ maxargs = 2;
+ break;
default:
maxargs = 1;
break;
@@ -1238,7 +1244,20 @@ in_line_argn(MACRO_PROT_ARGS)
return(0);
flushed = 1;
}
-
+
+ /*
+ * XXX: this is a hack to work around groff's ugliness
+ * as regards `Xr' and extraneous arguments. It should
+ * ideally be deprecated behaviour, but because this is
+ * code is no here, it's unlikely to be removed.
+ */
+ if (MDOC_Xr == tok && j == maxargs) {
+ if ( ! mdoc_elem_alloc(m, line, ppos, MDOC_Ns, NULL))
+ return(0);
+ if ( ! rew_elem(m, MDOC_Ns))
+ return(0);
+ }
+
if ( ! mdoc_word_alloc(m, line, la, p))
return(0);
}
@@ -1318,6 +1337,29 @@ in_line_eoln(MACRO_PROT_ARGS)
/* ARGSUSED */
static int
+ctx_synopsis(MACRO_PROT_ARGS)
+{
+
+ /* If we're not in the SYNOPSIS, go straight to in-line. */
+ if (SEC_SYNOPSIS != m->lastsec)
+ return(in_line(m, tok, line, ppos, pos, buf));
+
+ /* If we're a nested call, same place. */
+ if (ppos > 1)
+ return(in_line(m, tok, line, ppos, pos, buf));
+
+ /*
+ * XXX: this will open a block scope; however, if later we end
+ * up formatting the block scope, then child nodes will inherit
+ * the formatting. Be careful.
+ */
+
+ return(blk_part_imp(m, tok, line, ppos, pos, buf));
+}
+
+
+/* ARGSUSED */
+static int
obsolete(MACRO_PROT_ARGS)
{
diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c
index b3e3f0116d1..d6cbb0d1568 100644
--- a/usr.bin/mandoc/mdoc_term.c
+++ b/usr.bin/mandoc/mdoc_term.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_term.c,v 1.68 2010/01/02 02:42:06 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.69 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -128,6 +128,7 @@ static int termp_sq_pre(DECL_ARGS);
static int termp_ss_pre(DECL_ARGS);
static int termp_under_pre(DECL_ARGS);
static int termp_ud_pre(DECL_ARGS);
+static int termp_vt_pre(DECL_ARGS);
static int termp_xr_pre(DECL_ARGS);
static int termp_xx_pre(DECL_ARGS);
@@ -171,7 +172,7 @@ static const struct termact termacts[MDOC_MAX] = {
{ termp_rv_pre, NULL }, /* Rv */
{ NULL, NULL }, /* St */
{ termp_under_pre, NULL }, /* Va */
- { termp_under_pre, termp_vt_post }, /* Vt */
+ { termp_vt_pre, termp_vt_post }, /* Vt */
{ termp_xr_pre, NULL }, /* Xr */
{ NULL, termp____post }, /* %A */
{ termp_under_pre, termp____post }, /* %B */
@@ -1286,12 +1287,27 @@ termp_xr_pre(DECL_ARGS)
}
+static int
+termp_vt_pre(DECL_ARGS)
+{
+
+ if (MDOC_ELEM == n->type)
+ return(termp_under_pre(p, pair, m, n));
+ else if (MDOC_HEAD == n->type)
+ return(0);
+ else if (MDOC_BLOCK == n->type)
+ return(1);
+
+ return(termp_under_pre(p, pair, m, n));
+}
+
+
/* ARGSUSED */
static void
termp_vt_post(DECL_ARGS)
{
- if (n->sec != SEC_SYNOPSIS)
+ if (MDOC_BLOCK != n->type)
return;
if (n->next && MDOC_Vt == n->next->tok)
term_newln(p);
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index 2f87c6424a6..1c3b1b71a56 100644
--- a/usr.bin/mandoc/mdoc_validate.c
+++ b/usr.bin/mandoc/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.41 2010/01/01 22:20:24 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.42 2010/02/18 02:11:26 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -68,7 +68,6 @@ static int ebool(POST_ARGS);
static int eerr_eq0(POST_ARGS);
static int eerr_eq1(POST_ARGS);
static int eerr_ge1(POST_ARGS);
-static int eerr_le2(POST_ARGS);
static int eerr_le1(POST_ARGS);
static int ewarn_ge1(POST_ARGS);
static int herr_eq0(POST_ARGS);
@@ -90,6 +89,7 @@ static int post_sh(POST_ARGS);
static int post_sh_body(POST_ARGS);
static int post_sh_head(POST_ARGS);
static int post_st(POST_ARGS);
+static int post_vt(POST_ARGS);
static int pre_an(PRE_ARGS);
static int pre_bd(PRE_ARGS);
static int pre_bl(PRE_ARGS);
@@ -126,9 +126,10 @@ static v_post posts_ss[] = { herr_ge1, NULL };
static v_post posts_st[] = { eerr_eq1, post_st, NULL };
static v_post posts_text[] = { eerr_ge1, NULL };
static v_post posts_text1[] = { eerr_eq1, NULL };
+static v_post posts_vt[] = { post_vt, NULL };
static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL };
static v_post posts_wtext[] = { ewarn_ge1, NULL };
-static v_post posts_xr[] = { eerr_ge1, eerr_le2, NULL };
+static v_post posts_xr[] = { eerr_ge1, NULL };
static v_pre pres_an[] = { pre_an, NULL };
static v_pre pres_bd[] = { pre_display, pre_bd, NULL };
static v_pre pres_bl[] = { pre_bl, NULL };
@@ -186,7 +187,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
{ pres_rv, NULL }, /* Rv */
{ NULL, posts_st }, /* St */
{ NULL, NULL }, /* Va */
- { NULL, posts_text }, /* Vt */
+ { NULL, posts_vt }, /* Vt */
{ NULL, posts_xr }, /* Xr */
{ NULL, posts_text }, /* %A */
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */
@@ -402,7 +403,6 @@ CHECK_BODY_DEFN(ge1, warn, warn_child_gt, 0) /* bwarn_ge1() */
CHECK_BODY_DEFN(ge1, err, err_child_gt, 0) /* berr_ge1() */
CHECK_ELEM_DEFN(ge1, warn, warn_child_gt, 0) /* ewarn_gt1() */
CHECK_ELEM_DEFN(eq1, err, err_child_eq, 1) /* eerr_eq1() */
-CHECK_ELEM_DEFN(le2, err, err_child_lt, 3) /* eerr_le2() */
CHECK_ELEM_DEFN(le1, err, err_child_lt, 2) /* eerr_le1() */
CHECK_ELEM_DEFN(eq0, err, err_child_eq, 0) /* eerr_eq0() */
CHECK_ELEM_DEFN(ge1, err, err_child_gt, 0) /* eerr_ge1() */
@@ -887,6 +887,32 @@ post_lb(POST_ARGS)
static int
+post_vt(POST_ARGS)
+{
+ const struct mdoc_node *n;
+
+ /*
+ * The Vt macro comes in both ELEM and BLOCK form, both of which
+ * have different syntaxes (yet more context-sensitive
+ * behaviour). ELEM types must have a child; BLOCK types,
+ * specifically the BODY, should only have TEXT children.
+ */
+
+ if (MDOC_ELEM == mdoc->last->type)
+ return(eerr_ge1(mdoc));
+ if (MDOC_BODY != mdoc->last->type)
+ return(1);
+
+ for (n = mdoc->last->child; n; n = n->next)
+ if (MDOC_TEXT != n->type)
+ if ( ! mdoc_nwarn(mdoc, n, EBADCHILD))
+ return(0);
+
+ return(1);
+}
+
+
+static int
post_nm(POST_ARGS)
{