summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2008-12-03 19:21:58 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2008-12-03 19:21:58 +0000
commitc67723cb5220a19191e6836e53b8d0a489c86797 (patch)
treee75720ca8fbbb4d7f4a0ed25af3ab2b2ecf392b3
parentac4bc07079be4963163734d67749697140f23b4b (diff)
downloadmandoc-c67723cb5220a19191e6836e53b8d0a489c86797.tar.gz
Major update.
-rw-r--r--html.c204
-rw-r--r--mdocml.14
-rw-r--r--mdocml.c22
-rw-r--r--ml.c13
-rw-r--r--ml.h9
-rw-r--r--mlg.c133
-rw-r--r--private.h6
-rw-r--r--roff.c109
-rw-r--r--xml.c62
9 files changed, 421 insertions, 141 deletions
diff --git a/html.c b/html.c
index 0e15a1d5..1a7ea0fd 100644
--- a/html.c
+++ b/html.c
@@ -18,34 +18,228 @@
*/
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include "libmdocml.h"
#include "private.h"
+#include "ml.h"
+
+
+static ssize_t html_endtag(struct md_mbuf *,
+ const struct md_args *,
+ enum md_ns, int);
+static ssize_t html_begintag(struct md_mbuf *,
+ const struct md_args *,
+ enum md_ns, int,
+ const int *, const char **);
+static int html_begin(struct md_mbuf *,
+ const struct md_args *);
+static int html_end(struct md_mbuf *,
+ const struct md_args *);
+static ssize_t html_blocktagname(struct md_mbuf *,
+ const struct md_args *, int);
+static ssize_t html_blocktagargs(struct md_mbuf *,
+ const struct md_args *, int,
+ const int *, const char **);
+static ssize_t html_inlinetagname(struct md_mbuf *,
+ const struct md_args *, int);
+static ssize_t html_inlinetagargs(struct md_mbuf *,
+ const struct md_args *, int,
+ const int *, const char **);
+
+
+static int
+html_begin(struct md_mbuf *mbuf, const struct md_args *args)
+{
+ size_t res;
+
+ res = 0;
+ if ( ! ml_puts(mbuf, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD "
+ "HTML 4.01//EN\" \"http://www.w3.org"
+ "/TR/html4/strict.dtd\">\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, "<html>\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, "<head>\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, " <title>Manual page</title>\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, " <meta http-equiv=\"Content-Type\" "
+ "content=\"text/html; "
+ "charset=utf-8\">\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, " <meta name=\"resource-type\" "
+ "content=\"document\">\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, "</head>\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, "<body>", &res))
+ return(0);
+
+ return(1);
+}
+
+
+static int
+html_end(struct md_mbuf *mbuf, const struct md_args *args)
+{
+ size_t res;
+
+ res = 0;
+ if ( ! ml_puts(mbuf, "</body>\n</html>", &res))
+ return(0);
+
+ return(1);
+}
+
+
+static ssize_t
+html_blocktagname(struct md_mbuf *mbuf,
+ const struct md_args *args, int tok)
+{
+ size_t res;
+
+ res = 0;
+
+ switch (tok) {
+ case (ROFF_Sh):
+ if ( ! ml_puts(mbuf, "blockquote", &res))
+ return(-1);
+ break;
+ case (ROFF_Bd):
+ if ( ! ml_puts(mbuf, "pre", &res))
+ return(-1);
+ break;
+ case (ROFF_Bl):
+ if ( ! ml_puts(mbuf, "ul", &res))
+ return(-1);
+ break;
+ case (ROFF_It):
+ if ( ! ml_puts(mbuf, "li", &res))
+ return(-1);
+ break;
+ default:
+ if ( ! ml_puts(mbuf, "div", &res))
+ return(-1);
+ break;
+ }
+
+ return((size_t)res);
+}
+
+
+/* ARGSUSED */
+static ssize_t
+html_blocktagargs(struct md_mbuf *mbuf, const struct md_args *args,
+ int tok, const int *argc, const char **argv)
+{
+
+ switch (tok) {
+ default:
+ return(0);
+ }
+
+ return(-1);
+}
/* ARGSUSED */
+static ssize_t
+html_inlinetagargs(struct md_mbuf *mbuf, const struct md_args *args,
+ int tok, const int *argc, const char **argv)
+{
+
+ switch (tok) {
+ default:
+ return(0);
+ }
+
+ return(-1);
+}
+
+
+static ssize_t
+html_inlinetagname(struct md_mbuf *mbuf,
+ const struct md_args *args, int tok)
+{
+ size_t res;
+
+ res = 0;
+
+ switch (tok) {
+ case (ROFF_Sh):
+ if ( ! ml_puts(mbuf, "h1", &res))
+ return(-1);
+ break;
+ case (ROFF_Ss):
+ if ( ! ml_puts(mbuf, "h2", &res))
+ return(-1);
+ break;
+ default:
+ if ( ! ml_puts(mbuf, "span", &res))
+ return(-1);
+ break;
+ }
+
+ return((ssize_t)res);
+}
+
+
+static ssize_t
+html_begintag(struct md_mbuf *mbuf, const struct md_args *args,
+ enum md_ns ns, int tok,
+ const int *argc, const char **argv)
+{
+
+ assert(ns != MD_NS_DEFAULT);
+ if (MD_NS_BLOCK == ns) {
+ if ( ! html_blocktagname(mbuf, args, tok))
+ return(0);
+ return(html_blocktagargs(mbuf, args,
+ tok, argc, argv));
+ }
+
+ if ( ! html_inlinetagname(mbuf, args, tok))
+ return(0);
+ return(html_inlinetagargs(mbuf, args, tok, argc, argv));
+}
+
+
+static ssize_t
+html_endtag(struct md_mbuf *mbuf, const struct md_args *args,
+ enum md_ns ns, int tok)
+{
+
+ assert(ns != MD_NS_DEFAULT);
+ if (MD_NS_BLOCK == ns)
+ return(html_blocktagname(mbuf, args, tok));
+
+ return(html_inlinetagname(mbuf, args, tok));
+}
+
+
int
md_line_html(void *data, char *buf)
{
- return(1);
+ return(mlg_line((struct md_mlg *)data, buf));
}
-/* ARGSUSED */
int
md_exit_html(void *data, int flush)
{
- return(1);
+ return(mlg_exit((struct md_mlg *)data, flush));
}
-/* ARGSUSED */
void *
md_init_html(const struct md_args *args,
struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
{
- return(NULL);
+ return(mlg_alloc(args, rbuf, mbuf, html_begintag,
+ html_endtag, html_begin, html_end));
}
+
diff --git a/mdocml.1 b/mdocml.1
index 2c8317fd..8111153b 100644
--- a/mdocml.1
+++ b/mdocml.1
@@ -50,7 +50,9 @@ The XML filter, specified by
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 block ,
+.Qq head ,
+.Qq body ,
or
.Qq inline ,
corresponding to the display mode of a node. The document root is
diff --git a/mdocml.c b/mdocml.c
index 84ceec26..b3031c75 100644
--- a/mdocml.c
+++ b/mdocml.c
@@ -48,18 +48,21 @@ int
main(int argc, char *argv[])
{
int c;
- char *out, *in;
+ char *out, *in, *filter;
struct md_args args;
extern char *optarg;
extern int optind;
- out = in = NULL;
+ out = in = filter = NULL;
(void)memset(&args, 0, sizeof(struct md_args));
- while (-1 != (c = getopt(argc, argv, "o:vW")))
+ while (-1 != (c = getopt(argc, argv, "f:o:vW")))
switch (c) {
+ case ('f'):
+ filter = optarg;
+ break;
case ('o'):
out = optarg;
break;
@@ -80,6 +83,16 @@ main(int argc, char *argv[])
if (1 == argc)
in = *argv++;
+ if (filter) {
+ if (0 == strcmp(filter, "html"))
+ args.type = MD_HTML;
+ else if (0 == strcmp(filter, "xml"))
+ args.type = MD_XML;
+ else
+ errx(1, "invalid filter type");
+ } else
+ args.type = MD_XML;
+
return(begin_io(&args, out ? out : "-", in ? in : "-"));
}
@@ -220,5 +233,6 @@ usage(void)
{
extern char *__progname;
- (void)printf("usage: %s [-vW] [-o outfile] [infile]\n", __progname);
+ (void)printf("usage: %s [-vW] [-f filter] [-o outfile] "
+ "[infile]\n", __progname);
}
diff --git a/ml.c b/ml.c
index 46c1076d..04980b8f 100644
--- a/ml.c
+++ b/ml.c
@@ -76,6 +76,19 @@ ml_nputs(struct md_mbuf *p, const char *buf, size_t sz, size_t *pos)
int
+ml_puts(struct md_mbuf *p, const char *buf, size_t *pos)
+{
+ size_t sz;
+
+ sz = strlen(buf);
+ if ( ! md_buf_puts(p, buf, sz))
+ return(0);
+ *pos += sz;
+ return(1);
+}
+
+
+int
ml_putchars(struct md_mbuf *p, char buf, size_t count, size_t *pos)
{
size_t i;
diff --git a/ml.h b/ml.h
index 806a6e27..95a4712b 100644
--- a/ml.h
+++ b/ml.h
@@ -23,10 +23,16 @@ struct md_mlg;
enum md_ns {
MD_NS_BLOCK,
+ MD_NS_HEAD,
+ MD_NS_BODY,
MD_NS_INLINE,
MD_NS_DEFAULT,
};
+typedef int (*ml_begin)(struct md_mbuf *,
+ const struct md_args *);
+typedef int (*ml_end)(struct md_mbuf *,
+ const struct md_args *);
typedef ssize_t (*ml_endtag)(struct md_mbuf *,
const struct md_args *, enum md_ns, int);
typedef ssize_t (*ml_begintag)(struct md_mbuf *,
@@ -40,12 +46,13 @@ int ml_nputstring(struct md_mbuf *,
const char *, size_t, size_t *);
int ml_nputs(struct md_mbuf *,
const char *, size_t, size_t *);
+int ml_puts(struct md_mbuf *, const char *, size_t *);
int ml_putchars(struct md_mbuf *,
char, size_t, size_t *);
struct md_mlg *mlg_alloc(const struct md_args *,
const struct md_rbuf *, struct md_mbuf *,
- ml_begintag, ml_endtag);
+ ml_begintag, ml_endtag, ml_begin, ml_end);
int mlg_exit(struct md_mlg *, int);
int mlg_line(struct md_mlg *, char *);
diff --git a/mlg.c b/mlg.c
index 454751d0..eaf032e8 100644
--- a/mlg.c
+++ b/mlg.c
@@ -31,7 +31,7 @@
#define COLUMNS 72
#define INDENT 4
-#define MAXINDENT 8
+#define MAXINDENT 10
enum md_tok {
MD_TEXT,
@@ -53,6 +53,8 @@ struct md_mlg {
void *arg;
ml_begintag begintag;
ml_endtag endtag;
+ ml_begin begin;
+ ml_end end;
int flags;
#define ML_OVERRIDE_ONE (1 << 0)
#define ML_OVERRIDE_ALL (1 << 1)
@@ -68,7 +70,16 @@ static int mlg_roffdata(void *, int, char *);
static int mlg_roffout(void *, int);
static int mlg_roffblkin(void *, int, int *, char **);
static int mlg_roffblkout(void *, int);
-static int mlg_roffspecial(void *, int, int *, char **, char **);
+static int mlg_roffspecial(void *, int, int *,
+ char **, char **);
+static int mlg_roffblkheadin(void *, int, int *, char **);
+static int mlg_roffblkheadout(void *, int);
+static int mlg_roffblkbodyin(void *, int, int *, char **);
+static int mlg_roffblkbodyout(void *, int);
+
+static int mlg_beginblk(struct md_mlg *, enum md_ns, int,
+ int *, char **);
+static int mlg_endblk(struct md_mlg *, enum md_ns, int);
static int mlg_begintag(struct md_mlg *, enum md_ns,
int, int *, char **);
static int mlg_endtag(struct md_mlg *, enum md_ns, int);
@@ -84,6 +95,48 @@ extern size_t strlcpy(char *, const char *, size_t);
static int
+mlg_beginblk(struct md_mlg *p, enum md_ns ns, int tok,
+ int *argc, char **argv)
+{
+ if (0 != p->pos) {
+ if ( ! mlg_newline(p))
+ return(0);
+ if ( ! mlg_indent(p))
+ return(0);
+ } else if ( ! mlg_indent(p))
+ return(0);
+
+ p->indent++;
+ mlg_mode(p, MD_BLK_IN);
+
+ if ( ! mlg_begintag(p, ns, tok, argc, argv))
+ return(0);
+ return(mlg_newline(p));
+}
+
+
+static int
+mlg_endblk(struct md_mlg *p, enum md_ns ns, int tok)
+{
+
+ p->indent--;
+
+ if (0 != p->pos) {
+ if ( ! mlg_newline(p))
+ return(0);
+ if ( ! mlg_indent(p))
+ return(0);
+ } else if ( ! mlg_indent(p))
+ return(0);
+
+ mlg_mode(p, MD_BLK_OUT);
+ if ( ! mlg_endtag(p, ns, tok))
+ return(0);
+ return(mlg_newline(p));
+}
+
+
+static int
mlg_begintag(struct md_mlg *p, enum md_ns ns, int tok,
int *argc, char **argv)
{
@@ -251,7 +304,8 @@ struct md_mlg *
mlg_alloc(const struct md_args *args,
const struct md_rbuf *rbuf,
struct md_mbuf *mbuf,
- ml_begintag begintag, ml_endtag endtag)
+ ml_begintag begintag, ml_endtag endtag,
+ ml_begin begin, ml_end end)
{
struct roffcb cb;
struct md_mlg *p;
@@ -261,6 +315,10 @@ mlg_alloc(const struct md_args *args,
cb.roffin = mlg_roffin;
cb.roffout = mlg_roffout;
cb.roffblkin = mlg_roffblkin;
+ cb.roffblkheadin = mlg_roffblkheadin;
+ cb.roffblkheadout = mlg_roffblkheadout;
+ cb.roffblkbodyin = mlg_roffblkbodyin;
+ cb.roffblkbodyout = mlg_roffblkbodyout;
cb.roffblkout = mlg_roffblkout;
cb.roffspecial = mlg_roffspecial;
cb.roffmsg = mlg_roffmsg;
@@ -274,6 +332,8 @@ mlg_alloc(const struct md_args *args,
p->rbuf = rbuf;
p->begintag = begintag;
p->endtag = endtag;
+ p->begin = begin;
+ p->end = end;
if (NULL == (p->tree = roff_alloc(&cb, p))) {
free(p);
@@ -293,7 +353,7 @@ mlg_roffhead(void *arg)
p = (struct md_mlg *)arg;
mlg_mode(p, MD_BLK_IN);
- if ( ! mlg_begintag(p, MD_NS_DEFAULT, -1, NULL, NULL))
+ if ( ! (*p->begin)(p->mbuf, p->args))
return(0);
p->indent++;
@@ -313,7 +373,7 @@ mlg_rofftail(void *arg)
return(0);
mlg_mode(p, MD_BLK_OUT);
- if ( ! mlg_endtag(p, -1, MD_NS_DEFAULT))
+ if ( ! (*p->end)(p->mbuf, p->args))
return(0);
return(mlg_newline(p));
@@ -351,50 +411,51 @@ mlg_roffspecial(void *arg, int tok, int *argc, char **argv, char **more)
static int
mlg_roffblkin(void *arg, int tok, int *argc, char **argv)
{
- struct md_mlg *p;
- assert(arg);
- p = (struct md_mlg *)arg;
+ return(mlg_beginblk((struct md_mlg *)arg,
+ MD_NS_BLOCK, tok, argc, argv));
+}
- if (0 != p->pos) {
- if ( ! mlg_newline(p))
- return(0);
- if ( ! mlg_indent(p))
- return(0);
- } else if ( ! mlg_indent(p))
- return(0);
- p->indent++;
- mlg_mode(p, MD_BLK_IN);
+static int
+mlg_roffblkout(void *arg, int tok)
+{
- if ( ! mlg_begintag(p, MD_NS_BLOCK, tok, argc, argv))
- return(0);
- return(mlg_newline(p));
+ return(mlg_endblk((struct md_mlg *)arg, MD_NS_BLOCK, tok));
}
static int
-mlg_roffblkout(void *arg, int tok)
+mlg_roffblkbodyin(void *arg, int tok, int *argc, char **argv)
{
- struct md_mlg *p;
- assert(arg);
- p = (struct md_mlg *)arg;
+ return(mlg_beginblk((struct md_mlg *)arg,
+ MD_NS_BODY, tok, argc, argv));
+}
- p->indent--;
- if (0 != p->pos) {
- if ( ! mlg_newline(p))
- return(0);
- if ( ! mlg_indent(p))
- return(0);
- } else if ( ! mlg_indent(p))
- return(0);
+static int
+mlg_roffblkbodyout(void *arg, int tok)
+{
- mlg_mode(p, MD_BLK_OUT);
- if ( ! mlg_endtag(p, MD_NS_BLOCK, tok))
- return(0);
- return(mlg_newline(p));
+ return(mlg_endblk((struct md_mlg *)arg, MD_NS_BODY, tok));
+}
+
+
+static int
+mlg_roffblkheadin(void *arg, int tok, int *argc, char **argv)
+{
+
+ return(mlg_beginblk((struct md_mlg *)arg,
+ MD_NS_HEAD, tok, argc, argv));
+}
+
+
+static int
+mlg_roffblkheadout(void *arg, int tok)
+{
+
+ return(mlg_endblk((struct md_mlg *)arg, MD_NS_HEAD, tok));
}
diff --git a/private.h b/private.h
index e24deca2..1ed48a79 100644
--- a/private.h
+++ b/private.h
@@ -215,11 +215,15 @@ struct roffcb {
const char *, const char *, char *);
int (*roffhead)(void *);
int (*rofftail)(void *);
- int (*roffin)(void *, int, int *, char **);
int (*roffdata)(void *, int, char *);
+ int (*roffin)(void *, int, int *, char **);
int (*roffout)(void *, int);
int (*roffblkin)(void *, int, int *, char **);
int (*roffblkout)(void *, int);
+ int (*roffblkheadin)(void *, int, int *, char **);
+ int (*roffblkheadout)(void *, int);
+ int (*roffblkbodyin)(void *, int, int *, char **);
+ int (*roffblkbodyout)(void *, int);
int (*roffspecial)(void *, int, int *, char **, char **);
};
diff --git a/roff.c b/roff.c
index dcb37567..310a91e2 100644
--- a/roff.c
+++ b/roff.c
@@ -134,9 +134,9 @@ static int roffcall(struct rofftree *, int, char **);
static int roffparse(struct rofftree *, char *);
static int textparse(const struct rofftree *, char *);
-#ifdef __linux__ /* FIXME: remove */
-static size_t strlcat(char *, const char *, size_t);
-static size_t strlcpy(char *, const char *, size_t);
+#ifdef __linux__
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
extern int vsnprintf(char *, size_t,
const char *, va_list);
extern char *strptime(const char *, const char *,
@@ -1227,6 +1227,8 @@ roff_layout(ROFFCALL_ARGS)
return(0);
} else if (ROFF_EXIT == type) {
roffnode_free(tree);
+ if ( ! (*tree->cb.roffblkbodyout)(tree->arg, tok))
+ return(0);
return((*tree->cb.roffblkout)(tree->arg, tok));
}
@@ -1248,8 +1250,10 @@ roff_layout(ROFFCALL_ARGS)
if ( ! (*tree->cb.roffblkin)(tree->arg, tok, argcp, argvp))
return(0);
if (NULL == *argv)
- return(1);
- if ( ! (*tree->cb.roffin)(tree->arg, tok, argcp, argvp))
+ return((*tree->cb.roffblkbodyin)
+ (tree->arg, tok, argcp, argvp));
+
+ if ( ! (*tree->cb.roffblkheadin)(tree->arg, tok, argcp, argvp))
return(0);
/*
@@ -1264,7 +1268,10 @@ roff_layout(ROFFCALL_ARGS)
return(0);
i = 1;
}
- return((*tree->cb.roffout)(tree->arg, tok));
+ if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))
+ return(0);
+ return((*tree->cb.roffblkbodyin)
+ (tree->arg, tok, argcp, argvp));
}
/*
@@ -1293,8 +1300,12 @@ roff_layout(ROFFCALL_ARGS)
* macro.
*/
- if (NULL == *argv)
- return((*tree->cb.roffout)(tree->arg, tok));
+ if (NULL == *argv) {
+ if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))
+ return(0);
+ return((*tree->cb.roffblkbodyin)
+ (tree->arg, tok, argcp, argvp));
+ }
/*
* Expensive. Scan to the end of line then work backwards until
@@ -1304,7 +1315,10 @@ roff_layout(ROFFCALL_ARGS)
if ( ! roffpurgepunct(tree, argv))
return(0);
- return((*tree->cb.roffout)(tree->arg, tok));
+ if ( ! (*tree->cb.roffblkheadout)(tree->arg, tok))
+ return(0);
+ return((*tree->cb.roffblkbodyin)
+ (tree->arg, tok, argcp, argvp));
}
@@ -1445,80 +1459,3 @@ roff_err(const struct rofftree *tree, const char *pos, char *fmt, ...)
ROFF_ERROR, tree->cur, pos, buf);
}
-
-#ifdef __linux /* FIXME: remove. */
-/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * 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.
- */
-static size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past
- * end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return(dlen + strlen(s));
- while (*s != '\0') {
- if (n != 1) {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return(dlen + (s - src)); /* count does not include NUL */
-}
-
-
-static size_t
-strlcpy(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0) {
- while (--n != 0) {
- if ((*d++ = *s++) == '\0')
- break;
- }
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
-}
-#endif /*__linux__*/
diff --git a/xml.c b/xml.c
index 63737563..8b4387be 100644
--- a/xml.c
+++ b/xml.c
@@ -31,6 +31,41 @@ static ssize_t xml_begintag(struct md_mbuf *,
const struct md_args *,
enum md_ns, int,
const int *, const char **);
+static int xml_begin(struct md_mbuf *,
+ const struct md_args *);
+static int xml_end(struct md_mbuf *,
+ const struct md_args *);
+
+
+static int
+xml_begin(struct md_mbuf *mbuf, const struct md_args *args)
+{
+ size_t res;
+
+ if ( ! ml_puts(mbuf, "<?xml version=\"1.0\" "
+ "encoding=\"UTF-8\"?>\n", &res))
+ return(0);
+ if ( ! ml_puts(mbuf, "<mdoc xmlns:block=\"block\" "
+ "xmlns:special=\"special\" "
+ "xmlns:inline=\"inline\">", &res))
+ return(0);
+
+ return(1);
+}
+
+
+static int
+xml_end(struct md_mbuf *mbuf, const struct md_args *args)
+{
+ size_t res;
+
+ res = 0;
+ if ( ! ml_puts(mbuf, "</mdoc>", &res))
+ return(0);
+
+ return(1);
+}
+
static ssize_t
xml_begintag(struct md_mbuf *mbuf, const struct md_args *args,
@@ -46,14 +81,20 @@ xml_begintag(struct md_mbuf *mbuf, const struct md_args *args,
if ( ! ml_nputs(mbuf, "block:", 6, &res))
return(-1);
break;
+ case (MD_NS_BODY):
+ if ( ! ml_nputs(mbuf, "body:", 5, &res))
+ return(-1);
+ break;
+ case (MD_NS_HEAD):
+ if ( ! ml_nputs(mbuf, "head:", 5, &res))
+ return(-1);
+ break;
case (MD_NS_INLINE):
if ( ! ml_nputs(mbuf, "inline:", 7, &res))
return(-1);
break;
default:
- if ( ! ml_nputs(mbuf, "mbuf", 4, &res))
- return(-1);
- return((ssize_t)res);
+ break;
}
if ( ! ml_nputs(mbuf, toknames[tok],
@@ -81,10 +122,16 @@ xml_endtag(struct md_mbuf *mbuf, const struct md_args *args,
if ( ! ml_nputs(mbuf, "inline:", 7, &res))
return(-1);
break;
- default:
- if ( ! ml_nputs(mbuf, "mbuf", 4, &res))
+ case (MD_NS_BODY):
+ if ( ! ml_nputs(mbuf, "body:", 5, &res))
+ return(-1);
+ break;
+ case (MD_NS_HEAD):
+ if ( ! ml_nputs(mbuf, "head:", 5, &res))
return(-1);
- return((ssize_t)res);
+ break;
+ default:
+ break;
}
if ( ! ml_nputs(mbuf, toknames[tok],
@@ -116,6 +163,7 @@ md_init_xml(const struct md_args *args,
struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
{
- return(mlg_alloc(args, rbuf, mbuf, xml_begintag, xml_endtag));
+ return(mlg_alloc(args, rbuf, mbuf, xml_begintag,
+ xml_endtag, xml_begin, xml_end));
}