]>
git.ipfire.org Git - thirdparty/cups.git/blob - man/mantohtml.c
2 * "$Id: mantohtml.c 5142 2006-02-21 14:52:34Z mike $"
4 * Man page to HTML conversion program.
6 * Copyright 2004-2006 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * main() - Convert a man page to HTML.
27 * putc_entity() - Put a single character, using entities as needed.
28 * strmove() - Move characters within a string.
32 * Include necessary headers.
35 #include <cups/string.h>
44 static void putc_entity(int ch
, FILE *fp
);
45 static void strmove(char *d
, const char *s
);
49 * 'main()' - Convert a man page to HTML.
52 int /* O - Exit status */
53 main(int argc
, /* I - Number of command-line args */
54 char *argv
[]) /* I - Command-line arguments */
56 FILE *infile
, /* Input file */
57 *outfile
; /* Output file */
58 char line
[1024], /* Line from file */
59 *lineptr
, /* Pointer into line */
60 *endptr
, /* Pointer to end of current */
61 endchar
, /* End character */
62 *paren
, /* Pointer to parenthesis */
63 name
[1024]; /* Man page name */
64 int section
, /* Man page section */
65 pre
, /* Preformatted */
66 font
, /* Current font */
67 blist
, /* In a bullet list? */
68 list
, /* In a list? */
69 linenum
; /* Current line number */
70 const char *post
; /* Text to add after the current line */
71 static const char /* Start/end tags for fonts */
72 * const start_fonts
[] = { "", "<b>", "<i>" },
73 * const end_fonts
[] = { "", "</b>", "</i>" };
81 fputs("Usage: mantohtml [filename.man [filename.html]]\n", stderr
);
86 * Open files as needed...
91 if ((infile
= fopen(argv
[1], "r")) == NULL
)
102 if ((outfile
= fopen(argv
[2], "w")) == NULL
)
113 * Read from input and write the output...
116 fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" "
117 "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"
119 "<!-- SECTION: Man Pages -->\n"
121 "\t<style type='text/css'><!--\n"
122 "\th1, h2, h3, p { font-family: sans-serif; text-align: justify; }\n"
123 "\ttt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }\n"
124 "\tpre { font-weight: bold; color: #7f0000; margin-left: 2em; }\n"
125 "\th1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }\n"
126 "\t--></style>\n", outfile
);
136 while (fgets(line
, sizeof(line
), infile
))
143 * Strip leading whitespace...
146 while (line
[1] == ' ' || line
[1] == '\t')
147 strmove(line
+ 1, line
+ 2);
150 * Process man page commands...
153 if (!strncmp(line
, ".TH ", 4) && section
< 0)
156 * Grab man page title...
159 sscanf(line
+ 4, "%s%d", name
, §ion
);
162 "\t<title>%s(%d)</title>\n"
166 name
, section
, start_fonts
[font
]);
168 else if (section
< 0)
170 else if (!strncmp(line
, ".SH ", 4) || !strncmp(line
, ".Sh ", 4))
178 fputs(end_fonts
[font
], outfile
);
182 fputs("</li>\n</ul>\n", outfile
);
189 fputs("</dt>\n", outfile
);
191 fputs("</dd>\n", outfile
);
193 fputs("</dl>\n", outfile
);
197 line
[strlen(line
) - 1] = '\0'; /* Strip LF */
200 fputs("<h2><a name='", outfile
);
202 fputs("<h3><a name='", outfile
);
204 for (lineptr
= line
+ 4; *lineptr
; lineptr
++)
205 if (*lineptr
== '\"')
207 else if (*lineptr
== ' ')
208 putc_entity('_', outfile
);
210 putc_entity(*lineptr
, outfile
);
212 fputs("'>", outfile
);
214 for (lineptr
= line
+ 4; *lineptr
; lineptr
++)
215 if (*lineptr
== '\"')
217 else if (*lineptr
== ' ')
219 putc_entity(' ', outfile
);
226 putc_entity(*lineptr
, outfile
);
228 putc_entity(tolower(*lineptr
), outfile
);
234 fprintf(outfile
, "</a></h2>\n%s", start_fonts
[font
]);
236 fprintf(outfile
, "</a></h3>\n%s", start_fonts
[font
]);
238 else if (!strncmp(line
, ".LP", 3) || !strncmp(line
, ".PP", 3))
244 fputs(end_fonts
[font
], outfile
);
248 fputs("</li>\n</ul>\n", outfile
);
255 fputs("</dt>\n", outfile
);
257 fputs("</dd>\n", outfile
);
259 fputs("</dl>\n", outfile
);
263 fputs("<p>", outfile
);
266 else if (!strncmp(line
, ".TP ", 4))
272 fputs(end_fonts
[font
], outfile
);
276 fputs("</li>\n</ul>\n", outfile
);
281 fputs("<dl>\n", outfile
);
283 fputs("</dt>\n", outfile
);
285 fputs("</dd>\n", outfile
);
287 fputs("<dt>", outfile
);
291 else if (!strncmp(line
, ".br", 3))
299 fputs("</dt>\n<dd>", outfile
);
303 fputs("</dd>\n<dd>", outfile
);
305 fputs("<br>\n", outfile
);
307 else if (!strncmp(line
, ".de ", 4))
310 * Define macro - ignore...
313 while (fgets(line
, sizeof(line
), infile
))
317 if (!strncmp(line
, "..", 2))
321 else if (!strncmp(line
, ".RS", 3))
327 fputs("<div style='margin-left: 3em;'>\n", outfile
);
329 else if (!strncmp(line
, ".RE", 3))
335 fputs("</div>\n", outfile
);
337 else if (!strncmp(line
, ".ds ", 4) || !strncmp(line
, ".rm ", 4) ||
338 !strncmp(line
, ".tr ", 4) || !strncmp(line
, ".hy ", 4) ||
339 !strncmp(line
, ".IX ", 4) || !strncmp(line
, ".PD", 3) ||
340 !strncmp(line
, ".Sp", 3))
343 * Ignore unused commands...
346 else if (!strncmp(line
, ".Vb", 3) || !strncmp(line
, ".nf", 3))
349 * Start preformatted...
353 fputs("<pre>\n", outfile
);
355 else if (!strncmp(line
, ".Ve", 3) || !strncmp(line
, ".fi", 3))
358 * End preformatted...
364 fputs("</pre>\n", outfile
);
367 else if (!strncmp(line
, ".IP \\(bu", 8))
374 fputs("</li>\n", outfile
);
377 fputs("<ul>\n", outfile
);
381 fputs("<li>", outfile
);
383 else if (!strncmp(line
, ".IP ", 4))
386 * Indented paragraph...
391 fputs("</li>\n</ul>\n", outfile
);
395 fputs("<p style='margin-left: 3em;'>", outfile
);
397 for (lineptr
= line
+ 4; isspace(*lineptr
); lineptr
++);
399 if (*lineptr
== '\"')
401 strmove(line
, lineptr
+ 1);
403 if ((lineptr
= strchr(line
, '\"')) != NULL
)
408 strmove(line
, lineptr
);
410 if ((lineptr
= strchr(line
, ' ')) != NULL
)
415 * Process the text as if it was in-line...
418 post
= "\n<br />\n<br />";
421 else if (!strncmp(line
, ".\\}", 3))
424 * Ignore close block...
427 else if (!strncmp(line
, ".ie", 3) || !strncmp(line
, ".if", 3) ||
428 !strncmp(line
, ".el", 3))
431 * If/else - ignore...
434 if (strchr(line
, '{') != NULL
)
437 * Skip whole block...
440 while (fgets(line
, sizeof(line
), infile
))
444 if (strchr(line
, '}') != NULL
)
450 else if (!strncmp(line
, ". ", 4))
457 else if (!strncmp(line
, ".B ", 3))
463 fprintf(outfile
, "%s<b>%s</b>%s", end_fonts
[font
], line
+ 3,
466 else if (!strncmp(line
, ".I ", 3))
469 * Grab italic text...
472 fprintf(outfile
, "%s<i>%s</i>%s", end_fonts
[font
], line
+ 3,
475 else if (strncmp(line
, ".\\\"", 3))
481 if ((lineptr
= strchr(line
, ' ')) != NULL
)
483 else if ((lineptr
= strchr(line
, '\n')) != NULL
)
486 fprintf(stderr
, "mantohtml: Unknown man page command \'%s\' on line %d!\n",
491 * Skip continuation lines...
494 lineptr
= line
+ strlen(line
) - 2;
495 if (lineptr
>= line
&& *lineptr
== '\\')
497 while (fgets(line
, sizeof(line
), infile
))
500 lineptr
= line
+ strlen(line
) - 2;
502 if (lineptr
< line
|| *lineptr
!= '\\')
510 * Process man page text...
515 for (lineptr
= line
; *lineptr
; lineptr
++)
517 if (!strncmp(lineptr
, "http://", 7))
523 for (endptr
= lineptr
+ 7;
524 *endptr
&& !isspace(*endptr
& 255);
530 fprintf(outfile
, "<a href='%s'>%s</a>", lineptr
, lineptr
);
532 lineptr
= endptr
- 1;
534 else if (!strncmp(lineptr
, "\\fI", 3) &&
535 (endptr
= strstr(lineptr
, "\\fR")) != NULL
&&
536 (paren
= strchr(lineptr
, '(')) != NULL
&&
543 char manfile
[1024], /* Man page filename */
544 manurl
[1024]; /* Man page URL */
548 * See if the man file is available locally...
555 snprintf(manfile
, sizeof(manfile
), "%s.man", lineptr
);
556 snprintf(manurl
, sizeof(manurl
), "man-%s.html?TOPIC=Man+Pages",
563 if (access(manfile
, 0))
566 * Not a local man page, just do it italic...
569 fputs("<i>", outfile
);
571 putc_entity(*lineptr
++, outfile
);
572 fputs("</i>", outfile
);
577 * Local man page, do a link...
580 fprintf(outfile
, "<a href='%s'>", manurl
);
582 putc_entity(*lineptr
++, outfile
);
583 fputs("</a>", outfile
);
587 lineptr
= endptr
+ 2;
589 else if (*lineptr
== '\\')
594 else if (isdigit(lineptr
[0]) && isdigit(lineptr
[1]) &&
597 fprintf(outfile
, "&#%d;", ((lineptr
[0] - '0') * 8 +
598 lineptr
[1] - '0') * 8 +
602 else if (*lineptr
== '&')
604 else if (*lineptr
== 's')
606 while (lineptr
[1] == '-' || isdigit(lineptr
[1]))
609 else if (*lineptr
== '*')
613 else if (*lineptr
!= 'f')
614 putc_entity(*lineptr
, outfile
);
622 fputs(end_fonts
[font
], outfile
);
626 default : /* Regular */
629 case 'B' : /* Bold */
633 case 'I' : /* Italic */
639 fputs(start_fonts
[font
], outfile
);
644 putc_entity(*lineptr
, outfile
);
649 fputs(post
, outfile
);
655 fprintf(outfile
, "%s\n", end_fonts
[font
]);
659 fputs("</li>\n</ul>\n", outfile
);
666 fputs("</dt>\n", outfile
);
668 fputs("</dd>\n", outfile
);
670 fputs("</dl>\n", outfile
);
675 "</html>\n", outfile
);
684 if (outfile
!= stdout
)
688 * Return with no errors...
696 * 'putc_entity()' - Put a single character, using entities as needed.
700 putc_entity(int ch
, /* I - Character */
701 FILE *fp
) /* I - File */
713 * 'strmove()' - Move characters within a string.
717 strmove(char *d
, /* I - Destination */
718 const char *s
) /* I - Source */
728 * End of "$Id: mantohtml.c 5142 2006-02-21 14:52:34Z mike $".