mirror of
https://github.com/rwinkhart/go-highlite.git
synced 2026-08-30 05:46:28 -04:00
Add "ansi" package and "ansi.Colorize" function for quickly highlighting code strings
This commit is contained in:
@@ -27,26 +27,26 @@ $ go get github.com/rwinkhart/go-highlite
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
Below is a simple example for highlighting a string (a Go snippet in this case).
|
||||
It uses `github.com/fatih/color` to actually colorize the output to the console.
|
||||
Below is a simple example for highlighting a Go snippet with ANSI colors.
|
||||
|
||||
It must be built with `-tags=stxGo` or `-tags=stxAll` to include the Go syntax layer.
|
||||
|
||||
For a more advanced example on manually colorizing the output or colorizing it in a
|
||||
different, non-ANSI format, see the `ansi.Colorize` function.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/rwinkhart/go-highlite"
|
||||
"github.com/rwinkhart/go-highlite/syntax"
|
||||
"github.com/rwinkhart/go-highlite/ansi"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Here is the go code we will highlight
|
||||
inputString := `package main
|
||||
// Here is the go code we will highlight
|
||||
inputString := `package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
@@ -55,86 +55,12 @@ func helloWorld() {
|
||||
fmt.Println("Hello world")
|
||||
}`
|
||||
|
||||
// Load and parse the go syntax layer into a `*highlight.Def`
|
||||
syntaxDef, err := highlite.ParseDef(syntax.Get("go"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Make a new highlighter from the definition
|
||||
h := highlite.NewHighlighter(syntaxDef)
|
||||
|
||||
// Highlight the string
|
||||
// Matches is an array of maps which point to groups
|
||||
// matches[lineNum][colNum] will give you the change in group at that line and column number
|
||||
// Note that there is only a group at a line and column number if the syntax highlighting changed at that position
|
||||
matches := h.HighlightString(inputString)
|
||||
|
||||
// We split the string into a bunch of lines
|
||||
// Now we will print the string
|
||||
lines := strings.Split(inputString, "\n")
|
||||
for lineN, l := range lines {
|
||||
colN := 0
|
||||
for _, c := range l {
|
||||
if group, ok := matches[lineN][colN]; ok {
|
||||
switch group {
|
||||
case highlite.Groups["statement"]:
|
||||
fallthrough
|
||||
case highlite.Groups["green"]:
|
||||
color.Set(color.FgGreen)
|
||||
|
||||
case highlite.Groups["identifier"]:
|
||||
fallthrough
|
||||
case highlite.Groups["blue"]:
|
||||
color.Set(color.FgHiBlue)
|
||||
|
||||
case highlite.Groups["preproc"]:
|
||||
color.Set(color.FgHiRed)
|
||||
|
||||
case highlite.Groups["special"]:
|
||||
fallthrough
|
||||
case highlite.Groups["red"]:
|
||||
color.Set(color.FgRed)
|
||||
|
||||
case highlite.Groups["constant.string"]:
|
||||
fallthrough
|
||||
case highlite.Groups["constant"]:
|
||||
fallthrough
|
||||
case highlite.Groups["constant.number"]:
|
||||
fallthrough
|
||||
case highlite.Groups["cyan"]:
|
||||
color.Set(color.FgCyan)
|
||||
|
||||
case highlite.Groups["constant.specialChar"]:
|
||||
fallthrough
|
||||
case highlite.Groups["magenta"]:
|
||||
color.Set(color.FgHiMagenta)
|
||||
|
||||
case highlite.Groups["type"]:
|
||||
fallthrough
|
||||
case highlite.Groups["yellow"]:
|
||||
color.Set(color.FgYellow)
|
||||
|
||||
case highlite.Groups["comment"]:
|
||||
fallthrough
|
||||
case highlite.Groups["high.green"]:
|
||||
color.Set(color.FgHiGreen)
|
||||
default:
|
||||
color.Unset()
|
||||
}
|
||||
}
|
||||
fmt.Print(string(c))
|
||||
colN++
|
||||
}
|
||||
if group, ok := matches[lineN][colN]; ok {
|
||||
if group == highlite.Groups["default"] || group == highlite.Groups[""] {
|
||||
color.Unset()
|
||||
}
|
||||
}
|
||||
|
||||
color.Unset()
|
||||
fmt.Print("\n")
|
||||
}
|
||||
result, err := ansi.Colorize(inputString, "go")
|
||||
if err != nil {
|
||||
fmt.Println("Failed to colorize input: " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package ansi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/rwinkhart/go-highlite"
|
||||
"github.com/rwinkhart/go-highlite/syntax"
|
||||
)
|
||||
|
||||
// Colorize takes a string of code and a language ID, and returns the code
|
||||
// with ANSI color codes applied for syntax highlighting.
|
||||
func Colorize(inputCode, languageID string) (string, error) {
|
||||
// Load and parse the go syntax layer into a `*highlight.Def`
|
||||
syntaxDef, err := highlite.ParseDef(syntax.Get(languageID))
|
||||
if err != nil {
|
||||
return "", errors.New("unable to parse syntax layer: " + err.Error())
|
||||
}
|
||||
|
||||
// Make a new highlighter from the definition
|
||||
h := highlite.NewHighlighter(syntaxDef)
|
||||
|
||||
// Highlight the string
|
||||
matches := h.HighlightString(inputCode)
|
||||
|
||||
// We split the string into a bunch of lines
|
||||
lines := strings.Split(inputCode, "\n")
|
||||
var outputString strings.Builder
|
||||
|
||||
for lineN, l := range lines {
|
||||
colN := 0
|
||||
for _, c := range l {
|
||||
if group, ok := matches[lineN][colN]; ok {
|
||||
var colorCode string
|
||||
switch group {
|
||||
case highlite.Groups["statement"], highlite.Groups["green"]:
|
||||
colorCode = "\033[32m" // Green
|
||||
case highlite.Groups["identifier"], highlite.Groups["blue"]:
|
||||
colorCode = "\033[94m" // Bright Blue
|
||||
case highlite.Groups["preproc"]:
|
||||
colorCode = "\033[91m" // Bright Red
|
||||
case highlite.Groups["special"], highlite.Groups["red"]:
|
||||
colorCode = "\033[31m" // Red
|
||||
case highlite.Groups["constant.string"], highlite.Groups["constant"],
|
||||
highlite.Groups["constant.number"], highlite.Groups["cyan"]:
|
||||
colorCode = "\033[36m" // Cyan
|
||||
case highlite.Groups["constant.specialChar"], highlite.Groups["magenta"]:
|
||||
colorCode = "\033[95m" // Bright Magenta
|
||||
case highlite.Groups["type"], highlite.Groups["yellow"]:
|
||||
colorCode = "\033[33m" // Yellow
|
||||
case highlite.Groups["comment"], highlite.Groups["high.green"]:
|
||||
colorCode = "\033[92m" // Bright Green
|
||||
default:
|
||||
colorCode = "\033[0m" // Reset
|
||||
}
|
||||
outputString.WriteString(colorCode)
|
||||
}
|
||||
outputString.WriteRune(c)
|
||||
colN++
|
||||
}
|
||||
outputString.WriteString("\033[0m") // Reset colors at end of line
|
||||
if lineN < len(lines)-1 { // Don't add newline after last line
|
||||
outputString.WriteRune('\n')
|
||||
}
|
||||
}
|
||||
return outputString.String(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user