-/* $Id: xml.c,v 1.1 2008/11/30 21:41:35 kristaps Exp $ */
+/* $Id: xml.c,v 1.7 2008/12/02 00:15:41 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
#include "libmdocml.h"
#include "private.h"
-#define INDENT 4
-#define COLUMNS 60
+#define MAXINDENT 8
+#define COLUMNS 72
#ifdef __linux__ /* FIXME */
#define strlcat strncat
#endif
+enum md_ns {
+ MD_NS_BLOCK,
+ MD_NS_INLINE,
+ MD_NS_DEFAULT
+};
+
enum md_tok {
MD_BLKIN,
MD_BLKOUT,
MD_IN,
MD_OUT,
- MD_TEXT
+ MD_TEXT,
+ MD_OVERRIDE
};
struct md_xml {
const char *);
static int mbuf_nputstring(struct md_xml *,
const char *, size_t);
+static int mbuf_puts(struct md_xml *, const char *);
+static int mbuf_nputs(struct md_xml *,
+ const char *, size_t);
+static int mbuf_begintag(struct md_xml *, const char *,
+ enum md_ns, int *, char **);
+static int mbuf_endtag(struct md_xml *,
+ const char *, enum md_ns);
+
+
+static int
+mbuf_begintag(struct md_xml *p, const char *name, enum md_ns ns,
+ int *argc, char **argv)
+{
+ int i;
+
+ if ( ! mbuf_nputs(p, "<", 1))
+ return(0);
+
+ switch (ns) {
+ case (MD_NS_BLOCK):
+ if ( ! mbuf_nputs(p, "block:", 6))
+ return(0);
+ break;
+ case (MD_NS_INLINE):
+ if ( ! mbuf_nputs(p, "inline:", 7))
+ return(0);
+ break;
+ default:
+ break;
+ }
+
+ if ( ! mbuf_puts(p, name))
+ return(0);
+
+ for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
+ if ( ! mbuf_nputs(p, " ", 1))
+ return(0);
+ if ( ! mbuf_puts(p, tokargnames[argc[i]]))
+ return(0);
+ if ( ! mbuf_nputs(p, "=\"", 2))
+ return(0);
+ if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))
+ return(0);
+ if ( ! mbuf_nputs(p, "\"", 1))
+ return(0);
+ }
+ return(mbuf_nputs(p, ">", 1));
+}
+
+
+static int
+mbuf_endtag(struct md_xml *p, const char *tag, enum md_ns ns)
+{
+ if ( ! mbuf_nputs(p, "</", 2))
+ return(0);
+
+ switch (ns) {
+ case (MD_NS_BLOCK):
+ if ( ! mbuf_nputs(p, "block:", 6))
+ return(0);
+ break;
+ case (MD_NS_INLINE):
+ if ( ! mbuf_nputs(p, "inline:", 7))
+ return(0);
+ break;
+ default:
+ break;
+ }
+
+ if ( ! mbuf_puts(p, tag))
+ return(0);
+ return(mbuf_nputs(p, ">", 1));
+}
static int
static int
mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz)
+{
+ int i;
+
+ for (i = 0; i < (int)sz; i++) {
+ switch (buf[i]) {
+ case ('&'):
+ if ( ! md_buf_puts(p->mbuf, "&", 5))
+ return(0);
+ p->pos += 5;
+ break;
+ case ('"'):
+ if ( ! md_buf_puts(p->mbuf, """, 6))
+ return(0);
+ p->pos += 6;
+ break;
+ case ('<'):
+ if ( ! md_buf_puts(p->mbuf, "<", 4))
+ return(0);
+ p->pos += 4;
+ break;
+ case ('>'):
+ if ( ! md_buf_puts(p->mbuf, ">", 4))
+ return(0);
+ p->pos += 4;
+ break;
+ default:
+ if ( ! md_buf_putchar(p->mbuf, buf[i]))
+ return(0);
+ p->pos++;
+ break;
+ }
+ }
+ return(1);
+}
+
+
+static int
+mbuf_nputs(struct md_xml *p, const char *buf, size_t sz)
{
p->pos += sz;
}
+static int
+mbuf_puts(struct md_xml *p, const char *buf)
+{
+
+ return(mbuf_nputs(p, buf, strlen(buf)));
+}
+
+
static int
mbuf_indent(struct md_xml *p)
{
assert(p->pos == 0);
/* LINTED */
- for (i = 0; i < MIN(p->indent, INDENT); i++)
+ for (i = 0; i < MIN(p->indent, MAXINDENT); i++)
if ( ! md_buf_putstring(p->mbuf, " "))
return(0);
- p->pos += i * INDENT;
+ p->pos += i * 4;
return(1);
}
return(0);
if ( ! mbuf_nputstring(p, bufp, sz))
return(0);
- if (p->indent * INDENT + sz >= COLUMNS) {
+ if (p->indent * MAXINDENT + sz >= COLUMNS) {
if ( ! mbuf_newline(p))
return(0);
continue;
if ( ! mbuf_indent(p))
return(0);
} else if (space) {
- if ( ! mbuf_nputstring(p, " ", 1))
+ if ( ! mbuf_nputs(p, " ", 1))
return(0);
}
assert(arg);
p = (struct md_xml *)arg;
- if ( ! mbuf_putstring(p, "<?xml version=\"1.0\" "
+ if ( ! mbuf_puts(p, "<?xml version=\"1.0\" "
"encoding=\"UTF-8\"?>\n"))
return(0);
- if ( ! mbuf_nputstring(p, "<block:mdoc>", 12))
+ if ( ! mbuf_puts(p, "<mdoc xmlns:block=\"block\" "
+ "xmlns:special=\"special\" "
+ "xmlns:inline=\"inline\">"))
return(0);
p->indent++;
if (0 != p->pos && ! mbuf_newline(p))
return(0);
- if ( ! mbuf_nputstring(p, "</block:mdoc>", 13))
+ p->last = MD_BLKOUT;
+ if ( ! mbuf_endtag(p, "mdoc", MD_NS_DEFAULT))
return(0);
- p->last = MD_BLKOUT;
return(mbuf_newline(p));
}
-/* ARGSUSED */
static int
roffspecial(void *arg, int tok)
{
+ struct md_xml *p;
+
+ assert(arg);
+ p = (struct md_xml *)arg;
+
+ /* FIXME: this is completely ad hoc. */
+
+ switch (tok) {
+ case (ROFF_Ns):
+ p->last = MD_OVERRIDE;
+ break;
+ default:
+ break;
+ }
- /* FIXME */
return(1);
}
roffblkin(void *arg, int tok, int *argc, char **argv)
{
struct md_xml *p;
- int i;
assert(arg);
p = (struct md_xml *)arg;
} else if ( ! mbuf_indent(p))
return(0);
- if ( ! mbuf_nputstring(p, "<", 1))
- return(0);
- if ( ! mbuf_nputstring(p, "block:", 6))
- return(0);
- if ( ! mbuf_putstring(p, toknames[tok]))
- return(0);
-
- for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
- if ( ! mbuf_nputstring(p, " ", 1))
- return(0);
- if ( ! mbuf_putstring(p, tokargnames[argc[i]]))
- return(0);
- if ( ! mbuf_nputstring(p, "=\"", 2))
- return(0);
- if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))
- return(0);
- if ( ! mbuf_nputstring(p, "\"", 1))
- return(0);
- }
-
- if ( ! mbuf_nputstring(p, ">", 1))
- return(0);
+ /* FIXME: xml won't like standards args (e.g., p1003.1-90). */
p->last = MD_BLKIN;
p->indent++;
+
+ if ( ! mbuf_begintag(p, toknames[tok], MD_NS_BLOCK,
+ argc, argv))
+ return(0);
return(mbuf_newline(p));
}
} else if ( ! mbuf_indent(p))
return(0);
- if ( ! mbuf_nputstring(p, "</", 2))
- return(0);
- if ( ! mbuf_nputstring(p, "block:", 6))
- return(0);
- if ( ! mbuf_putstring(p, toknames[tok]))
- return(0);
- if ( ! mbuf_nputstring(p, ">", 1))
- return(0);
-
p->last = MD_BLKOUT;
+
+ if ( ! mbuf_endtag(p, toknames[tok], MD_NS_BLOCK))
+ return(0);
return(mbuf_newline(p));
}
roffin(void *arg, int tok, int *argc, char **argv)
{
struct md_xml *p;
- int i;
assert(arg);
p = (struct md_xml *)arg;
case (MD_TEXT):
/* FALLTHROUGH */
case (MD_OUT):
- if ( ! mbuf_nputstring(p, " ", 1))
+ if ( ! mbuf_nputs(p, " ", 1))
return(0);
break;
default:
return(0);
p->last = MD_IN;
-
- if ( ! mbuf_nputstring(p, "<", 1))
- return(0);
- if ( ! mbuf_nputstring(p, "inline:", 7))
- return(0);
- if ( ! mbuf_putstring(p, toknames[tok]))
- return(0);
-
- for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
- if ( ! mbuf_nputstring(p, " ", 1))
- return(0);
- if ( ! mbuf_putstring(p, tokargnames[argc[i]]))
- return(0);
- if ( ! mbuf_nputstring(p, "=\"", 2))
- return(0);
- if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))
- return(0);
- if ( ! mbuf_nputstring(p, "\"", 1))
- return(0);
- }
- return(mbuf_nputstring(p, ">", 1));
+ return(mbuf_begintag(p, toknames[tok],
+ MD_NS_INLINE, argc, argv));
}
return(0);
p->last = MD_OUT;
-
- if ( ! mbuf_nputstring(p, "</", 2))
- return(0);
- if ( ! mbuf_nputstring(p, "inline:", 7))
- return(0);
- if ( ! mbuf_putstring(p, toknames[tok]))
- return(0);
- return(mbuf_nputstring(p, ">", 1));
+ return(mbuf_endtag(p, toknames[tok], MD_NS_INLINE));
}
p->last = MD_TEXT;
return(1);
}
+