ref: 0b23d0b4a41bedb9d9b00bcef9c0b6414c4ef287
parent: 34ea5f4e771ff8af2f82f5683df3a9f47456751a
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Mar 28 12:46:45 EDT 2013
ren: diversion dl and dn registers
--- a/adj.c
+++ b/adj.c
@@ -53,7 +53,7 @@
}
/* move n words from the adjustment buffer to s */
-static void adj_move(struct adj *a, int n, char *s)
+static int adj_move(struct adj *a, int n, char *s)
{
struct word *cur;
int lendiff;
@@ -68,7 +68,7 @@
}
*s = '\0';
if (!n)
- return;
+ return 0;
lendiff = n < a->nwords ? a->words[n].beg : a->len;
memmove(a->buf, a->buf + lendiff, a->len - lendiff + 1);
a->len -= lendiff;
@@ -79,10 +79,11 @@
a->words[i].beg -= lendiff;
a->words[i].end -= lendiff;
}
+ return w;
}
/* fill and copy a line into s */
-void adj_fill(struct adj *a, int mode, int ll, char *s)
+int adj_fill(struct adj *a, int mode, int ll, char *s)
{
int adj_div, adj_rem;
int w = 0;
@@ -89,8 +90,7 @@
int i, n;
if (mode == ADJ_N || adj_fullnf(a)) {
a->nls--;
- adj_move(a, a->nwords, s);
- return;
+ return adj_move(a, a->nwords, s);
}
for (n = 0; n < a->nwords; n++) {
if (n && w + a->words[n].wid + a->words[n].gap > ll)
@@ -104,10 +104,11 @@
for (i = 0; i < n - 1; i++)
a->words[i + 1].gap += adj_div + (i < adj_rem);
}
- adj_move(a, n, s);
+ w = adj_move(a, n, s);
if (a->nwords)
a->wid -= a->words[0].gap;
a->words[0].gap = 0;
+ return w;
}
static void adj_wordbeg(struct adj *adj, int gap)
--- a/ren.c
+++ b/ren.c
@@ -12,6 +12,8 @@
struct div {
struct sbuf sbuf; /* diversion output */
int reg; /* diversion register */
+ int dl; /* diversion width */
+ int prev_d; /* previous \(.d value */
};
static struct div divs[NPREV]; /* diversion stack */
static struct div *cdiv; /* current diversion */
@@ -56,6 +58,8 @@
cdiv = cdiv ? cdiv + 1 : divs;
sbuf_init(&cdiv->sbuf);
cdiv->reg = REG(args[1][0], args[1][1]);
+ cdiv->dl = 0;
+ cdiv->prev_d = n_d;
if (args[0][2] == 'a' && str_get(cdiv->reg)) /* .da */
sbuf_append(&cdiv->sbuf, str_get(cdiv->reg));
n_d = 0;
@@ -63,6 +67,9 @@
sbuf_putnl(&cdiv->sbuf);
str_set(cdiv->reg, sbuf_buf(&cdiv->sbuf));
sbuf_done(&cdiv->sbuf);
+ n_dl = cdiv->dl;
+ n_dn = n_d;
+ n_d = cdiv->prev_d;
cdiv = cdiv > divs ? cdiv - 1 : NULL;
}
}
@@ -71,25 +78,27 @@
static void down(int n)
{
char cmd[32];
- n_d += n;
+ n_d += n ? n : n_v;
if (cdiv) {
sbuf_putnl(&cdiv->sbuf);
sprintf(cmd, ".sp %du\n", n);
- sbuf_append(&cdiv->sbuf, cmd);
+ if (n)
+ sbuf_append(&cdiv->sbuf, cmd);
} else {
n_nl = n_d;
if (n_nl <= n_p)
- OUT("v%d\n", n);
+ OUT("v%d\n", n ? n : n_v);
}
ren_ne(0);
}
-static void out_line(char *out)
+static void out_line(char *out, int w)
{
char cmd[32];
+ down(0);
if (cdiv) {
- if (!sbuf_empty(&cdiv->sbuf))
- down(n_v);
+ if (cdiv->dl < w)
+ cdiv->dl = w;
sprintf(cmd, "\\h'%d'", n_i);
sbuf_append(&cdiv->sbuf, DIV_BEG);
sbuf_append(&cdiv->sbuf, cmd);
@@ -96,7 +105,6 @@
sbuf_append(&cdiv->sbuf, out);
sbuf_append(&cdiv->sbuf, DIV_END);
} else {
- down(n_v);
OUT("H%d\n", n_o + n_i);
output(out);
}
@@ -105,10 +113,11 @@
static void ren_br(int sp, int force)
{
char out[LNLEN];
+ int w;
if (!adj_empty(adj, ADJ_MODE)) {
- adj_fill(adj, force ? ADJ_N : ADJ_MODE, ADJ_LL, out);
+ w = adj_fill(adj, force ? ADJ_N : ADJ_MODE, ADJ_LL, out);
ren_ne(n_v);
- out_line(out);
+ out_line(out, w);
ren_ne(n_v);
}
if (sp)
--- a/xroff.h
+++ b/xroff.h
@@ -147,7 +147,7 @@
struct adj *adj_alloc(void);
void adj_free(struct adj *adj);
-void adj_fill(struct adj *adj, int mode, int linelen, char *dst);
+int adj_fill(struct adj *adj, int mode, int linelen, char *dst);
void adj_put(struct adj *adj, int wid, char *s, ...);
void adj_swid(struct adj *adj, int swid);
int adj_full(struct adj *adj, int mode, int linelen);
@@ -165,6 +165,8 @@
#define n_s (*nreg(REG('.', 's')))
#define n_u (*nreg(REG('.', 'u')))
#define n_v (*nreg(REG('.', 'v')))
+#define n_dl (*nreg(REG('d', 'l')))
+#define n_dn (*nreg(REG('d', 'n')))
#define n_nl (*nreg(REG('n', 'l')))
#define n_pg (*nreg(REG('%', '\0'))) /* % */
#define n_f0 (*nreg(REG(0, 'f'))) /* last font */