all repos — bibel @ 01c758ad65f39049a6b57f85c0e09c74b5f1f1ea

Unnamed repository; edit this file 'description' to name the repository.

internal/formatter.go (view raw)

  1package bible
  2
  3import (
  4	"fmt"
  5	"strings"
  6)
  7
  8// Formatter handles formatting Bible text for display
  9type Formatter struct {
 10	useColours   bool
 11	headerFormat string
 12}
 13
 14// NewFormatter creates a new formatter with default settings
 15func NewFormatter() *Formatter {
 16	return &Formatter{
 17		useColours:   true,
 18		headerFormat: "{book} {chapter}\nw. {first_verse}-{second_verse}",
 19	}
 20}
 21
 22// NewFormatterWithConfig creates a new formatter with configuration
 23func NewFormatterWithConfig(useColours bool, headerFormat string) *Formatter {
 24	return &Formatter{
 25		useColours:   useColours,
 26		headerFormat: headerFormat,
 27	}
 28}
 29
 30// FormatHeader formats the header for a bookmark using the configured template
 31func (f *Formatter) FormatHeader(bookmark *Bookmark) string {
 32	template := f.headerFormat
 33	if template == "" {
 34		// Fall back to default template
 35		template = "{book} {chapter}\nw. {first_verse}-{second_verse}"
 36	}
 37	
 38	// Replace template variables
 39	result := template
 40	result = strings.ReplaceAll(result, "{book}", bookmark.Book.String())
 41	result = strings.ReplaceAll(result, "{chapter}", fmt.Sprintf("%d", bookmark.Chapter))
 42	result = strings.ReplaceAll(result, "{first_verse}", fmt.Sprintf("%d", bookmark.FirstVerse))
 43	result = strings.ReplaceAll(result, "{second_verse}", fmt.Sprintf("%d", bookmark.SecondVerse))
 44	
 45	if !f.useColours {
 46		return result
 47	}
 48	
 49	// Add ANSI colours - simple implementation
 50	// For more advanced templating, we'd need a proper template engine
 51	const (
 52		reset  = "\033[0m"
 53		green  = "\033[32m"
 54		yellow = "\033[33m"
 55	)
 56	
 57	// Simple colouring - book and chapter in green, verse range in yellow
 58	lines := strings.Split(result, "\n")
 59	if len(lines) >= 1 {
 60		lines[0] = green + lines[0] + reset
 61	}
 62	if len(lines) >= 2 {
 63		lines[1] = yellow + lines[1] + reset
 64	}
 65	result = strings.Join(lines, "\n")
 66	
 67	return result
 68}
 69
 70// FormatHeaderWithTemplate is deprecated - use FormatHeader instead
 71func (f *Formatter) FormatHeaderWithTemplate(bookmark *Bookmark) string {
 72	return f.FormatHeader(bookmark)
 73}
 74
 75// FormatSnippet formats the verse range text
 76func (f *Formatter) FormatSnippet(verses []*Verse) string {
 77	if len(verses) == 0 {
 78		return "Error: No text matched"
 79	}
 80
 81	var sb strings.Builder
 82	for i, verse := range verses {
 83		if i > 0 {
 84			sb.WriteString(" ")
 85		}
 86		// Remove any leading pilcrow (¶) and trim
 87		text := strings.TrimSpace(verse.Text)
 88		if strings.HasPrefix(text, "¶ ") {
 89			text = text[2:]
 90		} else if strings.HasPrefix(text, "¶") {
 91			text = text[1:]
 92		}
 93		sb.WriteString(text)
 94	}
 95
 96	return sb.String()
 97}
 98
 99// ExtractAndFormat extracts verses for a bookmark and formats them
100func (f *Formatter) ExtractAndFormat(bible *Bible, bookmark *Bookmark) string {
101	verses := bible.GetVerseRange(int(bookmark.Book), bookmark.Chapter,
102		bookmark.FirstVerse, bookmark.SecondVerse)
103	return f.FormatSnippet(verses)
104}
105
106// ExtractAndFormatWithHeader extracts verses and formats with header
107func (f *Formatter) ExtractAndFormatWithHeader(bible *Bible, bookmark *Bookmark) string {
108	header := f.FormatHeader(bookmark)
109	content := f.ExtractAndFormat(bible, bookmark)
110	return header + "\n" + content
111}