]>
git.cameronkatri.com Git - mandoc.git/blob - xml.c
1 /* $Id: xml.c,v 1.2 2008/11/30 23:05:57 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
47 const struct md_args
*args
;
48 const struct md_rbuf
*rbuf
;
51 struct rofftree
*tree
;
56 #define MD_LITERAL (1 << 0) /* FIXME */
59 static void roffmsg(void *arg
, enum roffmsg
,
60 const char *, const char *, char *);
61 static int roffhead(void *);
62 static int rofftail(void *);
63 static int roffin(void *, int, int *, char **);
64 static int roffdata(void *, int, char *);
65 static int roffout(void *, int);
66 static int roffblkin(void *, int, int *, char **);
67 static int roffblkout(void *, int);
68 static int roffspecial(void *, int);
70 static int mbuf_newline(struct md_xml
*);
71 static int mbuf_indent(struct md_xml
*);
72 static int mbuf_data(struct md_xml
*, int, char *);
73 static int mbuf_putstring(struct md_xml
*,
75 static int mbuf_nputstring(struct md_xml
*,
76 const char *, size_t);
77 static int mbuf_puts(struct md_xml
*, const char *);
78 static int mbuf_nputs(struct md_xml
*,
79 const char *, size_t);
83 mbuf_putstring(struct md_xml
*p
, const char *buf
)
86 return(mbuf_nputstring(p
, buf
, strlen(buf
)));
91 mbuf_nputstring(struct md_xml
*p
, const char *buf
, size_t sz
)
95 for (i
= 0; i
< sz
; i
++) {
98 if ( ! md_buf_puts(p
->mbuf
, "&", 5))
103 if ( ! md_buf_puts(p
->mbuf
, """, 6))
108 if ( ! md_buf_putchar(p
->mbuf
, buf
[i
]))
119 mbuf_nputs(struct md_xml
*p
, const char *buf
, size_t sz
)
123 return(md_buf_puts(p
->mbuf
, buf
, sz
));
128 mbuf_puts(struct md_xml
*p
, const char *buf
)
131 return(mbuf_nputs(p
, buf
, strlen(buf
)));
136 mbuf_indent(struct md_xml
*p
)
143 for (i
= 0; i
< MIN(p
->indent
, INDENT
); i
++)
144 if ( ! md_buf_putstring(p
->mbuf
, " "))
147 p
->pos
+= i
* INDENT
;
153 mbuf_newline(struct md_xml
*p
)
156 if ( ! md_buf_putchar(p
->mbuf
, '\n'))
165 mbuf_data(struct md_xml
*p
, int space
, char *buf
)
171 assert(0 != p
->indent
);
173 if (MD_LITERAL
& p
->flags
)
174 return(mbuf_putstring(p
, buf
));
177 while (*buf
&& isspace(*buf
))
184 while (*buf
&& ! isspace(*buf
))
193 if ( ! mbuf_indent(p
))
195 if ( ! mbuf_nputstring(p
, bufp
, sz
))
197 if (p
->indent
* INDENT
+ sz
>= COLUMNS
) {
198 if ( ! mbuf_newline(p
))
205 if (space
&& sz
+ p
->pos
>= COLUMNS
) {
206 if ( ! mbuf_newline(p
))
208 if ( ! mbuf_indent(p
))
211 if ( ! mbuf_nputs(p
, " ", 1))
215 if ( ! mbuf_nputstring(p
, bufp
, sz
))
218 if ( ! space
&& p
->pos
>= COLUMNS
)
219 if ( ! mbuf_newline(p
))
228 md_line_xml(void *arg
, char *buf
)
232 p
= (struct md_xml
*)arg
;
233 return(roff_engine(p
->tree
, buf
));
238 md_exit_xml(void *data
, int flush
)
243 p
= (struct md_xml
*)data
;
244 c
= roff_free(p
->tree
, flush
);
252 md_init_xml(const struct md_args
*args
,
253 struct md_mbuf
*mbuf
, const struct md_rbuf
*rbuf
)
258 cb
.roffhead
= roffhead
;
259 cb
.rofftail
= rofftail
;
261 cb
.roffout
= roffout
;
262 cb
.roffblkin
= roffblkin
;
263 cb
.roffblkout
= roffblkout
;
264 cb
.roffspecial
= roffspecial
;
265 cb
.roffmsg
= roffmsg
;
266 cb
.roffdata
= roffdata
;
268 if (NULL
== (p
= calloc(1, sizeof(struct md_xml
))))
277 if (NULL
== (p
->tree
= roff_alloc(&cb
, p
))) {
293 p
= (struct md_xml
*)arg
;
295 if ( ! mbuf_puts(p
, "<?xml version=\"1.0\" "
296 "encoding=\"UTF-8\"?>\n"))
298 if ( ! mbuf_puts(p
, "<mdoc xmlns:block=\"block\" "
299 "xmlns:special=\"special\" "
300 "xmlns:inline=\"inline\">"))
305 return(mbuf_newline(p
));
315 p
= (struct md_xml
*)arg
;
317 if (0 != p
->pos
&& ! mbuf_newline(p
))
320 if ( ! mbuf_puts(p
, "</mdoc>"))
324 return(mbuf_newline(p
));
330 roffspecial(void *arg
, int tok
)
339 roffblkin(void *arg
, int tok
, int *argc
, char **argv
)
345 p
= (struct md_xml
*)arg
;
348 if ( ! mbuf_newline(p
))
350 if ( ! mbuf_indent(p
))
352 } else if ( ! mbuf_indent(p
))
355 if ( ! mbuf_nputs(p
, "<", 1))
357 if ( ! mbuf_nputs(p
, "block:", 6))
359 if ( ! mbuf_puts(p
, toknames
[tok
]))
362 /* FIXME: xml won't like standards args (e.g., p1003.1-90). */
364 for (i
= 0; ROFF_ARGMAX
!= argc
[i
]; i
++) {
365 if ( ! mbuf_nputs(p
, " ", 1))
367 if ( ! mbuf_puts(p
, tokargnames
[argc
[i
]]))
369 if ( ! mbuf_nputs(p
, "=\"", 2))
371 if ( ! mbuf_putstring(p
, argv
[i
] ? argv
[i
] : "true"))
373 if ( ! mbuf_nputs(p
, "\"", 1))
377 if ( ! mbuf_nputs(p
, ">", 1))
382 return(mbuf_newline(p
));
387 roffblkout(void *arg
, int tok
)
392 p
= (struct md_xml
*)arg
;
397 if ( ! mbuf_newline(p
))
399 if ( ! mbuf_indent(p
))
401 } else if ( ! mbuf_indent(p
))
404 if ( ! mbuf_nputs(p
, "</", 2))
406 if ( ! mbuf_nputs(p
, "block:", 6))
408 if ( ! mbuf_puts(p
, toknames
[tok
]))
410 if ( ! mbuf_nputs(p
, ">", 1))
414 return(mbuf_newline(p
));
419 roffin(void *arg
, int tok
, int *argc
, char **argv
)
425 p
= (struct md_xml
*)arg
;
428 * FIXME: put all of this in a buffer, then check the buffer
429 * length versus the column width for nicer output. This is a
433 if (p
->pos
+ 11 > COLUMNS
)
434 if ( ! mbuf_newline(p
))
442 if ( ! mbuf_nputs(p
, " ", 1))
448 } else if ( ! mbuf_indent(p
))
453 if ( ! mbuf_nputs(p
, "<", 1))
455 if ( ! mbuf_nputs(p
, "inline:", 7))
457 if ( ! mbuf_puts(p
, toknames
[tok
]))
460 for (i
= 0; ROFF_ARGMAX
!= argc
[i
]; i
++) {
461 if ( ! mbuf_nputs(p
, " ", 1))
463 if ( ! mbuf_puts(p
, tokargnames
[argc
[i
]]))
465 if ( ! mbuf_nputs(p
, "=\"", 2))
467 if ( ! mbuf_putstring(p
, argv
[i
] ? argv
[i
] : "true"))
469 if ( ! mbuf_nputs(p
, "\"", 1))
472 return(mbuf_nputs(p
, ">", 1));
477 roffout(void *arg
, int tok
)
482 p
= (struct md_xml
*)arg
;
484 if (0 == p
->pos
&& ! mbuf_indent(p
))
489 if ( ! mbuf_nputs(p
, "</", 2))
491 if ( ! mbuf_nputs(p
, "inline:", 7))
493 if ( ! mbuf_puts(p
, toknames
[tok
]))
495 return(mbuf_nputs(p
, ">", 1));
500 roffmsg(void *arg
, enum roffmsg lvl
,
501 const char *buf
, const char *pos
, char *msg
)
507 p
= (struct md_xml
*)arg
;
511 if ( ! (MD_WARN_ALL
& p
->args
->warnings
))
523 (void)fprintf(stderr
, "%s:%zu: %s: %s (column %zu)\n",
524 p
->rbuf
->name
, p
->rbuf
->line
, level
,
527 (void)fprintf(stderr
, "%s: %s: %s\n",
528 p
->rbuf
->name
, level
, msg
);
534 roffdata(void *arg
, int space
, char *buf
)
539 p
= (struct md_xml
*)arg
;
540 if ( ! mbuf_data(p
, space
, buf
))