diff options
-rw-r--r-- | html.c | 4 | ||||
-rw-r--r-- | macro.c | 105 | ||||
-rw-r--r-- | mdocml.css | 3 | ||||
-rw-r--r-- | roff.c | 92 |
4 files changed, 203 insertions, 1 deletions
@@ -822,6 +822,10 @@ html_inlinetagname(struct md_mbuf *mbuf, { switch (tok) { + case (ROFF_Dl): + /* FALLTHROUGH */ + case (ROFF_D1): + return(html_stput(mbuf, HTML_TAG_DIV, res)); case (ROFF_Sh): return(html_stput(mbuf, HTML_TAG_A, res)); case (ROFF_Pp): diff --git a/macro.c b/macro.c new file mode 100644 index 00000000..722b2996 --- /dev/null +++ b/macro.c @@ -0,0 +1,105 @@ +/* $Id$ */ +/* + * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include <stdlib.h> + +#include "roff.h" + +static int +macro_args_next(struct rofftree *tree, int *pos, char *buf, char **v) +{ + int i; + + if (0 == buf[*pos]) + return(0); + + if ('\"' == buf[*pos]) { + /* Syntax error: quotation marks not allowed. */ + return(-1); + } + + *v = &buf[*pos]; + + while (buf[*pos] && ! isspace(buf[*pos])) + (*pos)++; + + if (buf[*pos + 1] && '\\' == buf[*pos]) { + /* Syntax error: escaped whitespace not allowed. */ + return(-1); + } + + buf[i] = 0; + return(1); +} + +/* + * Parses the following: + * + * .Xx foo bar baz ; foo "bar baz" ; ; + * ^---------- ^---------- + */ +static int +macro_fl(struct rofftree *tree, int tok, int *pos, char *buf) +{ + int i, j, c, first; + char *args[ROFF_MAXLINEARG]; + + first = *pos == 0; + + for (j = 0; ; ) { + i = *pos; + c = macro_args_next(tree, *i, buf, args[j]); + if (-1 == c) + return(0); + if (0 == c) + break; + + /* Break at the next command. */ + + if (ROFF_MAX != (c = rofffindcallable(args[pos]))) { + if ( ! macro(tree, tok, argc, argv, i, p)) + return(0); + if ( ! parse(tree, c, pos, args)) + return(0); + break; + } + + /* Continue if we're just words. */ + + if ( ! roffispunct(args[pos])) { + i++; + continue; + } + + /* Break if there's only remaining punctuation. */ + + if (args[pos + 1] && roffispunct(args[pos + 1])) + break; + + /* If there are remaining words, start anew. */ + + if ( ! macro(tree, tok, argc, argv, i, p)) + return(0); + + /* Spit out the punctuation. */ + + if ( ! word(tree, tok, *args++)) + return(0); + i++; + } +} @@ -27,7 +27,8 @@ div.inline-Pp { margin-bottom: 10px; } span.inline-Sy { font-weight: bolder; } span.inline-Tn { font-variant: small-caps; } - span.inline-D1 { margin-left: 20px; } + div.inline-D1 { margin-left: 20px; } + div.inline-Dl { margin-left: 20px; } span.head-Fo { font-weight: bolder; } span.body-Fo:before { content: '('; } span.body-Fo:after { content: ')'; } @@ -74,6 +74,7 @@ struct rofftree { void *arg; /* Callbacks' arg. */ int csec; /* Current section. */ int asec; /* Thus-far sections. */ + int literal; /* Literal mode. */ }; static struct roffnode *roffnode_new(int, struct rofftree *); @@ -218,6 +219,9 @@ textparse(struct rofftree *tree, char *buf) if ( ! (ROFFSec_NAME & tree->asec)) return(roff_err(tree, buf, "data before `NAME' section")); + if (tree->literal) + return(roffdata(tree, 0, buf)); + /* LINTED */ while (*buf) { while (*buf && isspace(*buf)) @@ -1228,6 +1232,10 @@ roff_layout(ROFFCALL_ARGS) /* +++ Begin run macro-specific hooks over argv. */ switch (tok) { + case (ROFF_Bd): + tree->literal++; + break; + case (ROFF_Sh): if (NULL == *argv) { argv--; @@ -1402,6 +1410,80 @@ roff_ordered(ROFFCALL_ARGS) } +static int +macro_default(struct rofftree *tree, int tok, char *args[]) +{ + char **p; + char *argv[ROFF_MAXLINEARG]; + int i, argc[ROFF_MAXLINEARG]; + + if ( ! roffparseopts(tree, tok, &args, argc, argv)) + return(0); + + if ( ! (ROFF_PARSED & tokens[tok].flags)) + return((*tree->cb.macro)(tree->arg, tok, argc, argv, 0, args)); + + p = args; + + while (*args) { + c = rofffindcallable(*args); + if (ROFF_MAX == c) { + if (roffispunct(*args)) { + + + } + } + + if (ROFF_MAX != (c = rofffindcallable(*argv))) { + if ( ! (ROFF_LSCOPE & tokens[tok].flags)) + if ( ! (*tree->cb.roffout)(tree->arg, tok)) + return(0); + + if ( ! roffcall(tree, c, argv)) + return(0); + if (ROFF_LSCOPE & tokens[tok].flags) + if ( ! (*tree->cb.roffout)(tree->arg, tok)) + return(0); + break; + } + + if ( ! roffispunct(*argv)) { + if ( ! roffdata(tree, i++, *argv++)) + return(0); + continue; + } + + i = 1; + for (j = 0; argv[j]; j++) + if ( ! roffispunct(argv[j])) + break; + + if (argv[j]) { + if (ROFF_LSCOPE & tokens[tok].flags) { + if ( ! roffdata(tree, 0, *argv++)) + return(0); + continue; + } + if ( ! (*tree->cb.roffout)(tree->arg, tok)) + return(0); + if ( ! roffdata(tree, 0, *argv++)) + return(0); + if ( ! (*tree->cb.roffin)(tree->arg, tok, + argcp, + (const char **)argvp)) + return(0); + + i = 0; + continue; + } + + if ( ! (*tree->cb.roffout)(tree->arg, tok)) + return(0); + break; + } +} + + /* ARGSUSED */ static int roff_text(ROFFCALL_ARGS) @@ -1516,6 +1598,14 @@ static int roff_noop(ROFFCALL_ARGS) { + switch (tok) { + case (ROFF_Ed): + tree->literal--; + break; + default: + break; + } + return(1); } @@ -1529,6 +1619,7 @@ roff_depr(ROFFCALL_ARGS) } +/* FIXME: push this into the filter. */ static int roff_warnp(const struct rofftree *tree, const char *pos, int tok, enum rofferr type) @@ -1563,6 +1654,7 @@ roff_warn(const struct rofftree *tree, const char *pos, char *fmt, ...) } +/* FIXME: push this into the filter. */ static int roff_errp(const struct rofftree *tree, const char *pos, int tok, enum rofferr type) |