version 1.1, 2008/11/29 14:14:21 |
version 1.5, 2008/11/30 20:00:08 |
|
|
#include "libmdocml.h" |
#include "libmdocml.h" |
#include "private.h" |
#include "private.h" |
|
|
|
#define INDENT 4 |
|
|
#ifdef __linux__ /* FIXME */ |
#ifdef __linux__ /* FIXME */ |
#define strlcat strncat |
#define strlcat strncat |
#endif |
#endif |
|
|
struct md_valid { |
struct md_valid { |
Line 50 static void roffmsg(void *arg, enum roffmsg, |
|
Line 52 static void roffmsg(void *arg, enum roffmsg, |
|
static int roffhead(void *); |
static int roffhead(void *); |
static int rofftail(void *); |
static int rofftail(void *); |
static int roffin(void *, int, int *, char **); |
static int roffin(void *, int, int *, char **); |
static int roffdata(void *, char *); |
static int roffdata(void *, int, char *); |
static int roffout(void *, int); |
static int roffout(void *, int); |
static int roffblkin(void *, int); |
static int roffblkin(void *, int, int *, char **); |
static int roffblkout(void *, int); |
static int roffblkout(void *, int); |
static int roffspecial(void *, int); |
static int roffspecial(void *, int); |
|
|
static int mbuf_newline(struct md_valid *); |
static int mbuf_newline(struct md_valid *); |
static int mbuf_indent(struct md_valid *); |
static int mbuf_indent(struct md_valid *); |
static int mbuf_data(struct md_valid *, char *); |
static int mbuf_data(struct md_valid *, int, char *); |
|
|
|
|
static int |
static int |
Line 66 mbuf_indent(struct md_valid *p) |
|
Line 68 mbuf_indent(struct md_valid *p) |
|
{ |
{ |
size_t i; |
size_t i; |
|
|
assert(0 == p->pos); |
assert(p->pos == 0); |
|
|
for (i = 0; i < MIN(p->indent, 4); i++) |
/* LINTED */ |
|
for (i = 0; i < MIN(p->indent, INDENT); i++) |
if ( ! md_buf_putstring(p->mbuf, " ")) |
if ( ! md_buf_putstring(p->mbuf, " ")) |
return(0); |
return(0); |
|
|
p->pos = i * 4; |
p->pos += i * INDENT; |
return(1); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
mbuf_atnewline(struct md_valid *p) |
|
{ |
|
|
|
return(p->pos == MIN(4, p->indent)); |
|
} |
|
|
|
|
|
static int |
|
mbuf_newline(struct md_valid *p) |
mbuf_newline(struct md_valid *p) |
{ |
{ |
|
|
if (mbuf_atnewline(p)) |
|
return(1); |
|
if ( ! md_buf_putchar(p->mbuf, '\n')) |
if ( ! md_buf_putchar(p->mbuf, '\n')) |
return(0); |
return(0); |
|
|
p->pos = 0; |
p->pos = 0; |
return(mbuf_indent(p)); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
mbuf_data(struct md_valid *p, char *buf) |
mbuf_data(struct md_valid *p, int space, char *buf) |
{ |
{ |
size_t sz; |
size_t sz; |
char *bufp; |
char *bufp; |
Line 111 mbuf_data(struct md_valid *p, char *buf) |
|
Line 104 mbuf_data(struct md_valid *p, char *buf) |
|
if (MD_LITERAL & p->flags) |
if (MD_LITERAL & p->flags) |
return(md_buf_putstring(p->mbuf, buf)); |
return(md_buf_putstring(p->mbuf, buf)); |
|
|
if (0 == p->pos) |
|
mbuf_indent(p); |
|
|
|
/* |
|
* Indent if we're at the beginning of a line. Don't indent |
|
* more than 16 or so characters. |
|
*/ |
|
|
|
while (*buf) { |
while (*buf) { |
while (*buf && isspace(*buf)) |
while (*buf && isspace(*buf)) |
buf++; |
buf++; |
Line 136 mbuf_data(struct md_valid *p, char *buf) |
|
Line 121 mbuf_data(struct md_valid *p, char *buf) |
|
/* Process word. */ |
/* Process word. */ |
|
|
sz = strlen(bufp); |
sz = strlen(bufp); |
|
|
if (sz + p->pos < 72) { |
if (0 == p->pos) { |
|
if ( ! mbuf_indent(p)) |
|
return(0); |
if ( ! md_buf_putstring(p->mbuf, bufp)) |
if ( ! md_buf_putstring(p->mbuf, bufp)) |
return(0); |
return(0); |
|
|
/* FIXME: check punctuation. */ |
if (p->indent * INDENT + sz >= 72) { |
|
if ( ! mbuf_newline(p)) |
|
return(0); |
|
continue; |
|
} |
|
|
if ( ! md_buf_putchar(p->mbuf, ' ')) |
p->pos += sz; |
return(0); |
|
p->pos += sz + 1; |
|
continue; |
continue; |
} |
} |
|
|
if ( ! mbuf_newline(p)) |
/* |
return(0); |
* FIXME: punctuation shouldn't have a newline before |
|
* it! |
|
*/ |
|
|
|
if (sz + p->pos >= 72) { |
|
if ( ! mbuf_newline(p)) |
|
return(0); |
|
if ( ! mbuf_indent(p)) |
|
return(0); |
|
} else if (space) |
|
if ( ! md_buf_putchar(p->mbuf, ' ')) |
|
return(0); |
|
|
if ( ! md_buf_putstring(p->mbuf, bufp)) |
if ( ! md_buf_putstring(p->mbuf, bufp)) |
return(0); |
return(0); |
|
|
/* FIXME: check punctuation. */ |
p->pos += sz + (size_t)(space ? 1 : 0); |
|
|
if ( ! md_buf_putchar(p->mbuf, ' ')) |
|
return(0); |
|
p->pos += sz + 1; |
|
} |
} |
|
|
return(1); |
return(1); |
Line 229 md_init_valid(const struct md_args *args, |
|
Line 225 md_init_valid(const struct md_args *args, |
|
static int |
static int |
roffhead(void *arg) |
roffhead(void *arg) |
{ |
{ |
|
struct md_valid *p; |
|
|
return(1); |
assert(arg); |
|
p = (struct md_valid *)arg; |
|
|
|
if ( ! md_buf_putstring(p->mbuf, "<?xml version=\"1.0\" " |
|
"encoding=\"UTF-8\"?>\n")) |
|
return(0); |
|
|
|
if ( ! md_buf_putstring(p->mbuf, "<mdoc>")) |
|
return(0); |
|
p->indent++; |
|
|
|
return(mbuf_newline(p)); |
} |
} |
|
|
|
|
Line 242 rofftail(void *arg) |
|
Line 250 rofftail(void *arg) |
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
|
|
if (mbuf_atnewline(p)) |
if (0 != p->pos && ! mbuf_newline(p)) |
return(1); |
return(0); |
|
return(md_buf_putstring(p->mbuf, "</mdoc>\n")); |
return(md_buf_putchar(p->mbuf, '\n')); |
|
} |
} |
|
|
|
|
|
/* ARGSUSED */ |
static int |
static int |
roffspecial(void *arg, int tok) |
roffspecial(void *arg, int tok) |
{ |
{ |
Line 258 roffspecial(void *arg, int tok) |
|
Line 266 roffspecial(void *arg, int tok) |
|
|
|
|
|
static int |
static int |
roffblkin(void *arg, int tok) |
roffblkin(void *arg, int tok, int *argc, char **argv) |
{ |
{ |
struct md_valid *p; |
struct md_valid *p; |
|
int i; |
|
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
|
|
if ( ! mbuf_atnewline(p)) { |
if (0 != p->pos) { |
if ( ! md_buf_putchar(p->mbuf, '\n')) |
if ( ! mbuf_newline(p)) |
return(0); |
return(0); |
p->pos = 0; |
|
if ( ! mbuf_indent(p)) |
if ( ! mbuf_indent(p)) |
return(0); |
return(0); |
} |
} else if ( ! mbuf_indent(p)) |
|
return(0); |
|
|
|
if ( ! md_buf_putchar(p->mbuf, '<')) |
|
return(0); |
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
return(0); |
return(0); |
|
|
if ( ! md_buf_putchar(p->mbuf, '\n')) |
for (i = 0; ROFF_ARGMAX != argc[i]; i++) { |
|
if ( ! md_buf_putchar(p->mbuf, ' ')) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, tokargnames[argc[i]])) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, "=\"")) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, argv[i] ? |
|
argv[i] : "true")) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, "\"")) |
|
return(0); |
|
} |
|
|
|
if ( ! md_buf_putchar(p->mbuf, '>')) |
return(0); |
return(0); |
|
if ( ! mbuf_newline(p)) |
|
return(0); |
|
|
p->pos = 0; |
|
p->indent++; |
p->indent++; |
|
return(1); |
return(mbuf_indent(p)); |
|
} |
} |
|
|
|
|
Line 294 roffblkout(void *arg, int tok) |
|
Line 319 roffblkout(void *arg, int tok) |
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
|
|
if ( ! md_buf_putchar(p->mbuf, '\n')) |
p->indent--; |
|
|
|
if (0 != p->pos) { |
|
if ( ! mbuf_newline(p)) |
|
return(0); |
|
if ( ! mbuf_indent(p)) |
|
return(0); |
|
} else if ( ! mbuf_indent(p)) |
return(0); |
return(0); |
|
|
p->pos = 0; |
if ( ! md_buf_putstring(p->mbuf, "</")) |
p->indent--; |
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, ">")) |
|
return(0); |
|
if ( ! mbuf_newline(p)) |
|
return(0); |
|
|
return(mbuf_indent(p)); |
return(1); |
} |
} |
|
|
|
|
static int |
static int |
roffin(void *arg, int tok, int *argcp, char **argvp) |
roffin(void *arg, int tok, int *argc, char **argv) |
{ |
{ |
|
struct md_valid *p; |
|
int i; |
|
|
|
assert(arg); |
|
p = (struct md_valid *)arg; |
|
|
|
if (0 == p->pos && ! mbuf_indent(p)) |
|
return(0); |
|
|
|
/* FIXME: put into a buffer before writing (line length). */ |
|
|
|
/* FIXME: not always with a space... */ |
|
|
|
if ( ! md_buf_putstring(p->mbuf, " <")) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
|
return(0); |
|
|
|
for (i = 0; ROFF_ARGMAX != argc[i]; i++) { |
|
if ( ! md_buf_putchar(p->mbuf, ' ')) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, tokargnames[argc[i]])) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, "=\"")) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, argv[i] ? |
|
argv[i] : "true")) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, "\"")) |
|
return(0); |
|
|
|
p->pos += strlen(toknames[tok]) + 4 + |
|
strlen(tokargnames[argc[i]]) + |
|
strlen(argv[i] ? argv[i] : "true"); |
|
} |
|
|
|
if ( ! md_buf_putstring(p->mbuf, ">")) |
|
return(0); |
|
|
|
p->pos += strlen(toknames[tok]) + 3; |
|
|
return(1); |
return(1); |
} |
} |
|
|
Line 315 roffin(void *arg, int tok, int *argcp, char **argvp) |
|
Line 393 roffin(void *arg, int tok, int *argcp, char **argvp) |
|
static int |
static int |
roffout(void *arg, int tok) |
roffout(void *arg, int tok) |
{ |
{ |
|
struct md_valid *p; |
|
|
|
assert(arg); |
|
p = (struct md_valid *)arg; |
|
|
|
if (0 == p->pos && ! mbuf_indent(p)) |
|
return(0); |
|
|
|
if ( ! md_buf_putstring(p->mbuf, "</")) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, toknames[tok])) |
|
return(0); |
|
if ( ! md_buf_putstring(p->mbuf, ">")) |
|
return(0); |
|
|
|
p->pos += strlen(toknames[tok]) + 2; |
|
|
return(1); |
return(1); |
} |
} |
|
|
Line 355 roffmsg(void *arg, enum roffmsg lvl, |
|
Line 449 roffmsg(void *arg, enum roffmsg lvl, |
|
|
|
|
|
static int |
static int |
roffdata(void *arg, char *buf) |
roffdata(void *arg, int space, char *buf) |
{ |
{ |
struct md_valid *p; |
struct md_valid *p; |
|
|
assert(arg); |
assert(arg); |
p = (struct md_valid *)arg; |
p = (struct md_valid *)arg; |
return(mbuf_data(p, buf)); |
return(mbuf_data(p, space, buf)); |
} |
} |