-/* $Id: html.c,v 1.9 2008/12/05 19:45:15 kristaps Exp $ */
+/* $Id: html.c,v 1.10 2008/12/05 22:34:30 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
struct htmlnode {
int tok;
enum md_ns ns;
- int *argc[ROFF_MAXLINEARG];
+ int argc[ROFF_MAXLINEARG];
char *argv[ROFF_MAXLINEARG];
struct htmlnode *parent;
};
static int html_end(struct md_mbuf *,
const struct md_args *);
static int html_blocktagname(struct md_mbuf *,
- const struct md_args *, int, size_t *);
+ const struct md_args *, int,
+ struct htmlq *, const int *,
+ const char **, size_t *);
static int html_blocktagargs(struct md_mbuf *,
const struct md_args *, int,
const int *, const char **, size_t *);
-static int html_blockheadtagname(struct md_mbuf *,
- const struct md_args *, int, size_t *);
-static int html_blockheadtagargs(struct md_mbuf *,
+static int html_headtagname(struct md_mbuf *,
+ const struct md_args *, int,
+ struct htmlq *, const int *,
+ const char **, size_t *);
+static int html_headtagargs(struct md_mbuf *,
const struct md_args *, int,
const int *, const char **, size_t *);
static int html_blockbodytagname(struct md_mbuf *,
- const struct md_args *, int, size_t *);
+ const struct md_args *,
+ int, struct htmlq *, const int *,
+ const char **, size_t *);
static int html_blockbodytagargs(struct md_mbuf *,
const struct md_args *, int,
const int *, const char **, size_t *);
static int html_inlinetagargs(struct md_mbuf *,
const struct md_args *, int,
const int *, const char **, size_t *);
+static int html_Bl_bodytagname(struct md_mbuf *,
+ struct htmlq *, const int *,
+ const char **, size_t *);
+static int html_It_blocktagname(struct md_mbuf *,
+ struct htmlq *, const int *,
+ const char **, size_t *);
+static int html_It_headtagname(struct md_mbuf *,
+ struct htmlq *, const int *,
+ const char **, size_t *);
+static int html_It_bodytagname(struct md_mbuf *,
+ struct htmlq *, const int *,
+ const char **, size_t *);
+
+
+/* ARGSUSED */
+static int
+html_It_headtagname(struct md_mbuf *mbuf, struct htmlq *q,
+ const int *argc, const char **argv, size_t *res)
+{
+ struct htmlnode *n;
+ int i, c;
+
+ for (n = q->last; n; n = n->parent)
+ if (n->tok == ROFF_Bl)
+ break;
+
+ assert(n);
+ for (i = 0; ROFF_ARGMAX != (c = n->argc[i]) &&
+ i < ROFF_MAXLINEARG; i++) {
+ switch (n->argc[i]) {
+ case (ROFF_Tag):
+ /* FALLTHROUGH */
+ case (ROFF_Column):
+ return(ml_nputs(mbuf, "td", 2, res));
+ default:
+ break;
+ }
+ }
+
+ assert(i != ROFF_MAXLINEARG);
+ abort();
+ /* NOTREACHED */
+
+ return(1);
+}
+
+
+/* ARGSUSED */
+static int
+html_It_bodytagname(struct md_mbuf *mbuf, struct htmlq *q,
+ const int *argc, const char **argv, size_t *res)
+{
+ struct htmlnode *n;
+ int i, c;
+
+ for (n = q->last; n; n = n->parent)
+ if (n->tok == ROFF_Bl)
+ break;
+
+ assert(n);
+ for (i = 0; ROFF_ARGMAX != (c = n->argc[i]) &&
+ i < ROFF_MAXLINEARG; i++) {
+ switch (n->argc[i]) {
+ case (ROFF_Enum):
+ /* FALLTHROUGH */
+ case (ROFF_Bullet):
+ /* FALLTHROUGH */
+ case (ROFF_Dash):
+ /* FALLTHROUGH */
+ case (ROFF_Hyphen):
+ /* FALLTHROUGH */
+ case (ROFF_Item):
+ /* FALLTHROUGH */
+ case (ROFF_Diag):
+ /* FALLTHROUGH */
+ case (ROFF_Hang):
+ /* FALLTHROUGH */
+ case (ROFF_Ohang):
+ /* FALLTHROUGH */
+ case (ROFF_Inset):
+ return(ml_nputs(mbuf, "div", 3, res));
+ case (ROFF_Tag):
+ /* FALLTHROUGH */
+ case (ROFF_Column):
+ return(ml_nputs(mbuf, "td", 2, res));
+ default:
+ break;
+ }
+ }
+
+ assert(i != ROFF_MAXLINEARG);
+ abort();
+ /* NOTREACHED */
+
+ return(1);
+}
+
+
+/* ARGSUSED */
+static int
+html_Bl_bodytagname(struct md_mbuf *mbuf, struct htmlq *q,
+ const int *argc, const char **argv, size_t *res)
+{
+ int c, i;
+
+ for (i = 0; ROFF_ARGMAX != (c = argc[i])
+ && i < ROFF_MAXLINEARG; i++) {
+ switch (argc[i]) {
+ case (ROFF_Enum):
+ return(ml_nputs(mbuf, "ol", 2, res));
+ case (ROFF_Bullet):
+ /* FALLTHROUGH */
+ case (ROFF_Dash):
+ /* FALLTHROUGH */
+ case (ROFF_Hyphen):
+ /* FALLTHROUGH */
+ case (ROFF_Item):
+ /* FALLTHROUGH */
+ case (ROFF_Diag):
+ /* FALLTHROUGH */
+ case (ROFF_Hang):
+ /* FALLTHROUGH */
+ case (ROFF_Ohang):
+ /* FALLTHROUGH */
+ case (ROFF_Inset):
+ return(ml_nputs(mbuf, "ul", 2, res));
+ case (ROFF_Tag):
+ /* FALLTHROUGH */
+ case (ROFF_Column):
+ return(ml_nputs(mbuf, "table", 5, res));
+ default:
+ break;
+ }
+ }
+
+ assert(i != ROFF_MAXLINEARG);
+ abort();
+ /* NOTREACHED */
+}
+
+
+/* ARGSUSED */
+static int
+html_It_blocktagname(struct md_mbuf *mbuf, struct htmlq *q,
+ const int *argc, const char **argv, size_t *res)
+{
+ struct htmlnode *n;
+ int i, c;
+
+ for (n = q->last; n; n = n->parent)
+ if (n->tok == ROFF_Bl)
+ break;
+
+ assert(n);
+ for (i = 0; ROFF_ARGMAX != (c = n->argc[i]) &&
+ i < ROFF_MAXLINEARG; i++) {
+ switch (n->argc[i]) {
+ case (ROFF_Enum):
+ /* FALLTHROUGH */
+ case (ROFF_Bullet):
+ /* FALLTHROUGH */
+ case (ROFF_Dash):
+ /* FALLTHROUGH */
+ case (ROFF_Hyphen):
+ /* FALLTHROUGH */
+ case (ROFF_Item):
+ /* FALLTHROUGH */
+ case (ROFF_Diag):
+ /* FALLTHROUGH */
+ case (ROFF_Hang):
+ /* FALLTHROUGH */
+ case (ROFF_Ohang):
+ /* FALLTHROUGH */
+ case (ROFF_Inset):
+ return(ml_nputs(mbuf, "li", 2, res));
+ case (ROFF_Tag):
+ /* FALLTHROUGH */
+ case (ROFF_Column):
+ return(ml_nputs(mbuf, "tr", 2, res));
+ default:
+ break;
+ }
+ }
+
+ assert(i != ROFF_MAXLINEARG);
+ abort();
+ /* NOTREACHED */
+}
static int
trail =
"</head>\n"
"<body>\n"
- "<div class=\"mdoc\">\n";
+ "<div class=\"mdoc\">";
res = 0;
/* ARGSUSED */
static int
html_blockbodytagname(struct md_mbuf *mbuf,
- const struct md_args *args, int tok, size_t *res)
+ const struct md_args *args, int tok, struct htmlq *q,
+ const int *argc, const char **argv, size_t *res)
{
+ switch (tok) {
+ case (ROFF_Bl):
+ return(html_Bl_bodytagname(mbuf, q, argc, argv, res));
+ case (ROFF_It):
+ return(html_It_bodytagname(mbuf, q, argc, argv, res));
+ default:
+ break;
+ }
+
return(ml_puts(mbuf, "div", res));
}
/* ARGSUSED */
static int
-html_blockheadtagname(struct md_mbuf *mbuf,
- const struct md_args *args, int tok, size_t *res)
+html_headtagname(struct md_mbuf *mbuf,
+ const struct md_args *args, int tok, struct htmlq *q,
+ const int *argc, const char **argv, size_t *res)
{
+ switch (tok) {
+ case (ROFF_It):
+ return(html_It_headtagname(mbuf, q, argc, argv, res));
+ case (ROFF_Sh):
+ return(ml_puts(mbuf, "h1", res));
+ case (ROFF_Ss):
+ return(ml_puts(mbuf, "h2", res));
+ default:
+ break;
+ }
+
return(ml_puts(mbuf, "div", res));
}
/* ARGSUSED */
static int
-html_blocktagname(struct md_mbuf *mbuf,
- const struct md_args *args, int tok, size_t *res)
+html_blocktagname(struct md_mbuf *mbuf, const struct md_args *args,
+ int tok, struct htmlq *q, const int *argc,
+ const char **argv, size_t *res)
{
+ switch (tok) {
+ case (ROFF_It):
+ return(html_It_blocktagname(mbuf, q, argc, argv, res));
+ default:
+ break;
+ }
+
return(ml_puts(mbuf, "div", res));
}
/* ARGSUSED */
static int
-html_blockheadtagargs(struct md_mbuf *mbuf,
+html_headtagargs(struct md_mbuf *mbuf,
const struct md_args *args, int tok,
const int *argc, const char **argv, size_t *res)
{
size_t res;
struct htmlq *q;
struct htmlnode *node;
+ int i, c;
assert(ns != MD_NS_DEFAULT);
res = 0;
node->tok = tok;
node->ns = ns;
+ if (argc) {
+ /* TODO: argv. */
+
+ assert(argv);
+ for (i = 0; ROFF_ARGMAX != (c = argc[i])
+ && i < ROFF_MAXLINEARG; i++)
+ node->argc[i] = argc[i];
+ assert(i != ROFF_MAXLINEARG);
+ } else
+ assert(NULL == argv);
+
+
q->last = node;
switch (ns) {
case (MD_NS_BLOCK):
- if ( ! html_blocktagname(mbuf, args, tok, &res))
+ if ( ! html_blocktagname(mbuf, args, tok,
+ q, argc, argv, &res))
return(-1);
if ( ! html_blocktagargs(mbuf, args, tok,
argc, argv, &res))
return(-1);
break;
case (MD_NS_BODY):
- if ( ! html_blockbodytagname(mbuf, args, tok, &res))
+ if ( ! html_blockbodytagname(mbuf, args, tok,
+ q, argc, argv, &res))
return(-1);
if ( ! html_blockbodytagargs(mbuf, args, tok,
argc, argv, &res))
return(-1);
break;
case (MD_NS_HEAD):
- if ( ! html_blockheadtagname(mbuf, args, tok, &res))
+ if ( ! html_headtagname(mbuf, args, tok, q,
+ argc, argv, &res))
return(-1);
- if ( ! html_blockheadtagargs(mbuf, args, tok,
+ if ( ! html_headtagargs(mbuf, args, tok,
argc, argv, &res))
return(-1);
break;
assert(data);
q = (struct htmlq *)data;
+ node = q->last;
switch (ns) {
case (MD_NS_BLOCK):
- if ( ! html_blocktagname(mbuf, args, tok, &res))
+ if ( ! html_blocktagname(mbuf, args, tok,
+ q, node->argc,
+ (const char **)node->argv, &res))
return(-1);
break;
case (MD_NS_BODY):
- if ( ! html_blockbodytagname(mbuf, args, tok, &res))
+ if ( ! html_blockbodytagname(mbuf, args, tok,
+ q, node->argc,
+ (const char **)node->argv, &res))
return(-1);
break;
case (MD_NS_HEAD):
- if ( ! html_blockheadtagname(mbuf, args, tok, &res))
+ if ( ! html_headtagname(mbuf, args, tok,
+ q, node->argc,
+ (const char **)node->argv, &res))
return(-1);
break;
default:
break;
}
- node = q->last;
q->last = node->parent;
free(node);
-/* $Id: roff.c,v 1.41 2008/12/05 11:28:17 kristaps Exp $ */
+/* $Id: roff.c,v 1.42 2008/12/05 22:34:30 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
struct roffnode *last; /* Last parsed node. */
char *cur; /* Line start. */
struct tm tm; /* `Dd' results. */
+ char name[64]; /* `Nm' results. */
char os[64]; /* `Os' results. */
char title[64]; /* `Dt' results. */
char section[64]; /* `Dt' results. */
void *arg; /* Callbacks' arg. */
};
-static int roff_Dd(ROFFCALL_ARGS);
-static int roff_Dt(ROFFCALL_ARGS);
-static int roff_Os(ROFFCALL_ARGS);
-static int roff_Ns(ROFFCALL_ARGS);
-static int roff_Sm(ROFFCALL_ARGS);
+static int roff_Dd(ROFFCALL_ARGS); /* FIXME: deprecate. */
+static int roff_Dt(ROFFCALL_ARGS); /* FIXME: deprecate. */
+static int roff_Os(ROFFCALL_ARGS); /* FIXME: deprecate. */
+static int roff_Ns(ROFFCALL_ARGS); /* FIXME: deprecate. */
+static int roff_Sm(ROFFCALL_ARGS); /* FIXME: deprecate. */
static int roff_layout(ROFFCALL_ARGS);
static int roff_text(ROFFCALL_ARGS);
static int roff_noop(ROFFCALL_ARGS);
static int textparse(struct rofftree *, char *);
static int roffdata(struct rofftree *, int, char *);
static int roffspecial(struct rofftree *, int, char **);
+static int roffsetname(struct rofftree *, char **);
+static int roffgetname(struct rofftree *, char **,
+ const char *);
#ifdef __linux__
extern size_t strlcat(char *, const char *, size_t);
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* In */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Li */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Nd */
- { roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Nm */ /* FIXME */
+ {roff_ordered, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Nm */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE | ROFF_LSCOPE }, /* Op */
{ roff_depr, NULL, NULL, NULL, 0, ROFF_TEXT, 0 }, /* Ot */
{ roff_text, NULL, NULL, NULL, 0, ROFF_TEXT, ROFF_PARSED | ROFF_CALLABLE }, /* Pa */
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, ROFF_VALUE, 0,
- 0, 0, 0, 0,
+ 0, ROFF_VALUE, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
}
+static int
+roffgetname(struct rofftree *tree, char **ordp, const char *start)
+{
+ if (0 == tree->name[0]) {
+ roff_err(tree, start, "`Nm' name not set");
+ return(0);
+ }
+ *ordp++ = tree->name;
+ *ordp = NULL;
+ return(1);
+}
+
+
+static int
+roffsetname(struct rofftree *tree, char **ordp)
+{
+
+ assert(*ordp);
+
+ /* FIXME: not all sections can set this. */
+
+ if (NULL != *(ordp + 1)) {
+ roff_err(tree, *ordp, "too many `Nm' args");
+ return(0);
+ }
+
+ if (strlcpy(tree->name, *ordp, sizeof(tree->name))
+ >= sizeof(tree->name)) {
+ roff_err(tree, *ordp, "`Nm' arg too long");
+ return(0);
+ }
+
+ return(1);
+}
+
+
/* ARGSUSED */
-static int
+static int
roff_Sm(ROFFCALL_ARGS)
{
char *morep[1], *p;
argv++;
if (NULL == *argv) {
+ switch (tok) {
+ case (ROFF_Nm):
+ if ( ! roffgetname(tree, ordp, *(argv - 1)))
+ return(0);
+ break;
+ default:
+ *ordp = NULL;
+ break;
+ }
- /* FIXME: satisfies number of args? */
-
- ordp[0] = NULL;
return(roffspecial(tree, tok, ordp));
}
i = 0;
while (*argv && i < ROFF_MAXLINEARG) {
- if (ROFF_MAX != (c = rofffindcallable(*argv)))
- return(roffcall(tree, c, argv));
- if (roffispunct(*argv))
+ c = rofffindcallable(*argv);
+
+ if (ROFF_MAX == c && ! roffispunct(*argv)) {
+ ordp[i++] = *argv++;
+ continue;
+ }
+ ordp[i] = NULL;
+
+ if (ROFF_MAX == c)
+ break;
+
+ switch (tok) {
+ case (ROFF_Nm):
+ if ( ! roffsetname(tree, ordp))
+ return(0);
+ break;
+ default:
break;
+ }
+
+ if ( ! roffspecial(tree, tok, ordp))
+ return(0);
- ordp[i++] = *argv++;
+ return(roffcall(tree, c, ordp));
}
+ assert(i != ROFF_MAXLINEARG);
ordp[i] = NULL;
- /* FIXME: too many or too few args? */
-
- if (i == ROFF_MAXLINEARG && *argv) {
- roff_err(tree, *argv, "too many args", toknames[tok]);
- return(0);
+ switch (tok) {
+ case (ROFF_Nm):
+ if ( ! roffsetname(tree, ordp))
+ return(0);
+ break;
+ default:
+ break;
}
- /* FIXME: error if there's stuff after the punctuation. */
-
if ( ! roffspecial(tree, tok, ordp))
return(0);
+ /* FIXME: error if there's stuff after the punctuation. */
+
if ( ! first || NULL == *argv)
return(1);