4 * (Reg register implementation is also here.)
18 * 001 001, 002, 003, ...
19 * i 0, i, ii, iii, iv, v, ...
20 * I 0, I, II, III, IV, V, ...
21 * a 0, a, b, ..., aa, ab, ..., zz, aaa, ...
22 * A 0, A, B, ..., AA, AB, ..., ZZ, AAA, ...
24 * \gx \g(xx return format of number register
29 typedef struct Reg Reg;
43 * Define strings and numbers.
46 dsnr(Rune *name, Rune *val, Reg **l)
50 for(s = *l; s != nil; s = *l){
51 if(runestrcmp(s->name, name) == 0)
65 s = emalloc(sizeof(Reg));
67 s->name = erunestrdup(name);
70 s->val = erunestrdup(val);
74 getdsnr(Rune *name, Reg *list)
78 for(s=list; s; s=s->next)
79 if(runestrcmp(name, s->name) == 0)
85 ds(Rune *name, Rune *val)
87 dsnr(name, val, &dslist);
91 as(Rune *name, Rune *val)
98 q = runemalloc(runestrlen(p)+runestrlen(val)+1);
108 return getdsnr(name, dslist);
118 for(s=dslist; s; s=s->next){
120 n = runestrlen(s->val);
125 fprint(2, "%S\t%d\n", s->name, n);
127 fprint(2, "total\t%d\n", total);
131 nr(Rune *name, int val)
135 runesnprint(buf, nelem(buf), "%d", val);
140 af(Rune *name, Rune *fmt)
144 if(_getnr(name) == nil)
146 for(s=nrlist; s; s=s->next)
147 if(runestrcmp(s->name, name) == 0)
148 s->fmt = erunestrdup(fmt);
156 for(s=nrlist; s; s=s->next)
157 if(runestrcmp(s->name, name) == 0)
167 for(r=nrlist; r; r=r->next)
168 fprint(2, "%S %S %d\n", r->name, r->val, r->inc);
172 * Some internal number registers are actually strings,
173 * so provide _ versions to get at them.
176 _nr(Rune *name, Rune *val)
178 dsnr(name, val, &nrlist);
184 return getdsnr(name, nrlist);
200 r_nr(int argc, Rune **argv)
209 if(argv[2][0] == '+')
210 nr(argv[1], getnr(argv[1])+eval(argv[2]+1));
211 else if(argv[2][0] == '-')
212 nr(argv[1], getnr(argv[1])-eval(argv[2]+1));
214 nr(argv[1], eval(argv[2]));
217 for(s=nrlist; s; s=s->next)
218 if(runestrcmp(s->name, argv[1]) == 0)
219 s->inc = eval(argv[3]);
225 r_af(int argc, Rune **argv)
229 af(argv[1], argv[2]);
232 /* remove register */
234 r_rr(int argc, Rune **argv)
238 for(i=1; i<argc; i++)
242 /* fmt integer in base 26 */
244 alpha(Rune *buf, int n, int a)
280 /* fmt integer in roman numerals! */
282 roman(Rune *buf, int n, int upper)
290 if(n >= 5000 || n <= 0){
291 runestrcpy(buf, L("-"));
311 static Rune buf[100];
313 /* XXX add [name] syntax as in groff */
318 warn("newline in name\n");
323 for(i=0; i<nelem(buf)-1; i++){
324 if((c = getrune()) < 0)
343 if(c == '\n' || cc == '\n'){
344 warn("newline in \\n");
355 /* \n - return number register */
360 Rune *name, *fmt, buf[100];
366 if(inc != '+' && inc != '-'){
371 if(_getnr(name) == nil)
373 for(s=nrlist; s; s=s->next){
374 if(runestrcmp(s->name, name) == 0){
375 if(s->fmt == nil && !inc && s->val[0]){
376 /* might be a string! */
377 pushinputstring(s->val);
386 runesnprint(buf, nelem(buf), "%d", v);
388 s->val = erunestrdup(buf);
396 roman(buf, v, fmt[0]=='I');
400 alpha(buf, v, fmt[0]);
406 runesnprint(buf, sizeof buf, "%0*d", l, v);
409 pushinputstring(buf);
413 pushinputstring(L(""));
417 /* \g - number register format */
423 p = getaf(getname());
431 r_pnr(int argc, Rune **argv)
441 addreq(L("nr"), r_nr, -1);
442 addreq(L("af"), r_af, 2);
443 addreq(L("rr"), r_rr, -1);
444 addreq(L("pnr"), r_pnr, 0);
446 addesc('n', e_n, CopyMode|ArgMode|HtmlMode);