mirror of
https://github.com/rwinkhart/go-highlite.git
synced 2026-09-05 16:37:20 -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
|
## Basic Usage
|
||||||
Below is a simple example for highlighting a string (a Go snippet in this case).
|
Below is a simple example for highlighting a Go snippet with ANSI colors.
|
||||||
It uses `github.com/fatih/color` to actually colorize the output to the console.
|
|
||||||
|
|
||||||
It must be built with `-tags=stxGo` or `-tags=stxAll` to include the Go syntax layer.
|
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
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"os"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/rwinkhart/go-highlite/ansi"
|
||||||
"github.com/rwinkhart/go-highlite"
|
|
||||||
"github.com/rwinkhart/go-highlite/syntax"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Here is the go code we will highlight
|
// Here is the go code we will highlight
|
||||||
inputString := `package main
|
inputString := `package main
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
@@ -55,86 +55,12 @@ func helloWorld() {
|
|||||||
fmt.Println("Hello world")
|
fmt.Println("Hello world")
|
||||||
}`
|
}`
|
||||||
|
|
||||||
// Load and parse the go syntax layer into a `*highlight.Def`
|
result, err := ansi.Colorize(inputString, "go")
|
||||||
syntaxDef, err := highlite.ParseDef(syntax.Get("go"))
|
if err != nil {
|
||||||
if err != nil {
|
fmt.Println("Failed to colorize input: " + err.Error())
|
||||||
fmt.Println(err)
|
os.Exit(1)
|
||||||
return
|
}
|
||||||
}
|
fmt.Println(result)
|
||||||
|
|
||||||
// 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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -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