ref: d7cc1c7e69a3b403e63ada5ead6600e86a2dd40f
parent: bb8d4fe83ef6e55a2189b1563512d129fc419700
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon May 6 06:48:09 EDT 2013
ren: support fields
--- a/ren.c
+++ b/ren.c
@@ -31,6 +31,9 @@
static int bp_next = 1; /* next page number */
static int bp_force; /* execute the traps until the next page */
+static int c_fa; /* field delimiter */
+static char c_fb[GNLEN]; /* field padding */
+
static int ren_next(void)
{
return ren_un > 0 ? ren_unbuf[--ren_un] : tr_next();
@@ -434,6 +437,17 @@
n_ce = args[1] ? atoi(args[1]) : 1;
}
+void tr_fc(char **args)
+{
+ if (args[1]) {
+ c_fa = args[1][0];
+ strcpy(c_fb, args[2] ? args[2] : " ");
+ } else {
+ c_fa = -1;
+ c_fb[0] = '\0';
+ }
+}
+
static void escarg_ren(char *d, int cmd, int (*next)(void), void (*back)(int))
{
char delim[GNLEN];
@@ -555,6 +569,8 @@
}
}
+static void ren_field(struct wb *wb, 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))
{
@@ -572,6 +588,10 @@
wb_hmov(wb, tab_next(n) - n);
return;
}
+ if (c[0] == c_fa) {
+ ren_field(wb, next, back);
+ return;
+ }
if (c[0] == c_ec) {
nextchar(c + 1, next);
if (c[1] == '(') {
@@ -630,11 +650,13 @@
return n;
}
-static void ren_until(struct wb *wb, char *delim, int (*next)(void), void (*back)(int))
+/* return 1 if the ending character (ec) was read */
+static int ren_until(struct wb *wb, char *delim, int ec,
+ int (*next)(void), void (*back)(int))
{
int c;
c = next();
- while (c >= 0 && c != '\n') {
+ while (c >= 0 && c != '\n' && c != ec) {
back(c);
if (!schar_jump(delim, next, back))
break;
@@ -643,6 +665,7 @@
}
if (c == '\n')
back(c);
+ return c == ec;
}
static void wb_cpy(struct wb *dst, struct wb *src, int left)
@@ -661,13 +684,13 @@
wb_init(&wb2);
schar_read(delim, next);
/* the left-adjusted string */
- ren_until(&wb2, delim, next, back);
+ ren_until(&wb2, delim, '\n', next, back);
wb_cpy(&wb, &wb2, 0);
/* the centered string */
- ren_until(&wb2, delim, next, back);
+ ren_until(&wb2, delim, '\n', next, back);
wb_cpy(&wb, &wb2, (n_lt - wb_wid(&wb2)) / 2);
/* the right-adjusted string */
- ren_until(&wb2, delim, next, back);
+ ren_until(&wb2, delim, '\n', next, back);
wb_cpy(&wb, &wb2, n_lt - wb_wid(&wb2));
/* flushing the line */
adj_ll(adj, n_lt);
@@ -677,6 +700,36 @@
adj_free(adj);
wb_done(&wb2);
wb_done(&wb);
+}
+
+static void ren_field(struct wb *wb, int (*next)(void), void (*back)(int))
+{
+ struct wb wbs[NFIELDS];
+ int i, n = 0;
+ int wid = 0;
+ int left, right, cur_left;
+ int pad, rem;
+ while (n < LEN(wbs)) {
+ wb_init(&wbs[n]);
+ if (ren_until(&wbs[n++], c_fb, c_fa, next, back))
+ break;
+ }
+ left = wb == &ren_wb ? f_hpos() : wb_wid(wb);
+ right = tab_next(left);
+ for (i = 0; i < n; i++)
+ wid += wb_wid(&wbs[i]);
+ pad = (right - left - wid) / (n > 1 ? n - 1 : 1);
+ rem = (right - left - wid) % (n > 1 ? n - 1 : 1);
+ for (i = 0; i < n; i++) {
+ if (i == 0)
+ cur_left = left;
+ else if (i == n - 1)
+ cur_left = right - wb_wid(&wbs[i]);
+ else
+ cur_left = wb_wid(wb) + pad + (i + rem >= n);
+ wb_cpy(wb, &wbs[i], cur_left);
+ wb_done(&wbs[i]);
+ }
}
/* read characters from in.c and pass rendered lines to out.c */
--- a/tr.c
+++ b/tr.c
@@ -582,6 +582,7 @@
{"eo", tr_eo},
{"ev", tr_ev},
{"ex", tr_ex},
+ {"fc", tr_fc},
{"fi", tr_fi},
{"fp", tr_fp},
{"ft", tr_ft},
--- a/xroff.h
+++ b/xroff.h
@@ -20,7 +20,8 @@
#define NPREV 16 /* environment stack depth */
#define NTRAPS 1024 /* number of traps per page */
#define NIES 128 /* number of nested .ie commands */
-#define NTABS 16 /* the number of tab stops */
+#define NTABS 16 /* number of tab stops */
+#define NFIELDS 32 /* number of fields */
/* escape sequences */
#define ESC_Q "bCDhHlLNoSvwxX" /* quoted escape sequences */
@@ -34,7 +35,7 @@
extern int c_ec; /* escape character (\) */
extern int c_cc; /* basic control character (.) */
extern int c_c2; /* no-break control character (') */
-#define c_ni 3 /* non-interpreted copy mode escape */
+#define c_ni 4 /* non-interpreted copy mode escape */
/* number registers */
int num_get(int id, int inc);
@@ -223,6 +224,7 @@
void tr_divend(char **args);
void tr_dt(char **args);
void tr_ev(char **args);
+void tr_fc(char **args);
void tr_fi(char **args);
void tr_fp(char **args);
void tr_ft(char **args);