fix(tui): excluded 4-digit hash colors from inline swatch parsing
- Updated hex color validation to accept only 3-, 6-, and 8-digit forms as swatchable. - Adjusted strict prose filtering to gate only 3-digit values without hex letters. - Added a regression test confirming 4-digit #TAG snapshot tags do not render swatches in prose or code spans.
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Stopped painting inline color swatches for 4-digit hex runs in Markdown rendering. The `#RGBA` CSS form collides with hashline `#TAG` snapshot tags (4 hex digits, e.g. `#6C5E`), which were sprouting spurious RGB swatches in prose and codespans. Only `#RGB`, `#RRGGBB`, and `#RRGGBBAA` qualify now.
|
||||
|
||||
## [15.7.6] - 2026-06-01
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -146,22 +146,24 @@ const DEFAULT_COLOR_SWATCH_GLYPH = "■";
|
||||
// entities like ☃ and paths like foo#fff) and not trailed by more hex
|
||||
// (so over-long runs never produce a misleading swatch). Length/letter rules
|
||||
// are enforced in classifyHexColor since the alternation can't express "exactly
|
||||
// 3, 4, 6, or 8".
|
||||
// 3, 6, or 8".
|
||||
const HEX_COLOR_REGEX = /(?<![\w#&])#([0-9a-fA-F]{3,8})(?![0-9a-fA-F])/g;
|
||||
const HEX_COLOR_EXACT_REGEX = /^#([0-9a-fA-F]{3,8})$/;
|
||||
|
||||
/**
|
||||
* Decide whether a run of hex digits denotes a renderable CSS color.
|
||||
*
|
||||
* Only the canonical CSS lengths (#RGB, #RGBA, #RRGGBB, #RRGGBBAA) qualify. In
|
||||
* `strict` mode (bare prose) a 3/4-digit run must contain a hex letter, so the
|
||||
* Only the canonical CSS lengths (#RGB, #RRGGBB, #RRGGBBAA) qualify. The 4-digit
|
||||
* #RGBA form is deliberately excluded: it collides with hashline `#TAG` snapshot
|
||||
* tags (4 hex digits, e.g. #6C5E), which would otherwise sprout spurious swatches.
|
||||
* In `strict` mode (bare prose) a 3-digit run must contain a hex letter, so the
|
||||
* far more common short issue/PR references (#123, #1011) don't sprout swatches.
|
||||
* Codespans opt out of strictness — the backticks already signal "this is a color".
|
||||
*/
|
||||
function classifyHexColor(hex: string, strict: boolean): boolean {
|
||||
const n = hex.length;
|
||||
if (n !== 3 && n !== 4 && n !== 6 && n !== 8) return false;
|
||||
if (strict && n <= 4 && !/[a-fA-F]/.test(hex)) return false;
|
||||
if (n !== 3 && n !== 6 && n !== 8) return false;
|
||||
if (strict && n === 3 && !/[a-fA-F]/.test(hex)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1187,6 +1187,15 @@ describe("Inline color swatches", () => {
|
||||
expect(out.includes(swatchFor("fff"))).toBeTruthy();
|
||||
});
|
||||
|
||||
it("does not swatch 4-digit hashline #TAG snapshot tags", () => {
|
||||
// Hashline tags are 4 hex digits with letters (e.g. #6C5E) and would
|
||||
// otherwise be read as #RGBA colors. Neither prose nor codespans swatch them.
|
||||
const prose = new Markdown("Re-anchor on #6C5E before editing.", 0, 0, defaultMarkdownTheme).render(80).join("");
|
||||
expect(prose.includes("■")).toBe(false);
|
||||
const code = new Markdown("Tag `#6C5E` stays plain.", 0, 0, defaultMarkdownTheme).render(80).join("");
|
||||
expect(code.includes("■")).toBe(false);
|
||||
});
|
||||
|
||||
it("uses the theme's colorSwatch symbol when provided", () => {
|
||||
const themed = { ...defaultMarkdownTheme, symbols: { ...defaultMarkdownTheme.symbols, colorSwatch: "▢" } };
|
||||
const out = new Markdown("Accent #C5FFD6.", 0, 0, themed).render(80).join("\n");
|
||||
|
||||
Reference in New Issue
Block a user