styles.go

  1// Package styles define styling and theming for the project.
  2package styles
  3
  4import (
  5	"fmt"
  6	"image/color"
  7	"strings"
  8
  9	"charm.land/bubbles/v2/filepicker"
 10	"charm.land/bubbles/v2/help"
 11	"charm.land/bubbles/v2/textarea"
 12	"charm.land/bubbles/v2/textinput"
 13	"charm.land/glamour/v2/ansi"
 14	"charm.land/lipgloss/v2"
 15	"github.com/alecthomas/chroma/v2"
 16	"github.com/charmbracelet/crush/internal/ui/diffview"
 17)
 18
 19const (
 20	CheckIcon       string = "βœ“"
 21	SpinnerIcon     string = "β‹―"
 22	LoadingIcon     string = "⟳"
 23	ModelIcon       string = "β—‡"
 24	HypercreditIcon string = "β—†"
 25
 26	ArrowRightIcon string = "β†’"
 27
 28	ToolPending string = "●"
 29	ToolSuccess string = "βœ“"
 30	ToolError   string = "Γ—"
 31
 32	RadioOn  string = "β—‰"
 33	RadioOff string = "β—‹"
 34
 35	BorderThin  string = "β”‚"
 36	BorderThick string = "β–Œ"
 37
 38	SectionSeparator string = "─"
 39
 40	TodoCompletedIcon  string = "βœ“"
 41	TodoPendingIcon    string = "β€’"
 42	TodoInProgressIcon string = "β†’"
 43
 44	ImageIcon string = "β– "
 45	TextIcon  string = "≑"
 46
 47	ScrollbarThumb string = "┃"
 48	ScrollbarTrack string = "β”‚"
 49
 50	LSPErrorIcon   string = "E"
 51	LSPWarningIcon string = "W"
 52	LSPInfoIcon    string = "I"
 53	LSPHintIcon    string = "H"
 54)
 55
 56const (
 57	defaultMargin     = 2
 58	defaultListIndent = 2
 59)
 60
 61type Styles struct {
 62	// Header
 63	Header struct {
 64		Charm             lipgloss.Style // Style for "Charmβ„’" label
 65		Diagonals         lipgloss.Style // Style for diagonal separators (β•±)
 66		Percentage        lipgloss.Style // Style for context percentage
 67		Hypercredit       lipgloss.Style // Style for Hypercredit count (β—† N)
 68		Keystroke         lipgloss.Style // Style for keystroke hints (e.g., "ctrl+d")
 69		KeystrokeTip      lipgloss.Style // Style for keystroke action text (e.g., "open", "close")
 70		WorkingDir        lipgloss.Style // Style for current working directory
 71		Separator         lipgloss.Style // Style for separator dots (β€’)
 72		Wrapper           lipgloss.Style // Outer container for the entire header row
 73		LogoGradCanvas    lipgloss.Style // Canvas for the compact "CRUSH" gradient
 74		LogoGradFromColor color.Color    // "CRUSH" wordmark gradient start
 75		LogoGradToColor   color.Color    // "CRUSH" wordmark gradient end
 76	}
 77
 78	CompactDetails struct {
 79		View    lipgloss.Style
 80		Version lipgloss.Style
 81		Title   lipgloss.Style
 82	}
 83
 84	// Tool calls
 85	ToolCallSuccess lipgloss.Style
 86
 87	// Text selection
 88	TextSelection lipgloss.Style
 89
 90	// Markdown & Chroma
 91	Markdown      ansi.StyleConfig
 92	QuietMarkdown ansi.StyleConfig
 93
 94	// Inputs
 95	TextInput textinput.Styles
 96
 97	// Help
 98	Help help.Styles
 99
100	// Diff
101	Diff diffview.Style
102
103	// FilePicker
104	FilePicker filepicker.Styles
105
106	// Buttons
107	Button struct {
108		Focused lipgloss.Style
109		Blurred lipgloss.Style
110	}
111
112	// Editor
113	Editor struct {
114		Textarea textarea.Styles
115
116		// Normal mode prompt (default "::: ").
117		PromptNormalFocused lipgloss.Style
118		PromptNormalBlurred lipgloss.Style
119
120		// YOLO mode prompt (" ! " icon + ":::" dots).
121		PromptYoloIconFocused lipgloss.Style
122		PromptYoloIconBlurred lipgloss.Style
123		PromptYoloDotsFocused lipgloss.Style
124		PromptYoloDotsBlurred lipgloss.Style
125	}
126
127	// Radio
128	Radio struct {
129		On    lipgloss.Style
130		Off   lipgloss.Style
131		Label lipgloss.Style // Text next to a radio button
132	}
133
134	// Background
135	Background color.Color
136
137	// Logo
138	Logo struct {
139		FieldColor         color.Color
140		TitleColorA        color.Color
141		TitleColorB        color.Color
142		CharmColor         color.Color
143		VersionColor       color.Color
144		SmallCharm         lipgloss.Style // "Charmβ„’" label in SmallRender
145		SmallDiagonals     lipgloss.Style // Diagonal line fill in SmallRender
146		GradCanvas         lipgloss.Style // Blank canvas for gradient painting
147		SmallGradFromColor color.Color    // Small "Crush" wordmark gradient start
148		SmallGradToColor   color.Color    // Small "Crush" wordmark gradient end
149	}
150
151	// Working indicator gradient (spinners/shimmers on assistant "thinking",
152	// tool-call pending, CLI generating, startup).
153	WorkingGradFromColor color.Color
154	WorkingGradToColor   color.Color
155	WorkingLabelColor    color.Color // Label text color next to the indicator
156
157	// Section Title
158	Section struct {
159		Title lipgloss.Style
160		Line  lipgloss.Style
161	}
162
163	// Initialize
164	Initialize struct {
165		Header  lipgloss.Style
166		Content lipgloss.Style
167		Accent  lipgloss.Style
168	}
169
170	// LSP
171	LSP struct {
172		ErrorDiagnostic   lipgloss.Style
173		WarningDiagnostic lipgloss.Style
174		HintDiagnostic    lipgloss.Style
175		InfoDiagnostic    lipgloss.Style
176	}
177
178	// Sidebar
179	Sidebar struct {
180		SessionTitle lipgloss.Style // Current session title at top of sidebar
181		WorkingDir   lipgloss.Style // Working directory path (PrettyPath)
182	}
183
184	// ModelInfo (model name, provider, reasoning, token/cost summary)
185	ModelInfo struct {
186		Icon             lipgloss.Style // Model icon (β—‡)
187		Name             lipgloss.Style // Model name text
188		Provider         lipgloss.Style // "via <provider>" text
189		ProviderFallback lipgloss.Style // Provider on its own second line
190		Reasoning        lipgloss.Style // Reasoning effort text
191		TokenCount       lipgloss.Style // "(42K)" token count
192		TokenPercentage  lipgloss.Style // "42%" percent of context window
193		Cost             lipgloss.Style // "$0.42" cost readout
194		HypercreditIcon  lipgloss.Style // Hypercredit icon (β—†)
195		HypercreditText  lipgloss.Style // Remaining Hypercredits text
196	}
197
198	// Resource styles the LSP/MCP/skills sidebar lists: their heading,
199	// each row's status icon, name, status text, and truncation hints.
200	Resource struct {
201		Heading         lipgloss.Style // Section header ("LSPs", "MCPs", "Skills")
202		Name            lipgloss.Style // Resource name (e.g. "gopls")
203		StatusText      lipgloss.Style // Row status description (e.g. "starting...")
204		OfflineIcon     lipgloss.Style // Offline/unstarted/stopped status icon
205		DisabledIcon    lipgloss.Style // Disabled status icon
206		BusyIcon        lipgloss.Style // Busy/starting status icon
207		ErrorIcon       lipgloss.Style // Error status icon
208		OnlineIcon      lipgloss.Style // Online/ready status icon
209		AdditionalText  lipgloss.Style // "None" and "…and N more" text
210		CapabilityCount lipgloss.Style // "N tools" / "N prompts" / "N resources"
211		RowTitleBase    lipgloss.Style // Base style applied over row titles in common.Status
212		RowDescBase     lipgloss.Style // Base style applied over row descriptions in common.Status
213		DefaultTitleFg  color.Color    // Default title color when opt is zero
214		DefaultDescFg   color.Color    // Default description color when opt is zero
215	}
216
217	// Files
218	Files struct {
219		Path           lipgloss.Style
220		Additions      lipgloss.Style
221		Deletions      lipgloss.Style
222		SectionTitle   lipgloss.Style // "Modified Files" heading
223		EmptyMessage   lipgloss.Style // "None" placeholder when no files
224		TruncationHint lipgloss.Style // "…and N more" message
225	}
226
227	// Chat
228	// Messages - chat message item styles
229	Messages struct {
230		UserBlurred      lipgloss.Style
231		UserFocused      lipgloss.Style
232		AssistantBlurred lipgloss.Style
233		AssistantFocused lipgloss.Style
234		NoContent        lipgloss.Style
235		Thinking         lipgloss.Style
236		ErrorTag         lipgloss.Style
237		ErrorTitle       lipgloss.Style
238		ErrorDetails     lipgloss.Style
239		ToolCallFocused  lipgloss.Style
240		ToolCallCompact  lipgloss.Style
241		ToolCallBlurred  lipgloss.Style
242		SectionHeader    lipgloss.Style
243
244		// Thinking section styles
245		ThinkingBox            lipgloss.Style // Background for thinking content
246		ThinkingTruncationHint lipgloss.Style // "… (N lines hidden)" hint
247		ThinkingFooterTitle    lipgloss.Style // "Thought for" text
248		ThinkingFooterDuration lipgloss.Style // Duration value
249		AssistantInfoIcon      lipgloss.Style
250		AssistantInfoModel     lipgloss.Style
251		AssistantInfoProvider  lipgloss.Style
252		AssistantInfoDuration  lipgloss.Style
253		AssistantCanceled      lipgloss.Style // Italic "Canceled" footer
254	}
255
256	// Tool - styles for tool call rendering
257	Tool struct {
258		// Icon styles with tool status
259		IconPending   lipgloss.Style
260		IconSuccess   lipgloss.Style
261		IconError     lipgloss.Style
262		IconCancelled lipgloss.Style
263
264		// Tool name styles
265		NameNormal lipgloss.Style // Top-level tool name
266		NameNested lipgloss.Style // Nested child tool name (inside Agent/Agentic Fetch)
267
268		// Parameter list styles
269		ParamMain lipgloss.Style
270		ParamKey  lipgloss.Style
271
272		// Content rendering styles
273		ContentLine           lipgloss.Style // Individual content line with background and width
274		ContentTruncation     lipgloss.Style // Truncation message "… (N lines)"
275		ContentCodeLine       lipgloss.Style // Code line with background and width
276		ContentCodeTruncation lipgloss.Style // Code truncation message with bgBase
277		ContentCodeBg         color.Color    // Background color for syntax highlighting
278		Body                  lipgloss.Style // Body content padding (PaddingLeft(2))
279
280		// Deprecated - kept for backward compatibility
281		ContentBg         lipgloss.Style // Content background
282		ContentText       lipgloss.Style // Content text
283		ContentLineNumber lipgloss.Style // Line numbers in code
284
285		// State message styles
286		StateWaiting   lipgloss.Style // "Waiting for tool response..."
287		StateCancelled lipgloss.Style // "Canceled."
288
289		// Error styles
290		ErrorTag     lipgloss.Style // ERROR tag
291		ErrorMessage lipgloss.Style // Error message text
292
293		// Diff styles
294		DiffTruncation lipgloss.Style // Diff truncation message with padding
295
296		// Multi-edit note styles
297		NoteTag     lipgloss.Style // NOTE tag (yellow background)
298		NoteMessage lipgloss.Style // Note message text
299
300		// Job header styles (for bash jobs)
301		JobIconPending lipgloss.Style // Pending job icon (green dark)
302		JobIconError   lipgloss.Style // Error job icon (red dark)
303		JobIconSuccess lipgloss.Style // Success job icon (green)
304		JobToolName    lipgloss.Style // Job tool name "Bash" (blue)
305		JobAction      lipgloss.Style // Action text (Start, Output, Kill)
306		JobPID         lipgloss.Style // PID text
307		JobDescription lipgloss.Style // Description text
308
309		// Agent task styles
310		AgentTaskTag lipgloss.Style // Agent task tag (blue background, bold)
311		AgentPrompt  lipgloss.Style // Agent prompt text
312
313		// Agentic fetch styles
314		AgenticFetchPromptTag lipgloss.Style // Agentic fetch prompt tag (green background, bold)
315
316		// Todo styles
317		TodoRatio          lipgloss.Style // Todo ratio (e.g., "2/5")
318		TodoCompletedIcon  lipgloss.Style // Completed todo icon
319		TodoInProgressIcon lipgloss.Style // In-progress todo icon
320		TodoPendingIcon    lipgloss.Style // Pending todo icon
321		TodoStatusNote     lipgloss.Style // " Β· completed N" / " Β· starting task" trailing note
322		TodoItem           lipgloss.Style // Default body text for todo list items
323		TodoJustStarted    lipgloss.Style // Text of the just-started todo in tool-call bodies
324
325		// MCP tools
326		MCPName     lipgloss.Style // The mcp name
327		MCPToolName lipgloss.Style // The mcp tool name
328		MCPArrow    lipgloss.Style // The mcp arrow icon
329
330		// Images and external resources
331		ResourceLoadedText      lipgloss.Style
332		ResourceLoadedIndicator lipgloss.Style
333		ResourceName            lipgloss.Style
334		ResourceSize            lipgloss.Style
335		MediaType               lipgloss.Style
336
337		// Hooks
338		HookLabel        lipgloss.Style // "Hook" label
339		HookName         lipgloss.Style // Hook command name
340		HookMatcher      lipgloss.Style // Matcher regex pattern
341		HookArrow        lipgloss.Style // Arrow indicator
342		HookDetail       lipgloss.Style // Decision detail text
343		HookOK           lipgloss.Style // "OK" status
344		HookDenied       lipgloss.Style // "Denied" status
345		HookDeniedLabel  lipgloss.Style // "Hook" label when denied
346		HookDeniedReason lipgloss.Style // Denied reason text
347		HookRewrote      lipgloss.Style // "Rewrote Input" indicator
348
349		// Action verb colors for tool-call headers.
350		ActionCreate  lipgloss.Style // Constructive actions (e.g. "Add", "Create")
351		ActionDestroy lipgloss.Style // Destructive actions (e.g. "Remove", "Delete")
352
353		// Tool result helpers.
354		ResultEmpty      lipgloss.Style // "No results" placeholder
355		ResultTruncation lipgloss.Style // "… and N more" truncation line
356		ResultItemName   lipgloss.Style // Item name (left column in result lists)
357		ResultItemDesc   lipgloss.Style // Item description (right column)
358	}
359
360	// Dialog styles
361	Dialog struct {
362		Title              lipgloss.Style
363		TitleText          lipgloss.Style
364		TitleError         lipgloss.Style
365		TitleAccent        lipgloss.Style
366		TitleLineBase      lipgloss.Style // Base for the gradient β•±β•±β•± next to dialog titles
367		TitleGradFromColor color.Color    // Default dialog title β•±β•±β•± gradient start
368		TitleGradToColor   color.Color    // Default dialog title β•±β•±β•± gradient end
369		// View is the main content area style.
370		View          lipgloss.Style
371		PrimaryText   lipgloss.Style
372		SecondaryText lipgloss.Style
373		// HelpView is the line that contains the help.
374		HelpView lipgloss.Style
375		Help     struct {
376			Ellipsis       lipgloss.Style
377			ShortKey       lipgloss.Style
378			ShortDesc      lipgloss.Style
379			ShortSeparator lipgloss.Style
380			FullKey        lipgloss.Style
381			FullDesc       lipgloss.Style
382			FullSeparator  lipgloss.Style
383		}
384
385		NormalItem   lipgloss.Style
386		SelectedItem lipgloss.Style
387		InputPrompt  lipgloss.Style
388
389		List lipgloss.Style
390
391		Spinner lipgloss.Style
392
393		// ContentPanel is used for content blocks with subtle background.
394		ContentPanel lipgloss.Style
395
396		// Scrollbar styles for scrollable content.
397		ScrollbarThumb lipgloss.Style
398		ScrollbarTrack lipgloss.Style
399
400		// Arguments
401		Arguments struct {
402			Content                  lipgloss.Style
403			Description              lipgloss.Style
404			InputLabelBlurred        lipgloss.Style
405			InputLabelFocused        lipgloss.Style
406			InputRequiredMarkBlurred lipgloss.Style
407			InputRequiredMarkFocused lipgloss.Style
408		}
409
410		// ListItem styles the info-text rendered alongside list items (commands,
411		// models, reasoning options). Sessions have their own overrides below.
412		ListItem struct {
413			InfoBlurred lipgloss.Style
414			InfoFocused lipgloss.Style
415		}
416
417		Models struct {
418			ConfiguredText lipgloss.Style // "Configured" badge shown on the ModelGroup header
419		}
420
421		Permissions struct {
422			KeyText   lipgloss.Style // Left key cell of a key/value row
423			ValueText lipgloss.Style // Right value cell of a key/value row
424			ParamsBg  color.Color    // Background color behind highlighted JSON parameters
425		}
426
427		Quit struct {
428			Content lipgloss.Style // Wrapper for the quit dialog's inner content
429			Frame   lipgloss.Style // Outer rounded border framing the quit dialog
430		}
431
432		APIKey struct {
433			Spinner lipgloss.Style // Loading spinner while validating the key
434		}
435
436		OAuth struct {
437			Spinner      lipgloss.Style // Loading spinner
438			Instructions lipgloss.Style // Emphasized instruction text
439			UserCode     lipgloss.Style // Prominent user code display
440			Success      lipgloss.Style // Positive status text (e.g. "Authentication successful!")
441			Link         lipgloss.Style // Underlined verification URL
442			Enter        lipgloss.Style // "enter" keyword highlight in instructions
443			ErrorText    lipgloss.Style // Error message when authentication fails
444			StatusText   lipgloss.Style // Narrative status text ("Initializing...", "Verifying...", etc.)
445			UserCodeBg   color.Color    // Background color of the centered user-code box
446		}
447
448		ImagePreview lipgloss.Style
449
450		Sessions struct {
451			// styles for when we are in delete mode
452			DeletingView                   lipgloss.Style
453			DeletingItemFocused            lipgloss.Style
454			DeletingItemBlurred            lipgloss.Style
455			DeletingTitle                  lipgloss.Style
456			DeletingMessage                lipgloss.Style
457			DeletingTitleGradientFromColor color.Color
458			DeletingTitleGradientToColor   color.Color
459
460			// styles for when we are in update mode
461			RenamingView                   lipgloss.Style
462			RenamingingItemFocused         lipgloss.Style
463			RenamingItemBlurred            lipgloss.Style
464			RenamingingTitle               lipgloss.Style
465			RenamingingMessage             lipgloss.Style
466			RenamingTitleGradientFromColor color.Color
467			RenamingTitleGradientToColor   color.Color
468			RenamingPlaceholder            lipgloss.Style
469
470			InfoBlurred lipgloss.Style // Timestamp text on unfocused session items
471			InfoFocused lipgloss.Style // Timestamp text on the focused session item
472		}
473	}
474
475	// Status bar and help
476	Status struct {
477		Help lipgloss.Style
478
479		ErrorIndicator   lipgloss.Style
480		WarnIndicator    lipgloss.Style
481		InfoIndicator    lipgloss.Style
482		UpdateIndicator  lipgloss.Style
483		SuccessIndicator lipgloss.Style
484
485		ErrorMessage   lipgloss.Style
486		WarnMessage    lipgloss.Style
487		InfoMessage    lipgloss.Style
488		UpdateMessage  lipgloss.Style
489		SuccessMessage lipgloss.Style
490	}
491
492	// Completions popup styles
493	Completions struct {
494		Normal  lipgloss.Style
495		Focused lipgloss.Style
496		Match   lipgloss.Style
497	}
498
499	// Attachments styles
500	Attachments struct {
501		Normal   lipgloss.Style
502		Image    lipgloss.Style
503		Text     lipgloss.Style
504		Deleting lipgloss.Style
505	}
506
507	// Pills styles for todo/queue pills
508	Pills struct {
509		Base               lipgloss.Style // Base pill style with padding
510		Focused            lipgloss.Style // Focused pill with visible border
511		Blurred            lipgloss.Style // Blurred pill with hidden border
512		QueueItemPrefix    lipgloss.Style // Prefix for queue list items
513		QueueItemText      lipgloss.Style // Queue list item body text
514		QueueLabel         lipgloss.Style // "N Queued" label text
515		QueueIconBase      lipgloss.Style // Base style for queue gradient triangles
516		QueueGradFromColor color.Color    // Start color for queue indicator gradient
517		QueueGradToColor   color.Color    // End color for queue indicator gradient
518		TodoLabel          lipgloss.Style // "To-Do" label
519		TodoProgress       lipgloss.Style // Todo ratio (e.g. "2/5")
520		TodoCurrentTask    lipgloss.Style // Current in-progress task name
521		TodoSpinner        lipgloss.Style // Todo spinner style
522		HelpKey            lipgloss.Style // Keystroke hint style
523		HelpText           lipgloss.Style // Help action text style
524		Area               lipgloss.Style // Pills area container
525	}
526}
527
528// ChromaTheme converts the current markdown chroma styles to a chroma
529// StyleEntries map.
530func (s *Styles) ChromaTheme() chroma.StyleEntries {
531	rules := s.Markdown.CodeBlock
532
533	return chroma.StyleEntries{
534		chroma.Text:                chromaStyle(rules.Chroma.Text),
535		chroma.Error:               chromaStyle(rules.Chroma.Error),
536		chroma.Comment:             chromaStyle(rules.Chroma.Comment),
537		chroma.CommentPreproc:      chromaStyle(rules.Chroma.CommentPreproc),
538		chroma.Keyword:             chromaStyle(rules.Chroma.Keyword),
539		chroma.KeywordReserved:     chromaStyle(rules.Chroma.KeywordReserved),
540		chroma.KeywordNamespace:    chromaStyle(rules.Chroma.KeywordNamespace),
541		chroma.KeywordType:         chromaStyle(rules.Chroma.KeywordType),
542		chroma.Operator:            chromaStyle(rules.Chroma.Operator),
543		chroma.Punctuation:         chromaStyle(rules.Chroma.Punctuation),
544		chroma.Name:                chromaStyle(rules.Chroma.Name),
545		chroma.NameBuiltin:         chromaStyle(rules.Chroma.NameBuiltin),
546		chroma.NameTag:             chromaStyle(rules.Chroma.NameTag),
547		chroma.NameAttribute:       chromaStyle(rules.Chroma.NameAttribute),
548		chroma.NameClass:           chromaStyle(rules.Chroma.NameClass),
549		chroma.NameConstant:        chromaStyle(rules.Chroma.NameConstant),
550		chroma.NameDecorator:       chromaStyle(rules.Chroma.NameDecorator),
551		chroma.NameException:       chromaStyle(rules.Chroma.NameException),
552		chroma.NameFunction:        chromaStyle(rules.Chroma.NameFunction),
553		chroma.NameOther:           chromaStyle(rules.Chroma.NameOther),
554		chroma.Literal:             chromaStyle(rules.Chroma.Literal),
555		chroma.LiteralNumber:       chromaStyle(rules.Chroma.LiteralNumber),
556		chroma.LiteralDate:         chromaStyle(rules.Chroma.LiteralDate),
557		chroma.LiteralString:       chromaStyle(rules.Chroma.LiteralString),
558		chroma.LiteralStringEscape: chromaStyle(rules.Chroma.LiteralStringEscape),
559		chroma.GenericDeleted:      chromaStyle(rules.Chroma.GenericDeleted),
560		chroma.GenericEmph:         chromaStyle(rules.Chroma.GenericEmph),
561		chroma.GenericInserted:     chromaStyle(rules.Chroma.GenericInserted),
562		chroma.GenericStrong:       chromaStyle(rules.Chroma.GenericStrong),
563		chroma.GenericSubheading:   chromaStyle(rules.Chroma.GenericSubheading),
564		chroma.Background:          chromaStyle(rules.Chroma.Background),
565	}
566}
567
568// DialogHelpStyles returns the styles for dialog help.
569func (s *Styles) DialogHelpStyles() help.Styles {
570	return help.Styles(s.Dialog.Help)
571}
572
573// hex returns a pointer to the "#rrggbb" representation of c. It's used to
574// satisfy glamour's string-pointer API when configuring markdown colors
575// from the theme palette.
576func hex(c color.Color) *string {
577	r, g, b, _ := c.RGBA()
578	s := fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
579	return &s
580}
581
582func chromaStyle(style ansi.StylePrimitive) string {
583	var s strings.Builder
584
585	if style.Color != nil {
586		s.WriteString(*style.Color)
587	}
588	if style.BackgroundColor != nil {
589		if s.Len() > 0 {
590			s.WriteString(" ")
591		}
592		s.WriteString("bg:")
593		s.WriteString(*style.BackgroundColor)
594	}
595	if style.Italic != nil && *style.Italic {
596		if s.Len() > 0 {
597			s.WriteString(" ")
598		}
599		s.WriteString("italic")
600	}
601	if style.Bold != nil && *style.Bold {
602		if s.Len() > 0 {
603			s.WriteString(" ")
604		}
605		s.WriteString("bold")
606	}
607	if style.Underline != nil && *style.Underline {
608		if s.Len() > 0 {
609			s.WriteString(" ")
610		}
611		s.WriteString("underline")
612	}
613
614	return s.String()
615}