shithub: spread

Download patch

ref: 28539de81a1a7beb10e8281a9825b9c39e8482cf
parent: eaadfa055fc6b9e7074449a8ad6b0a4ff25cb346
author: sirjofri <sirjofri@sirjofri.de>
date: Tue Jul 16 07:43:01 EDT 2024

adds cell alignment

--- a/README.md
+++ b/README.md
@@ -26,6 +26,16 @@
 while cells divided by a `;` sign are string literals. Only calculation
 functions (cells with `=`) will end up being hoc functions.
 
+A newer version supports cell alignment by prepending the following chars
+to the lines:
+
+- `<`: left align (default if empty)
+- `>`: right align
+- `|`: center align
+- `.`: dot align (not implemented yet)
+
+These chars also work for entry lines.
+
 # Usage
 
 	spread [-di] file
--- a/cells.c
+++ b/cells.c
@@ -28,12 +28,12 @@
 	while (s = findvaluep(s, &p)) {
 		c = getcell(p);
 		if (!c)
-			addcell(p, strdup("0"), FUNCTION);
+			addcell(p, strdup("0"), FUNCTION, Aleft);
 	}
 }
 
 void
-addcell(P cell, char *value, int type)
+addcell(P cell, char *value, int type, int align)
 {
 	Cell *c;
 	
@@ -54,6 +54,7 @@
 			free(c->procvalue);
 		c->value = strdup(value);
 		c->type = type;
+		c->align = align;
 		preprocess(c);
 		addempty(c->procvalue);
 		return;
@@ -69,6 +70,7 @@
 	c->p = cell;
 	c->value = strdup(value);
 	c->type = type;
+	c->align = align;
 	preprocess(c);
 	addempty(c->procvalue);
 }
--- a/engine.c
+++ b/engine.c
@@ -379,6 +379,7 @@
 {
 	P p;
 	char *a;
+	int align;
 	
 	switch (type) {
 	case L_FUNC:
@@ -394,8 +395,28 @@
 	*a = 0;
 	a++;
 	
+	align = Aleft;
+	switch (*s) {
+	case '<':
+		align = Aleft;
+		s++;
+		break;
+	case '>':
+		align = Aright;
+		s++;
+		break;
+	case '|':
+		align = Acenter;
+		s++;
+		break;
+	case '.':
+		align = Adot;
+		s++;
+		break;
+	}
+	
 	p = atop(s);
-	addcell(p, a, type);
+	addcell(p, a, type, align);
 }
 
 static void
@@ -480,6 +501,22 @@
 	return 1;
 }
 
+static char
+alignchar(int align)
+{
+	switch (align) {
+	default:
+	case Aleft:
+		return '<';
+	case Aright:
+		return '>';
+	case Acenter:
+		return '|';
+	case Adot:
+		return '.';
+	}
+}
+
 static void
 writecell(Cell *c, void *aux)
 {
@@ -487,12 +524,12 @@
 	
 	switch (c->type) {
 	case FUNCTION:
-		Bprint(b, "%s=%s\n", ptoa(c->p), c->value);
+		Bprint(b, "%c%s=%s\n", alignchar(c->align), ptoa(c->p), c->value);
 		break;
 	case STRING:
 		if (!c->value || !c->value[0])
 			break;
-		Bprint(b, "%s;%s\n", ptoa(c->p), c->value);
+		Bprint(b, "%c%s;%s\n", alignchar(c->align), ptoa(c->p), c->value);
 		break;
 	}
 }
--- a/spread.c
+++ b/spread.c
@@ -158,6 +158,30 @@
 	}
 }
 
+static void
+drawcell(char *s, int align, Point p, int cw, Image *img)
+{
+	int w;
+	
+	switch (align) {
+	default:
+	case Aleft:
+		string(screen, p, img, ZP, font, s);
+		break;
+	case Adot:
+	case Aright:
+		w = stringwidth(font, s);
+		p.x += cw - w;
+		string(screen, p, img, ZP, font, s);
+		break;
+	case Acenter:
+		w = stringwidth(font, s);
+		p.x += (cw - w)/2;
+		string(screen, p, img, ZP, font, s);
+		break;
+	}
+}
+
 void
 redraw(void)
 {
@@ -172,6 +196,7 @@
 	Image *img;
 	Response r;
 	char buf[10];
+	int cellwidth;
 	
 	draw(screen, screen->r, colors.bg, nil, ZP);
 	
@@ -217,7 +242,8 @@
 	}
 	
 	first = dstate.firstcell;
-	for (x = first.x; x < first.x + dim.x; x++)
+	for (x = first.x; x < first.x + dim.x; x++) {
+		cellwidth = getwidth(x);
 		for (y = first.y; y < first.y + dim.y; y++) {
 			cell.x = x;
 			cell.y = y;
@@ -229,12 +255,15 @@
 				p = addpt(getcellpos(cell, &dstate), dstate.r.min);
 				p.x += dstate.leftpad;
 				p.y += dstate.toppad;
-				string(screen, p,
+				drawcell(r.msg, c->align, p, cellwidth,
+					r.error ? colors.err : img);
+/*				string(screen, p,
 					r.error ? colors.err : img,
-					ZP, font, r.msg);
+					ZP, font, r.msg); */
 				freeresponse(&r);
 			}
 		}
+	}
 }
 
 void
@@ -259,18 +288,42 @@
 set(P p, char *value)
 {
 	int type;
+	int align;
 	char *s;
 	Cell *c;
 	
+	align = Aleft;
 	type = STRING;
 	s = value;
-	if (*value == '=') {
+	
+	switch (*s) {
+	case '<':
+		align = Aleft;
+		s++;
+		break;
+	case '>':
+		align = Aright;
+		s++;
+		break;
+	case '|':
+		align = Acenter;
+		s++;
+		break;
+	case '.':
+		align = Adot;
+		s++;
+		break;
+	}
+	
+	if (*s == '=') {
 		type = FUNCTION;
-		s += 1;
+		s++;
 	}
 	
 	if (c = getcell(p)) {
-		if (c->type == type && strcmp(c->value, s) == 0)
+		if (c->type == type
+		 && strcmp(c->value, s) == 0
+		 && c->align == align)
 			return;
 	}
 	
@@ -277,7 +330,7 @@
 	if (!s[0])
 		return;
 	
-	addcell(p, s, type);
+	addcell(p, s, type, align);
 	if (!updatecells()) {
 		rerrstr(errstring, ERRMAX);
 		error = errstring;
@@ -292,6 +345,7 @@
 {
 	Cell *c;
 	char buf[512];
+	char *s;
 	char addr[25];
 	int n;
 	
@@ -299,13 +353,33 @@
 	if (!c)
 		buf[0] = 0;
 	else {
+		s = buf;
+		switch (c->align) {
+		case Aleft:
+			*s = '<';
+			s++;
+			break;
+		case Aright:
+			*s = '>';
+			s++;
+			break;
+		case Acenter:
+			*s = '|';
+			s++;
+			break;
+		case Adot:
+			*s = '.';
+			s++;
+			break;
+		}
 		switch (c->type) {
 		case FUNCTION:
-			*buf = '=';
-			strncpy(buf+1, c->value, sizeof(buf)-1);
+			*s = '=';
+			s++;
+			strncpy(s, c->value, sizeof(buf)-1);
 			break;
 		case STRING:
-			strncpy(buf, c->value, sizeof(buf));
+			strncpy(s, c->value, sizeof(buf));
 			break;
 		}
 	}
--- a/spread.h
+++ b/spread.h
@@ -18,7 +18,7 @@
 void freeresponse(Response*);
 int getwidth(int);
 
-void addcell(P cell, char *value, int type);
+void addcell(P cell, char *value, int type, int align);
 void rmcell(P cell);
 Cell* getcell(P cell);
 void gccells(void);
--- a/test/test.rc
+++ b/test/test.rc
@@ -11,7 +11,7 @@
 A1=3
 A2;hello
 A4=A1()+A3()
-A3=5
+>A3=5
 B1=2
 B2=3
 B3=4