summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/alecthomas/chroma/lexers/internal/api.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/alecthomas/chroma/lexers/internal/api.go')
-rw-r--r--vendor/github.com/alecthomas/chroma/lexers/internal/api.go201
1 files changed, 201 insertions, 0 deletions
diff --git a/vendor/github.com/alecthomas/chroma/lexers/internal/api.go b/vendor/github.com/alecthomas/chroma/lexers/internal/api.go
new file mode 100644
index 000000000..12fa45ff8
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/lexers/internal/api.go
@@ -0,0 +1,201 @@
+// Package internal contains common API functions and structures shared between lexer packages.
+package internal
+
+import (
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/alecthomas/chroma"
+)
+
+var (
+ ignoredSuffixes = [...]string{
+ // Editor backups
+ "~", ".bak", ".old", ".orig",
+ // Debian and derivatives apt/dpkg/ucf backups
+ ".dpkg-dist", ".dpkg-old", ".ucf-dist", ".ucf-new", ".ucf-old",
+ // Red Hat and derivatives rpm backups
+ ".rpmnew", ".rpmorig", ".rpmsave",
+ // Build system input/template files
+ ".in",
+ }
+)
+
+// Registry of Lexers.
+var Registry = struct {
+ Lexers chroma.Lexers
+ byName map[string]chroma.Lexer
+ byAlias map[string]chroma.Lexer
+}{
+ byName: map[string]chroma.Lexer{},
+ byAlias: map[string]chroma.Lexer{},
+}
+
+// Names of all lexers, optionally including aliases.
+func Names(withAliases bool) []string {
+ out := []string{}
+ for _, lexer := range Registry.Lexers {
+ config := lexer.Config()
+ out = append(out, config.Name)
+ if withAliases {
+ out = append(out, config.Aliases...)
+ }
+ }
+ sort.Strings(out)
+ return out
+}
+
+// Get a Lexer by name, alias or file extension.
+func Get(name string) chroma.Lexer {
+ if lexer := Registry.byName[name]; lexer != nil {
+ return lexer
+ }
+ if lexer := Registry.byAlias[name]; lexer != nil {
+ return lexer
+ }
+ if lexer := Registry.byName[strings.ToLower(name)]; lexer != nil {
+ return lexer
+ }
+ if lexer := Registry.byAlias[strings.ToLower(name)]; lexer != nil {
+ return lexer
+ }
+
+ candidates := chroma.PrioritisedLexers{}
+ // Try file extension.
+ if lexer := Match("filename." + name); lexer != nil {
+ candidates = append(candidates, lexer)
+ }
+ // Try exact filename.
+ if lexer := Match(name); lexer != nil {
+ candidates = append(candidates, lexer)
+ }
+ if len(candidates) == 0 {
+ return nil
+ }
+ sort.Sort(candidates)
+ return candidates[0]
+}
+
+// MatchMimeType attempts to find a lexer for the given MIME type.
+func MatchMimeType(mimeType string) chroma.Lexer {
+ matched := chroma.PrioritisedLexers{}
+ for _, l := range Registry.Lexers {
+ for _, lmt := range l.Config().MimeTypes {
+ if mimeType == lmt {
+ matched = append(matched, l)
+ }
+ }
+ }
+ if len(matched) != 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ return nil
+}
+
+// Match returns the first lexer matching filename.
+func Match(filename string) chroma.Lexer {
+ filename = filepath.Base(filename)
+ matched := chroma.PrioritisedLexers{}
+ // First, try primary filename matches.
+ for _, lexer := range Registry.Lexers {
+ config := lexer.Config()
+ for _, glob := range config.Filenames {
+ ok, err := filepath.Match(glob, filename)
+ if err != nil { // nolint
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ } else {
+ for _, suf := range &ignoredSuffixes {
+ ok, err := filepath.Match(glob+suf, filename)
+ if err != nil {
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ break
+ }
+ }
+ }
+ }
+ }
+ if len(matched) > 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ matched = nil
+ // Next, try filename aliases.
+ for _, lexer := range Registry.Lexers {
+ config := lexer.Config()
+ for _, glob := range config.AliasFilenames {
+ ok, err := filepath.Match(glob, filename)
+ if err != nil { // nolint
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ } else {
+ for _, suf := range &ignoredSuffixes {
+ ok, err := filepath.Match(glob+suf, filename)
+ if err != nil {
+ panic(err)
+ } else if ok {
+ matched = append(matched, lexer)
+ break
+ }
+ }
+ }
+ }
+ }
+ if len(matched) > 0 {
+ sort.Sort(matched)
+ return matched[0]
+ }
+ return nil
+}
+
+// Analyse text content and return the "best" lexer..
+func Analyse(text string) chroma.Lexer {
+ var picked chroma.Lexer
+ highest := float32(0.0)
+ for _, lexer := range Registry.Lexers {
+ if analyser, ok := lexer.(chroma.Analyser); ok {
+ weight := analyser.AnalyseText(text)
+ if weight > highest {
+ picked = lexer
+ highest = weight
+ }
+ }
+ }
+ return picked
+}
+
+// Register a Lexer with the global registry.
+func Register(lexer chroma.Lexer) chroma.Lexer {
+ config := lexer.Config()
+ Registry.byName[config.Name] = lexer
+ Registry.byName[strings.ToLower(config.Name)] = lexer
+ for _, alias := range config.Aliases {
+ Registry.byAlias[alias] = lexer
+ Registry.byAlias[strings.ToLower(alias)] = lexer
+ }
+ Registry.Lexers = append(Registry.Lexers, lexer)
+ return lexer
+}
+
+// PlaintextRules is used for the fallback lexer as well as the explicit
+// plaintext lexer.
+func PlaintextRules() chroma.Rules {
+ return chroma.Rules{
+ "root": []chroma.Rule{
+ {`.+`, chroma.Text, nil},
+ {`\n`, chroma.Text, nil},
+ },
+ }
+}
+
+// Fallback lexer if no other is found.
+var Fallback chroma.Lexer = chroma.MustNewLazyLexer(&chroma.Config{
+ Name: "fallback",
+ Filenames: []string{"*"},
+}, PlaintextRules)