- converted 1st stage setup stub from message box style to property sheet style
[reactos.git] / rosapps / applications / mc / src / man2hlp.c
1 /* Man page to help file converter
2 Copyright (C) 1994, 1995 Janne Kukonlehto
3
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.
8
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.
13
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. */
17
18 #include <config.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include "help.h"
24
25 #define BUFFER_SIZE 256
26
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.
36 0 = don't skip,
37 1 = skipping title,
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 */
41
42 /* Report error in input */
43 void print_error (char *message)
44 {
45 fprintf (stderr, "man2hlp: %s in file \"%s\" at row %d\n", message, filename, in_row);
46 }
47
48 /* Change output line */
49 void newline (void)
50 {
51 out_row ++;
52 col = 0;
53 printf("\n");
54 }
55
56 /* Calculate the length of string */
57 int string_len (char *buffer)
58 {
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 */
62 int i; /* Index */
63 int c; /* Current character */
64 int len = 0; /* Result: the length of the string */
65
66 for (i = 0; i < strlen (buffer); i ++)
67 {
68 c = 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 */
75 anchor_flag = 1;
76 /* Ugly hack to prevent loss of one space */
77 len ++;
78 }
79 /* Don't add control characters to the length */
80 if (c < 32)
81 continue;
82 /* Attempt to handle backslash quoting */
83 if (c == '\\' && !backslash_flag){
84 backslash_flag = 1;
85 continue;
86 }
87 backslash_flag = 0;
88 /* Increase length if not inside anchor name or link target name */
89 if (!anchor_flag && !link_flag)
90 len ++;
91 if (anchor_flag && c == ']'){
92 /* Node anchor name ends */
93 anchor_flag = 0;
94 }
95 }
96 return len;
97 }
98
99 /* Output the string */
100 void print_string (char *buffer)
101 {
102 int len; /* The length of current word */
103 int i; /* Index */
104 int c; /* Current character */
105 int backslash_flag = 0;
106
107 /* Skipping lines? */
108 if (skip_flag)
109 return;
110 /* Copying verbatim? */
111 if (verbatim_flag){
112 printf("%s", buffer);
113 return;
114 }
115 if (width){
116 /* HLP format */
117 /* Split into words */
118 buffer = strtok (buffer, " \t\n");
119 /* Repeat for each word */
120 while (buffer){
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)
126 newline ();
127 /* Words are separated by spaces */
128 if (col > 0){
129 printf (" ");
130 col ++;
131 }
132 /* Attempt to handle backslash quoting */
133 for (i = 0; i < strlen (buffer); i++)
134 {
135 c = buffer [i];
136 if (c == '\\' && !backslash_flag){
137 backslash_flag = 1;
138 continue;
139 }
140 backslash_flag = 0;
141 printf ("%c", c);
142 }
143 /* Increase column */
144 col += len;
145 }
146 /* Get the next word */
147 buffer = strtok (NULL, " \t\n");
148 } /* while */
149 } else {
150 /* HTML format */
151 if (strlen (buffer) > 0){
152 /* Attempt to handle backslash quoting */
153 for (i = 0; i < strlen (buffer); i++)
154 {
155 c = buffer [i];
156 if (c == '\\' && !backslash_flag){
157 backslash_flag = 1;
158 continue;
159 }
160 backslash_flag = 0;
161 printf ("%c", c);
162 }
163 }
164 } /* if (width) */
165 }
166
167 /* Like print_string but with printf-like syntax */
168 void printf_string (char *format, ...)
169 {
170 va_list args;
171 char buffer [BUFFER_SIZE];
172
173 va_start (args, format);
174 vsprintf (buffer, format, args);
175 va_end (args);
176 print_string (buffer);
177 }
178
179 /* Handle all the roff dot commands */
180 void handle_command (char *buffer)
181 {
182 int i, len, heading_level;
183
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 */
188 if (skip_flag == 2){
189 skip_flag = 0;
190 }
191 /* Get the command parameters */
192 buffer = strtok (NULL, "");
193 if (buffer == NULL){
194 print_error ("Syntax error: .SH: no title");
195 return;
196 } else {
197 /* Remove quotes */
198 if (buffer[0] == '"'){
199 buffer ++;
200 len = strlen (buffer);
201 if (buffer[len-1] == '"'){
202 len --;
203 buffer[len] = 0;
204 }
205 }
206 /* Calculate heading level */
207 heading_level = 0;
208 while (buffer [heading_level] == ' ')
209 heading_level ++;
210 /* Heading level must be even */
211 if (heading_level & 1)
212 print_error ("Syntax error: .SH: odd heading level");
213 if (no_split_flag){
214 /* Don't start a new section */
215 if (width){
216 /* HLP format */
217 newline ();
218 print_string (buffer);
219 newline ();
220 newline ();
221 } else {
222 /* HTML format */
223 newline ();
224 printf_string ("<h4>%s</h4>", buffer);
225 newline ();
226 }
227 no_split_flag = 0;
228 }
229 else if (skip_flag){
230 /* Skipping title and marking text for skipping */
231 skip_flag = 2;
232 }
233 else {
234 /* Start a new section */
235 if (width){
236 /* HLP format */
237 printf ("%c[%s]", CHAR_NODE_END, buffer);
238 col ++;
239 newline ();
240 print_string (buffer + heading_level);
241 newline ();
242 newline ();
243 } else {
244 /* HTML format */
245 if (buffer [0]){
246 if (heading_level > old_heading_level){
247 for (i = old_heading_level; i < heading_level; i += 2)
248 fprintf (index_file, "<ul>");
249 } else {
250 for (i = heading_level; i < old_heading_level; i += 2)
251 fprintf (index_file, "</ul>");
252 }
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);
257 newline ();
258 fprintf (index_file, "<li><a href=\"#%s\">%s</a>\n",
259 buffer + heading_level, buffer + heading_level);
260 } else {
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");
265 }
266 } /* if (width) */
267 } /* Start new section */
268 } /* Has parameters */
269 } /* Command .SH */
270 else if (strcmp (buffer, ".\\\"DONT_SPLIT\"") == 0){
271 no_split_flag = 1;
272 }
273 else if (strcmp (buffer, ".\\\"SKIP_SECTION\"") == 0){
274 skip_flag = 1;
275 }
276 else if (strcmp (buffer, ".\\\"LINK\"") == 0){
277 /* Next input line is a link */
278 link_flag = 1;
279 }
280 else if (strcmp (buffer, ".\\\"LINK2\"") == 0){
281 /* Next two input lines form a link */
282 link_flag = 2;
283 }
284 else if (strcmp (buffer, ".PP") == 0){
285 /* End of paragraph */
286 if (width){
287 /* HLP format */
288 if (col > 0) newline();
289 } else /* HTML format */
290 print_string ("<p>");
291 newline ();
292 }
293 else if (strcmp (buffer, ".nf") == 0){
294 /* Following input lines are to be handled verbatim */
295 verbatim_flag = 1;
296 if (width){
297 /* HLP format */
298 if (col > 0) newline ();
299 } else {
300 /* HTML format */
301 print_string ("<pre>");
302 newline ();
303 }
304 }
305 else if (strcmp (buffer, ".I") == 0 || strcmp (buffer, ".B") == 0){
306 /* Bold text or italics text */
307 char type = buffer [1];
308
309 buffer = strtok (NULL, "");
310 if (buffer == NULL){
311 print_error ("Syntax error: .I / .B: no text");
312 return;
313 }
314 else {
315 if (!width){
316 /* HTML format */
317 /* Remove quotes */
318 if (buffer[0] == '"'){
319 buffer ++;
320 len = strlen (buffer);
321 if (buffer[len-1] == '"'){
322 len --;
323 buffer[len] = 0;
324 }
325 }
326 printf_string ("<%c>%s</%c>", type, buffer, type);
327 newline ();
328 } else /* HLP format */
329 printf_string ("%c%s%c",
330 (type == 'I') ? CHAR_ITALIC_ON : CHAR_BOLD_ON,
331 buffer, CHAR_BOLD_OFF);
332 }
333 }
334 else if (strcmp (buffer, ".TP") == 0){
335 /* End of paragraph? */
336 if (width){
337 /* HLP format */
338 if (col > 0) newline ();
339 } else {
340 /* HTML format */
341 print_string ("<p>");
342 }
343 newline ();
344 }
345 else {
346 /* Other commands are ignored */
347 }
348 }
349
350 void handle_link (char *buffer)
351 {
352 static char old [80];
353 int len;
354
355 switch (link_flag){
356 case 1:
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);
360 else {
361 /* HTML format */
362 printf_string ("<a href=\"#%s\">%s</a>", buffer, buffer);
363 newline ();
364 }
365 link_flag = 0;
366 break;
367 case 2:
368 /* First part of new format link */
369 strcpy (old, buffer);
370 link_flag = 3;
371 break;
372 case 3:
373 /* Second part of new format link */
374 if (buffer [0] == '.')
375 buffer++;
376 if (buffer [0] == '\\')
377 buffer++;
378 if (buffer [0] == '"')
379 buffer++;
380 len = strlen (buffer);
381 if (len && buffer [len-1] == '"'){
382 buffer [--len] = 0;
383 }
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);
386 else {
387 /* HTML format */
388 printf_string ("<a href=\"#%s\">%s</a>", buffer, old);
389 newline ();
390 }
391 link_flag = 0;
392 break;
393 }
394 }
395
396 int main (int argc, char **argv)
397 {
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 */
402 int i, j;
403
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");
408 return 3;
409 }
410
411 /* Open the input file */
412 filename = argv[2];
413 file = fopen (filename, "r");
414 if (file == NULL){
415 sprintf (buffer, "man2hlp: Can't open file \"%s\"", filename);
416 perror (buffer);
417 return 3;
418 }
419
420 if (!width){
421 /* HTML format */
422 index_file = fopen ("index.html", "w");
423 if (index_file == NULL){
424 perror ("man2hlp: Can't open file \"index.html\"");
425 return 3;
426 }
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=\""
429 " \n"
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"
446 " \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",
449 VERSION, __DATE__);
450 fprintf (index_file, "<hr><h2>Contents</h2><ul>\n");
451 }
452
453 /* Repeat for each input line */
454 while (!feof (file)){
455 /* Read a line */
456 if (!fgets (buffer2, BUFFER_SIZE, file)){
457 break;
458 }
459 if (!width){
460 /* HTML format */
461 if (buffer2 [0] == '\\' && buffer2 [1] == '&')
462 i = 2;
463 else
464 i = 0;
465 for (j = 0; i < strlen (buffer2); i++, j++){
466 if (buffer2 [i] == '<'){
467 buffer [j++] = '&';
468 buffer [j++] = 'l';
469 buffer [j++] = 't';
470 buffer [j] = ';';
471 } else if (buffer2 [i] == '>'){
472 buffer [j++] = '&';
473 buffer [j++] = 'g';
474 buffer [j++] = 't';
475 buffer [j] = ';';
476 } else
477 buffer [j] = buffer2 [i];
478 }
479 buffer [j] = 0;
480 } else {
481 /* HLP format */
482 if (buffer2 [0] == '\\' && buffer2 [1] == '&')
483 strcpy (buffer, buffer2 + 2);
484 else
485 strcpy (buffer, buffer2);
486 }
487 in_row ++;
488 len = strlen (buffer);
489 /* Remove terminating newline */
490 if (buffer [len-1] == '\n')
491 {
492 len --;
493 buffer [len] = 0;
494 }
495 if (verbatim_flag){
496 /* Copy the line verbatim */
497 if (strcmp (buffer, ".fi") == 0){
498 verbatim_flag = 0;
499 if (!width) print_string ("</pre>"); /* HTML format */
500 } else {
501 print_string (buffer);
502 newline ();
503 }
504 }
505 else if (link_flag)
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);
511 else
512 {
513 /* A normal line, just output it */
514 print_string (buffer);
515 if (!width) newline (); /* HTML format */
516 }
517 }
518
519 /* All done */
520 newline ();
521 if (!width){
522 /* HTML format */
523 print_string ("<hr></body></html>");
524 newline ();
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");
529 fclose (index_file);
530 }
531 fclose (file);
532 return 0;
533 }