diff options
-rw-r--r-- | mdocml.1 | 62 | ||||
-rw-r--r-- | roff.c | 152 | ||||
-rw-r--r-- | xml.c | 18 |
3 files changed, 145 insertions, 87 deletions
@@ -1,8 +1,4 @@ -.\" $OpenBSD: mdoc.template,v 1.10 2007/05/31 22:10:19 jmc Exp $ .\" -.\" The following requests are required for all man pages. -.\" -.\" Remove `\&' from the line below. .Dd $Mdocdate$ .Dt mdocml 1 .Os @@ -23,53 +19,49 @@ The .Nm utility parses .Xr mdoc -formatted manual source and passes results into the output filter -dictated by -.Fl f Ar filter . -The only current output filter is +formatted manual source and passes results into an output filter. The +only current output filter is .Ar xml , the default. The arguments are as follows: .Bl -tag -width "\-o outfile" .It Fl f Ar filter -The output filter name, which defaults to -.Ar xml . +The output filter name. .It Fl o Ar outfile -Place output in +Write output to .Ar outfile , which may be .Qq \- -for stdout. The default is stdout. +for stdout. .It Fl W -Print compiler warnings to stderr. +Print warnings to stderr. .It Ar infile Read input from .Ar infile , which may be .Qq \- -for stdin. The default is stdin. +for stdin. .El +.Pp +By default, +.Nm +reads from stdin and writes to stdout using the xml filter. +.\" .Ss XML Filter The XML filter, specified by .Fl f Ar xml , is the default filter. It creates an XML document where element names are their respective roff macro names. Each element name has an associated namespace, which is one of -.Qq block , -.Qq inline , +.Qq block or -.Qq special , -corresponding to the display mode of a node. -.\" The following requests should be uncommented and used where appropriate. -.\" This next request is for sections 2, 3, and 9 function return values only. -.\" .Sh RETURN VALUES +.Qq inline , +corresponding to the display mode of a node. The document root is +always the +.Qq mdoc +element, in the default namespace. .\" This next request is for sections 1, 6, 7 & 8 only. .\" .Sh ENVIRONMENT -.\" .Sh FILES -.\" .Sh EXAMPLES -.\" This next request is for sections 1, 4, 6, and 8 only. -.\" .Sh DIAGNOSTICS -.\" The next request is for sections 2, 3, and 9 error and signal handling only. -.\" .Sh ERRORS +.\" .Sh SEE ALSO .Xr groff 1 , .Xr mdoc.samples 7 , @@ -91,15 +83,21 @@ or the necessary limitations of converting an ad hoc language into structured ones: .Bl -enum -compact -offset indent .It -The engine doesn't understand -.Sq \&Xo +The engine doesn't understand the +.Sq \&Xo , +.Sq \&Xc , +.Sq \&Ns , +.Sq \&No , +.Sq \&Db , +.Sq \&Sm , +.Sq \&Xc , and -.Sq \&Xc -troff macros. +.Sq \&Xo +mdoc macros. .It All macro arguments may be quoted, instead of only some. .It -Blank lines raise warnings. +Blank lines raise errors. .It If terminating punctuation is found, then .Em all @@ -105,12 +105,14 @@ struct rofftree { static int roff_Dd(ROFFCALL_ARGS); static int roff_Dt(ROFFCALL_ARGS); static int roff_Os(ROFFCALL_ARGS); +#ifdef notyet +static int roff_Ns(ROFFCALL_ARGS); +#endif static int roff_layout(ROFFCALL_ARGS); static int roff_text(ROFFCALL_ARGS); static int roff_comment(ROFFCALL_ARGS); static int roff_close(ROFFCALL_ARGS); -static int roff_special(ROFFCALL_ARGS); static struct roffnode *roffnode_new(int, struct rofftree *); static void roffnode_free(struct rofftree *); @@ -235,7 +237,7 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Bq */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Bsx */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Bx */ - {roff_special, NULL, NULL, NULL, 0, ROFF_SPECIAL, 0 }, /* Db */ + { NULL, NULL, NULL, NULL, 0, ROFF_SPECIAL, 0 }, /* Db */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Dc */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Do */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Dq */ @@ -246,11 +248,11 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Fx */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ms */ { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* No */ - { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ns */ + { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Ns */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Nx */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Ox */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pc */ - { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Pf */ + { NULL, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED }, /* Pf */ { roff_text, NULL, NULL, NULL, 0, ROFF_LAYOUT, ROFF_PARSED | ROFF_CALLABLE }, /* Po */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pq */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Qc */ @@ -262,7 +264,7 @@ static const struct rofftok tokens[ROFF_MAX] = { { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sc */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* So */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sq */ - {roff_special, NULL, NULL, NULL, 0, ROFF_SPECIAL, 0 }, /* Sm */ + { NULL, NULL, NULL, NULL, 0, ROFF_SPECIAL, 0 }, /* Sm */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sx */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Sy */ { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Tn */ @@ -494,7 +496,6 @@ roffargs(const struct rofftree *tree, } -/* XXX */ static int roffscan(int tok, const int *tokv) { @@ -998,22 +999,25 @@ roff_layout(ROFFCALL_ARGS) i = 0; while (*argv) { - if (ROFF_MAX != (c = rofffindcallable(*argv))) { - if (NULL == tokens[c].cb) { - roff_err(tree, *argv, "unsupported " - "macro `%s'", - toknames[c]); - return(0); - } - if ( ! (*tokens[c].cb)(c, tree, argv, ROFF_ENTER)) + if (ROFF_MAX == (c = rofffindcallable(*argv))) { + assert(tree->arg); + if ( ! (*tree->cb.roffdata) + (tree->arg, i, *argv++)) return(0); - break; + i = 1; + continue; } - assert(tree->arg); - if ( ! (*tree->cb.roffdata)(tree->arg, i, *argv++)) + if (NULL == tokens[c].cb) { + roff_err(tree, *argv, "unsupported macro `%s'", + toknames[c]); return(0); - i = 1; + } + + if ( ! (*tokens[c].cb)(c, tree, argv, ROFF_ENTER)) + return(0); + + break; } /* @@ -1022,26 +1026,27 @@ roff_layout(ROFFCALL_ARGS) * the end of line. */ - if (ROFF_PARSED & tokens[tok].flags && *argv) { - i = 0; - while (argv[i]) - i++; + if ( ! (ROFF_PARSED & tokens[tok].flags && *argv)) + return((*tree->cb.roffout)(tree->arg, tok)); - assert(i > 0); - if ( ! roffispunct(argv[--i])) - return((*tree->cb.roffout)(tree->arg, tok)); + i = 0; + while (argv[i]) + i++; - while (i >= 0 && roffispunct(argv[i])) - i--; + assert(i > 0); + if ( ! roffispunct(argv[--i])) + return((*tree->cb.roffout)(tree->arg, tok)); - assert(0 != i); - i++; + while (i >= 0 && roffispunct(argv[i])) + i--; - /* LINTED */ - while (argv[i]) - if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++])) - return(0); - } + assert(0 != i); + i++; + + /* LINTED */ + while (argv[i]) + if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++])) + return(0); return((*tree->cb.roffout)(tree->arg, tok)); } @@ -1108,7 +1113,8 @@ roff_text(ROFFCALL_ARGS) i = 1; } - if ( ! (*tree->cb.roffdata)(tree->arg, i, *argv++)) + if ( ! (*tree->cb.roffdata) + (tree->arg, i, *argv++)) return(0); i = 1; @@ -1141,26 +1147,27 @@ roff_text(ROFFCALL_ARGS) * the end of line. */ - if (first && *argv) { - i = 0; - while (argv[i]) - i++; + if ( ! (first && *argv)) + return(1); - assert(i > 0); - if ( ! roffispunct(argv[--i])) - return(1); + i = 0; + while (argv[i]) + i++; - while (i >= 0 && roffispunct(argv[i])) - i--; + assert(i > 0); + if ( ! roffispunct(argv[--i])) + return(1); - assert(0 != i); - i++; + while (i >= 0 && roffispunct(argv[i])) + i--; - /* LINTED */ - while (argv[i]) - if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++])) - return(0); - } + assert(0 != i); + i++; + + /* LINTED */ + while (argv[i]) + if ( ! (*tree->cb.roffdata)(tree->arg, 0, argv[i++])) + return(0); return(1); } @@ -1184,13 +1191,52 @@ roff_close(ROFFCALL_ARGS) } +#if notyet /* ARGSUSED */ static int -roff_special(ROFFCALL_ARGS) +roff_Ns(ROFFCALL_ARGS) { + int c; + + argv++; - return((*tree->cb.roffspecial)(tree->arg, tok)); + if (ROFF_MAX != (c = rofffindcallable(*argv))) { + if (NULL == tokens[c].cb) { + roff_err(tree, *argv, "unsupported macro `%s'", + toknames[c]); + return(0); + } + if ( ! (*tree->cb.roffspecial)(tree->arg, tok)) + return(0); + if ( ! (*tokens[c].cb)(c, tree, argv, ROFF_ENTER)) + return(0); + + return(1); + } else if ( ! (*tree->cb.roffdata)(tree->arg, 0, *argv++)) + return(0); + + while (*argv) { + if (ROFF_MAX == (c = rofffindcallable(*argv))) { + assert(tree->arg); + if ( ! (*tree->cb.roffdata) + (tree->arg, 1, *argv++)) + return(0); + continue; + } + if (NULL == tokens[c].cb) { + roff_err(tree, *argv, "unsupported macro `%s'", + toknames[c]); + return(0); + } + if ( ! (*tokens[c].cb)(c, tree, argv, ROFF_ENTER)) + return(0); + + break; + } + + return(1); } +#endif static void @@ -40,7 +40,8 @@ enum md_tok { MD_BLKOUT, MD_IN, MD_OUT, - MD_TEXT + MD_TEXT, + MD_OVERRIDE }; struct md_xml { @@ -329,8 +330,19 @@ rofftail(void *arg) static int roffspecial(void *arg, int tok) { + struct md_xml *p; + + assert(arg); + p = (struct md_xml *)arg; + + switch (tok) { + case (ROFF_Ns): + p->last = MD_OVERRIDE; + break; + default: + break; + } - /* FIXME */ return(1); } @@ -481,6 +493,8 @@ roffout(void *arg, int tok) assert(arg); p = (struct md_xml *)arg; + /* Continue with a regular out token. */ + if (0 == p->pos && ! mbuf_indent(p)) return(0); |