diff options
Diffstat (limited to 'internal/comic/helpers.go')
| -rw-r--r-- | internal/comic/helpers.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/internal/comic/helpers.go b/internal/comic/helpers.go new file mode 100644 index 0000000..0458db5 --- /dev/null +++ b/internal/comic/helpers.go @@ -0,0 +1,85 @@ +package comic + +import ( + "strings" +) + +// slugify converts a comic title into a safe file-name component. +func slugify(title string) string { + title = strings.ToLower(strings.TrimSpace(title)) + var b strings.Builder + prevHyphen := false + for _, r := range title { + switch { + case r >= 'a' && r <= 'z', r >= '0' && r <= '9': + b.WriteRune(r) + prevHyphen = false + case r == ' ' || r == '-' || r == '_': + if !prevHyphen && b.Len() > 0 { + b.WriteByte('-') + prevHyphen = true + } + } + } + + slug := strings.TrimRight(b.String(), "-") + if slug == "" { + return "comic" + } + return slug +} + +// splitIntoSections divides text into n sections, preferring paragraph boundaries. +func splitIntoSections(text string, n int) []string { + paragraphs := splitParagraphs(text) + if len(paragraphs) >= n { + return distributeParagraphs(paragraphs, n) + } + return splitByChars(text, n) +} + +// splitParagraphs returns non-empty paragraphs separated by blank lines. +func splitParagraphs(text string) []string { + var out []string + for _, paragraph := range strings.Split(text, "\n\n") { + if paragraph = strings.TrimSpace(paragraph); paragraph != "" { + out = append(out, paragraph) + } + } + return out +} + +func distributeParagraphs(paragraphs []string, n int) []string { + sections := make([]string, n) + size, rem, idx := len(paragraphs)/n, len(paragraphs)%n, 0 + for i := range n { + count := size + if i < rem { + count++ + } + sections[i] = strings.Join(paragraphs[idx:idx+count], "\n\n") + idx += count + } + return sections +} + +func splitByChars(text string, n int) []string { + size := len(text) / n + sections := make([]string, n) + for i := range n { + start := i * size + end := start + size + if i == n-1 { + end = len(text) + } + sections[i] = strings.TrimSpace(text[start:end]) + } + return sections +} + +func orDefault(value, fallback string) string { + if strings.TrimSpace(value) != "" { + return value + } + return fallback +} |
