- Start rosapps rearrange and cleanup process.
[reactos.git] / rosapps / applications / mc / src / fixhlp.c
1 /* HLP converter
2 Copyright (C) 1994, 1995 Janne Kukonlehto
3 Copyright (C) 1995 Jakub Jelinek
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include "help.h"
25
26 #define BUFFER_SIZE 256
27
28 static int width; /* Output width in characters */
29 static int col = 0; /* Current output column */
30 static FILE *toc_file; /* TOC file */
31 static int out_row = 1; /* Current output row */
32 static int in_row = 0; /* Current input row */
33 static int indent = 1;
34 static int curindent = 1;
35 static int freshnl = 1;
36 static int firstlen = 0;
37 static int verbatim = 0;
38
39 /* Report error in input */
40 void print_error (char *message)
41 {
42 fprintf (stderr, "fixhlp: %s at row %d\n", message, in_row);
43 }
44
45 /* Change output line */
46 void newline (void)
47 {
48 out_row ++;
49 col = indent;
50 curindent = indent;
51 printf("\n%*s", indent, "");
52 freshnl = 1;
53 firstlen = 0;
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 i; /* Index */
62 int c; /* Current character */
63 int len = 0; /* Result: the length of the string */
64
65 for (i = 0; i < strlen (buffer); i ++)
66 {
67 c = buffer [i];
68 if (c == CHAR_LINK_POINTER)
69 link_flag = 1; /* Link target name starts */
70 else if (c == CHAR_LINK_END)
71 link_flag = 0; /* Link target name ends */
72 else if (c == CHAR_NODE_END){
73 /* Node anchor name starts */
74 anchor_flag = 1;
75 /* Ugly hack to prevent loss of one space */
76 len ++;
77 }
78 /* Don't add control characters to the length */
79 if (c < 32)
80 continue;
81 /* Attempt to handle backslash quoting */
82 /* Increase length if not inside anchor name or link target name */
83 if (!anchor_flag && !link_flag)
84 len ++;
85 if (anchor_flag && c == ']'){
86 /* Node anchor name ends */
87 anchor_flag = 0;
88 }
89 }
90 return len;
91 }
92
93 /* Output the string */
94 void print_string (char *buffer)
95 {
96 int len; /* The length of current word */
97 int i; /* Index */
98 int c; /* Current character */
99 char *p;
100
101 /* Split into words */
102 if (verbatim) {
103 printf ("%s", buffer);
104 newline ();
105 return;
106 }
107 p = strchr (buffer, CHAR_LINK_POINTER);
108 if (p) {
109 char *q;
110
111 *p = 0;
112 print_string (buffer);
113 q = strchr (p + 1, CHAR_LINK_END);
114 if (q) {
115 *q = 0;
116 printf ("%c%s%c", CHAR_LINK_POINTER, p + 1, CHAR_LINK_END);
117 print_string (q + 1);
118 } else {
119 /* Error, but try to handle it somehow */
120 printf ("%c", CHAR_LINK_END);
121 }
122 return;
123 }
124 buffer = strtok (buffer, " \t\n");
125 /* Repeat for each word */
126 while (buffer){
127 /* Skip empty strings */
128 if (strlen (buffer) > 0){
129 len = string_len (buffer);
130 /* Change the line if about to break the right margin */
131 if (col + len >= width)
132 newline ();
133 /* Words are separated by spaces */
134 if (col > curindent){
135 printf (" ");
136 col ++;
137 }
138 printf ("%s", buffer);
139 /* Increase column */
140 col += len;
141 }
142 /* Get the next word */
143 buffer = strtok (NULL, " \t\n");
144 } /* while */
145 if (freshnl) {
146 firstlen = col - curindent;
147 freshnl = 0;
148 }
149 }
150
151 /* Like print_string but with printf-like syntax */
152 void printf_string (char *format, ...)
153 {
154 va_list args;
155 char buffer [BUFFER_SIZE];
156
157 va_start (args, format);
158 vsprintf (buffer, format, args);
159 va_end (args);
160 print_string (buffer);
161 }
162
163 int main (int argc, char **argv)
164 {
165 int len; /* Length of input line */
166 char buffer [BUFFER_SIZE]; /* Input line */
167 int i, j;
168 char *p;
169 int ignore_newline = 0;
170
171 /* Validity check for arguments */
172 if (argc != 3 || (width = atoi (argv[1])) <= 10){
173 fprintf (stderr, _("Usage: fixhlp <width> <tocname>\n"));
174 return 3;
175 }
176
177 if ((toc_file = fopen (argv[2], "w")) == NULL) {
178 fprintf (stderr, _("fixhlp: Cannot open toc for writing"));
179 return 4;
180 }
181 fprintf (toc_file, _("\04[Contents]\n Topics:\n\n"));
182
183 /* Repeat for each input line */
184 while (!feof (stdin)){
185 /* Read a line */
186 if (!fgets (buffer, BUFFER_SIZE, stdin)){
187 break;
188 }
189 in_row ++;
190 len = strlen (buffer);
191 /* Remove terminating newline */
192 if (buffer [len-1] == '\n')
193 {
194 len --;
195 buffer [len] = 0;
196 }
197 if (!buffer[0]) {
198 if (ignore_newline)
199 ignore_newline = 0;
200 else
201 newline ();
202 } else {
203 if (buffer [0] == 4 && buffer [1] == '[') {
204 for (p = buffer + 2; *p == ' '; p++);
205 fprintf (toc_file, "%*s\01 %s \02%s\03\n", p - buffer + 1, "", p, p);
206 printf ("\04[%s]\n %s", p, p);
207 } else if (buffer [0] == CHAR_RESERVED && buffer [1] == '"') {
208 continue;
209 } else {
210 char *p, *q;
211 int i;
212
213 for (p = buffer, q = strchr (p, CHAR_RESERVED); q != NULL;
214 p = q + 1, q = strchr (p, CHAR_RESERVED)) {
215 *q = 0;
216 if (*p)
217 print_string (p);
218 q++;
219 if (*q == '/')
220 ignore_newline = 1;
221 else if (*q == 'v')
222 verbatim = 1;
223 else if (*q == 'n')
224 verbatim = 0;
225 else {
226 indent = *q - '0';
227 if (ignore_newline) {
228 i = firstlen;
229 if (i > indent - curindent - 1)
230 ignore_newline = 0;
231 else {
232 i = indent - curindent - i - 1;
233 printf ("%*s", i, "");
234 col += i;
235 }
236 }
237 }
238 }
239 print_string (p);
240 }
241 }
242 }
243
244 /* All done */
245 newline ();
246 return 0;
247 }