英文:
Automatically add New Line(s) after 80th character in a string containing ANSI Escape Codes
问题
我想要一个Go程序,能够显示一个使用CP437编码的ANSI艺术文件,宽度为80列,其中包含ANSI转义码(颜色、光标定位等)和扩展的ANSI(CP437)框图代码。
当在Linux终端中查看ANSI文件(请参见下面的Playground链接),并且使用80列的CP437兼容终端时,文件会正确显示,例如换行符会被隐式读取;然而,当使用更宽的终端查看时(这是目标),新的行不会被隐式处理/添加,文件可能会显示不正确,没有必要的换行符。
如何遍历.ans文件,并在第80个字符之后手动添加新行,只计算实际显示的字符(而不是转义码)?
我已经尝试过像ansiwrap和reflow这样的Go库。ansiwrap只是用于文本换行,但是Reflow最接近目标,但换行符不太正确。
我的测试代码与Reflow的Playground链接。
在CP437终端(132x37)中的渲染效果:
应该的外观(来自艺术程序):
英文:
I want a Go program to display a CP437-encoded 'ANSI art file', 80 columns wide, that contains ANSI escape codes -- color, cursor placement, etc. and extended ANSI (CP437) box drawing codes.
When viewing the ANSI file in a linux terminal (see Playground link below) with a 80 col CP437-capable terminal, the file displays properly, e.g. line breaks are implicitly read; however, when viewing with a wider terminal (which is the goal), new lines are not implicitly processed/added and the file may display improperly, without required line breaks.
How do I iterate through the .ans file and manually add new lines after the 80th character, counting only the actual characters displayed (not the escape codes)?
I've tried go libraries like ansiwrap and reflow. Ansiwrap is really just for text wrapping, but Reflow gets the closest to the goal, but the line breaks are not quite right.
Playground link of my test code with Reflow.
How it renders (in a CP437 terminal, 132x37):
How it should look (from art program):
答案1
得分: 1
为了解决这个问题,首先我从golang.org/x/term
包中提取了visualLength
函数1,然后我为这个用例编写了一个bufio.SplitFunc
2。
package main
func ansi(data []byte, eof bool) (int, []byte, error) {
var s []rune
for i, r := range string(data) {
if s = append(s, r); visualLength(s) == 80 {
width := len(string(r))
return i+width, data[:i+width], nil
}
}
return 0, nil, nil
}
结果:
package main
import (
"bufio"
"golang.org/x/text/encoding/charmap"
"os"
)
func main() {
f, err := os.Open("LDA-PHASE90.ANS")
if err != nil {
panic(err)
}
defer f.Close()
s := bufio.NewScanner(charmap.CodePage437.NewDecoder().Reader(f))
s.Split(ansi)
for s.Scan() {
println(s.Text())
}
}
- https://github.com/golang/term/blob/6886f2df/terminal.go#L431-L450
- https://golang.org/pkg/bufio#SplitFunc
英文:
To solve this, first I pulled visualLength
function from the
golang.org/x/term
package 1, then I wrote a bufio.SplitFunc
2 for this
use case.
package main
func ansi(data []byte, eof bool) (int, []byte, error) {
var s []rune
for i, r := range string(data) {
if s = append(s, r); visualLength(s) == 80 {
width := len(string(r))
return i+width, data[:i+width], nil
}
}
return 0, nil, nil
}
Result:
package main
import (
"bufio"
"golang.org/x/text/encoding/charmap"
"os"
)
func main() {
f, err := os.Open("LDA-PHASE90.ANS")
if err != nil {
panic(err)
}
defer f.Close()
s := bufio.NewScanner(charmap.CodePage437.NewDecoder().Reader(f))
s.Split(ansi)
for s.Scan() {
println(s.Text())
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论