Skip to content

Commit 2fd3e0c

Browse files
authored
fix(caption): count runes when centering text (#91)
Captions containing accented, Greek or Cyrillic letters are shifted left because centering uses UTF-8 byte lengths. Count runes when calculating caption padding, consistent with the existing axis-label calculations. Four regression cases fail before the fix, while the ASCII control passes. The full Go test suite passes afterward with race detection and 95% library statement coverage; `go vet ./...` and gofmt checks also pass.
1 parent 3934c9c commit 2fd3e0c

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

‎asciigraph.go‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,9 @@ func PlotMany(data [][]float64, options ...Option) string {
353353
if config.Caption != "" {
354354
lines.WriteString(config.LineEnding)
355355
lines.WriteString(strings.Repeat(" ", leftPad))
356-
if len(config.Caption) < lenMax {
357-
lines.WriteString(strings.Repeat(" ", (lenMax-len(config.Caption))/2))
356+
captionLength := utf8.RuneCountInString(config.Caption)
357+
if captionLength < lenMax {
358+
lines.WriteString(strings.Repeat(" ", (lenMax-captionLength)/2))
358359
}
359360
if config.CaptionColor != Default {
360361
lines.WriteString(config.CaptionColor.String())

‎asciigraph_test.go‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,34 @@ func TestLineEndingPlotMany(t *testing.T) {
612612
}
613613
}
614614

615+
func TestCaptionCenteringWithMultibyteText(t *testing.T) {
616+
data := make([]float64, 16)
617+
for i := range data {
618+
data[i] = 1
619+
}
620+
621+
for _, tc := range []struct {
622+
caption string
623+
padding int
624+
}{
625+
{"test", 13},
626+
{"café", 13},
627+
{"θεός", 13},
628+
{"тест", 13},
629+
{"тесттест", 11},
630+
} {
631+
t.Run(tc.caption, func(t *testing.T) {
632+
graph := Plot(data, Caption(tc.caption))
633+
lines := strings.Split(graph, "\n")
634+
// Center captions within the 16-column plot, after the seven-column offset.
635+
want := strings.Repeat(" ", tc.padding) + tc.caption
636+
if got := lines[len(lines)-1]; got != want {
637+
t.Errorf("caption line: want %q, got %q", want, got)
638+
}
639+
})
640+
}
641+
}
642+
615643
func TestLineEndingWithCaption(t *testing.T) {
616644
data := []float64{1, 2, 3}
617645

0 commit comments

Comments
 (0)