]>
git.cameronkatri.com Git - mandoc.git/blob - xml.c
1 /* $Id: xml.c,v 1.4 2008/12/01 15:32:36 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/param.h>
28 #include "libmdocml.h"
34 #ifdef __linux__ /* FIXME */
35 #define strlcat strncat
48 const struct md_args
*args
;
49 const struct md_rbuf
*rbuf
;
52 struct rofftree
*tree
;
57 #define MD_LITERAL (1 << 0) /* FIXME */
60 static void roffmsg(void *arg
, enum roffmsg
,
61 const char *, const char *, char *);
62 static int roffhead(void *);
63 static int rofftail(void *);
64 static int roffin(void *, int, int *, char **);
65 static int roffdata(void *, int, char *);
66 static int roffout(void *, int);
67 static int roffblkin(void *, int, int *, char **);
68 static int roffblkout(void *, int);
69 static int roffspecial(void *, int);
71 static int mbuf_newline(struct md_xml
*);
72 static int mbuf_indent(struct md_xml
*);
73 static int mbuf_data(struct md_xml
*, int, char *);
74 static int mbuf_putstring(struct md_xml
*,
76 static int mbuf_nputstring(struct md_xml
*,
77 const char *, size_t);
78 static int mbuf_puts(struct md_xml
*, const char *);
79 static int mbuf_nputs(struct md_xml
*,
80 const char *, size_t);
84 mbuf_putstring(struct md_xml
*p
, const char *buf
)
87 return(mbuf_nputstring(p
, buf
, strlen(buf
)));
92 mbuf_nputstring(struct md_xml
*p
, const char *buf
, size_t sz
)
96 for (i
= 0; i
< sz
; i
++) {
99 if ( ! md_buf_puts(p
->mbuf
, "&", 5))
104 if ( ! md_buf_puts(p
->mbuf
, """, 6))
109 if ( ! md_buf_putchar(p
->mbuf
, buf
[i
]))
120 mbuf_nputs(struct md_xml
*p
, const char *buf
, size_t sz
)
124 return(md_buf_puts(p
->mbuf
, buf
, sz
));
129 mbuf_puts(struct md_xml
*p
, const char *buf
)
132 return(mbuf_nputs(p
, buf
, strlen(buf
)));
137 mbuf_indent(struct md_xml
*p
)
144 for (i
= 0; i
< MIN(p
->indent
, INDENT
); i
++)
145 if ( ! md_buf_putstring(p
->mbuf
, " "))
148 p
->pos
+= i
* INDENT
;
154 mbuf_newline(struct md_xml
*p
)
157 if ( ! md_buf_putchar(p
->mbuf
, '\n'))
166 mbuf_data(struct md_xml
*p
, int space
, char *buf
)
172 assert(0 != p
->indent
);
174 if (MD_LITERAL
& p
->flags
)
175 return(mbuf_putstring(p
, buf
));
178 while (*buf
&& isspace(*buf
))
185 while (*buf
&& ! isspace(*buf
))
194 if ( ! mbuf_indent(p
))
196 if ( ! mbuf_nputstring(p
, bufp
, sz
))
198 if (p
->indent
* INDENT
+ sz
>= COLUMNS
) {
199 if ( ! mbuf_newline(p
))
206 if (space
&& sz
+ p
->pos
>= COLUMNS
) {
207 if ( ! mbuf_newline(p
))
209 if ( ! mbuf_indent(p
))
212 if ( ! mbuf_nputs(p
, " ", 1))
216 if ( ! mbuf_nputstring(p
, bufp
, sz
))
219 if ( ! space
&& p
->pos
>= COLUMNS
)
220 if ( ! mbuf_newline(p
))
229 md_line_xml(void *arg
, char *buf
)
233 p
= (struct md_xml
*)arg
;
234 return(roff_engine(p
->tree
, buf
));
239 md_exit_xml(void *data
, int flush
)
244 p
= (struct md_xml
*)data
;
245 c
= roff_free(p
->tree
, flush
);
253 md_init_xml(const struct md_args
*args
,
254 struct md_mbuf
*mbuf
, const struct md_rbuf
*rbuf
)
259 cb
.roffhead
= roffhead
;
260 cb
.rofftail
= rofftail
;
262 cb
.roffout
= roffout
;
263 cb
.roffblkin
= roffblkin
;
264 cb
.roffblkout
= roffblkout
;
265 cb
.roffspecial
= roffspecial
;
266 cb
.roffmsg
= roffmsg
;
267 cb
.roffdata
= roffdata
;
269 if (NULL
== (p
= calloc(1, sizeof(struct md_xml
))))
278 if (NULL
== (p
->tree
= roff_alloc(&cb
, p
))) {
294 p
= (struct md_xml
*)arg
;
296 if ( ! mbuf_puts(p
, "<?xml version=\"1.0\" "
297 "encoding=\"UTF-8\"?>\n"))
299 if ( ! mbuf_puts(p
, "<mdoc xmlns:block=\"block\" "
300 "xmlns:special=\"special\" "
301 "xmlns:inline=\"inline\">"))
306 return(mbuf_newline(p
));
316 p
= (struct md_xml
*)arg
;
318 if (0 != p
->pos
&& ! mbuf_newline(p
))
321 if ( ! mbuf_puts(p
, "</mdoc>"))
325 return(mbuf_newline(p
));
331 roffspecial(void *arg
, int tok
)
336 p
= (struct md_xml
*)arg
;
340 p
->last
= MD_OVERRIDE
;
351 roffblkin(void *arg
, int tok
, int *argc
, char **argv
)
357 p
= (struct md_xml
*)arg
;
360 if ( ! mbuf_newline(p
))
362 if ( ! mbuf_indent(p
))
364 } else if ( ! mbuf_indent(p
))
367 if ( ! mbuf_nputs(p
, "<", 1))
369 if ( ! mbuf_nputs(p
, "block:", 6))
371 if ( ! mbuf_puts(p
, toknames
[tok
]))
374 /* FIXME: xml won't like standards args (e.g., p1003.1-90). */
376 for (i
= 0; ROFF_ARGMAX
!= argc
[i
]; i
++) {
377 if ( ! mbuf_nputs(p
, " ", 1))
379 if ( ! mbuf_puts(p
, tokargnames
[argc
[i
]]))
381 if ( ! mbuf_nputs(p
, "=\"", 2))
383 if ( ! mbuf_putstring(p
, argv
[i
] ? argv
[i
] : "true"))
385 if ( ! mbuf_nputs(p
, "\"", 1))
389 if ( ! mbuf_nputs(p
, ">", 1))
394 return(mbuf_newline(p
));
399 roffblkout(void *arg
, int tok
)
404 p
= (struct md_xml
*)arg
;
409 if ( ! mbuf_newline(p
))
411 if ( ! mbuf_indent(p
))
413 } else if ( ! mbuf_indent(p
))
416 if ( ! mbuf_nputs(p
, "</", 2))
418 if ( ! mbuf_nputs(p
, "block:", 6))
420 if ( ! mbuf_puts(p
, toknames
[tok
]))
422 if ( ! mbuf_nputs(p
, ">", 1))
426 return(mbuf_newline(p
));
431 roffin(void *arg
, int tok
, int *argc
, char **argv
)
437 p
= (struct md_xml
*)arg
;
440 * FIXME: put all of this in a buffer, then check the buffer
441 * length versus the column width for nicer output. This is a
445 if (p
->pos
+ 11 > COLUMNS
)
446 if ( ! mbuf_newline(p
))
454 if ( ! mbuf_nputs(p
, " ", 1))
460 } else if ( ! mbuf_indent(p
))
465 if ( ! mbuf_nputs(p
, "<", 1))
467 if ( ! mbuf_nputs(p
, "inline:", 7))
469 if ( ! mbuf_puts(p
, toknames
[tok
]))
472 for (i
= 0; ROFF_ARGMAX
!= argc
[i
]; i
++) {
473 if ( ! mbuf_nputs(p
, " ", 1))
475 if ( ! mbuf_puts(p
, tokargnames
[argc
[i
]]))
477 if ( ! mbuf_nputs(p
, "=\"", 2))
479 if ( ! mbuf_putstring(p
, argv
[i
] ? argv
[i
] : "true"))
481 if ( ! mbuf_nputs(p
, "\"", 1))
484 return(mbuf_nputs(p
, ">", 1));
489 roffout(void *arg
, int tok
)
494 p
= (struct md_xml
*)arg
;
496 /* Continue with a regular out token. */
498 if (0 == p
->pos
&& ! mbuf_indent(p
))
503 if ( ! mbuf_nputs(p
, "</", 2))
505 if ( ! mbuf_nputs(p
, "inline:", 7))
507 if ( ! mbuf_puts(p
, toknames
[tok
]))
509 return(mbuf_nputs(p
, ">", 1));
514 roffmsg(void *arg
, enum roffmsg lvl
,
515 const char *buf
, const char *pos
, char *msg
)
521 p
= (struct md_xml
*)arg
;
525 if ( ! (MD_WARN_ALL
& p
->args
->warnings
))
537 (void)fprintf(stderr
, "%s:%zu: %s: %s (column %zu)\n",
538 p
->rbuf
->name
, p
->rbuf
->line
, level
,
541 (void)fprintf(stderr
, "%s: %s: %s\n",
542 p
->rbuf
->name
, level
, msg
);
548 roffdata(void *arg
, int space
, char *buf
)
553 p
= (struct md_xml
*)arg
;
554 if ( ! mbuf_data(p
, space
, buf
))