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