]> code.citadel.org Git - citadel.git/blob - citadel/html.c
* HTML updates
[citadel.git] / citadel / html.c
1 /*
2  * html.c -- Functions which handle translation between HTML and plain text
3  * $Id$
4  */
5
6 #include "sysdep.h"
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <fcntl.h>
11 #include <signal.h>
12 #include <time.h>
13 #include <ctype.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <limits.h>
17 #ifdef HAVE_PTHREAD_H
18 #include <pthread.h>
19 #endif
20 #include <syslog.h>
21 #include "citadel.h"
22 #include "server.h"
23 #include "control.h"
24 #include "sysdep_decls.h"
25 #include "support.h"
26 #include "config.h"
27 #include "msgbase.h"
28 #include "tools.h"
29 #include "room_ops.h"
30 #include "html.h"
31  
32
33 /*
34  * Convert HTML to plain text.
35  */
36 char *html_to_ascii(char *inputmsg, int screenwidth) {
37         char inbuf[256];
38         char outbuf[256];
39         char tag[1024];
40         int done_reading = 0;
41         char *inptr;
42         int i, j, ch, did_out, rb;
43         int nest = 0;           /* Bracket nesting level */
44
45         inptr = inputmsg;
46         strcpy(inbuf, "");
47         strcpy(outbuf, "");
48
49         do {
50                 /* Fill the input buffer */
51                 if ( (done_reading == 0) && (strlen(inbuf) < 128) ) {
52
53                         /* FIX ... genericize this */
54                         ch = *inputmsg++;
55                         if (ch > 0) {
56                                 inbuf[strlen(inbuf)+1] = 0;
57                                 inbuf[strlen(inbuf)] = ch;
58                         } 
59                         else {
60                                 done_reading = 1;
61                         }
62
63                 }
64
65                 /* Do some parsing */
66                 if (strlen(inbuf)>0) {
67
68                     /* Fold in all the spacing */
69                     for (i=0; i<strlen(inbuf); ++i) {
70                         if (inbuf[i]==10) inbuf[i]=32;
71                         if (inbuf[i]==13) inbuf[i]=32;
72                         if (inbuf[i]==9) inbuf[i]=32;
73                         if ((inbuf[i]<32) || (inbuf[i]>126))
74                                 strcpy(&inbuf[i], &inbuf[i+1]);
75                         while ((inbuf[i]==32)&&(inbuf[i+1]==32))
76                                 strcpy(&inbuf[i], &inbuf[i+1]);
77                     }
78
79                     for (i=0; i<strlen(inbuf); ++i) {
80
81                         ch = inbuf[i];
82
83                         if (ch == '<') {
84                                 ++nest;
85                                 strcpy(tag, "");
86                         }
87
88                         else if (ch == '>') {
89                                 if (nest > 0) --nest;
90                                 
91                                 if (!strcasecmp(tag, "P")) {
92                                         strcat(outbuf, "\n\n");
93                                 }
94
95                                 else if (!strcasecmp(tag, "H1")) {
96                                         strcat(outbuf, "\n\n");
97                                 }
98
99                                 else if (!strcasecmp(tag, "H2")) {
100                                         strcat(outbuf, "\n\n");
101                                 }
102
103                                 else if (!strcasecmp(tag, "H3")) {
104                                         strcat(outbuf, "\n\n");
105                                 }
106
107                                 else if (!strcasecmp(tag, "H4")) {
108                                         strcat(outbuf, "\n\n");
109                                 }
110
111                                 else if (!strcasecmp(tag, "/H1")) {
112                                         strcat(outbuf, "\n");
113                                 }
114
115                                 else if (!strcasecmp(tag, "/H2")) {
116                                         strcat(outbuf, "\n");
117                                 }
118
119                                 else if (!strcasecmp(tag, "/H3")) {
120                                         strcat(outbuf, "\n");
121                                 }
122
123                                 else if (!strcasecmp(tag, "/H4")) {
124                                         strcat(outbuf, "\n");
125                                 }
126
127                                 else if (!strcasecmp(tag, "HR")) {
128                                         strcat(outbuf, "\n ");
129                                         for (j=0; j<screenwidth-2; ++j)
130                                                 strcat(outbuf, "-");
131                                         strcat(outbuf, "\n");
132                                 }
133
134                                 else if (!strcasecmp(tag, "BR")) {
135                                         strcat(outbuf, "\n");
136                                 }
137
138                                 else if (!strcasecmp(tag, "TR")) {
139                                         strcat(outbuf, "\n");
140                                 }
141
142                                 else if (!strcasecmp(tag, "/TABLE")) {
143                                         strcat(outbuf, "\n");
144                                 }
145
146                         }
147
148                         else if ((nest > 0) && (strlen(tag)<(sizeof(tag)-1))) {
149                                 tag[strlen(tag)+1] = 0;
150                                 tag[strlen(tag)] = ch;
151                         }
152                                 
153                         else if (!nest) {
154                                 outbuf[strlen(outbuf)+1] = 0;
155                                 outbuf[strlen(outbuf)] = ch;
156                         }
157                     }
158                     strcpy(inbuf, &inbuf[i]);
159                 }
160
161                 /* Convert &; tags to the forbidden characters */
162                 if (strlen(outbuf)>0) for (i=0; i<strlen(outbuf); ++i) {
163
164                         if (!strncasecmp(&outbuf[i], "&nbsp;", 6)) {
165                                 outbuf[i] = ' ';
166                                 strcpy(&outbuf[i+1], &outbuf[i+6]);
167                         }
168
169                         else if (!strncasecmp(&outbuf[i], "&lt;", 4)) {
170                                 outbuf[i] = '<';
171                                 strcpy(&outbuf[i+1], &outbuf[i+4]);
172                         }
173
174                         else if (!strncasecmp(&outbuf[i], "&gt;", 4)) {
175                                 outbuf[i] = '>';
176                                 strcpy(&outbuf[i+1], &outbuf[i+4]);
177                         }
178
179                         else if (!strncasecmp(&outbuf[i], "&amp;", 5)) {
180                                 strcpy(&outbuf[i+1], &outbuf[i+5]);
181                         }
182
183                         else if (!strncasecmp(&outbuf[i], "&quot;", 6)) {
184                                 outbuf[i] = '\"';
185                                 strcpy(&outbuf[i+1], &outbuf[i+6]);
186                         }
187
188                         else if (!strncasecmp(&outbuf[i], "&copy;", 6)) {
189                                 outbuf[i] = '(';
190                                 outbuf[i+1] = 'c';
191                                 outbuf[i+2] = ')';
192                                 strcpy(&outbuf[i+3], &outbuf[i+6]);
193                         }
194
195                 }
196
197                 /* Output any lines terminated with hard line breaks */
198                 do {
199                         did_out = 0;
200                         if (strlen(outbuf)>0)
201                             for (i = 0; i<strlen(outbuf); ++i) {
202                                 if ( (i<(screenwidth-2)) && (outbuf[i]=='\n')) {
203                                         fwrite(outbuf, i+1, 1, stdout);
204                                         strcpy(outbuf, &outbuf[i+1]);
205                                         i = 0;
206                                         did_out = 1;
207                                 }
208                         }
209                 } while (did_out);
210
211                 /* Add soft line breaks */
212                 if (strlen(outbuf) > (screenwidth - 2)) {
213                         rb = (-1);
214                         for (i=0; i<(screenwidth-2); ++i) {
215                                 if (outbuf[i]==32) rb = i;
216                         }
217                         if (rb>=0) {
218                                 fwrite(outbuf, rb, 1, stdout);
219                                 fwrite("\n", 1, 1, stdout);
220                                 strcpy(outbuf, &outbuf[rb+1]);
221                         } else {
222                                 fwrite(outbuf, screenwidth-2, 1, stdout);
223                                 fwrite("\n", 1, 1, stdout);
224                                 strcpy(outbuf, &outbuf[screenwidth-2]);
225                         }
226                 }
227
228         } while (done_reading == 0);
229         fwrite(outbuf, strlen(outbuf), 1, stdout);
230         fwrite("\n", 1, 1, stdout);
231
232         inptr = mallok(100);
233         strcpy(inptr, "This is eekish.\n");
234         return inptr;
235
236 }
237