ref: e4eb154d9ae6e0d3d7d2669e363820b9c3c8fc1a
parent: 5d02c6a0d1b06573e92154d2df5df0bcac744fd2
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sun Jul 28 18:15:00 EDT 2013
ren: right adjusting and centering tab types
--- a/reg.c
+++ b/reg.c
@@ -11,6 +11,7 @@
struct env {
int eregs[NENVS]; /* environment-specific number registers */
int tabs[NTABS]; /* tab stops */
+ char tabs_type[NTABS]; /* type of tabs: L, C, R */
struct adj *adj; /* per environment line buffer */
char tc[GNLEN]; /* tab character (.tc) */
char lc[GNLEN]; /* leader character (.lc) */
@@ -306,17 +307,33 @@
void tr_ta(char **args)
{
int i;
- for (i = 0; i < NARGS && args[i]; i++)
+ char *s;
+ for (i = 0; i < NARGS && args[i]; i++) {
env->tabs[i] = eval_re(args[i], i > 0 ? env->tabs[i - 1] : 0, 'm');
+ s = args[i][0] ? strchr(args[i], '\0') - 1 : "";
+ env->tabs_type[i] = strchr("LRC", *s) ? *s : 'L';
+ }
}
-int tab_next(int pos)
+static int tab_idx(int pos)
{
int i;
for (i = 0; i < LEN(env->tabs); i++)
if (env->tabs[i] > pos)
- return env->tabs[i];
- return pos;
+ return i;
+ return -1;
+}
+
+int tab_next(int pos)
+{
+ int i = tab_idx(pos);
+ return i >= 0 ? env->tabs[i] : pos;
+}
+
+int tab_type(int pos)
+{
+ int i = tab_idx(pos);
+ return i >= 0 && env->tabs_type[i] ? env->tabs_type[i] : 'L';
}
/* number register format (.af) */
--- a/ren.c
+++ b/ren.c
@@ -718,6 +718,7 @@
}
static void ren_field(struct wb *wb, int (*next)(void), void (*back)(int));
+static void ren_tab(struct wb *wb, char *tc, int (*next)(void), void (*back)(int));
/* read one character and place it inside wb buffer */
void ren_char(struct wb *wb, int (*next)(void), void (*back)(int))
@@ -725,7 +726,7 @@
char c[GNLEN * 4];
char arg[ILNLEN];
struct glyph *g;
- char *s, *tc;
+ char *s;
int w, n, l;
nextchar(c, next);
if (c[0] == ' ' || c[0] == '\n') {
@@ -733,12 +734,7 @@
return;
}
if (c[0] == '\t' || c[0] == '') {
- n = RENWB(wb) ? f_hpos() : wb_wid(wb);
- tc = c[0] == '\t' ? c_tc : c_lc;
- if (!tc[0])
- wb_hmov(wb, tab_next(n) - n);
- else
- ren_hline(wb, tab_next(n) - n, tc);
+ ren_tab(wb, c[0] == '\t' ? c_tc : c_lc, next, back);
return;
}
if (c[0] == c_fa) {
@@ -905,6 +901,35 @@
wb_cpy(wb, &wbs[i], cur_left);
wb_done(&wbs[i]);
}
+}
+
+static void ren_tab(struct wb *wb, char *tc, int (*next)(void), void (*back)(int))
+{
+ struct wb t;
+ int pos = RENWB(wb) ? f_hpos() : wb_wid(wb);
+ int ins = tab_next(pos); /* insertion position */
+ int typ = tab_type(pos); /* tab type */
+ int c;
+ wb_init(&t);
+ if (typ == 'R' || typ == 'C') {
+ c = next();
+ while (c >= 0 && c != '\n' && c != '\t' && c != '') {
+ back(c);
+ ren_char(&t, next, back);
+ c = next();
+ }
+ back(c);
+ }
+ if (typ == 'C')
+ ins -= wb_wid(&t) / 2;
+ if (typ == 'R')
+ ins -= wb_wid(&t);
+ if (!tc[0] || ins <= pos)
+ wb_hmov(wb, ins - pos);
+ else
+ ren_hline(wb, ins - pos, tc);
+ wb_cat(wb, &t);
+ wb_done(&t);
}
/* read characters from in.c and pass rendered lines to out.c */
--- a/roff.h
+++ b/roff.h
@@ -80,6 +80,7 @@
char *env_tc(void);
char *env_lc(void);
int tab_next(int pos);
+int tab_type(int pos);
/* device related variables */
extern int dev_res;