1 /* Man page to help file converter
2 Copyright (C) 1994, 1995 Janne Kukonlehto
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #define BUFFER_SIZE 256
27 static char *filename
; /* The name of the input file */
28 static int width
; /* Output width in characters */
29 static int col
= 0; /* Current output column */
30 static FILE *index_file
; /* HTML index file */
31 static int out_row
= 1; /* Current output row */
32 static int in_row
= 0; /* Current input row */
33 static int old_heading_level
= 0;/* Level of the last heading */
34 static int no_split_flag
= 0; /* Flag: Don't split section on next ".SH" */
35 static int skip_flag
= 0; /* Flag: Skip this section.
38 2 = title skipped, skipping text */
39 static int link_flag
= 0; /* Flag: Next line is a link */
40 static int verbatim_flag
= 0; /* Flag: Copy input to output verbatim */
42 /* Report error in input */
43 void print_error (char *message
)
45 fprintf (stderr
, "man2hlp: %s in file \"%s\" at row %d\n", message
, filename
, in_row
);
48 /* Change output line */
56 /* Calculate the length of string */
57 int string_len (char *buffer
)
59 static int anchor_flag
= 0; /* Flag: Inside hypertext anchor name */
60 static int link_flag
= 0; /* Flag: Inside hypertext link target name */
61 int backslash_flag
= 0; /* Flag: Backslash quoting */
63 int c
; /* Current character */
64 int len
= 0; /* Result: the length of the string */
66 for (i
= 0; i
< strlen (buffer
); i
++)
69 if (c
== CHAR_LINK_POINTER
)
70 link_flag
= 1; /* Link target name starts */
71 else if (c
== CHAR_LINK_END
)
72 link_flag
= 0; /* Link target name ends */
73 else if (c
== CHAR_NODE_END
){
74 /* Node anchor name starts */
76 /* Ugly hack to prevent loss of one space */
79 /* Don't add control characters to the length */
82 /* Attempt to handle backslash quoting */
83 if (c
== '\\' && !backslash_flag
){
88 /* Increase length if not inside anchor name or link target name */
89 if (!anchor_flag
&& !link_flag
)
91 if (anchor_flag
&& c
== ']'){
92 /* Node anchor name ends */
99 /* Output the string */
100 void print_string (char *buffer
)
102 int len
; /* The length of current word */
104 int c
; /* Current character */
105 int backslash_flag
= 0;
107 /* Skipping lines? */
110 /* Copying verbatim? */
112 printf("%s", buffer
);
117 /* Split into words */
118 buffer
= strtok (buffer
, " \t\n");
119 /* Repeat for each word */
121 /* Skip empty strings */
122 if (strlen (buffer
) > 0){
123 len
= string_len (buffer
);
124 /* Change the line if about to break the right margin */
125 if (col
+ len
>= width
)
127 /* Words are separated by spaces */
132 /* Attempt to handle backslash quoting */
133 for (i
= 0; i
< strlen (buffer
); i
++)
136 if (c
== '\\' && !backslash_flag
){
143 /* Increase column */
146 /* Get the next word */
147 buffer
= strtok (NULL
, " \t\n");
151 if (strlen (buffer
) > 0){
152 /* Attempt to handle backslash quoting */
153 for (i
= 0; i
< strlen (buffer
); i
++)
156 if (c
== '\\' && !backslash_flag
){
167 /* Like print_string but with printf-like syntax */
168 void printf_string (char *format
, ...)
171 char buffer
[BUFFER_SIZE
];
173 va_start (args
, format
);
174 vsprintf (buffer
, format
, args
);
176 print_string (buffer
);
179 /* Handle all the roff dot commands */
180 void handle_command (char *buffer
)
182 int i
, len
, heading_level
;
184 /* Get the command name */
185 strtok (buffer
, " \t");
186 if (strcmp (buffer
, ".SH") == 0){
187 /* If we already skipped a section, don't skip another */
191 /* Get the command parameters */
192 buffer
= strtok (NULL
, "");
194 print_error ("Syntax error: .SH: no title");
198 if (buffer
[0] == '"'){
200 len
= strlen (buffer
);
201 if (buffer
[len
-1] == '"'){
206 /* Calculate heading level */
208 while (buffer
[heading_level
] == ' ')
210 /* Heading level must be even */
211 if (heading_level
& 1)
212 print_error ("Syntax error: .SH: odd heading level");
214 /* Don't start a new section */
218 print_string (buffer
);
224 printf_string ("<h4>%s</h4>", buffer
);
230 /* Skipping title and marking text for skipping */
234 /* Start a new section */
237 printf ("%c[%s]", CHAR_NODE_END
, buffer
);
240 print_string (buffer
+ heading_level
);
246 if (heading_level
> old_heading_level
){
247 for (i
= old_heading_level
; i
< heading_level
; i
+= 2)
248 fprintf (index_file
, "<ul>");
250 for (i
= heading_level
; i
< old_heading_level
; i
+= 2)
251 fprintf (index_file
, "</ul>");
253 old_heading_level
= heading_level
;
254 printf_string ("<h%d><a name=\"%s\">%s</a></h%d>",
255 heading_level
/ 2 + 2, buffer
+ heading_level
,
256 buffer
+ heading_level
, heading_level
/ 2 + 2);
258 fprintf (index_file
, "<li><a href=\"#%s\">%s</a>\n",
259 buffer
+ heading_level
, buffer
+ heading_level
);
261 for (i
= 0; i
< old_heading_level
; i
+= 2)
262 fprintf (index_file
, "</ul>");
263 old_heading_level
= 0;
264 fprintf (index_file
, "</ul><p><ul>\n");
267 } /* Start new section */
268 } /* Has parameters */
270 else if (strcmp (buffer
, ".\\\"DONT_SPLIT\"") == 0){
273 else if (strcmp (buffer
, ".\\\"SKIP_SECTION\"") == 0){
276 else if (strcmp (buffer
, ".\\\"LINK\"") == 0){
277 /* Next input line is a link */
280 else if (strcmp (buffer
, ".\\\"LINK2\"") == 0){
281 /* Next two input lines form a link */
284 else if (strcmp (buffer
, ".PP") == 0){
285 /* End of paragraph */
288 if (col
> 0) newline();
289 } else /* HTML format */
290 print_string ("<p>");
293 else if (strcmp (buffer
, ".nf") == 0){
294 /* Following input lines are to be handled verbatim */
298 if (col
> 0) newline ();
301 print_string ("<pre>");
305 else if (strcmp (buffer
, ".I") == 0 || strcmp (buffer
, ".B") == 0){
306 /* Bold text or italics text */
307 char type
= buffer
[1];
309 buffer
= strtok (NULL
, "");
311 print_error ("Syntax error: .I / .B: no text");
318 if (buffer
[0] == '"'){
320 len
= strlen (buffer
);
321 if (buffer
[len
-1] == '"'){
326 printf_string ("<%c>%s</%c>", type
, buffer
, type
);
328 } else /* HLP format */
329 printf_string ("%c%s%c",
330 (type
== 'I') ? CHAR_ITALIC_ON
: CHAR_BOLD_ON
,
331 buffer
, CHAR_BOLD_OFF
);
334 else if (strcmp (buffer
, ".TP") == 0){
335 /* End of paragraph? */
338 if (col
> 0) newline ();
341 print_string ("<p>");
346 /* Other commands are ignored */
350 void handle_link (char *buffer
)
352 static char old
[80];
357 /* Old format link */
358 if (width
) /* HLP format */
359 printf_string ("%c%s%c%s%c\n", CHAR_LINK_START
, buffer
, CHAR_LINK_POINTER
, buffer
, CHAR_LINK_END
);
362 printf_string ("<a href=\"#%s\">%s</a>", buffer
, buffer
);
368 /* First part of new format link */
369 strcpy (old
, buffer
);
373 /* Second part of new format link */
374 if (buffer
[0] == '.')
376 if (buffer
[0] == '\\')
378 if (buffer
[0] == '"')
380 len
= strlen (buffer
);
381 if (len
&& buffer
[len
-1] == '"'){
384 if (width
) /* HLP format */
385 printf_string ("%c%s%c%s%c\n", CHAR_LINK_START
, old
, CHAR_LINK_POINTER
, buffer
, CHAR_LINK_END
);
388 printf_string ("<a href=\"#%s\">%s</a>", buffer
, old
);
396 int main (int argc
, char **argv
)
398 int len
; /* Length of input line */
399 FILE *file
; /* Input file */
400 char buffer2
[BUFFER_SIZE
]; /* Temp input line */
401 char buffer
[BUFFER_SIZE
]; /* Input line */
404 /* Validity check for arguments */
405 if (argc
!= 3 || (strcmp (argv
[1], "0") && (width
= atoi (argv
[1])) <= 10)){
406 fprintf (stderr
, "Usage: man2hlp <width> <file.man>\n");
407 fprintf (stderr
, "zero width will create a html file instead of a hlp file\n");
411 /* Open the input file */
413 file
= fopen (filename
, "r");
415 sprintf (buffer
, "man2hlp: Can't open file \"%s\"", filename
);
422 index_file
= fopen ("index.html", "w");
423 if (index_file
== NULL
){
424 perror ("man2hlp: Can't open file \"index.html\"");
427 fprintf (index_file
, "<html><head><title>Midnight Commander manual</title>\n");
428 fprintf (index_file
, "</head><body><pre><img src=\"mc.logo.small.gif\" width=180 height=85 align=\"right\" alt=\""
430 "______________ ____ ____ \n"
431 "|////////////# |//# |//# \n"
432 "|//##+//##+//# |//# |//# \n"
433 "|//# |//# |//# ____ |//# ____ |//# \n"
434 "|//# |//# |//# |//# |//# |//# |//# \n"
435 "|//# |//# |//# +### |//# +### |//# ____ \n"
436 "|//# |//# |//# ____ _____|//# _________ ____ _________ |//#______ _|//#__ \n"
437 "|@@# |@@# |@/# |//# |///////# |///////# |//# |///////# |////////# |/////# \n"
438 "|@@# |@@# |@@# |@/# |//##+//# |//##+//# |//# |//##+//# |//###+//# +#/@### \n"
439 "|@@# |@@# |@@# |@@# |@@# |@@# |@/# |//# |//# |//# |/@# |@@# |@@# |@@# ____\n"
440 "|@@# |@@# |@@# |@@# |@@#_|@@# |@@# |@@# |@@# |@@#_|@@# |@@# |@@# |@@#_|@@#\n"
441 "|@@# |@@# |@@# |@@# |@@@@@@@# |@@# |@@# |@@# |@@@@@@@# |@@# |@@# |@@@@@@@#\n"
442 "+### +### +### +### +######## +### +### +### +####+@@# +### +### +########\n"
443 " _______________________________________|@@# \n"
444 " |@@@@@@@@@@@ C O M M A N D E R @@@@@@@@@@@# \n"
445 " +########################################## \n"
447 "\"></pre><h1>Manual</h1>\nThis is the manual for Midnight Commander version %s.\n"
448 "This HTML version of the manual has been compiled from the NROFF version at %s.<p>\n",
450 fprintf (index_file
, "<hr><h2>Contents</h2><ul>\n");
453 /* Repeat for each input line */
454 while (!feof (file
)){
456 if (!fgets (buffer2
, BUFFER_SIZE
, file
)){
461 if (buffer2
[0] == '\\' && buffer2
[1] == '&')
465 for (j
= 0; i
< strlen (buffer2
); i
++, j
++){
466 if (buffer2
[i
] == '<'){
471 } else if (buffer2
[i
] == '>'){
477 buffer
[j
] = buffer2
[i
];
482 if (buffer2
[0] == '\\' && buffer2
[1] == '&')
483 strcpy (buffer
, buffer2
+ 2);
485 strcpy (buffer
, buffer2
);
488 len
= strlen (buffer
);
489 /* Remove terminating newline */
490 if (buffer
[len
-1] == '\n')
496 /* Copy the line verbatim */
497 if (strcmp (buffer
, ".fi") == 0){
499 if (!width
) print_string ("</pre>"); /* HTML format */
501 print_string (buffer
);
506 /* The line is a link */
507 handle_link (buffer
);
508 else if (buffer
[0] == '.')
509 /* The line is a roff command */
510 handle_command (buffer
);
513 /* A normal line, just output it */
514 print_string (buffer
);
515 if (!width
) newline (); /* HTML format */
523 print_string ("<hr></body></html>");
525 for (i
= 0; i
< old_heading_level
; i
+= 2)
526 fprintf (index_file
, "</ul>");
527 old_heading_level
= 0;
528 fprintf (index_file
, "</ul><hr>\n");