Centre the console banner mark and measure it from its file #6

Merged
marcos-mendez merged 2 commits from fix/banner-centre-the-mark into master 2026-09-27 16:57:43 -03:00
marcos-mendez commented 2026-09-27 15:14:57 -03:00 (Migrated from github.com)

The problem

The mark of the console banner stood left of centre on every console, as the
screenshot of the login shows. On an 80 column terminal the 38 column mark
began at column one and left 42 empty columns to its right, next to a title
and address lines that start at column one by design.

Under that sat a second defect, independent of the art: the size of the two
exported marks was written into the comments, into COVERAGE.md and above all
into the tests, which asserted 19 38 and 11 23, indexed the rendered
block at ROWS[18] and ROWS[10], and expected 26, 24 and 18 rows.

The diagnosis

keel_banner_render printed the chosen mark with cat, which can only ever
put it at column one. keel_banner_mark_size and keel_banner_choose_mark
already measured the files they were given, so the library was nearly free of
the size assumption; the tests were not, and would have failed on the next
re-export even with the renderer right.

The fix

keel_banner_center_mark WIDTH FILE prints the file's lines shifted right by
one common indent, max(0, (WIDTH - mark width) / 2), with the mark's width
measured from the file as its widest line. The block moves as a whole, so the
mark keeps its internal alignment; padding each line to its own centre would
have pulled the picture apart. A mark as wide as the width or wider starts at
column one and is never cut, a blank line stays blank instead of becoming a
line of spaces, and no line ends in whitespace. keel_banner_render calls it
for the mark it picked; the title and the address lines stay at column one.
The fallback rule is untouched: the mark shrinks to the small one and then
disappears before any address line is lost.

Every size now comes from the file it describes. The tests derive their
expectations from keel_banner_mark_size, ask the library which mark fits
instead of naming one, pin the fallback ladder with synthetic marks whose
size the test itself chooses, and render a mark of a third size to prove no
size is assumed. Also added: an odd and an even leftover so the rounding is
pinned, a mark wider than the width, a mark exactly the width, a blank line
inside the mark, and a check that no rendered line ends in whitespace.

COVERAGE.md no longer states the marks as "38 by 19 and 23 by 11": it says
the size is whatever the exported files carry, that the renderer measures it
and centres the mark, and carries the new measured number. tests/README.md
loses the same assumption ("24 rows falls back to banner-small.txt").

Two tests that hold this open

The suite already refused to write down the size of the installed art. Two
tests now prove the properties that matter when the art changes under it,
both on fixtures of the test file's own rather than the shipped marks.

The block stands in the middle, whatever the width. It reads the blank
columns off each side of the centred block and requires them equal, or the
one odd column left on the right, at eight widths from narrower than the
mark to far wider. It measures the block rather than recomputing the
indent, so it fails on a block pushed to either side instead of agreeing
with whatever the renderer did. Its fixture has its widest line neither
first nor last, and one line indented in the art itself, so an indent taken
from the wrong line or applied line by line shows up.

A mark of a size nobody drew. It renders marks of 1 by 1, 2 by 3, 9 by
17, 31 by 71 and 44 by 7. Each comes out whole and centred, the title and
the addresses keep their order and their column one, and a terminal one row
or one column short drops the mark and keeps every address line.

Both catch the mutation they exist for: right aligning the block fails the
first, and hard coding the mark at 19 rows fails the second.

The numbers

  • bats tests/banner.bats: 64 tests green, was 48.
  • COVERAGE_THRESHOLD=100 tests/coverage.sh (bats under kcov 43):
    banner.sh 100.00 percent, 115 of 115 lines; boot-test-lib.sh
    unchanged at 100.00 percent, 109 of 109 lines.
  • shellcheck overlay/usr/lib/keel/banner.sh: clean.
  • Replayed against synthetic art of 12 rows by 39 columns and 7 rows by 13
    columns, neither of today's sizes: 64 tests green, coverage unchanged. With
    the old cat restored, 4 tests fail, so the defect is caught.

The art

overlay/etc/keel/banner.txt and overlay/etc/keel/banner-small.txt are
untouched in this pull request. They are exports of the design system and are
being redrawn separately by the maintainer against the documented row budget
(full mark at most 12 rows by 38 columns, small mark at most 7 rows). Nothing
here needs to change when they land; two things the new art should respect,
both now checked by a test: the small mark stays shorter than and no wider
than the full one, and neither file carries trailing whitespace on a line,
which would otherwise widen the measured mark and pull the centring left.

## The problem The mark of the console banner stood left of centre on every console, as the screenshot of the login shows. On an 80 column terminal the 38 column mark began at column one and left 42 empty columns to its right, next to a title and address lines that start at column one by design. Under that sat a second defect, independent of the art: the size of the two exported marks was written into the comments, into COVERAGE.md and above all into the tests, which asserted `19 38` and `11 23`, indexed the rendered block at `ROWS[18]` and `ROWS[10]`, and expected 26, 24 and 18 rows. ## The diagnosis `keel_banner_render` printed the chosen mark with `cat`, which can only ever put it at column one. `keel_banner_mark_size` and `keel_banner_choose_mark` already measured the files they were given, so the library was nearly free of the size assumption; the tests were not, and would have failed on the next re-export even with the renderer right. ## The fix `keel_banner_center_mark WIDTH FILE` prints the file's lines shifted right by one common indent, `max(0, (WIDTH - mark width) / 2)`, with the mark's width measured from the file as its widest line. The block moves as a whole, so the mark keeps its internal alignment; padding each line to its own centre would have pulled the picture apart. A mark as wide as the width or wider starts at column one and is never cut, a blank line stays blank instead of becoming a line of spaces, and no line ends in whitespace. `keel_banner_render` calls it for the mark it picked; the title and the address lines stay at column one. The fallback rule is untouched: the mark shrinks to the small one and then disappears before any address line is lost. Every size now comes from the file it describes. The tests derive their expectations from `keel_banner_mark_size`, ask the library which mark fits instead of naming one, pin the fallback ladder with synthetic marks whose size the test itself chooses, and render a mark of a third size to prove no size is assumed. Also added: an odd and an even leftover so the rounding is pinned, a mark wider than the width, a mark exactly the width, a blank line inside the mark, and a check that no rendered line ends in whitespace. COVERAGE.md no longer states the marks as "38 by 19 and 23 by 11": it says the size is whatever the exported files carry, that the renderer measures it and centres the mark, and carries the new measured number. `tests/README.md` loses the same assumption ("24 rows falls back to banner-small.txt"). ## Two tests that hold this open The suite already refused to write down the size of the installed art. Two tests now prove the properties that matter when the art changes under it, both on fixtures of the test file's own rather than the shipped marks. *The block stands in the middle, whatever the width.* It reads the blank columns off each side of the centred block and requires them equal, or the one odd column left on the right, at eight widths from narrower than the mark to far wider. It measures the block rather than recomputing the indent, so it fails on a block pushed to either side instead of agreeing with whatever the renderer did. Its fixture has its widest line neither first nor last, and one line indented in the art itself, so an indent taken from the wrong line or applied line by line shows up. *A mark of a size nobody drew.* It renders marks of 1 by 1, 2 by 3, 9 by 17, 31 by 71 and 44 by 7. Each comes out whole and centred, the title and the addresses keep their order and their column one, and a terminal one row or one column short drops the mark and keeps every address line. Both catch the mutation they exist for: right aligning the block fails the first, and hard coding the mark at 19 rows fails the second. ## The numbers - `bats tests/banner.bats`: 64 tests green, was 48. - `COVERAGE_THRESHOLD=100 tests/coverage.sh` (bats under kcov 43): `banner.sh` **100.00 percent, 115 of 115 lines**; `boot-test-lib.sh` unchanged at 100.00 percent, 109 of 109 lines. - `shellcheck overlay/usr/lib/keel/banner.sh`: clean. - Replayed against synthetic art of 12 rows by 39 columns and 7 rows by 13 columns, neither of today's sizes: 64 tests green, coverage unchanged. With the old `cat` restored, 4 tests fail, so the defect is caught. ## The art `overlay/etc/keel/banner.txt` and `overlay/etc/keel/banner-small.txt` are untouched in this pull request. They are exports of the design system and are being redrawn separately by the maintainer against the documented row budget (full mark at most 12 rows by 38 columns, small mark at most 7 rows). Nothing here needs to change when they land; two things the new art should respect, both now checked by a test: the small mark stays shorter than and no wider than the full one, and neither file carries trailing whitespace on a line, which would otherwise widen the measured mark and pull the centring left.
Sign in to join this conversation.
No description provided.