ref: efde0d26267c0cc73323abd95d5fa5357383ecf1
parent: 6b44fd3626537191cc393a23bda5b7c091b8697b
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Jul 25 11:00:01 EDT 2013
ren: add .nm and .nn
--- a/reg.c
+++ b/reg.c
@@ -23,31 +23,15 @@
static struct env *envs[NREGS2];/* environments */
static struct env *env; /* current enviroment */
static int env_id; /* current environment id */
-static int eregs_idx[NREGS]; /* register environment index in eregs[] */
+static int eregs_idx[NREGS2]; /* register environment index in eregs[] */
-static int eregs[] = { /* environment-specific number registers */
- REG('.', 'f'),
- REG('.', 'i'),
- REG('.', 'j'),
- REG('.', 'l'),
- REG('.', 'L'),
- REG('.', 'm'),
- REG('.', 's'),
- REG('.', 'u'),
- REG('.', 'v'),
- REG(0, 'c'),
- REG(0, 'f'),
- REG(0, 'h'),
- REG(0, 'i'),
- REG(0, 'l'),
- REG(0, 'L'),
- REG(0, 'n'),
- REG(0, 'm'),
- REG(0, 'p'),
- REG(0, 's'),
- REG(0, 't'),
- REG(0, 'T'),
- REG(0, 'v'),
+static char *eregs[] = { /* environment-specific number registers */
+ "ln", ".f", ".i", ".j", ".l",
+ ".L", ".nI", ".nm", ".nM", ".nn",
+ ".nS", ".m", ".s", ".u", ".v",
+ "\0c", "\0f", "\0h", "\0i", "\0l",
+ "\0L", "\0n", "\0m", "\0p", "\0s",
+ "\0t", "\0T", "\0v",
};
/* return the address of a number register */
@@ -200,6 +184,8 @@
n_lt = SC_IN * 65 / 10;
n_hy = 1;
n_ss = 12;
+ n_nM = 1;
+ n_nS = 1;
strcpy(env->hc, "\\%");
adj_ll(env->adj, n_l);
adj_in(env->adj, n_i);
@@ -223,7 +209,7 @@
int i;
init_time();
for (i = 0; i < LEN(eregs); i++)
- eregs_idx[eregs[i]] = i + 1;
+ eregs_idx[map(eregs[i])] = i + 1;
env_set(0);
}
--- a/ren.c
+++ b/ren.c
@@ -220,8 +220,8 @@
}
}
-/* flush the given line and send it to out.c */
-static void ren_line(char *s, int w, int ad, int ll, int li, int lt)
+/* line adjustment */
+static void ren_ljust(struct sbuf *spre, int w, int ad, int ll, int li, int lt)
{
int ljust = lt >= 0 ? lt : li;
int llen = ll - ljust;
@@ -230,16 +230,25 @@
ljust += llen > w ? (llen - w) / 2 : 0;
if (ad == AD_R)
ljust += llen - w;
+ if (ljust)
+ sbuf_printf(spre, "%ch'%du'", c_ec, ljust);
+ if (cdiv && cdiv->dl < w)
+ cdiv->dl = w;
+}
+
+/* append the line to the current diversion or send it to out.c */
+static void ren_line(struct sbuf *spre, struct sbuf *sbuf)
+{
if (cdiv) {
- if (cdiv->dl < w)
- cdiv->dl = w;
- if (ljust)
- sbuf_printf(&cdiv->sbuf, "%ch'%du'", c_ec, ljust);
- sbuf_append(&cdiv->sbuf, s);
+ if (!sbuf_empty(spre))
+ sbuf_append(&cdiv->sbuf, sbuf_buf(spre));
+ sbuf_append(&cdiv->sbuf, sbuf_buf(sbuf));
} else {
- out("H%d\n", n_o + ljust);
+ out("H%d\n", n_o);
out("V%d\n", n_d);
- out_line(s);
+ if (!sbuf_empty(spre))
+ out_line(sbuf_buf(spre));
+ out_line(sbuf_buf(sbuf));
}
}
@@ -251,16 +260,49 @@
out("%s\n", s);
}
+static int zwid(void)
+{
+ struct glyph *g = dev_glyph("0", n_f);
+ return charwid(n_f, n_s, g ? g->wid : SC_DW);
+}
+
+/* append the line number to the output line */
+static void ren_lnum(struct sbuf *spre)
+{
+ char num[16] = "";
+ char dig[16] = "";
+ struct wb wb;
+ int i = 0;
+ wb_init(&wb);
+ if (n_nn <= 0 && (n_ln % n_nM) == 0)
+ sprintf(num, "%d", n_ln);
+ wb_hmov(&wb, n_nI * zwid());
+ if (strlen(num) < 3)
+ wb_hmov(&wb, (3 - strlen(num)) * zwid());
+ while (num[i]) {
+ dig[0] = num[i++];
+ wb_put(&wb, dig);
+ }
+ wb_hmov(&wb, n_nS * zwid());
+ sbuf_append(spre, sbuf_buf(&wb.sbuf));
+ wb_done(&wb);
+ if (n_nn > 0)
+ n_nn--;
+ else
+ n_ln++;
+}
+
/* return 1 if triggered a trap */
-static int ren_bradj(struct adj *adj, int fill, int ad)
+static int ren_bradj(struct adj *adj, int fill, int ad, int body)
{
char cmd[16];
- struct sbuf sbuf;
+ struct sbuf sbuf, spre;
int ll, li, lt, els_neg, els_pos;
int w, prev_d, lspc;
ren_first();
if (!adj_empty(adj, fill)) {
sbuf_init(&sbuf);
+ sbuf_init(&spre);
w = adj_fill(adj, ad == AD_B, fill, n_hy, &sbuf,
&ll, &li, <, &els_neg, &els_pos);
prev_d = n_d;
@@ -268,9 +310,13 @@
ren_sp(-els_neg, 1);
if (!n_ns || !sbuf_empty(&sbuf) || els_neg || els_pos) {
ren_sp(0, 0);
- ren_line(sbuf_buf(&sbuf), w, ad, ll, li, lt);
+ if (!sbuf_empty(&sbuf) && n_nm && body)
+ ren_lnum(&spre);
+ ren_ljust(&spre, w, ad, ll, li, lt);
+ ren_line(&spre, &sbuf);
n_ns = 0;
}
+ sbuf_done(&spre);
sbuf_done(&sbuf);
if (els_pos)
ren_sp(els_pos, 1);
@@ -293,8 +339,12 @@
/* return 1 if triggered a trap */
static int ren_br(int force)
{
- return ren_bradj(cadj, !force && !n_ce && n_u,
- n_ce ? AD_C : (n_u && !n_na && (n_j != AD_B || !force) ? n_j : AD_L));
+ int ad = n_j;
+ if (!n_u || n_na || (n_j == AD_B && force))
+ ad = AD_L;
+ if (n_ce)
+ ad = AD_C;
+ return ren_bradj(cadj, !force && !n_ce && n_u, ad, 1);
}
void tr_br(char **args)
@@ -575,7 +625,6 @@
static void ren_cmd(struct wb *wb, int c, char *arg)
{
- struct glyph *g;
switch (c) {
case ' ':
wb_hmov(wb, spacewid(n_f, n_s));
@@ -636,8 +685,7 @@
wb_els(wb, eval(arg, 'v'));
break;
case '0':
- g = dev_glyph("0", n_f);
- wb_hmov(wb, charwid(n_f, n_s, g ? g->wid : SC_DW));
+ wb_hmov(wb, zwid());
break;
case '|':
wb_hmov(wb, SC_EM / 6);
@@ -802,7 +850,7 @@
adj_ll(adj, n_lt);
adj_wb(adj, &wb);
adj_nl(adj);
- ren_bradj(adj, 0, AD_L);
+ ren_bradj(adj, 0, AD_L, 0);
adj_free(adj);
wb_done(&wb2);
wb_done(&wb);
--- a/roff.h
+++ b/roff.h
@@ -253,7 +253,6 @@
void ren_bracket(struct wb *wb, char *arg); /* \b */
void ren_over(struct wb *wb, char *arg); /* \o */
void ren_draw(struct wb *wb, char *arg); /* \D */
-void ren_putc(struct wb *wb, char *c); /* handling .cs and .bd */
/* out.c */
void out_line(char *s); /* output rendered line */
@@ -337,6 +336,11 @@
#define n_l (*nreg(REG('.', 'l')))
#define n_L (*nreg(REG('.', 'L')))
#define n_n (*nreg(REG('.', 'n')))
+#define n_nI (*nreg(map(".nI"))) /* i for .nm */
+#define n_nm (*nreg(map(".nm"))) /* .nm enabled */
+#define n_nM (*nreg(map(".nM"))) /* m for .nm */
+#define n_nn (*nreg(map(".nn"))) /* remaining .nn */
+#define n_nS (*nreg(map(".nS"))) /* s for .nm */
#define n_m (*nreg(REG('.', 'm')))
#define n_o (*nreg(REG('.', 'o')))
#define n_p (*nreg(REG('.', 'p')))
@@ -346,6 +350,7 @@
#define n_ct (*nreg(REG('c', 't')))
#define n_dl (*nreg(REG('d', 'l')))
#define n_dn (*nreg(REG('d', 'n')))
+#define n_ln (*nreg(REG('l', 'n')))
#define n_nl (*nreg(REG('n', 'l')))
#define n_sb (*nreg(REG('s', 'b')))
#define n_st (*nreg(REG('s', 't')))
--- a/tr.c
+++ b/tr.c
@@ -452,6 +452,28 @@
dev_setcs(dev_pos(args[1]), args[2] ? eval(args[2], 0) : 0);
}
+static void tr_nm(char **args)
+{
+ if (!args[1]) {
+ n_nm = 0;
+ return;
+ }
+ n_nm = 1;
+ n_ln = eval_re(args[1], n_ln, 0);
+ n_ln = MAX(0, n_ln);
+ if (args[2] && isdigit(args[2][0]))
+ n_nM = MAX(1, eval(args[2], 0));
+ if (args[3] && isdigit(args[3][0]))
+ n_nS = MAX(0, eval(args[3], 0));
+ if (args[4] && isdigit(args[4][0]))
+ n_nI = MAX(0, eval(args[4], 0));
+}
+
+static void tr_nn(char **args)
+{
+ n_nn = args[1] ? eval(args[1], 0) : 1;
+}
+
static void tr_bd(char **args)
{
if (!args[1] || !strcmp("S", args[1]))
@@ -675,6 +697,8 @@
{"ne", tr_ne},
{"nf", tr_nf},
{"nh", tr_nh},
+ {"nm", tr_nm},
+ {"nn", tr_nn},
{"nr", tr_nr, mkargs_reg1},
{"ns", tr_ns},
{"nx", tr_nx},