Files

72 lines
2.4 KiB
Go

// Fenrir console screen reader.
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
// Package presentation names screen text and characters for reader output.
package presentation
import (
"strconv"
"strings"
"unicode"
"git.stormux.org/storm/fenrir/internal/i18n"
"git.stormux.org/storm/fenrir/internal/screen"
)
// Line describes a visible row, including blank rows.
func Line(s screen.Snapshot, row int) string {
text := s.Text(row)
if strings.TrimSpace(text) == "" {
return i18n.T("blank")
}
return text
}
// Line_message describes a row with Python's blank-line sound alternative.
func Line_message(s screen.Snapshot, row int) Message {
message := Message{Text: Line(s, row)}
if strings.TrimSpace(s.Text(row)) == "" {
message.Cue = Blank
}
return message
}
func Character_message(char rune) Message {
return Message{Text: Character(char), Character: &char}
}
// Character describes punctuation and whitespace. Capital cues are applied by
// the shared speech presenter using the original character.
func Character(char rune) string {
names := map[rune]string{
' ': "space", '\t': "tab", '.': "dot", ',': "comma", ':': "colon", ';': "semicolon",
'!': "bang", '?': "question?", '-': "dash", '_': "line", '/': "slash",
'\\': "backslash", '(': "left paren", ')': "right paren", '[': "left bracket",
']': "right bracket", '{': "left brace", '}': "right brace", '<': "less", '>': "greater",
'\'': "apostrophe", '"': "quote", '@': "at", '#': "hash", '$': "dollar", '%': "percent",
'^': "carrot", '&': "and", '*': "star", '+': "plus", '=': "equals", '|': "bar", '~': "tilde", '`': "grave",
}
if name, ok := names[char]; ok {
return i18n.T(name)
}
if unicode.IsControl(char) {
return i18n.Format("character {0}", strconv.Itoa(int(char)))
}
return string(char)
}