Blame


1 c42a1d3d 2006-02-21 devnull /*
2 c42a1d3d 2006-02-21 devnull * Emit html. Keep track of tags so that user doesn't have to.
3 c42a1d3d 2006-02-21 devnull */
4 c42a1d3d 2006-02-21 devnull
5 c42a1d3d 2006-02-21 devnull #include "a.h"
6 c42a1d3d 2006-02-21 devnull
7 c42a1d3d 2006-02-21 devnull typedef struct Tag Tag;
8 c42a1d3d 2006-02-21 devnull struct Tag
9 c42a1d3d 2006-02-21 devnull {
10 c42a1d3d 2006-02-21 devnull Tag *next;
11 c42a1d3d 2006-02-21 devnull Rune *id;
12 c42a1d3d 2006-02-21 devnull Rune *open;
13 c42a1d3d 2006-02-21 devnull Rune *close;
14 c42a1d3d 2006-02-21 devnull };
15 c42a1d3d 2006-02-21 devnull
16 c42a1d3d 2006-02-21 devnull Tag *tagstack;
17 c42a1d3d 2006-02-21 devnull Tag *tagset;
18 c42a1d3d 2006-02-21 devnull int hidingset;
19 c42a1d3d 2006-02-21 devnull
20 c42a1d3d 2006-02-21 devnull static Rune*
21 c42a1d3d 2006-02-21 devnull closingtag(Rune *s)
22 c42a1d3d 2006-02-21 devnull {
23 c42a1d3d 2006-02-21 devnull Rune *t;
24 c42a1d3d 2006-02-21 devnull Rune *p0, *p;
25 fa325e9b 2020-01-10 cross
26 c42a1d3d 2006-02-21 devnull t = runemalloc(sizeof(Rune));
27 c42a1d3d 2006-02-21 devnull if(s == nil)
28 c42a1d3d 2006-02-21 devnull return t;
29 c42a1d3d 2006-02-21 devnull for(p=s; *p; p++){
30 c42a1d3d 2006-02-21 devnull if(*p == Ult){
31 c42a1d3d 2006-02-21 devnull p++;
32 c42a1d3d 2006-02-21 devnull if(*p == '/'){
33 c42a1d3d 2006-02-21 devnull while(*p && *p != Ugt)
34 c42a1d3d 2006-02-21 devnull p++;
35 c42a1d3d 2006-02-21 devnull goto close;
36 c42a1d3d 2006-02-21 devnull }
37 c42a1d3d 2006-02-21 devnull p0 = p;
38 c42a1d3d 2006-02-21 devnull while(*p && !isspacerune(*p) && *p != Uspace && *p != Ugt)
39 c42a1d3d 2006-02-21 devnull p++;
40 c42a1d3d 2006-02-21 devnull t = runerealloc(t, 1+(p-p0)+2+runestrlen(t)+1);
41 c42a1d3d 2006-02-21 devnull runemove(t+(p-p0)+3, t, runestrlen(t)+1);
42 c42a1d3d 2006-02-21 devnull t[0] = Ult;
43 c42a1d3d 2006-02-21 devnull t[1] = '/';
44 c42a1d3d 2006-02-21 devnull runemove(t+2, p0, p-p0);
45 c42a1d3d 2006-02-21 devnull t[2+(p-p0)] = Ugt;
46 c42a1d3d 2006-02-21 devnull }
47 fa325e9b 2020-01-10 cross
48 c42a1d3d 2006-02-21 devnull if(*p == Ugt && p>s && *(p-1) == '/'){
49 c42a1d3d 2006-02-21 devnull close:
50 c42a1d3d 2006-02-21 devnull for(p0=t+1; *p0 && *p0 != Ult; p0++)
51 c42a1d3d 2006-02-21 devnull ;
52 c42a1d3d 2006-02-21 devnull runemove(t, p0, runestrlen(p0)+1);
53 c42a1d3d 2006-02-21 devnull }
54 c42a1d3d 2006-02-21 devnull }
55 fa325e9b 2020-01-10 cross return t;
56 c42a1d3d 2006-02-21 devnull }
57 c42a1d3d 2006-02-21 devnull
58 c42a1d3d 2006-02-21 devnull void
59 c42a1d3d 2006-02-21 devnull html(Rune *id, Rune *s)
60 c42a1d3d 2006-02-21 devnull {
61 c42a1d3d 2006-02-21 devnull Rune *es;
62 c42a1d3d 2006-02-21 devnull Tag *t, *tt, *next;
63 c42a1d3d 2006-02-21 devnull
64 c42a1d3d 2006-02-21 devnull br();
65 c42a1d3d 2006-02-21 devnull hideihtml(); /* br already did, but be paranoid */
66 c42a1d3d 2006-02-21 devnull for(t=tagstack; t; t=t->next){
67 c42a1d3d 2006-02-21 devnull if(runestrcmp(t->id, id) == 0){
68 c42a1d3d 2006-02-21 devnull for(tt=tagstack;; tt=next){
69 c42a1d3d 2006-02-21 devnull next = tt->next;
70 c42a1d3d 2006-02-21 devnull free(tt->id);
71 c42a1d3d 2006-02-21 devnull free(tt->open);
72 c42a1d3d 2006-02-21 devnull out(tt->close);
73 c42a1d3d 2006-02-21 devnull outrune('\n');
74 c42a1d3d 2006-02-21 devnull free(tt->close);
75 c42a1d3d 2006-02-21 devnull free(tt);
76 c42a1d3d 2006-02-21 devnull if(tt == t){
77 c42a1d3d 2006-02-21 devnull tagstack = next;
78 c42a1d3d 2006-02-21 devnull goto cleared;
79 c42a1d3d 2006-02-21 devnull }
80 c42a1d3d 2006-02-21 devnull }
81 c42a1d3d 2006-02-21 devnull }
82 c42a1d3d 2006-02-21 devnull }
83 c42a1d3d 2006-02-21 devnull
84 c42a1d3d 2006-02-21 devnull cleared:
85 c42a1d3d 2006-02-21 devnull if(s == nil || s[0] == 0)
86 c42a1d3d 2006-02-21 devnull return;
87 c42a1d3d 2006-02-21 devnull out(s);
88 c42a1d3d 2006-02-21 devnull outrune('\n');
89 c42a1d3d 2006-02-21 devnull es = closingtag(s);
90 c42a1d3d 2006-02-21 devnull if(es[0] == 0){
91 c42a1d3d 2006-02-21 devnull free(es);
92 c42a1d3d 2006-02-21 devnull return;
93 c42a1d3d 2006-02-21 devnull }
94 c42a1d3d 2006-02-21 devnull if(runestrcmp(id, L("-")) == 0){
95 c42a1d3d 2006-02-21 devnull out(es);
96 c42a1d3d 2006-02-21 devnull outrune('\n');
97 c42a1d3d 2006-02-21 devnull free(es);
98 c42a1d3d 2006-02-21 devnull return;
99 c42a1d3d 2006-02-21 devnull }
100 c42a1d3d 2006-02-21 devnull t = emalloc(sizeof *t);
101 c42a1d3d 2006-02-21 devnull t->id = erunestrdup(id);
102 c42a1d3d 2006-02-21 devnull t->close = es;
103 c42a1d3d 2006-02-21 devnull t->next = tagstack;
104 c42a1d3d 2006-02-21 devnull tagstack = t;
105 c42a1d3d 2006-02-21 devnull }
106 c42a1d3d 2006-02-21 devnull
107 c42a1d3d 2006-02-21 devnull void
108 c42a1d3d 2006-02-21 devnull closehtml(void)
109 c42a1d3d 2006-02-21 devnull {
110 c42a1d3d 2006-02-21 devnull Tag *t, *next;
111 fa325e9b 2020-01-10 cross
112 c42a1d3d 2006-02-21 devnull br();
113 c42a1d3d 2006-02-21 devnull hideihtml();
114 c42a1d3d 2006-02-21 devnull for(t=tagstack; t; t=next){
115 c42a1d3d 2006-02-21 devnull next = t->next;
116 c42a1d3d 2006-02-21 devnull out(t->close);
117 c42a1d3d 2006-02-21 devnull outrune('\n');
118 c42a1d3d 2006-02-21 devnull free(t->id);
119 c42a1d3d 2006-02-21 devnull free(t->close);
120 c42a1d3d 2006-02-21 devnull free(t);
121 c42a1d3d 2006-02-21 devnull }
122 c42a1d3d 2006-02-21 devnull }
123 c42a1d3d 2006-02-21 devnull
124 c42a1d3d 2006-02-21 devnull static void
125 c42a1d3d 2006-02-21 devnull rshow(Tag *t, Tag *end)
126 c42a1d3d 2006-02-21 devnull {
127 c42a1d3d 2006-02-21 devnull if(t == nil || t == end)
128 c42a1d3d 2006-02-21 devnull return;
129 c42a1d3d 2006-02-21 devnull rshow(t->next, end);
130 c42a1d3d 2006-02-21 devnull out(t->open);
131 c42a1d3d 2006-02-21 devnull }
132 c42a1d3d 2006-02-21 devnull
133 c42a1d3d 2006-02-21 devnull void
134 c42a1d3d 2006-02-21 devnull ihtml(Rune *id, Rune *s)
135 c42a1d3d 2006-02-21 devnull {
136 c42a1d3d 2006-02-21 devnull Tag *t, *tt, **l;
137 c42a1d3d 2006-02-21 devnull
138 c42a1d3d 2006-02-21 devnull for(t=tagset; t; t=t->next){
139 c42a1d3d 2006-02-21 devnull if(runestrcmp(t->id, id) == 0){
140 c42a1d3d 2006-02-21 devnull if(s && t->open && runestrcmp(t->open, s) == 0)
141 c42a1d3d 2006-02-21 devnull return;
142 c42a1d3d 2006-02-21 devnull for(l=&tagset; (tt=*l); l=&tt->next){
143 c42a1d3d 2006-02-21 devnull if(!hidingset)
144 c42a1d3d 2006-02-21 devnull out(tt->close);
145 c42a1d3d 2006-02-21 devnull if(tt == t)
146 c42a1d3d 2006-02-21 devnull break;
147 c42a1d3d 2006-02-21 devnull }
148 c42a1d3d 2006-02-21 devnull *l = t->next;
149 c42a1d3d 2006-02-21 devnull free(t->id);
150 c42a1d3d 2006-02-21 devnull free(t->close);
151 c42a1d3d 2006-02-21 devnull free(t->open);
152 c42a1d3d 2006-02-21 devnull free(t);
153 c42a1d3d 2006-02-21 devnull if(!hidingset)
154 c42a1d3d 2006-02-21 devnull rshow(tagset, *l);
155 c42a1d3d 2006-02-21 devnull goto cleared;
156 c42a1d3d 2006-02-21 devnull }
157 c42a1d3d 2006-02-21 devnull }
158 c42a1d3d 2006-02-21 devnull
159 c42a1d3d 2006-02-21 devnull cleared:
160 c42a1d3d 2006-02-21 devnull if(s == nil || s[0] == 0)
161 c42a1d3d 2006-02-21 devnull return;
162 c42a1d3d 2006-02-21 devnull t = emalloc(sizeof *t);
163 c42a1d3d 2006-02-21 devnull t->id = erunestrdup(id);
164 c42a1d3d 2006-02-21 devnull t->open = erunestrdup(s);
165 c42a1d3d 2006-02-21 devnull t->close = closingtag(s);
166 c42a1d3d 2006-02-21 devnull if(!hidingset)
167 c42a1d3d 2006-02-21 devnull out(s);
168 c42a1d3d 2006-02-21 devnull t->next = tagset;
169 c42a1d3d 2006-02-21 devnull tagset = t;
170 c42a1d3d 2006-02-21 devnull }
171 c42a1d3d 2006-02-21 devnull
172 c42a1d3d 2006-02-21 devnull void
173 c42a1d3d 2006-02-21 devnull hideihtml(void)
174 c42a1d3d 2006-02-21 devnull {
175 c42a1d3d 2006-02-21 devnull Tag *t;
176 c42a1d3d 2006-02-21 devnull
177 c42a1d3d 2006-02-21 devnull if(hidingset)
178 c42a1d3d 2006-02-21 devnull return;
179 c42a1d3d 2006-02-21 devnull hidingset = 1;
180 c42a1d3d 2006-02-21 devnull for(t=tagset; t; t=t->next)
181 c42a1d3d 2006-02-21 devnull out(t->close);
182 c42a1d3d 2006-02-21 devnull }
183 c42a1d3d 2006-02-21 devnull
184 c42a1d3d 2006-02-21 devnull void
185 c42a1d3d 2006-02-21 devnull showihtml(void)
186 c42a1d3d 2006-02-21 devnull {
187 c42a1d3d 2006-02-21 devnull if(!hidingset)
188 c42a1d3d 2006-02-21 devnull return;
189 c42a1d3d 2006-02-21 devnull hidingset = 0;
190 c42a1d3d 2006-02-21 devnull rshow(tagset, nil);
191 c42a1d3d 2006-02-21 devnull }
192 c42a1d3d 2006-02-21 devnull
193 c42a1d3d 2006-02-21 devnull int
194 c42a1d3d 2006-02-21 devnull e_lt(void)
195 c42a1d3d 2006-02-21 devnull {
196 c42a1d3d 2006-02-21 devnull return Ult;
197 c42a1d3d 2006-02-21 devnull }
198 c42a1d3d 2006-02-21 devnull
199 c42a1d3d 2006-02-21 devnull int
200 c42a1d3d 2006-02-21 devnull e_gt(void)
201 c42a1d3d 2006-02-21 devnull {
202 c42a1d3d 2006-02-21 devnull return Ugt;
203 c42a1d3d 2006-02-21 devnull }
204 c42a1d3d 2006-02-21 devnull
205 c42a1d3d 2006-02-21 devnull int
206 c42a1d3d 2006-02-21 devnull e_at(void)
207 c42a1d3d 2006-02-21 devnull {
208 c42a1d3d 2006-02-21 devnull return Uamp;
209 c42a1d3d 2006-02-21 devnull }
210 c42a1d3d 2006-02-21 devnull
211 c42a1d3d 2006-02-21 devnull int
212 c42a1d3d 2006-02-21 devnull e_tick(void)
213 c42a1d3d 2006-02-21 devnull {
214 c42a1d3d 2006-02-21 devnull return Utick;
215 c42a1d3d 2006-02-21 devnull }
216 c42a1d3d 2006-02-21 devnull
217 c42a1d3d 2006-02-21 devnull int
218 c42a1d3d 2006-02-21 devnull e_btick(void)
219 c42a1d3d 2006-02-21 devnull {
220 c42a1d3d 2006-02-21 devnull return Ubtick;
221 c42a1d3d 2006-02-21 devnull }
222 c42a1d3d 2006-02-21 devnull
223 c42a1d3d 2006-02-21 devnull int
224 c42a1d3d 2006-02-21 devnull e_minus(void)
225 c42a1d3d 2006-02-21 devnull {
226 c42a1d3d 2006-02-21 devnull return Uminus;
227 c42a1d3d 2006-02-21 devnull }
228 c42a1d3d 2006-02-21 devnull
229 c42a1d3d 2006-02-21 devnull void
230 c42a1d3d 2006-02-21 devnull r_html(Rune *name)
231 c42a1d3d 2006-02-21 devnull {
232 c42a1d3d 2006-02-21 devnull Rune *id, *line, *p;
233 fa325e9b 2020-01-10 cross
234 c42a1d3d 2006-02-21 devnull id = copyarg();
235 c42a1d3d 2006-02-21 devnull line = readline(HtmlMode);
236 c42a1d3d 2006-02-21 devnull for(p=line; *p; p++){
237 c42a1d3d 2006-02-21 devnull switch(*p){
238 c42a1d3d 2006-02-21 devnull case '<':
239 c42a1d3d 2006-02-21 devnull *p = Ult;
240 c42a1d3d 2006-02-21 devnull break;
241 c42a1d3d 2006-02-21 devnull case '>':
242 c42a1d3d 2006-02-21 devnull *p = Ugt;
243 c42a1d3d 2006-02-21 devnull break;
244 c42a1d3d 2006-02-21 devnull case '&':
245 c42a1d3d 2006-02-21 devnull *p = Uamp;
246 c42a1d3d 2006-02-21 devnull break;
247 c42a1d3d 2006-02-21 devnull case ' ':
248 c42a1d3d 2006-02-21 devnull *p = Uspace;
249 c42a1d3d 2006-02-21 devnull break;
250 c42a1d3d 2006-02-21 devnull }
251 c42a1d3d 2006-02-21 devnull }
252 c42a1d3d 2006-02-21 devnull if(name[0] == 'i')
253 c42a1d3d 2006-02-21 devnull ihtml(id, line);
254 c42a1d3d 2006-02-21 devnull else
255 c42a1d3d 2006-02-21 devnull html(id, line);
256 c42a1d3d 2006-02-21 devnull free(id);
257 c42a1d3d 2006-02-21 devnull free(line);
258 c42a1d3d 2006-02-21 devnull }
259 c42a1d3d 2006-02-21 devnull
260 c42a1d3d 2006-02-21 devnull char defaultfont[] =
261 c42a1d3d 2006-02-21 devnull ".ihtml f1\n"
262 c42a1d3d 2006-02-21 devnull ".ihtml f\n"
263 495eda0b 2006-05-09 devnull ".ihtml f <span style=\"font-size: \\n(.spt\">\n"
264 c42a1d3d 2006-02-21 devnull ".if \\n(.f==2 .ihtml f1 <i>\n"
265 c42a1d3d 2006-02-21 devnull ".if \\n(.f==3 .ihtml f1 <b>\n"
266 c42a1d3d 2006-02-21 devnull ".if \\n(.f==4 .ihtml f1 <b><i>\n"
267 c42a1d3d 2006-02-21 devnull ".if \\n(.f==5 .ihtml f1 <tt>\n"
268 c42a1d3d 2006-02-21 devnull ".if \\n(.f==6 .ihtml f1 <tt><i>\n"
269 c42a1d3d 2006-02-21 devnull "..\n"
270 c42a1d3d 2006-02-21 devnull ;
271 c42a1d3d 2006-02-21 devnull
272 c42a1d3d 2006-02-21 devnull void
273 c42a1d3d 2006-02-21 devnull htmlinit(void)
274 c42a1d3d 2006-02-21 devnull {
275 c42a1d3d 2006-02-21 devnull addraw(L("html"), r_html);
276 c42a1d3d 2006-02-21 devnull addraw(L("ihtml"), r_html);
277 c42a1d3d 2006-02-21 devnull
278 c42a1d3d 2006-02-21 devnull addesc('<', e_lt, CopyMode);
279 c42a1d3d 2006-02-21 devnull addesc('>', e_gt, CopyMode);
280 c42a1d3d 2006-02-21 devnull addesc('\'', e_tick, CopyMode);
281 c42a1d3d 2006-02-21 devnull addesc('`', e_btick, CopyMode);
282 c42a1d3d 2006-02-21 devnull addesc('-', e_minus, CopyMode);
283 c42a1d3d 2006-02-21 devnull addesc('@', e_at, CopyMode);
284 fa325e9b 2020-01-10 cross
285 c42a1d3d 2006-02-21 devnull ds(L("font"), L(defaultfont));
286 c42a1d3d 2006-02-21 devnull }