2 c42a1d3d 2006-02-21 devnull * 7. Macros, strings, diversion, and position traps.
4 c42a1d3d 2006-02-21 devnull * macros can override builtins
5 c42a1d3d 2006-02-21 devnull * builtins can be renamed or removed!
8 c42a1d3d 2006-02-21 devnull #include "a.h"
12 c42a1d3d 2006-02-21 devnull MAXARG = 10,
13 c42a1d3d 2006-02-21 devnull MAXMSTACK = 40
16 c42a1d3d 2006-02-21 devnull /* macro invocation frame */
17 c42a1d3d 2006-02-21 devnull typedef struct Mac Mac;
18 c42a1d3d 2006-02-21 devnull struct Mac
20 c42a1d3d 2006-02-21 devnull int argc;
21 c42a1d3d 2006-02-21 devnull Rune *argv[MAXARG];
24 c42a1d3d 2006-02-21 devnull Mac mstack[MAXMSTACK];
25 c42a1d3d 2006-02-21 devnull int nmstack;
26 c42a1d3d 2006-02-21 devnull void emitdi(void);
27 c42a1d3d 2006-02-21 devnull void flushdi(void);
30 c42a1d3d 2006-02-21 devnull * Run a user-defined macro.
32 c42a1d3d 2006-02-21 devnull void popmacro(void);
34 c42a1d3d 2006-02-21 devnull runmacro(int dot, int argc, Rune **argv)
40 c42a1d3d 2006-02-21 devnull if(verbose && isupperrune(argv[0][0])) fprint(2, "run: %S\n", argv[0]);
41 c42a1d3d 2006-02-21 devnull p = getds(argv[0]);
42 c42a1d3d 2006-02-21 devnull if(p == nil){
43 c42a1d3d 2006-02-21 devnull if(verbose)
44 c42a1d3d 2006-02-21 devnull warn("ignoring unknown request %C%S", dot, argv[0]);
45 c42a1d3d 2006-02-21 devnull if(verbose > 1){
46 c42a1d3d 2006-02-21 devnull for(i=0; i<argc; i++)
47 c42a1d3d 2006-02-21 devnull fprint(2, " %S", argv[i]);
48 c42a1d3d 2006-02-21 devnull fprint(2, "\n");
50 c42a1d3d 2006-02-21 devnull return -1;
52 c42a1d3d 2006-02-21 devnull if(nmstack >= nelem(mstack)){
53 c42a1d3d 2006-02-21 devnull fprint(2, "%L: macro stack overflow:");
54 c42a1d3d 2006-02-21 devnull for(i=0; i<nmstack; i++)
55 c42a1d3d 2006-02-21 devnull fprint(2, " %S", mstack[i].argv[0]);
56 c42a1d3d 2006-02-21 devnull fprint(2, "\n");
57 c42a1d3d 2006-02-21 devnull return -1;
59 c42a1d3d 2006-02-21 devnull m = &mstack[nmstack++];
60 c42a1d3d 2006-02-21 devnull m->argc = argc;
61 c42a1d3d 2006-02-21 devnull for(i=0; i<argc; i++)
62 c42a1d3d 2006-02-21 devnull m->argv[i] = erunestrdup(argv[i]);
63 c42a1d3d 2006-02-21 devnull pushinputstring(p);
64 c42a1d3d 2006-02-21 devnull nr(L(".$"), argc-1);
65 c42a1d3d 2006-02-21 devnull inputnotify(popmacro);
66 c42a1d3d 2006-02-21 devnull return 0;
70 c42a1d3d 2006-02-21 devnull popmacro(void)
75 c42a1d3d 2006-02-21 devnull if(--nmstack < 0){
76 c42a1d3d 2006-02-21 devnull fprint(2, "%L: macro stack underflow\n");
79 c42a1d3d 2006-02-21 devnull m = &mstack[nmstack];
80 c42a1d3d 2006-02-21 devnull for(i=0; i<m->argc; i++)
81 c42a1d3d 2006-02-21 devnull free(m->argv[i]);
82 c42a1d3d 2006-02-21 devnull if(nmstack > 0)
83 c42a1d3d 2006-02-21 devnull nr(L(".$"), mstack[nmstack-1].argc-1);
85 c42a1d3d 2006-02-21 devnull nr(L(".$"), 0);
88 c42a1d3d 2006-02-21 devnull void popmacro1(void);
89 c42a1d3d 2006-02-21 devnull jmp_buf runjb[10];
90 c42a1d3d 2006-02-21 devnull int nrunjb;
93 c42a1d3d 2006-02-21 devnull runmacro1(Rune *name)
95 c42a1d3d 2006-02-21 devnull Rune *argv[2];
96 c42a1d3d 2006-02-21 devnull int obol;
98 c42a1d3d 2006-02-21 devnull if(verbose) fprint(2, "outcb %p\n", outcb);
99 c42a1d3d 2006-02-21 devnull obol = bol;
100 c42a1d3d 2006-02-21 devnull argv[0] = name;
101 c42a1d3d 2006-02-21 devnull argv[1] = nil;
102 c42a1d3d 2006-02-21 devnull bol = 1;
103 c42a1d3d 2006-02-21 devnull if(runmacro('.', 1, argv) >= 0){
104 c42a1d3d 2006-02-21 devnull inputnotify(popmacro1);
105 c42a1d3d 2006-02-21 devnull if(!setjmp(runjb[nrunjb++]))
106 c42a1d3d 2006-02-21 devnull runinput();
108 c42a1d3d 2006-02-21 devnull if(verbose) fprint(2, "finished %S\n", name);
110 c42a1d3d 2006-02-21 devnull bol = obol;
114 c42a1d3d 2006-02-21 devnull popmacro1(void)
116 c42a1d3d 2006-02-21 devnull popmacro();
117 c42a1d3d 2006-02-21 devnull if(nrunjb >= 0)
118 c42a1d3d 2006-02-21 devnull longjmp(runjb[--nrunjb], 1);
122 c42a1d3d 2006-02-21 devnull * macro arguments
124 c42a1d3d 2006-02-21 devnull * "" means " inside " "
125 c42a1d3d 2006-02-21 devnull * "" empty string
126 c42a1d3d 2006-02-21 devnull * \newline can be done
127 c42a1d3d 2006-02-21 devnull * argument separator is space (not tab)
128 c42a1d3d 2006-02-21 devnull * number register .$ = number of arguments
129 c42a1d3d 2006-02-21 devnull * no arguments outside macros or in strings
131 c42a1d3d 2006-02-21 devnull * arguments copied in copy mode
135 c42a1d3d 2006-02-21 devnull * diversions
137 c42a1d3d 2006-02-21 devnull * processed output diverted
138 c42a1d3d 2006-02-21 devnull * dn dl registers vertical and horizontal size of last diversion
139 c42a1d3d 2006-02-21 devnull * .z - current diversion name
145 c42a1d3d 2006-02-21 devnull * skip most
146 c42a1d3d 2006-02-21 devnull * .t register - distance to next trap
148 c42a1d3d 2006-02-21 devnull static Rune *trap0;
151 c42a1d3d 2006-02-21 devnull outtrap(void)
153 c42a1d3d 2006-02-21 devnull Rune *t;
155 c42a1d3d 2006-02-21 devnull if(outcb)
157 c42a1d3d 2006-02-21 devnull if(trap0){
158 c42a1d3d 2006-02-21 devnull if(verbose) fprint(2, "trap: %S\n", trap0);
159 c42a1d3d 2006-02-21 devnull t = trap0;
160 c42a1d3d 2006-02-21 devnull trap0 = nil;
161 c42a1d3d 2006-02-21 devnull runmacro1(t);
162 c42a1d3d 2006-02-21 devnull free(t);
166 c42a1d3d 2006-02-21 devnull /* .wh - install trap */
168 c42a1d3d 2006-02-21 devnull r_wh(int argc, Rune **argv)
172 c42a1d3d 2006-02-21 devnull if(argc < 2)
175 c42a1d3d 2006-02-21 devnull i = eval(argv[1]);
176 c42a1d3d 2006-02-21 devnull if(argc == 2){
177 c42a1d3d 2006-02-21 devnull if(i == 0){
178 c42a1d3d 2006-02-21 devnull free(trap0);
179 c42a1d3d 2006-02-21 devnull trap0 = nil;
181 c42a1d3d 2006-02-21 devnull if(verbose)
182 c42a1d3d 2006-02-21 devnull warn("not removing trap at %d", i);
184 c42a1d3d 2006-02-21 devnull if(argc > 2){
185 c42a1d3d 2006-02-21 devnull if(i == 0){
186 c42a1d3d 2006-02-21 devnull free(trap0);
187 c42a1d3d 2006-02-21 devnull trap0 = erunestrdup(argv[2]);
189 c42a1d3d 2006-02-21 devnull if(verbose)
190 c42a1d3d 2006-02-21 devnull warn("not installing %S trap at %d", argv[2], i);
195 c42a1d3d 2006-02-21 devnull r_ch(int argc, Rune **argv)
199 c42a1d3d 2006-02-21 devnull if(argc == 2){
200 c42a1d3d 2006-02-21 devnull if(trap0 && runestrcmp(argv[1], trap0) == 0){
201 c42a1d3d 2006-02-21 devnull free(trap0);
202 c42a1d3d 2006-02-21 devnull trap0 = nil;
204 c42a1d3d 2006-02-21 devnull if(verbose)
205 c42a1d3d 2006-02-21 devnull warn("not removing %S trap", argv[1]);
208 c42a1d3d 2006-02-21 devnull if(argc >= 3){
209 c42a1d3d 2006-02-21 devnull i = eval(argv[2]);
210 c42a1d3d 2006-02-21 devnull if(i == 0){
211 c42a1d3d 2006-02-21 devnull free(trap0);
212 c42a1d3d 2006-02-21 devnull trap0 = erunestrdup(argv[1]);
214 c42a1d3d 2006-02-21 devnull if(verbose)
215 c42a1d3d 2006-02-21 devnull warn("not moving %S trap to %d", argv[1], i);
220 c42a1d3d 2006-02-21 devnull r_dt(int argc, Rune **argv)
222 c42a1d3d 2006-02-21 devnull USED(argc);
223 c42a1d3d 2006-02-21 devnull USED(argv);
224 c42a1d3d 2006-02-21 devnull warn("ignoring diversion trap");
227 c42a1d3d 2006-02-21 devnull /* define macro - .de, .am, .ig */
229 c42a1d3d 2006-02-21 devnull r_de(int argc, Rune **argv)
231 c42a1d3d 2006-02-21 devnull Rune *end, *p;
232 c42a1d3d 2006-02-21 devnull Fmt fmt;
233 c42a1d3d 2006-02-21 devnull int ignore, len;
235 c42a1d3d 2006-02-21 devnull delreq(argv[1]);
236 c42a1d3d 2006-02-21 devnull delraw(argv[1]);
237 c42a1d3d 2006-02-21 devnull ignore = runestrcmp(argv[0], L("ig")) == 0;
238 c42a1d3d 2006-02-21 devnull if(!ignore)
239 c42a1d3d 2006-02-21 devnull runefmtstrinit(&fmt);
240 c42a1d3d 2006-02-21 devnull end = L("..");
241 c42a1d3d 2006-02-21 devnull if(argc >= 3)
242 c42a1d3d 2006-02-21 devnull end = argv[2];
243 c42a1d3d 2006-02-21 devnull if(runestrcmp(argv[0], L("am")) == 0 && (p=getds(argv[1])) != nil)
244 c42a1d3d 2006-02-21 devnull fmtrunestrcpy(&fmt, p);
245 c42a1d3d 2006-02-21 devnull len = runestrlen(end);
246 c42a1d3d 2006-02-21 devnull while((p = readline(CopyMode)) != nil){
247 c42a1d3d 2006-02-21 devnull if(runestrncmp(p, end, len) == 0
248 c42a1d3d 2006-02-21 devnull && (p[len]==' ' || p[len]==0 || p[len]=='\t'
249 c42a1d3d 2006-02-21 devnull || (p[len]=='\\' && p[len+1]=='}'))){
250 c42a1d3d 2006-02-21 devnull free(p);
251 c42a1d3d 2006-02-21 devnull goto done;
253 c42a1d3d 2006-02-21 devnull if(!ignore)
254 c42a1d3d 2006-02-21 devnull fmtprint(&fmt, "%S\n", p);
255 c42a1d3d 2006-02-21 devnull free(p);
257 c42a1d3d 2006-02-21 devnull warn("eof in %C%S %S - looking for %#Q", dot, argv[0], argv[1], end);
259 c42a1d3d 2006-02-21 devnull if(ignore)
261 c42a1d3d 2006-02-21 devnull p = runefmtstrflush(&fmt);
262 c42a1d3d 2006-02-21 devnull if(p == nil)
263 c42a1d3d 2006-02-21 devnull sysfatal("out of memory");
264 c42a1d3d 2006-02-21 devnull ds(argv[1], p);
265 c42a1d3d 2006-02-21 devnull free(p);
268 c42a1d3d 2006-02-21 devnull /* define string .ds .as */
270 c42a1d3d 2006-02-21 devnull r_ds(Rune *cmd)
272 c42a1d3d 2006-02-21 devnull Rune *name, *line, *p;
274 c42a1d3d 2006-02-21 devnull name = copyarg();
275 c42a1d3d 2006-02-21 devnull line = readline(CopyMode);
276 c42a1d3d 2006-02-21 devnull if(name == nil || line == nil){
277 c42a1d3d 2006-02-21 devnull free(name);
280 c42a1d3d 2006-02-21 devnull p = line;
281 c42a1d3d 2006-02-21 devnull if(*p == '"')
283 c42a1d3d 2006-02-21 devnull if(cmd[0] == 'd')
284 c42a1d3d 2006-02-21 devnull ds(name, p);
286 c42a1d3d 2006-02-21 devnull as(name, p);
287 c42a1d3d 2006-02-21 devnull free(name);
288 c42a1d3d 2006-02-21 devnull free(line);
291 c42a1d3d 2006-02-21 devnull /* remove request, macro, or string */
293 c42a1d3d 2006-02-21 devnull r_rm(int argc, Rune **argv)
297 c42a1d3d 2006-02-21 devnull emitdi();
298 c42a1d3d 2006-02-21 devnull for(i=1; i<argc; i++){
299 c42a1d3d 2006-02-21 devnull delreq(argv[i]);
300 c42a1d3d 2006-02-21 devnull delraw(argv[i]);
301 c42a1d3d 2006-02-21 devnull ds(argv[i], nil);
305 c42a1d3d 2006-02-21 devnull /* .rn - rename request, macro, or string */
307 c42a1d3d 2006-02-21 devnull r_rn(int argc, Rune **argv)
309 c42a1d3d 2006-02-21 devnull USED(argc);
310 c42a1d3d 2006-02-21 devnull renreq(argv[1], argv[2]);
311 c42a1d3d 2006-02-21 devnull renraw(argv[1], argv[2]);
312 c42a1d3d 2006-02-21 devnull ds(argv[2], getds(argv[1]));
313 c42a1d3d 2006-02-21 devnull ds(argv[1], nil);
316 c42a1d3d 2006-02-21 devnull /* .di - divert output to macro xx */
317 c42a1d3d 2006-02-21 devnull /* .da - divert, appending to macro */
318 c42a1d3d 2006-02-21 devnull /* page offsetting is not done! */
319 c42a1d3d 2006-02-21 devnull Fmt difmt;
320 c42a1d3d 2006-02-21 devnull int difmtinit;
321 c42a1d3d 2006-02-21 devnull Rune di[20][100];
322 c42a1d3d 2006-02-21 devnull int ndi;
325 c42a1d3d 2006-02-21 devnull emitdi(void)
327 c42a1d3d 2006-02-21 devnull flushdi();
328 c42a1d3d 2006-02-21 devnull runefmtstrinit(&difmt);
329 c42a1d3d 2006-02-21 devnull difmtinit = 1;
330 c42a1d3d 2006-02-21 devnull fmtrune(&difmt, Uformatted);
334 c42a1d3d 2006-02-21 devnull flushdi(void)
337 c42a1d3d 2006-02-21 devnull Rune *p;
339 c42a1d3d 2006-02-21 devnull if(ndi == 0 || difmtinit == 0)
341 c42a1d3d 2006-02-21 devnull fmtrune(&difmt, Uunformatted);
342 c42a1d3d 2006-02-21 devnull p = runefmtstrflush(&difmt);
343 c42a1d3d 2006-02-21 devnull memset(&difmt, 0, sizeof difmt);
344 c42a1d3d 2006-02-21 devnull difmtinit = 0;
345 c42a1d3d 2006-02-21 devnull if(p == nil)
346 c42a1d3d 2006-02-21 devnull warn("out of memory in diversion %C%S", dot, di[ndi-1]);
348 c42a1d3d 2006-02-21 devnull n = runestrlen(p);
349 c42a1d3d 2006-02-21 devnull if(n > 0 && p[n-1] != '\n'){
350 c42a1d3d 2006-02-21 devnull p = runerealloc(p, n+2);
351 c42a1d3d 2006-02-21 devnull p[n] = '\n';
352 c42a1d3d 2006-02-21 devnull p[n+1] = 0;
355 c42a1d3d 2006-02-21 devnull as(di[ndi-1], p);
356 c42a1d3d 2006-02-21 devnull free(p);
360 c42a1d3d 2006-02-21 devnull outdi(Rune r)
362 c42a1d3d 2006-02-21 devnull if(!difmtinit) abort();
363 c42a1d3d 2006-02-21 devnull if(r == Uempty)
365 c42a1d3d 2006-02-21 devnull fmtrune(&difmt, r);
368 c42a1d3d 2006-02-21 devnull /* .di, .da */
370 c42a1d3d 2006-02-21 devnull r_di(int argc, Rune **argv)
373 c42a1d3d 2006-02-21 devnull if(argc > 2)
374 c42a1d3d 2006-02-21 devnull warn("extra arguments to %C%S", dot, argv[0]);
375 c42a1d3d 2006-02-21 devnull if(argc == 1){
376 c42a1d3d 2006-02-21 devnull /* end diversion */
377 c42a1d3d 2006-02-21 devnull if(ndi <= 0){
378 cbeb0b26 2006-04-01 devnull /* warn("unmatched %C%S", dot, argv[0]); */
381 c42a1d3d 2006-02-21 devnull flushdi();
382 c42a1d3d 2006-02-21 devnull if(--ndi == 0){
383 c42a1d3d 2006-02-21 devnull _nr(L(".z"), nil);
384 c42a1d3d 2006-02-21 devnull outcb = nil;
386 c42a1d3d 2006-02-21 devnull _nr(L(".z"), di[ndi-1]);
387 c42a1d3d 2006-02-21 devnull runefmtstrinit(&difmt);
388 c42a1d3d 2006-02-21 devnull fmtrune(&difmt, Uformatted);
389 c42a1d3d 2006-02-21 devnull difmtinit = 1;
393 c42a1d3d 2006-02-21 devnull /* start diversion */
394 c42a1d3d 2006-02-21 devnull /* various register state should be saved, but it's all useless to us */
395 c42a1d3d 2006-02-21 devnull flushdi();
396 c42a1d3d 2006-02-21 devnull if(ndi >= nelem(di))
397 c42a1d3d 2006-02-21 devnull sysfatal("%Cdi overflow", dot);
398 c42a1d3d 2006-02-21 devnull if(argv[0][1] == 'i')
399 c42a1d3d 2006-02-21 devnull ds(argv[1], nil);
400 c42a1d3d 2006-02-21 devnull _nr(L(".z"), argv[1]);
401 c42a1d3d 2006-02-21 devnull runestrcpy(di[ndi++], argv[1]);
402 c42a1d3d 2006-02-21 devnull runefmtstrinit(&difmt);
403 c42a1d3d 2006-02-21 devnull fmtrune(&difmt, Uformatted);
404 c42a1d3d 2006-02-21 devnull difmtinit = 1;
405 c42a1d3d 2006-02-21 devnull outcb = outdi;
408 c42a1d3d 2006-02-21 devnull /* .wh - install trap */
409 c42a1d3d 2006-02-21 devnull /* .ch - change trap */
410 c42a1d3d 2006-02-21 devnull /* .dt - install diversion trap */
412 c42a1d3d 2006-02-21 devnull /* set input-line count trap */
413 c42a1d3d 2006-02-21 devnull int itrapcount;
414 c42a1d3d 2006-02-21 devnull int itrapwaiting;
415 c42a1d3d 2006-02-21 devnull Rune *itrapname;
418 c42a1d3d 2006-02-21 devnull r_it(int argc, Rune **argv)
420 c42a1d3d 2006-02-21 devnull if(argc < 3){
421 c42a1d3d 2006-02-21 devnull itrapcount = 0;
424 c42a1d3d 2006-02-21 devnull itrapcount = eval(argv[1]);
425 c42a1d3d 2006-02-21 devnull free(itrapname);
426 c42a1d3d 2006-02-21 devnull itrapname = erunestrdup(argv[2]);
430 c42a1d3d 2006-02-21 devnull itrap(void)
432 c42a1d3d 2006-02-21 devnull itrapset();
433 c42a1d3d 2006-02-21 devnull if(itrapwaiting){
434 c42a1d3d 2006-02-21 devnull itrapwaiting = 0;
435 c42a1d3d 2006-02-21 devnull runmacro1(itrapname);
440 c42a1d3d 2006-02-21 devnull itrapset(void)
442 c42a1d3d 2006-02-21 devnull if(itrapcount > 0 && --itrapcount == 0)
443 c42a1d3d 2006-02-21 devnull itrapwaiting = 1;
446 c42a1d3d 2006-02-21 devnull /* .em - invoke macro when all input is over */
448 c42a1d3d 2006-02-21 devnull r_em(int argc, Rune **argv)
450 c42a1d3d 2006-02-21 devnull Rune buf[20];
452 c42a1d3d 2006-02-21 devnull USED(argc);
453 c42a1d3d 2006-02-21 devnull runesnprint(buf, nelem(buf), ".%S\n", argv[1]);
454 c42a1d3d 2006-02-21 devnull as(L("eof"), buf);
458 c42a1d3d 2006-02-21 devnull e_star(void)
460 c42a1d3d 2006-02-21 devnull Rune *p;
462 c42a1d3d 2006-02-21 devnull p = getds(getname());
464 c42a1d3d 2006-02-21 devnull pushinputstring(p);
465 c42a1d3d 2006-02-21 devnull return 0;
469 c42a1d3d 2006-02-21 devnull e_t(void)
471 c42a1d3d 2006-02-21 devnull if(inputmode&CopyMode)
472 c42a1d3d 2006-02-21 devnull return '\t';
473 c42a1d3d 2006-02-21 devnull return 0;
477 c42a1d3d 2006-02-21 devnull e_a(void)
479 c42a1d3d 2006-02-21 devnull if(inputmode&CopyMode)
480 c42a1d3d 2006-02-21 devnull return '\a';
481 c42a1d3d 2006-02-21 devnull return 0;
485 c42a1d3d 2006-02-21 devnull e_backslash(void)
487 c42a1d3d 2006-02-21 devnull if(inputmode&ArgMode)
488 c42a1d3d 2006-02-21 devnull ungetrune('\\');
489 c42a1d3d 2006-02-21 devnull return backslash;
493 c42a1d3d 2006-02-21 devnull e_dot(void)
495 c42a1d3d 2006-02-21 devnull return '.';
499 c42a1d3d 2006-02-21 devnull e_dollar(void)
503 c42a1d3d 2006-02-21 devnull c = getnext();
504 c42a1d3d 2006-02-21 devnull if(c < '1' || c > '9'){
505 c42a1d3d 2006-02-21 devnull ungetnext(c);
506 c42a1d3d 2006-02-21 devnull return 0;
508 c42a1d3d 2006-02-21 devnull c -= '0';
509 c42a1d3d 2006-02-21 devnull if(nmstack <= 0 || mstack[nmstack-1].argc <= c)
510 c42a1d3d 2006-02-21 devnull return 0;
511 c42a1d3d 2006-02-21 devnull pushinputstring(mstack[nmstack-1].argv[c]);
512 c42a1d3d 2006-02-21 devnull return 0;
516 c42a1d3d 2006-02-21 devnull t7init(void)
518 c42a1d3d 2006-02-21 devnull addreq(L("de"), r_de, -1);
519 c42a1d3d 2006-02-21 devnull addreq(L("am"), r_de, -1);
520 c42a1d3d 2006-02-21 devnull addreq(L("ig"), r_de, -1);
521 c42a1d3d 2006-02-21 devnull addraw(L("ds"), r_ds);
522 c42a1d3d 2006-02-21 devnull addraw(L("as"), r_ds);
523 c42a1d3d 2006-02-21 devnull addreq(L("rm"), r_rm, -1);
524 c42a1d3d 2006-02-21 devnull addreq(L("rn"), r_rn, -1);
525 c42a1d3d 2006-02-21 devnull addreq(L("di"), r_di, -1);
526 c42a1d3d 2006-02-21 devnull addreq(L("da"), r_di, -1);
527 c42a1d3d 2006-02-21 devnull addreq(L("it"), r_it, -1);
528 c42a1d3d 2006-02-21 devnull addreq(L("em"), r_em, 1);
529 c42a1d3d 2006-02-21 devnull addreq(L("wh"), r_wh, -1);
530 c42a1d3d 2006-02-21 devnull addreq(L("ch"), r_ch, -1);
531 c42a1d3d 2006-02-21 devnull addreq(L("dt"), r_dt, -1);
533 c42a1d3d 2006-02-21 devnull addesc('$', e_dollar, CopyMode|ArgMode|HtmlMode);
534 c42a1d3d 2006-02-21 devnull addesc('*', e_star, CopyMode|ArgMode|HtmlMode);
535 c42a1d3d 2006-02-21 devnull addesc('t', e_t, CopyMode|ArgMode);
536 c42a1d3d 2006-02-21 devnull addesc('a', e_a, CopyMode|ArgMode);
537 c42a1d3d 2006-02-21 devnull addesc('\\', e_backslash, ArgMode|CopyMode);
538 c42a1d3d 2006-02-21 devnull addesc('.', e_dot, CopyMode|ArgMode);
540 c42a1d3d 2006-02-21 devnull ds(L("eof"), L(".sp 0.5i\n"));
541 c42a1d3d 2006-02-21 devnull ds(L(".."), L(""));