summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--html.c4
-rw-r--r--macro.c105
-rw-r--r--mdocml.css3
-rw-r--r--roff.c92
4 files changed, 203 insertions, 1 deletions
diff --git a/html.c b/html.c
index b71e9fca..6d34045f 100644
--- a/html.c
+++ b/html.c
@@ -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++;
+ }
+}
diff --git a/mdocml.css b/mdocml.css
index 50acf27a..05f7906a 100644
--- a/mdocml.css
+++ b/mdocml.css
@@ -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: ')'; }
diff --git a/roff.c b/roff.c
index f8e734da..68707b91 100644
--- a/roff.c
+++ b/roff.c
@@ -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)