From d52588d63563d16b23630de6a1b3bce3e1c47743 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sat, 5 Sep 2026 03:26:29 +0000 Subject: [PATCH] add CollapseWhitespace for flattening runs of whitespace CollapseWhitespace turns every run of whitespace into a single space and trims the ends, so a block of text becomes one tidy line. Comes with a doc comment and table-driven tests. (closes #7) Model: opus-5 --- whitespace.go | 12 ++++++++++++ whitespace_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 whitespace.go create mode 100644 whitespace_test.go diff --git a/whitespace.go b/whitespace.go new file mode 100644 index 0000000..8143b76 --- /dev/null +++ b/whitespace.go @@ -0,0 +1,12 @@ +package util + +import "strings" + +// CollapseWhitespace replaces every run of whitespace in s with a single space +// and removes any whitespace at the start and end. Tabs, newlines and spaces +// outside ASCII such as the non-breaking space all count as whitespace, so a +// block of text comes back as one line with single spaces between the words. +// A string that is nothing but whitespace comes back empty. +func CollapseWhitespace(s string) string { + return strings.Join(strings.Fields(s), " ") +} diff --git a/whitespace_test.go b/whitespace_test.go new file mode 100644 index 0000000..28c97db --- /dev/null +++ b/whitespace_test.go @@ -0,0 +1,36 @@ +package util + +import "testing" + +// Written as a code point so that it is visible in the source rather than +// looking like an ordinary space. +const nonBreakingSpace = string(rune(0x00a0)) + +func TestCollapseWhitespace(t *testing.T) { + tests := []struct { + name string + input string + expected string + }{ + {"nothing to change", "one two", "one two"}, + {"leading and trailing spaces", " one two ", "one two"}, + {"run in the middle", "one two", "one two"}, + {"tabs and newlines", "one\t\ttwo\nthree", "one two three"}, + {"windows line endings", "one\r\ntwo", "one two"}, + {"non-breaking space", "one" + nonBreakingSpace + "two", "one two"}, + {"mixed whitespace run", "one \t" + nonBreakingSpace + " two", "one two"}, + {"only whitespace", " \t\n ", ""}, + {"empty string", "", ""}, + {"single word with padding", "\tword\n", "word"}, + {"paragraph becomes one line", "first line\n\nsecond line\n", "first line second line"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := CollapseWhitespace(test.input) + if got != test.expected { + t.Errorf("expected %q got %q", test.expected, got) + } + }) + } +} -- 2.49.1