123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- /*
- * man2html.c -- convert nroff output to html
- *
- * Convert backspace/overstrikes to bold.
- * Convert backspace/underbar (either order) to italic.
- * Convert bar/backspace/dash to `+' (also handle bold rendering)
- * Convert bar/backspace/equals to `*' (also handle bold rendering)
- * Convert plus/backspace/o to `o'
- * Convert `<' to `<'; `>' to `>'; and `&' to `&'
- * If -u specified, compress duplicate blank lines.
- *
- * $Id$
- */
- #include <stdio.h>
- #define BUFSIZE 4096
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char buf[BUFSIZE];
- static int blank = 1, uopt = 0, lineno = 0, bksp = 0;
- /*
- * Options.
- */
- if (argc > 2)
- usage();
- if (argc == 2) {
- if (strcmp(argv[1], "-u") == 0)
- uopt = 1;
- else
- usage();
- }
- /*
- * Enclose in html envelope
- */
- puts("<BODY><PRE>");
- /*
- * Process each line. Count unresolved backspaces and issue
- * a warning message at the end.
- */
- while (fgets(buf, BUFSIZE, stdin)) {
-
- lineno++;
- /*
- * if -u specified, compress duplicate blank lines
- */
- if (uopt) {
- if (blankline(buf)) {
- if (blank)
- continue;
- else
- blank = 1;
- } else
- blank = 0;
- }
- bksp += html(buf, lineno);
- }
- /*
- * Close html envelope.
- */
- puts("</PRE></BODY>");
- /*
- * Warn about any unresolved backspaces.
- */
- if (bksp > 0)
- fprintf(stderr,
- "man2html: warning: %d unresolved backspaces\n", bksp);
- exit(0);
- }
- usage()
- {
- fprintf(stderr, "man2html: usage: man2html [-u]\n");
- exit(1);
- }
- /*
- * Given a line, print it out as html.
- * Return the number of unprocessed backspaces in this line.
- */
- int
- html(s, lineno)
- char *s;
- int lineno;
- {
- char *p;
- int bold, italic, bksp;
- unsigned char buf2[BUFSIZE];
- /*
- * two bits in each element of buf2 indicate attributes of
- * corresponding character in `s'.
- * bit 1, when set, indicates bold
- * bit 2, when set, indicates underscore
- */
- /*
- * pass 1: set character attributes (and delete overstrikes)
- */
- bzero(buf2, BUFSIZE);
- for (p = s; *p; p++) {
- if (p == s || *p != '\b')
- continue;
- /* detect a backspace/overstrike (bold <B>) */
- if (*(p - 1) == *(p + 1)) {
- /* get rid of backspace and overstrike */
- strcpy(p - 1, p + 1);
- /* flag character as bold */
- buf2[p - 1 - s] |= 1;
-
- p--;
- /* detect an underbar/backspace (italic <I>) */
- } else if (*(p - 1) == '_') {
- /* get rid of backspace and underbar */
- strcpy(p - 1, p + 1);
- /* flag character as underscored */
- buf2[p - 1 - s] |= 2;
- p--;
- /* detect a backspace/underbar (reverse of above) */
- } else if (*(p + 1) == '_') {
- /* get rid of backspace and underbar */
- strcpy(p, p + 2);
- /* flag character as underscored */
- buf2[p - 1 - s] |= 2;
- p--;
- /* convert bar/backspace/dash to `+' */
- } else if (strncmp(p - 1, "|\b-", 3) == 0
- || strncmp(p - 1, "+\b-", 3) == 0
- || strncmp(p - 1, "+\b|", 3) == 0) {
- /* get rid of backspace and bar, change dash to `+' */
- strcpy(p - 1, p + 1);
- *(p - 1) = '+';
- p--;
- /* convert bar/backspace/equals to `*' */
- } else if (strncmp(p - 1, "|\b=", 3) == 0
- || strncmp(p - 1, "*\b=", 3) == 0
- || strncmp(p - 1, "*\b|", 3) == 0) {
- strcpy(p - 1, p + 1);
- *(p - 1) = '*';
- p--;
- /* convert plus/backspace/o to bold `o' */
- } else if (strncmp(p - 1, "+\bo", 3) == 0
- || strncmp(p - 1, "o\b+", 3) == 0) {
- strcpy(p - 1, p + 1);
- *(p - 1) = 'o';
- /* flag character as bold */
- buf2[p - 1 - s] |= 1;
- p--;
- }
- }
- /*
- * pass 2: print out line as html
- */
- bold = italic = bksp = 0;
- for (p = s; *p; p++) {
- /* bold */
- if (buf2[p - s] & 1) {
- if (!bold) {
- /*
- * an overstrike/underbar is ambiguous.
- * change to italic if we are in an italic
- * context right now
- */
- if (italic && *p == '_')
- buf2[p - s] |= 2;
- else {
- fputs("<B>", stdout);
- bold = 1;
- }
- }
- } else {
- if (bold && *p != ' ') {
- fputs("</B>", stdout);
- bold = 0;
- }
- }
- /* italic */
- if (buf2[p - s] & 2) {
- if (!italic) {
- fputs("<I>", stdout);
- italic = 1;
- }
- } else {
- if (italic && *p != ' ') {
- fputs("</I>", stdout);
- italic = 0;
- }
- }
- /* print the char, escaping the three html special chars */
- switch (*p) {
- case '<':
- fputs("<", stdout);
- break;
- case '>':
- fputs(">", stdout);
- break;
- case '&':
- fputs("&", stdout);
- break;
- case '\b':
- #ifdef notdef
- fprintf(stderr,
- "man2html: warning, \\b on line %d\n", lineno);
- #endif
- bksp++;
- default:
- putchar(*p);
- }
- }
- if (bold)
- fputs("</B>", stdout);
- if (italic)
- fputs("</I>", stdout);
- return(bksp);
- }
- int
- blankline(s)
- char *s;
- {
- while (*s) {
- if (!isspace(*s))
- return(0);
- s++;
- }
- return(1);
- }
|