diff options
-rw-r--r-- | usr.bin/mandoc/chars.c | 16 | ||||
-rw-r--r-- | usr.bin/mandoc/chars.in | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/html.c | 132 | ||||
-rw-r--r-- | usr.bin/mandoc/html.h | 12 | ||||
-rw-r--r-- | usr.bin/mandoc/main.c | 11 | ||||
-rw-r--r-- | usr.bin/mandoc/main.h | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/man.3 | 42 | ||||
-rw-r--r-- | usr.bin/mandoc/man.7 | 24 | ||||
-rw-r--r-- | usr.bin/mandoc/man.c | 39 | ||||
-rw-r--r-- | usr.bin/mandoc/man_html.c | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.1 | 53 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.c | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc.3 | 40 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc.7 | 106 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc.c | 37 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_html.c | 11 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_macro.c | 50 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_term.c | 22 | ||||
-rw-r--r-- | usr.bin/mandoc/mdoc_validate.c | 36 |
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, "¿", 6) CHAR("em", 2, "--", 2, "—", 7) CHAR("en", 2, "-", 1, "–", 7) CHAR("hy", 2, "-", 1, "‐", 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) { |