From f6554e35926287a43198c594e1e097219e5e68c6 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Wed, 8 Jul 2026 13:46:13 +0100 Subject: Ignore ANSI escapes in string length calculation --- tabulate.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tabulate.cpp b/tabulate.cpp index f5cfb4f..7b262da 100644 --- a/tabulate.cpp +++ b/tabulate.cpp @@ -26,7 +26,7 @@ static void usage(const char *argv0) { "has multiple values in the input, the values are appended using the separator\n" "character.\n" "Row, column and table labels are printed in order of occurrence in the input.\n" - "UTF-8 is assumed for string-length calculation.\n" + "String-length calculation assumes UTF-8 and ignores ANSI escape sequences.\n" "\n" "Options:\n" " -h Show help.\n" @@ -96,8 +96,20 @@ static std::ostream& operator<<(std::ostream &os, Spaces spaces) { } static int swidth(const std::string &s) { + bool saw_escape = false; + bool in_ansi_escape = false; int len = 0; - for (char c : s) len += (c & 0xc0) != 0x80; + for (char c : s) { + if (in_ansi_escape) { + if (0x40 <= c && c <= 0x7E) in_ansi_escape = false; + } else if (c == '\x1B') { + saw_escape = true; + } else if (saw_escape && c == '[') { + in_ansi_escape = true; + } else { + len += (c & 0xc0) != 0x80; + } + } return len; } -- cgit v1.3.1