Files

73 lines
2.7 KiB
Go

// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package presentation
import (
"fmt"
"git.stormux.org/storm/fenrir/internal/i18n"
"git.stormux.org/storm/fenrir/internal/screen"
"strings"
)
// Default_attribute_format is Python Fenrir's default, including its tokens.
const Default_attribute_format = "Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize"
func attribute_color(color uint32, background bool) string {
if color == screen.ColorDefault {
return i18n.T("default")
}
if color&screen.ColorIndexed == 0 {
return fmt.Sprintf("#%06x", color)
}
index := color &^ screen.ColorIndexed
names := []string{"black", "red", "green", "brown/yellow", "blue", "magenta", "cyan", "light gray", "dark gray", "light red", "light green", "light yellow", "light blue", "light magenta", "light cyan", "white"}
if index < 16 {
if background && index == 7 {
return i18n.T("white")
}
return i18n.T(names[index])
}
// xterm's fixed 256-color cube and grayscale, without approximate names.
if index < 232 {
level := []uint32{0, 95, 135, 175, 215, 255}
index -= 16
return fmt.Sprintf("#%02x%02x%02x", level[index/36], level[index/6%6], level[index%6])
}
value := 8 + 10*(index-232)
return fmt.Sprintf("#%02x%02x%02x", value, value, value)
}
// Format_attributes substitutes the Python tokens. Font metadata is not
// available from either backend; default means unspecified, not a detected font.
func Format_attributes(attribute screen.Attribute, format string) string {
pairs := []string{"fenrirFGColor", attribute_color(attribute.Foreground, false), "fenrirBGColor", attribute_color(attribute.Background, true), "fenrirFontSize", i18n.T("default"), "fenrirFont", i18n.T("default")}
for _, style := range []struct {
token, text string
mask uint32
}{
{"fenrirBold", "bold", screen.Bold}, {"fenrirItalics", "italic", screen.Italic},
{"fenrirUnderline", "underline", screen.Underline}, {"fenrirStrikethrough", "strikethrough", screen.Strike},
{"fenrirReverse", "reverse", screen.Reverse}, {"fenrirBlink", "blink", screen.Blink},
} {
text := ""
if attribute.Style&style.mask != 0 {
text = i18n.T(style.text)
}
pairs = append(pairs, style.token, text)
}
return strings.NewReplacer(pairs...).Replace(format)
}
func Attribute_message(attribute screen.Attribute, mode, format string) Message {
text := Format_attributes(attribute, format)
if mode == "beeps" || strings.TrimSpace(text) == "" && !attribute.Default() {
text = i18n.T("has attribute")
}
message := Message{Text: text, Attributes: &Attributes{Speech: mode != "beeps"}}
if mode == "beeps" || mode == "both" {
message.Cue = HasAttributes
}
return message
}