From 8ac512362ab4b1c54c9ded5b79d8831f46d979b6 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 00:08:44 +0000 Subject: [PATCH] feat: add StripTags for render-reverse pipeline Co-Authored-By: Claude Opus 4.6 --- pipeline.go | 30 +++++++++++++++++++++++++++++ pipeline_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 pipeline.go create mode 100644 pipeline_test.go diff --git a/pipeline.go b/pipeline.go new file mode 100644 index 0000000..3b2bddf --- /dev/null +++ b/pipeline.go @@ -0,0 +1,30 @@ +package html + +import "strings" + +// StripTags removes HTML tags from rendered output, returning plain text. +// Tag boundaries are replaced with a single space; result is trimmed. +func StripTags(html string) string { + var b strings.Builder + inTag := false + for _, r := range html { + if r == '<' { + inTag = true + b.WriteByte(' ') + continue + } + if r == '>' { + inTag = false + continue + } + if !inTag { + b.WriteRune(r) + } + } + // Collapse multiple spaces into one. + result := b.String() + for strings.Contains(result, " ") { + result = strings.ReplaceAll(result, " ", " ") + } + return strings.TrimSpace(result) +} diff --git a/pipeline_test.go b/pipeline_test.go new file mode 100644 index 0000000..87b808a --- /dev/null +++ b/pipeline_test.go @@ -0,0 +1,49 @@ +package html + +import "testing" + +func TestStripTags_Simple(t *testing.T) { + got := StripTags(`
hello
`) + want := "hello" + if got != want { + t.Errorf("StripTags(
hello
) = %q, want %q", got, want) + } +} + +func TestStripTags_Nested(t *testing.T) { + got := StripTags(`

Title

`) + want := "Title" + if got != want { + t.Errorf("StripTags(nested) = %q, want %q", got, want) + } +} + +func TestStripTags_MultipleRegions(t *testing.T) { + got := StripTags(`
Head
Body
`) + want := "Head Body Foot" + if got != want { + t.Errorf("StripTags(multi) = %q, want %q", got, want) + } +} + +func TestStripTags_Empty(t *testing.T) { + got := StripTags("") + if got != "" { + t.Errorf("StripTags(\"\") = %q, want empty", got) + } +} + +func TestStripTags_NoTags(t *testing.T) { + got := StripTags("plain text") + if got != "plain text" { + t.Errorf("StripTags(plain) = %q, want %q", got, "plain text") + } +} + +func TestStripTags_Entities(t *testing.T) { + got := StripTags(`<script>`) + want := "<script>" + if got != want { + t.Errorf("StripTags should preserve entities, got %q, want %q", got, want) + } +}