summaryrefslogtreecommitdiff
path: root/vendor/github.com/alecthomas/chroma/v2/mutators.go
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-10-25 00:47:47 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-10-25 00:47:47 +0200
commitc6cc0108ca7738023b45e0eeac0fa2390532dd93 (patch)
tree36890e6cd3091bbab8efbe686cc56f467f645bfd /vendor/github.com/alecthomas/chroma/v2/mutators.go
parent0130404a1dc663d4aa68d780c9bcb23a4243e68d (diff)
downloadjbmafp-master.tar.gz
Added vendor lock on depsHEADmaster
Diffstat (limited to 'vendor/github.com/alecthomas/chroma/v2/mutators.go')
-rw-r--r--vendor/github.com/alecthomas/chroma/v2/mutators.go201
1 files changed, 201 insertions, 0 deletions
diff --git a/vendor/github.com/alecthomas/chroma/v2/mutators.go b/vendor/github.com/alecthomas/chroma/v2/mutators.go
new file mode 100644
index 0000000..ae648aa
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/mutators.go
@@ -0,0 +1,201 @@
+package chroma
+
+import (
+ "encoding/xml"
+ "fmt"
+ "strings"
+)
+
+// A Mutator modifies the behaviour of the lexer.
+type Mutator interface {
+ // Mutate the lexer state machine as it is processing.
+ Mutate(state *LexerState) error
+}
+
+// SerialisableMutator is a Mutator that can be serialised and deserialised.
+type SerialisableMutator interface {
+ Mutator
+ MutatorKind() string
+}
+
+// A LexerMutator is an additional interface that a Mutator can implement
+// to modify the lexer when it is compiled.
+type LexerMutator interface {
+ // MutateLexer can be implemented to mutate the lexer itself.
+ //
+ // Rules are the lexer rules, state is the state key for the rule the mutator is associated with.
+ MutateLexer(rules CompiledRules, state string, rule int) error
+}
+
+// A MutatorFunc is a Mutator that mutates the lexer state machine as it is processing.
+type MutatorFunc func(state *LexerState) error
+
+func (m MutatorFunc) Mutate(state *LexerState) error { return m(state) } // nolint
+
+type multiMutator struct {
+ Mutators []Mutator `xml:"mutator"`
+}
+
+func (m *multiMutator) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+ for {
+ token, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch token := token.(type) {
+ case xml.StartElement:
+ mutator, err := unmarshalMutator(d, token)
+ if err != nil {
+ return err
+ }
+ m.Mutators = append(m.Mutators, mutator)
+
+ case xml.EndElement:
+ return nil
+ }
+ }
+}
+
+func (m *multiMutator) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ name := xml.Name{Local: "mutators"}
+ if err := e.EncodeToken(xml.StartElement{Name: name}); err != nil {
+ return err
+ }
+ for _, m := range m.Mutators {
+ if err := marshalMutator(e, m); err != nil {
+ return err
+ }
+ }
+ return e.EncodeToken(xml.EndElement{Name: name})
+}
+
+func (m *multiMutator) MutatorKind() string { return "multiple" }
+
+func (m *multiMutator) Mutate(state *LexerState) error {
+ for _, modifier := range m.Mutators {
+ if err := modifier.Mutate(state); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// Mutators applies a set of Mutators in order.
+func Mutators(modifiers ...Mutator) Mutator {
+ return &multiMutator{modifiers}
+}
+
+type includeMutator struct {
+ State string `xml:"state,attr"`
+}
+
+// Include the given state.
+func Include(state string) Rule {
+ return Rule{Mutator: &includeMutator{state}}
+}
+
+func (i *includeMutator) MutatorKind() string { return "include" }
+
+func (i *includeMutator) Mutate(s *LexerState) error {
+ return fmt.Errorf("should never reach here Include(%q)", i.State)
+}
+
+func (i *includeMutator) MutateLexer(rules CompiledRules, state string, rule int) error {
+ includedRules, ok := rules[i.State]
+ if !ok {
+ return fmt.Errorf("invalid include state %q", i.State)
+ }
+ rules[state] = append(rules[state][:rule], append(includedRules, rules[state][rule+1:]...)...)
+ return nil
+}
+
+type combinedMutator struct {
+ States []string `xml:"state,attr"`
+}
+
+func (c *combinedMutator) MutatorKind() string { return "combined" }
+
+// Combined creates a new anonymous state from the given states, and pushes that state.
+func Combined(states ...string) Mutator {
+ return &combinedMutator{states}
+}
+
+func (c *combinedMutator) Mutate(s *LexerState) error {
+ return fmt.Errorf("should never reach here Combined(%v)", c.States)
+}
+
+func (c *combinedMutator) MutateLexer(rules CompiledRules, state string, rule int) error {
+ name := "__combined_" + strings.Join(c.States, "__")
+ if _, ok := rules[name]; !ok {
+ combined := []*CompiledRule{}
+ for _, state := range c.States {
+ rules, ok := rules[state]
+ if !ok {
+ return fmt.Errorf("invalid combine state %q", state)
+ }
+ combined = append(combined, rules...)
+ }
+ rules[name] = combined
+ }
+ rules[state][rule].Mutator = Push(name)
+ return nil
+}
+
+type pushMutator struct {
+ States []string `xml:"state,attr"`
+}
+
+func (p *pushMutator) MutatorKind() string { return "push" }
+
+func (p *pushMutator) Mutate(s *LexerState) error {
+ if len(p.States) == 0 {
+ s.Stack = append(s.Stack, s.State)
+ } else {
+ for _, state := range p.States {
+ if state == "#pop" {
+ s.Stack = s.Stack[:len(s.Stack)-1]
+ } else {
+ s.Stack = append(s.Stack, state)
+ }
+ }
+ }
+ return nil
+}
+
+// Push states onto the stack.
+func Push(states ...string) Mutator {
+ return &pushMutator{states}
+}
+
+type popMutator struct {
+ Depth int `xml:"depth,attr"`
+}
+
+func (p *popMutator) MutatorKind() string { return "pop" }
+
+func (p *popMutator) Mutate(state *LexerState) error {
+ if len(state.Stack) == 0 {
+ return fmt.Errorf("nothing to pop")
+ }
+ state.Stack = state.Stack[:len(state.Stack)-p.Depth]
+ return nil
+}
+
+// Pop state from the stack when rule matches.
+func Pop(n int) Mutator {
+ return &popMutator{n}
+}
+
+// Default returns a Rule that applies a set of Mutators.
+func Default(mutators ...Mutator) Rule {
+ return Rule{Mutator: Mutators(mutators...)}
+}
+
+// Stringify returns the raw string for a set of tokens.
+func Stringify(tokens ...Token) string {
+ out := []string{}
+ for _, t := range tokens {
+ out = append(out, t.Value)
+ }
+ return strings.Join(out, "")
+}