ref: 08b6db376a3ed78a46af972ca853256160dddbab
parent: b6fac629b65e7769dfaf2b9252221e99cd4568dc
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Apr 16 17:09:49 EDT 2013
adj: delay the effect of .in, .ll, and .ti for partial lines
--- a/adj.c
+++ b/adj.c
@@ -4,6 +4,8 @@
#include <string.h>
#include "xroff.h"
+#define ADJ_LL(a) ((a)->ll > (a)->li + (a)->lt ? (a)->ll - (a)->li - (a)->lt : 0)
+
struct word {
int beg; /* word beginning offset */
int end; /* word ending offset */
@@ -21,8 +23,41 @@
int swid; /* current space width */
int gap; /* space before the next word */
int nls; /* newlines before the next word */
+ int l, i, t; /* current .l, .i and ti */
+ int ll, li, lt; /* current line's .l, .i and ti */
};
+void adj_ll(struct adj *adj, int ll)
+{
+ adj->l = ll;
+}
+
+void adj_ti(struct adj *adj, int ti)
+{
+ adj->t = ti;
+}
+
+void adj_in(struct adj *adj, int in)
+{
+ adj->i = in;
+}
+
+void adj_conf(struct adj *adj, int *ll, int *in, int *ti)
+{
+ *ll = adj->ll;
+ *in = adj->li;
+ *ti = adj->lt;
+}
+
+/* .ll, .in and .ti are delayed until the partial line is output */
+static void adj_confupdate(struct adj *adj)
+{
+ adj->ll = adj->l;
+ adj->li = adj->i;
+ adj->lt = adj->t;
+ adj->t = 0;
+}
+
/* does the adjustment buffer need to be flushed without filling? */
static int adj_fullnf(struct adj *a)
{
@@ -31,13 +66,13 @@
}
/* does the adjustment buffer need to be flushed? */
-int adj_full(struct adj *a, int linelen)
+int adj_full(struct adj *a, int fill)
{
- if (!linelen)
+ if (!fill)
return a->nls;
if (adj_fullnf(a))
return 1;
- return !a->word && a->wid > linelen;
+ return !a->word && a->wid > ADJ_LL(a);
}
/* is the adjustment buffer empty? */
@@ -79,16 +114,19 @@
a->words[i].beg -= lendiff;
a->words[i].end -= lendiff;
}
+ if (a->nwords) /* apply the new .l and .i */
+ adj_confupdate(a);
return w;
}
/* fill and copy a line into s */
-int adj_fill(struct adj *a, int ad_b, int ll, char *s)
+int adj_fill(struct adj *a, int ad_b, int fill, char *s)
{
int adj_div, adj_rem;
int w = 0;
int i, n;
- if (!ll || adj_fullnf(a)) {
+ int ll = ADJ_LL(a);
+ if (!fill || adj_fullnf(a)) {
a->nls--;
return adj_move(a, a->nwords, s);
}
@@ -144,6 +182,8 @@
adj->swid = wid;
return;
}
+ if (!adj->nwords) /* apply the new .l and .i */
+ adj_confupdate(adj);
if (!adj->word) {
if (adj->nls && !adj->gap && adj->nwords >= 1)
adj->gap = adj->swid;
--- a/reg.c
+++ b/reg.c
@@ -33,7 +33,6 @@
REG(0, 'l'),
REG(0, 'n'),
REG(0, 's'),
- REG(0, 't'),
REG(0, 'v'),
};
@@ -153,6 +152,8 @@
n_s0 = n_s;
n_f0 = n_f;
n_na = 0;
+ adj_ll(env->adj, n_l);
+ adj_in(env->adj, n_i);
}
}
--- a/ren.c
+++ b/ren.c
@@ -4,8 +4,6 @@
#include <string.h>
#include "xroff.h"
-#define ADJ_LL (n_u ? n_l - n_i : 0) /* effective line length */
-#define ADJ_B (n_u && !n_na && n_j == AD_B)
#define cadj env_adj() /* line buffer */
/* diversions */
@@ -179,10 +177,13 @@
int prev_d = n_d;
int ljust = 0;
char cmd[32];
+ int ll, li, lt, linelen;
ren_sp(0);
n_n = w;
+ adj_conf(cadj, &ll, &li, <);
+ linelen = ll - li - lt;
if (n_u && !n_na && (n_j == AD_C || n_j == AD_R))
- ljust = n_j == AD_C ? (ADJ_LL - w) / 2 : ADJ_LL - w;
+ ljust = n_j == AD_C ? (linelen - w) / 2 : linelen - w;
if (cdiv) {
if (cdiv->dl < w)
cdiv->dl = w;
@@ -192,7 +193,7 @@
}
sbuf_append(&cdiv->sbuf, out);
} else {
- OUT("H%d\n", n_o + n_i + ljust);
+ OUT("H%d\n", n_o + li + lt + ljust);
OUT("V%d\n", n_d);
output(out);
}
@@ -203,9 +204,10 @@
static void ren_br(int force)
{
char out[LNLEN];
- int w;
+ int adj_b, w;
if (!adj_empty(cadj, n_u)) {
- w = adj_fill(cadj, !force && ADJ_B, force ? 0: ADJ_LL, out);
+ adj_b = n_u && !n_na && n_j == AD_B;
+ w = adj_fill(cadj, !force && adj_b, !force && n_u, out);
out_line(out, w);
}
}
@@ -262,6 +264,14 @@
ren_ps(args[1]);
}
+void tr_ll(char **args)
+{
+ int ll = args[1] ? eval(args[1], n_l, 'm') : n_l0;
+ n_l0 = n_l;
+ n_l = ll;
+ adj_ll(cadj, ll);
+}
+
void tr_in(char **args)
{
int in = args[1] ? eval(args[1], n_i, 'm') : n_i0;
@@ -269,6 +279,7 @@
ren_br(1);
n_i0 = n_i;
n_i = in;
+ adj_in(cadj, in);
}
void tr_ti(char **args)
@@ -276,7 +287,7 @@
if (args[0][0] == '.')
ren_br(1);
if (args[1])
- n_ti = eval(args[1], 0, 'm');
+ adj_ti(cadj, eval(args[1], 0, 'm'));
}
static void ren_ft(char *s)
@@ -400,10 +411,6 @@
return 0;
}
}
- if (n_ti && adj_empty(cadj, n_u)) {
- adj_put(adj, n_ti, "\\h'%du'", n_ti);
- n_ti = 0;
- }
if (ren_s != n_s) {
adj_swid(adj, charwid(dev_spacewid(), n_s));
adj_put(adj, 0, "\\s(%02d", n_s);
@@ -431,6 +438,7 @@
int type = 0;
wid_c = ren_next();
c = ren_next();
+ adj_ll(adj, n_l);
odiv_beg();
while (c >= 0 && c != wid_c) {
ren_back(c);
@@ -455,7 +463,7 @@
ren_back(c);
render_char(cadj);
}
- while (adj_full(cadj, ADJ_LL))
+ while (adj_full(cadj, n_u))
ren_br(0);
if (c != ' ' && c != '\n') {
ren_back(c);
--- a/tr.c
+++ b/tr.c
@@ -14,13 +14,6 @@
} while (c >= 0 && c != '\n');
}
-static void tr_ll(char **args)
-{
- int ll = args[1] ? eval(args[1], n_l, 'm') : n_l0;
- n_l0 = n_l;
- n_l = ll;
-}
-
static void tr_vs(char **args)
{
int vs = args[1] ? eval(args[1], n_v, 'p') : n_v0;
--- a/xroff.h
+++ b/xroff.h
@@ -127,6 +127,7 @@
void tr_fp(char **args);
void tr_ft(char **args);
void tr_in(char **args);
+void tr_ll(char **args);
void tr_ne(char **args);
void tr_nf(char **args);
void tr_ps(char **args);
@@ -167,12 +168,16 @@
struct adj *adj_alloc(void);
void adj_free(struct adj *adj);
-int adj_fill(struct adj *adj, int ad_b, int linelen, char *dst);
+int adj_fill(struct adj *adj, int ad_b, int fill, 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 linelen);
+int adj_full(struct adj *adj, int fill);
int adj_empty(struct adj *adj, int fill);
int adj_wid(struct adj *adj);
+void adj_ll(struct adj *adj, int ll);
+void adj_in(struct adj *adj, int in);
+void adj_ti(struct adj *adj, int ti);
+void adj_conf(struct adj *adj, int *ll, int *in, int *ti);
/* builtin number registers; n_X for .X register */
#define REG(c1, c2) ((c1) * 256 + (c2))
@@ -200,7 +205,6 @@
#define n_na (*nreg(REG(0, 'n'))) /* .na mode */
#define n_o0 (*nreg(REG(0, 'o'))) /* last .o */
#define n_s0 (*nreg(REG(0, 's'))) /* last .s */
-#define n_ti (*nreg(REG(0, 't'))) /* temp indent */
#define n_v0 (*nreg(REG(0, 'v'))) /* last .v */
/* functions for implementing read-only registers */