From ba1b441e1da4e99546b3b7e755c8d31b73055343 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 30 Jul 2026 11:02:48 +0200 Subject: reader: verse number in a left column, hang-indent wrapped text putwrapped now peels the leading chap:verse token into a fixed VNUM-wide column (new config knob, default 8) and hang-indents continuation lines under the text, so the reading has a straight left margin instead of wrapping flush to column 0. Verses without a numeric prefix still wrap flush-left; the WRAP<=0 (terminal-fit) path is unchanged. --- clectio.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'clectio.c') diff --git a/clectio.c b/clectio.c index 61d25a0..0032557 100644 --- a/clectio.c +++ b/clectio.c @@ -98,17 +98,42 @@ static int termwidth(void) { return 72; } -/* Print s wrapped at w columns, breaking on spaces (greedy). w <= 0 prints s - * unwrapped. UTF-8 aware: continuation bytes (0x80-0xBF) do not count as a - * column, so multibyte letters measure as one. */ +/* Print one verse: a leading "chap:verse" number in a fixed left column (VNUM + * wide), then the text wrapped at w columns, breaking on spaces (greedy), with + * continuation lines hang-indented under the text so its left edge stays + * straight. w <= 0 prints the text on one line after the number column. UTF-8 + * aware: continuation bytes (0x80-0xBF) do not count as a column, so multibyte + * letters measure as one. A verse that does not begin with a digit gets no + * number column (indent 0) and wraps flush-left, as before. */ static void putwrapped(const char *s, int w) { + const char *text = s; + int indent = 0, first = 1; + + if (*s >= '0' && *s <= '9') { /* peel the leading "chap:verse " token */ + const char *sp = strchr(s, ' '); + if (sp) { + int numlen = (int)(sp - s), pad = VNUM - numlen; + fwrite(s, 1, (size_t)numlen, stdout); + if (pad < 1) + pad = 1; /* always a space, even after a long number */ + while (pad-- > 0) + putchar(' '); + indent = VNUM; + text = sp + 1; + } + } + if (w <= 0) { - printf("%s\n", s); + printf("%s\n", text); return; } - while (*s) { - const char *p = s, *brk = NULL; - int col = 0; + + while (*text) { + const char *p = text, *brk = NULL; + int col = indent, k; + if (!first) /* hang-indent continuation lines under the text */ + for (k = 0; k < indent; k++) + putchar(' '); while (*p && col < w) { if (*p == ' ') brk = p; @@ -116,16 +141,17 @@ static void putwrapped(const char *s, int w) { col++; p++; } - if (!*p) { /* the rest fits on one line */ - printf("%s\n", s); + if (!*p) { /* the rest fits on this line */ + printf("%s\n", text); return; } - if (!brk) /* a single word longer than w: hard-break at the column */ + if (!brk) /* a single word longer than the line: hard-break */ brk = p; - fwrite(s, 1, (size_t)(brk - s), stdout); + fwrite(text, 1, (size_t)(brk - text), stdout); putchar('\n'); - for (s = brk; *s == ' '; s++) /* skip the space(s) we broke on */ + for (text = brk; *text == ' '; text++) /* skip the break space(s) */ ; + first = 0; } } -- cgit v1.3