summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--html.c288
-rw-r--r--mdocml.12
-rw-r--r--mdocml.css1
-rw-r--r--mlg.c11
-rw-r--r--roff.c111
5 files changed, 368 insertions, 45 deletions
diff --git a/html.c b/html.c
index debb631c..0df24101 100644
--- a/html.c
+++ b/html.c
@@ -37,7 +37,7 @@
struct htmlnode {
int tok;
enum md_ns ns;
- int *argc[ROFF_MAXLINEARG];
+ int argc[ROFF_MAXLINEARG];
char *argv[ROFF_MAXLINEARG];
struct htmlnode *parent;
};
@@ -70,17 +70,23 @@ static int html_printargs(struct md_mbuf *, int,
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 *);
@@ -89,6 +95,194 @@ static int html_inlinetagname(struct md_mbuf *,
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
@@ -172,7 +366,7 @@ html_begin(struct md_mbuf *mbuf, const struct md_args *args,
trail =
"</head>\n"
"<body>\n"
- "<div class=\"mdoc\">\n";
+ "<div class=\"mdoc\">";
res = 0;
@@ -216,29 +410,59 @@ html_end(struct md_mbuf *mbuf, const struct md_args *args)
/* 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));
}
@@ -263,7 +487,7 @@ html_printargs(struct md_mbuf *mbuf, int tok, const char *ns,
/* 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)
{
@@ -330,6 +554,7 @@ html_begintag(struct md_mbuf *mbuf, void *data,
size_t res;
struct htmlq *q;
struct htmlnode *node;
+ int i, c;
assert(ns != MD_NS_DEFAULT);
res = 0;
@@ -346,27 +571,42 @@ html_begintag(struct md_mbuf *mbuf, void *data,
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;
@@ -396,18 +636,25 @@ html_endtag(struct md_mbuf *mbuf, void *data,
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:
@@ -416,7 +663,6 @@ html_endtag(struct md_mbuf *mbuf, void *data,
break;
}
- node = q->last;
q->last = node->parent;
free(node);
diff --git a/mdocml.1 b/mdocml.1
index 920dfe9b..79468461 100644
--- a/mdocml.1
+++ b/mdocml.1
@@ -128,8 +128,6 @@ structured ones:
.Bl -enum -compact -offset indent
.It
The engine doesn't understand the
-.Sq \&Xo ,
-.Sq \&Xc ,
.Sq \&No ,
.Sq \&Db ,
.Sq \&Xc ,
diff --git a/mdocml.css b/mdocml.css
index f59f009a..ec65255e 100644
--- a/mdocml.css
+++ b/mdocml.css
@@ -14,6 +14,7 @@
span.inline-Nd:before { content: ' \2014 '; }
span.inline-Fl:before { content: '-'; }
span.inline-Fl { font-weight: bolder; }
+ span.inline-Nm { font-weight: bolder; }
span.inline-Ar { text-decoration: underline; }
span.inline-Pa { text-decoration: underline; }
span.inline-Op:before { content: '['; }
diff --git a/mlg.c b/mlg.c
index 2ba7101b..8be61e3e 100644
--- a/mlg.c
+++ b/mlg.c
@@ -447,6 +447,17 @@ mlg_roffspecial(void *arg, int tok, const char *start, char **more)
return(0);
break;
case (ROFF_Fn):
+ abort(); /* TODO */
+ break;
+ case (ROFF_Nm):
+ assert(*more);
+ if ( ! mlg_begintag(p, MD_NS_INLINE, tok, NULL, NULL))
+ return(0);
+ if ( ! ml_puts(p->mbuf, *more++, &p->pos))
+ return(0);
+ assert(NULL == *more);
+ if ( ! mlg_endtag(p, MD_NS_INLINE, tok))
+ return(0);
break;
case (ROFF_Ns):
p->flags |= ML_OVERRIDE_ONE;
diff --git a/roff.c b/roff.c
index 104ff6a5..8af1fe1d 100644
--- a/roff.c
+++ b/roff.c
@@ -84,6 +84,7 @@ struct rofftree {
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. */
@@ -98,11 +99,11 @@ struct rofftree {
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);
@@ -131,6 +132,9 @@ static int roffparse(struct rofftree *, char *);
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);
@@ -207,7 +211,7 @@ static const struct rofftok tokens[ROFF_MAX] = {
{ 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 */
@@ -291,7 +295,7 @@ static const int tokenargs[ROFF_ARGMAX] = {
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,
@@ -1145,8 +1149,44 @@ roff_Dt(ROFFCALL_ARGS)
}
+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;
@@ -1394,37 +1434,64 @@ roff_ordered(ROFFCALL_ARGS)
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);