-
Notifications
You must be signed in to change notification settings - Fork 0
/
ansichroma.go
137 lines (108 loc) · 3.16 KB
/
ansichroma.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package ansichroma
import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/quick"
"github.com/alecthomas/chroma/v2/styles"
"github.com/charmbracelet/lipgloss"
)
type NotTextFile struct {
FileName string
}
// test
func (e *NotTextFile) Error() string {
return fmt.Sprintf("'%s' is not a text file", e.FileName)
}
// Hightlight text file. When linesToRead is 0. the complete file is read.
func HighlightFromFile(path string, linesToRead int, style, background string) (resultString string, err error) {
var buf bytes.Buffer
var fileContent string
var codeHighlight []chroma.Token
fileFullPath, err := filepath.Abs(path)
if err != nil {
return "", errors.New("this file path is invalid")
}
fileName := filepath.Base(fileFullPath)
lexer := lexers.Match(fileName)
if lexer == nil {
return "", &NotTextFile{FileName: fileName}
}
if linesToRead == 0 {
file, err := os.ReadFile(fileFullPath)
if err != nil {
return "", err
}
fileContent = string(file)
} else {
file, err := os.Open(fileFullPath)
if err != nil {
return "", err
}
defer file.Close()
scanner := bufio.NewScanner(file)
lineCount := 0
for scanner.Scan() {
fileContent += scanner.Text() + "\n"
lineCount++
if linesToRead > 0 && lineCount >= linesToRead {
break
}
}
if err := scanner.Err(); err != nil {
return "", err
}
}
if err := quick.Highlight(&buf, fileContent, lexer.Config().Name, "json", ""); err != nil {
return "", err
}
if err := json.Unmarshal(buf.Bytes(), &codeHighlight); err != nil {
return "", err
}
s := styles.Get(style)
for _, data := range codeHighlight {
color := s.Get(data.Type)
renderString, countLineBreaks := trimTrailingNewlines(data.Value)
colorStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color(color.Colour.String())).
Background(lipgloss.Color(background)).
Bold(getTrileanToBool(color.Bold)).
Italic(getTrileanToBool(color.Italic)).
Underline(getTrileanToBool(color.Underline))
resultString += colorStyle.Render(renderString)
resultString += strings.Repeat("\n", countLineBreaks)
}
return resultString, nil
}
// Hightlight text string.
func HightlightString(fileContent, format string, style, background string) (resultString string, err error) {
var buf bytes.Buffer
var codeHighlight []chroma.Token
if err := quick.Highlight(&buf, fileContent, format, "json", ""); err != nil {
return "", err
}
if err := json.Unmarshal(buf.Bytes(), &codeHighlight); err != nil {
return "", err
}
s := styles.Get(style)
for _, data := range codeHighlight {
color := s.Get(data.Type)
renderString, countLineBreaks := trimTrailingNewlines(data.Value)
colorStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color(color.Colour.String())).
Background(lipgloss.Color(background)).
Bold(getTrileanToBool(color.Bold)).
Italic(getTrileanToBool(color.Italic)).
Underline(getTrileanToBool(color.Underline))
resultString += colorStyle.Render(renderString)
resultString += strings.Repeat("\n", countLineBreaks)
}
return resultString, nil
}