]>
git.ipfire.org Git - thirdparty/cups.git/blob - man/mantohtml.c
2 * "$Id: mantohtml.c 7720 2008-07-11 22:46:21Z mike $"
4 * Man page to HTML conversion program.
6 * Copyright 2007-2009 by Apple Inc.
7 * Copyright 2004-2006 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
17 * main() - Convert a man page to HTML.
18 * putc_entity() - Put a single character, using entities as needed.
19 * strmove() - Move characters within a string.
23 * Include necessary headers.
26 #include <cups/string.h>
35 static void putc_entity(int ch
, FILE *fp
);
36 static void strmove(char *d
, const char *s
);
40 * 'main()' - Convert a man page to HTML.
43 int /* O - Exit status */
44 main(int argc
, /* I - Number of command-line args */
45 char *argv
[]) /* I - Command-line arguments */
47 FILE *infile
, /* Input file */
48 *outfile
; /* Output file */
49 char line
[1024], /* Line from file */
50 *lineptr
, /* Pointer into line */
51 *endptr
, /* Pointer to end of current */
52 endchar
, /* End character */
53 *paren
, /* Pointer to parenthesis */
54 name
[1024]; /* Man page name */
55 int section
, /* Man page section */
56 pre
, /* Preformatted */
57 font
, /* Current font */
58 blist
, /* In a bullet list? */
59 list
, /* In a list? */
60 linenum
; /* Current line number */
61 const char *post
; /* Text to add after the current line */
62 static const char /* Start/end tags for fonts */
63 * const start_fonts
[] = { "", "<b>", "<i>" },
64 * const end_fonts
[] = { "", "</b>", "</i>" };
72 fputs("Usage: mantohtml [filename.man [filename.html]]\n", stderr
);
77 * Open files as needed...
82 if ((infile
= fopen(argv
[1], "r")) == NULL
)
93 if ((outfile
= fopen(argv
[2], "w")) == NULL
)
104 * Read from input and write the output...
107 fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
108 "\"http://www.w3.org/TR/html4/loose.dtd\">\n"
110 "<!-- SECTION: Man Pages -->\n"
112 "\t<link rel=\"stylesheet\" type=\"text/css\" "
113 "href=\"../cups-printable.css\">\n", outfile
);
123 while (fgets(line
, sizeof(line
), infile
))
130 * Strip leading whitespace...
133 while (line
[1] == ' ' || line
[1] == '\t')
134 strmove(line
+ 1, line
+ 2);
137 * Process man page commands...
140 if (!strncmp(line
, ".TH ", 4) && section
< 0)
143 * Grab man page title...
146 sscanf(line
+ 4, "%s%d", name
, §ion
);
149 "\t<title>%s(%d)</title>\n"
152 "<h1 class=\"title\">%s(%d)</h1>\n"
154 name
, section
, name
, section
, start_fonts
[font
]);
156 else if (section
< 0)
158 else if (!strncmp(line
, ".SH ", 4) || !strncmp(line
, ".SS ", 4))
166 fputs(end_fonts
[font
], outfile
);
170 fputs("</li>\n</ul>\n", outfile
);
177 fputs("</dt>\n", outfile
);
179 fputs("</dd>\n", outfile
);
181 fputs("</dl>\n", outfile
);
185 line
[strlen(line
) - 1] = '\0'; /* Strip LF */
188 fputs("<h2 class=\"title\"><a name=\"", outfile
);
190 fputs("<h3><a name=\"", outfile
);
192 for (lineptr
= line
+ 4; *lineptr
; lineptr
++)
193 if (*lineptr
== '\"')
195 else if (*lineptr
== ' ')
196 putc_entity('_', outfile
);
198 putc_entity(*lineptr
, outfile
);
200 fputs("\">", outfile
);
202 for (lineptr
= line
+ 4; *lineptr
; lineptr
++)
203 if (*lineptr
== '\"')
205 else if (*lineptr
== ' ')
207 putc_entity(' ', outfile
);
214 putc_entity(*lineptr
, outfile
);
216 putc_entity(tolower(*lineptr
), outfile
);
222 fprintf(outfile
, "</a></h2>\n%s", start_fonts
[font
]);
224 fprintf(outfile
, "</a></h3>\n%s", start_fonts
[font
]);
226 else if (!strncmp(line
, ".LP", 3) || !strncmp(line
, ".PP", 3))
232 fputs(end_fonts
[font
], outfile
);
236 fputs("</li>\n</ul>\n", outfile
);
243 fputs("</dt>\n", outfile
);
245 fputs("</dd>\n", outfile
);
247 fputs("</dl>\n", outfile
);
251 fputs("<p>", outfile
);
254 else if (!strncmp(line
, ".TP ", 4))
260 fputs(end_fonts
[font
], outfile
);
264 fputs("</li>\n</ul>\n", outfile
);
269 fputs("<dl>\n", outfile
);
271 fputs("</dt>\n", outfile
);
273 fputs("</dd>\n", outfile
);
275 fputs("<dt>", outfile
);
279 else if (!strncmp(line
, ".br", 3))
287 fputs("</dt>\n<dd>", outfile
);
291 fputs("</dd>\n<dd>", outfile
);
293 fputs("<br>\n", outfile
);
295 else if (!strncmp(line
, ".de ", 4))
298 * Define macro - ignore...
301 while (fgets(line
, sizeof(line
), infile
))
305 if (!strncmp(line
, "..", 2))
309 else if (!strncmp(line
, ".RS", 3))
315 fputs("<div style='margin-left: 3em;'>\n", outfile
);
317 else if (!strncmp(line
, ".RE", 3))
323 fputs("</div>\n", outfile
);
325 else if (!strncmp(line
, ".ds ", 4) || !strncmp(line
, ".rm ", 4) ||
326 !strncmp(line
, ".tr ", 4) || !strncmp(line
, ".hy ", 4) ||
327 !strncmp(line
, ".IX ", 4) || !strncmp(line
, ".PD", 3) ||
328 !strncmp(line
, ".Sp", 3))
331 * Ignore unused commands...
334 else if (!strncmp(line
, ".Vb", 3) || !strncmp(line
, ".nf", 3))
337 * Start preformatted...
341 fputs("<pre>\n", outfile
);
343 else if (!strncmp(line
, ".Ve", 3) || !strncmp(line
, ".fi", 3))
346 * End preformatted...
352 fputs("</pre>\n", outfile
);
355 else if (!strncmp(line
, ".IP \\(bu", 8))
362 fputs("</li>\n", outfile
);
365 fputs("<ul>\n", outfile
);
369 fputs("<li>", outfile
);
371 else if (!strncmp(line
, ".IP ", 4))
374 * Indented paragraph...
379 fputs("</li>\n</ul>\n", outfile
);
383 fputs("<p style='margin-left: 3em;'>", outfile
);
385 for (lineptr
= line
+ 4; isspace(*lineptr
); lineptr
++);
387 if (*lineptr
== '\"')
389 strmove(line
, lineptr
+ 1);
391 if ((lineptr
= strchr(line
, '\"')) != NULL
)
396 strmove(line
, lineptr
);
398 if ((lineptr
= strchr(line
, ' ')) != NULL
)
403 * Process the text as if it was in-line...
406 post
= "\n<br />\n<br />";
409 else if (!strncmp(line
, ".\\}", 3))
412 * Ignore close block...
415 else if (!strncmp(line
, ".ie", 3) || !strncmp(line
, ".if", 3) ||
416 !strncmp(line
, ".el", 3))
419 * If/else - ignore...
422 if (strchr(line
, '{') != NULL
)
425 * Skip whole block...
428 while (fgets(line
, sizeof(line
), infile
))
432 if (strchr(line
, '}') != NULL
)
438 else if (!strncmp(line
, ". ", 4))
445 else if (!strncmp(line
, ".B ", 3))
451 fprintf(outfile
, "%s<b>%s</b>%s", end_fonts
[font
], line
+ 3,
454 else if (!strncmp(line
, ".I ", 3))
457 * Grab italic text...
460 fprintf(outfile
, "%s<i>%s</i>%s", end_fonts
[font
], line
+ 3,
463 else if (strncmp(line
, ".\\\"", 3))
469 if ((lineptr
= strchr(line
, ' ')) != NULL
)
471 else if ((lineptr
= strchr(line
, '\n')) != NULL
)
474 fprintf(stderr
, "mantohtml: Unknown man page command \'%s\' on line %d!\n",
479 * Skip continuation lines...
482 lineptr
= line
+ strlen(line
) - 2;
483 if (lineptr
>= line
&& *lineptr
== '\\')
485 while (fgets(line
, sizeof(line
), infile
))
488 lineptr
= line
+ strlen(line
) - 2;
490 if (lineptr
< line
|| *lineptr
!= '\\')
498 * Process man page text...
503 for (lineptr
= line
; *lineptr
; lineptr
++)
505 if (!strncmp(lineptr
, "http://", 7))
511 for (endptr
= lineptr
+ 7;
512 *endptr
&& !isspace(*endptr
& 255);
518 fprintf(outfile
, "<a href='%s'>%s</a>", lineptr
, lineptr
);
520 lineptr
= endptr
- 1;
522 else if (!strncmp(lineptr
, "\\fI", 3) &&
523 (endptr
= strstr(lineptr
, "\\fR")) != NULL
&&
524 (paren
= strchr(lineptr
, '(')) != NULL
&&
531 char manfile
[1024], /* Man page filename */
532 manurl
[1024]; /* Man page URL */
536 * See if the man file is available locally...
543 snprintf(manfile
, sizeof(manfile
), "%s.man", lineptr
);
544 snprintf(manurl
, sizeof(manurl
), "man-%s.html?TOPIC=Man+Pages",
551 if (access(manfile
, 0))
554 * Not a local man page, just do it italic...
557 fputs("<i>", outfile
);
559 putc_entity(*lineptr
++, outfile
);
560 fputs("</i>", outfile
);
565 * Local man page, do a link...
568 fprintf(outfile
, "<a href='%s'>", manurl
);
570 putc_entity(*lineptr
++, outfile
);
571 fputs("</a>", outfile
);
575 lineptr
= endptr
+ 2;
577 else if (*lineptr
== '\\')
582 else if (isdigit(lineptr
[0]) && isdigit(lineptr
[1]) &&
585 fprintf(outfile
, "&#%d;", ((lineptr
[0] - '0') * 8 +
586 lineptr
[1] - '0') * 8 +
590 else if (*lineptr
== '&')
592 else if (*lineptr
== 's')
594 while (lineptr
[1] == '-' || isdigit(lineptr
[1]))
597 else if (*lineptr
== '*')
601 else if (*lineptr
!= 'f')
602 putc_entity(*lineptr
, outfile
);
610 fputs(end_fonts
[font
], outfile
);
614 default : /* Regular */
617 case 'B' : /* Bold */
621 case 'I' : /* Italic */
627 fputs(start_fonts
[font
], outfile
);
632 putc_entity(*lineptr
, outfile
);
637 fputs(post
, outfile
);
643 fprintf(outfile
, "%s\n", end_fonts
[font
]);
647 fputs("</li>\n</ul>\n", outfile
);
653 fputs("</dt>\n", outfile
);
655 fputs("</dd>\n", outfile
);
657 fputs("</dl>\n", outfile
);
661 "</html>\n", outfile
);
670 if (outfile
!= stdout
)
674 * Return with no errors...
682 * 'putc_entity()' - Put a single character, using entities as needed.
686 putc_entity(int ch
, /* I - Character */
687 FILE *fp
) /* I - File */
699 * 'strmove()' - Move characters within a string.
703 strmove(char *d
, /* I - Destination */
704 const char *s
) /* I - Source */
714 * End of "$Id: mantohtml.c 7720 2008-07-11 22:46:21Z mike $".