1
1
mirror of https://github.com/walles/moar.git synced 2024-09-17 15:07:11 +03:00

WIP Restart heading parsing implementation

This commit is contained in:
Johan Walles 2024-01-11 06:29:10 +01:00
parent 84f332d020
commit 06747d3c96

View File

@ -1,29 +1,20 @@
package textstyles
import (
"unicode"
"unicode/utf8"
"github.com/walles/moar/twin"
)
func manPageHeadingFromString(s string) *CellsWithTrailer {
if !isManPageHeading(s) {
if !parseManPageHeading(s, func(_ twin.Cell) {}) {
return nil
}
cells := make([]twin.Cell, 0, len(s)/3)
cellIndex := -1
for _, char := range s {
cellIndex++
if cellIndex%3 > 0 {
continue
}
cells = append(
cells,
twin.Cell{Rune: char, Style: ManPageHeading},
)
cells := make([]twin.Cell, 0, len(s)/2)
ok := parseManPageHeading(s, func(cell twin.Cell) {
cells = append(cells, cell)
})
if !ok {
panic("man page heading state changed")
}
return &CellsWithTrailer{
@ -32,53 +23,21 @@ func manPageHeadingFromString(s string) *CellsWithTrailer {
}
}
// Reports back one cell at a time. Returns true if the entire string was a man
// page heading.
//
// If it was not, false will be returned and the cell reporting will be
// interrupted.
//
// A man page heading is all caps. Also, each character is encoded as
// char+backspace+char, where both chars need to be the same.
func isManPageHeading(s string) bool {
// char+backspace+char, where both chars need to be the same. Whitespace is an
// exception, they can be not bold.
func parseManPageHeading(s string, reportCell func(twin.Cell)) bool {
if len(s) < 3 {
// We don't want to match empty strings. Also, strings of length 1 and 2
// cannot be man page headings since "char+backspace+char" is 3 bytes.
return false
}
var currentChar rune
nextCharNumber := 0
for _, char := range s {
currentCharNumber := nextCharNumber
nextCharNumber++
switch currentCharNumber % 3 {
case 0:
if !isManPageHeadingChar(char) {
return false
}
currentChar = char
case 1:
if char != '\b' {
return false
}
case 2:
if char != currentChar {
return false
}
default:
panic("Impossible")
}
}
firstChar, _ := utf8.DecodeRuneInString(s)
if unicode.IsSpace(firstChar) {
// Headings are not indented
return false
}
return nextCharNumber%3 == 0
}
// Alphabetic chars must be upper case, all others are fine.
func isManPageHeadingChar(char rune) bool {
if !unicode.IsLetter(char) {
return true
}
return unicode.IsUpper(char)
Johan: Write code here
}