diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca99310 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Binaries for programs and plugins +.git +.idea +.vscode +.hermit +*.exe +*.dll +*.so +*.dylib +/cmd/chroma/chroma + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +_models/ + +_examples/ +*.min.* +build/ \ No newline at end of file diff --git a/base16/base16.go b/base16/base16.go new file mode 100644 index 0000000..98f9336 --- /dev/null +++ b/base16/base16.go @@ -0,0 +1,138 @@ +package base16 + +import ( + "io" + + "gopkg.in/yaml.v3" + "toastielab.dev/toastie-stuff/chroma/v2" +) + +type Base16 struct { + // Scheme is the name of the scheme. + Scheme string `yaml:"scheme"` + // Author is the name of the author. + Author string `yaml:"author"` + // Theme is either "light" or "dark". + Theme string `yaml:"theme"` + // Base00 Default Background + Base00 string `yaml:"base00"` + // Base01 Lighter Background (Used for status bars, line number and folding marks) + Base01 string `yaml:"base01"` + // Base02 Selection Background + Base02 string `yaml:"base02"` + // Base03 Comments, Invisibles, Line Highlighting + Base03 string `yaml:"base03"` + // Base04 Dark Foreground (Used for status bars) + Base04 string `yaml:"base04"` + // Base05 Default Foreground, Caret, Delimiters, Operators + Base05 string `yaml:"base05"` + // Base06 Light Foreground (Not often used) + Base06 string `yaml:"base06"` + // Base07 Light Background (Not often used) + Base07 string `yaml:"base07"` + // Base08 Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted + Base08 string `yaml:"base08"` + // Base09 Integers, Boolean, Constants, XML Attributes, Markup Link Url + Base09 string `yaml:"base09"` + // Base0A Classes, Markup Bold, Search Text Background + Base0A string `yaml:"base0A"` + // Base0B Strings, Inherited Class, Markup Code, Diff Inserted + Base0B string `yaml:"base0B"` + // Base0C Support, Regular Expressions, Escape Characters, Markup Quotes + Base0C string `yaml:"base0C"` + // Base0D Functions, Methods, Attribute IDs, Headings + Base0D string `yaml:"base0D"` + // Base0E Keywords, Storage, Selector, Markup Italic, Diff Changed + Base0E string `yaml:"base0E"` + // Base0F Deprecated, Opening/Closing Embedded Language Tags, e.g. `<?php ?>` + Base0F string `yaml:"base0F"` +} + +func (b *Base16) toStyle() (*chroma.Style, error) { + entries := chroma.StyleEntries{ + chroma.Other: "#" + b.Base05, + chroma.Error: "#" + b.Base08, + chroma.Background: "bg:" + "#" + b.Base00, + chroma.Keyword: "#" + b.Base0E, + chroma.KeywordConstant: "#" + b.Base0E, + chroma.KeywordDeclaration: "#" + b.Base08, + chroma.KeywordNamespace: "#" + b.Base0E, + chroma.KeywordPseudo: "#" + b.Base0E, + chroma.KeywordReserved: "#" + b.Base0E, + chroma.KeywordType: "#" + b.Base0C, + chroma.Name: "#" + b.Base05, + chroma.NameAttribute: "#" + b.Base0D, + chroma.NameBuiltin: "#" + b.Base08, + chroma.NameBuiltinPseudo: "#" + b.Base05, + chroma.NameClass: "#" + b.Base0A, + chroma.NameConstant: "#" + b.Base09, + chroma.NameDecorator: "#" + b.Base09, + chroma.NameEntity: "#" + b.Base05, + chroma.NameException: "#" + b.Base05, + chroma.NameFunction: "#" + b.Base0D, + chroma.NameLabel: "#" + b.Base08, + chroma.NameNamespace: "#" + b.Base05, + chroma.NameOther: "#" + b.Base05, + chroma.NameTag: "#" + b.Base0E, + chroma.NameVariable: "#" + b.Base08, + chroma.NameVariableClass: "#" + b.Base08, + chroma.NameVariableGlobal: "#" + b.Base08, + chroma.NameVariableInstance: "#" + b.Base08, + chroma.Literal: "#" + b.Base05, + chroma.LiteralDate: "#" + b.Base05, + chroma.LiteralString: "#" + b.Base0B, + chroma.LiteralStringBacktick: "#" + b.Base0B, + chroma.LiteralStringChar: "#" + b.Base0B, + chroma.LiteralStringDoc: "#" + b.Base0B, + chroma.LiteralStringDouble: "#" + b.Base0B, + chroma.LiteralStringEscape: "#" + b.Base0B, + chroma.LiteralStringHeredoc: "#" + b.Base0B, + chroma.LiteralStringInterpol: "#" + b.Base0B, + chroma.LiteralStringOther: "#" + b.Base0B, + chroma.LiteralStringRegex: "#" + b.Base0B, + chroma.LiteralStringSingle: "#" + b.Base0B, + chroma.LiteralStringSymbol: "#" + b.Base0B, + chroma.LiteralNumber: "#" + b.Base09, + chroma.LiteralNumberBin: "#" + b.Base09, + chroma.LiteralNumberFloat: "#" + b.Base09, + chroma.LiteralNumberHex: "#" + b.Base09, + chroma.LiteralNumberInteger: "#" + b.Base09, + chroma.LiteralNumberIntegerLong: "#" + b.Base09, + chroma.LiteralNumberOct: "#" + b.Base09, + chroma.Operator: "#" + b.Base0E, + chroma.OperatorWord: "#" + b.Base0E, + chroma.Punctuation: "#" + b.Base05, + chroma.Comment: "#" + b.Base03, + chroma.CommentHashbang: "#" + b.Base03, + chroma.CommentMultiline: "#" + b.Base03, + chroma.CommentSingle: "#" + b.Base03, + chroma.CommentSpecial: "#" + b.Base03, + chroma.CommentPreproc: "#" + b.Base03, + chroma.Generic: "#" + b.Base05, + chroma.GenericDeleted: "#" + b.Base08, + chroma.GenericEmph: "underline #" + b.Base05, + chroma.GenericError: "#" + b.Base08, + chroma.GenericHeading: "bold #" + b.Base05, + chroma.GenericInserted: "bold #" + b.Base05, + chroma.GenericOutput: "#" + b.Base02, + chroma.GenericPrompt: "#" + b.Base05, + chroma.GenericStrong: "italic #" + b.Base05, + chroma.GenericSubheading: "bold #" + b.Base05, + chroma.GenericTraceback: "#" + b.Base05, + chroma.GenericUnderline: "underline", + chroma.Text: "#" + b.Base05, + chroma.TextWhitespace: "#" + b.Base05, + } + + return chroma.NewStyle(b.Scheme, b.Theme, entries) +} + +func NewStyle(r io.Reader) (*chroma.Style, error) { + dec := yaml.NewDecoder(r) + b16 := &Base16{} + if err := dec.Decode(b16); err != nil { + return nil, err + } + + return b16.toStyle() +} diff --git a/coalesce.go b/coalesce.go new file mode 100644 index 0000000..f504895 --- /dev/null +++ b/coalesce.go @@ -0,0 +1,35 @@ +package chroma + +// Coalesce is a Lexer interceptor that collapses runs of common types into a single token. +func Coalesce(lexer Lexer) Lexer { return &coalescer{lexer} } + +type coalescer struct{ Lexer } + +func (d *coalescer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { + var prev Token + it, err := d.Lexer.Tokenise(options, text) + if err != nil { + return nil, err + } + return func() Token { + for token := it(); token != (EOF); token = it() { + if len(token.Value) == 0 { + continue + } + if prev == EOF { + prev = token + } else { + if prev.Type == token.Type && len(prev.Value) < 8192 { + prev.Value += token.Value + } else { + out := prev + prev = token + return out + } + } + } + out := prev + prev = EOF + return out + }, nil +} diff --git a/coalesce_test.go b/coalesce_test.go new file mode 100644 index 0000000..fc39cb8 --- /dev/null +++ b/coalesce_test.go @@ -0,0 +1,19 @@ +package chroma + +import ( + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestCoalesce(t *testing.T) { + lexer := Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": []Rule{ + {`[!@#$%^&*()]`, Punctuation, nil}, + }, + })) + actual, err := Tokenise(lexer, nil, "!@#$") + assert.NoError(t, err) + expected := []Token{{Punctuation, "!@#$"}} + assert.Equal(t, expected, actual) +} diff --git a/colour.go b/colour.go new file mode 100644 index 0000000..b7fd6e0 --- /dev/null +++ b/colour.go @@ -0,0 +1,192 @@ +package chroma + +import ( + "fmt" + "math" + "strconv" + "strings" +) + +// ANSI2RGB maps ANSI colour names, as supported by Chroma, to hex RGB values. +var ANSI2RGB = map[string]string{ + "#ansiblack": "000000", + "#ansidarkred": "7f0000", + "#ansidarkgreen": "007f00", + "#ansibrown": "7f7fe0", + "#ansidarkblue": "00007f", + "#ansipurple": "7f007f", + "#ansiteal": "007f7f", + "#ansilightgray": "e5e5e5", + // Normal + "#ansidarkgray": "555555", + "#ansired": "ff0000", + "#ansigreen": "00ff00", + "#ansiyellow": "ffff00", + "#ansiblue": "0000ff", + "#ansifuchsia": "ff00ff", + "#ansiturquoise": "00ffff", + "#ansiwhite": "ffffff", + + // Aliases without the "ansi" prefix, because...why? + "#black": "000000", + "#darkred": "7f0000", + "#darkgreen": "007f00", + "#brown": "7f7fe0", + "#darkblue": "00007f", + "#purple": "7f007f", + "#teal": "007f7f", + "#lightgray": "e5e5e5", + // Normal + "#darkgray": "555555", + "#red": "ff0000", + "#green": "00ff00", + "#yellow": "ffff00", + "#blue": "0000ff", + "#fuchsia": "ff00ff", + "#turquoise": "00ffff", + "#white": "ffffff", +} + +// Colour represents an RGB colour. +type Colour int32 + +// NewColour creates a Colour directly from RGB values. +func NewColour(r, g, b uint8) Colour { + return ParseColour(fmt.Sprintf("%02x%02x%02x", r, g, b)) +} + +// Distance between this colour and another. +// +// This uses the approach described here (https://www.compuphase.com/cmetric.htm). +// This is not as accurate as LAB, et. al. but is *vastly* simpler and sufficient for our needs. +func (c Colour) Distance(e2 Colour) float64 { + ar, ag, ab := int64(c.Red()), int64(c.Green()), int64(c.Blue()) + br, bg, bb := int64(e2.Red()), int64(e2.Green()), int64(e2.Blue()) + rmean := (ar + br) / 2 + r := ar - br + g := ag - bg + b := ab - bb + return math.Sqrt(float64((((512 + rmean) * r * r) >> 8) + 4*g*g + (((767 - rmean) * b * b) >> 8))) +} + +// Brighten returns a copy of this colour with its brightness adjusted. +// +// If factor is negative, the colour is darkened. +// +// Uses approach described here (http://www.pvladov.com/2012/09/make-color-lighter-or-darker.html). +func (c Colour) Brighten(factor float64) Colour { + r := float64(c.Red()) + g := float64(c.Green()) + b := float64(c.Blue()) + + if factor < 0 { + factor++ + r *= factor + g *= factor + b *= factor + } else { + r = (255-r)*factor + r + g = (255-g)*factor + g + b = (255-b)*factor + b + } + return NewColour(uint8(r), uint8(g), uint8(b)) +} + +// BrightenOrDarken brightens a colour if it is < 0.5 brightness or darkens if > 0.5 brightness. +func (c Colour) BrightenOrDarken(factor float64) Colour { + if c.Brightness() < 0.5 { + return c.Brighten(factor) + } + return c.Brighten(-factor) +} + +// ClampBrightness returns a copy of this colour with its brightness adjusted such that +// it falls within the range [min, max] (or very close to it due to rounding errors). +// The supplied values use the same [0.0, 1.0] range as Brightness. +func (c Colour) ClampBrightness(min, max float64) Colour { + if !c.IsSet() { + return c + } + + min = math.Max(min, 0) + max = math.Min(max, 1) + current := c.Brightness() + target := math.Min(math.Max(current, min), max) + if current == target { + return c + } + + r := float64(c.Red()) + g := float64(c.Green()) + b := float64(c.Blue()) + rgb := r + g + b + if target > current { + // Solve for x: target == ((255-r)*x + r + (255-g)*x + g + (255-b)*x + b) / 255 / 3 + return c.Brighten((target*255*3 - rgb) / (255*3 - rgb)) + } + // Solve for x: target == (r*(x+1) + g*(x+1) + b*(x+1)) / 255 / 3 + return c.Brighten((target*255*3)/rgb - 1) +} + +// Brightness of the colour (roughly) in the range 0.0 to 1.0. +func (c Colour) Brightness() float64 { + return (float64(c.Red()) + float64(c.Green()) + float64(c.Blue())) / 255.0 / 3.0 +} + +// ParseColour in the forms #rgb, #rrggbb, #ansi<colour>, or #<colour>. +// Will return an "unset" colour if invalid. +func ParseColour(colour string) Colour { + colour = normaliseColour(colour) + n, err := strconv.ParseUint(colour, 16, 32) + if err != nil { + return 0 + } + return Colour(n + 1) +} + +// MustParseColour is like ParseColour except it panics if the colour is invalid. +// +// Will panic if colour is in an invalid format. +func MustParseColour(colour string) Colour { + parsed := ParseColour(colour) + if !parsed.IsSet() { + panic(fmt.Errorf("invalid colour %q", colour)) + } + return parsed +} + +// IsSet returns true if the colour is set. +func (c Colour) IsSet() bool { return c != 0 } + +func (c Colour) String() string { return fmt.Sprintf("#%06x", int(c-1)) } +func (c Colour) GoString() string { return fmt.Sprintf("Colour(0x%06x)", int(c-1)) } + +// Red component of colour. +func (c Colour) Red() uint8 { return uint8(((c - 1) >> 16) & 0xff) } + +// Green component of colour. +func (c Colour) Green() uint8 { return uint8(((c - 1) >> 8) & 0xff) } + +// Blue component of colour. +func (c Colour) Blue() uint8 { return uint8((c - 1) & 0xff) } + +// Colours is an orderable set of colours. +type Colours []Colour + +func (c Colours) Len() int { return len(c) } +func (c Colours) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +func (c Colours) Less(i, j int) bool { return c[i] < c[j] } + +// Convert colours to #rrggbb. +func normaliseColour(colour string) string { + if ansi, ok := ANSI2RGB[colour]; ok { + return ansi + } + if strings.HasPrefix(colour, "#") { + colour = colour[1:] + if len(colour) == 3 { + return colour[0:1] + colour[0:1] + colour[1:2] + colour[1:2] + colour[2:3] + colour[2:3] + } + } + return colour +} diff --git a/colour_test.go b/colour_test.go new file mode 100644 index 0000000..8d75f64 --- /dev/null +++ b/colour_test.go @@ -0,0 +1,91 @@ +package chroma + +import ( + "math" + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestColourRGB(t *testing.T) { + colour := ParseColour("#8913af") + assert.Equal(t, uint8(0x89), colour.Red()) + assert.Equal(t, uint8(0x13), colour.Green()) + assert.Equal(t, uint8(0xaf), colour.Blue()) +} + +func TestColourString(t *testing.T) { + assert.Equal(t, "#8913af", ParseColour("#8913af").String()) +} + +func distance(a, b uint8) uint8 { + if a < b { + return b - a + } + return a - b +} + +func TestColourBrighten(t *testing.T) { + actual := NewColour(128, 128, 128).Brighten(0.5) + // Closeish to what we expect is fine. + assert.True(t, distance(192, actual.Red()) <= 2) + assert.True(t, distance(192, actual.Blue()) <= 2) + assert.True(t, distance(192, actual.Green()) <= 2) + actual = NewColour(128, 128, 128).Brighten(-0.5) + assert.True(t, distance(65, actual.Red()) <= 2) + assert.True(t, distance(65, actual.Blue()) <= 2) + assert.True(t, distance(65, actual.Green()) <= 2) +} + +func TestColourBrightess(t *testing.T) { + actual := NewColour(128, 128, 128).Brightness() + assert.True(t, distance(128, uint8(actual*255.0)) <= 2) +} + +// hue returns c's hue. See https://stackoverflow.com/a/23094494. +func hue(c Colour) float64 { + r := float64(c.Red()) / 255 + g := float64(c.Green()) / 255 + b := float64(c.Blue()) / 255 + + min := math.Min(math.Min(r, g), b) + max := math.Max(math.Max(r, g), b) + + switch { + case r == min: + return (g - b) / (max - min) + case g == min: + return 2 + (b-r)/(max-min) + default: + return 4 + (r-g)/(max-min) + } +} + +func TestColourClampBrightness(t *testing.T) { + // Start with a colour with a brightness close to 0.5. + initial := NewColour(0, 128, 255) + br := initial.Brightness() + assertInDelta(t, 0.5, br) + + // Passing a range that includes the colour's brightness should be a no-op. + assert.Equal(t, initial.String(), initial.ClampBrightness(br-0.01, br+0.01).String()) + + // Clamping to [0, 0] or [1, 1] should produce black or white, respectively. + assert.Equal(t, "#000000", initial.ClampBrightness(0, 0).String()) + assert.Equal(t, "#ffffff", initial.ClampBrightness(1, 1).String()) + + // Clamping to a brighter or darker range should produce the requested + // brightness while preserving the colour's hue. + brighter := initial.ClampBrightness(0.75, 1) + assertInDelta(t, 0.75, brighter.Brightness()) + assertInDelta(t, hue(initial), hue(brighter)) + + darker := initial.ClampBrightness(0, 0.25) + assertInDelta(t, 0.25, darker.Brightness()) + assertInDelta(t, hue(initial), hue(darker)) +} + +func assertInDelta(t *testing.T, expected, actual float64) { + const delta = 0.01 // used for brightness and hue comparisons + assert.True(t, actual > (expected-delta) && actual < (expected+delta)) +} diff --git a/delegate.go b/delegate.go new file mode 100644 index 0000000..f848194 --- /dev/null +++ b/delegate.go @@ -0,0 +1,152 @@ +package chroma + +import ( + "bytes" +) + +type delegatingLexer struct { + root Lexer + language Lexer +} + +// DelegatingLexer combines two lexers to handle the common case of a language embedded inside another, such as PHP +// inside HTML or PHP inside plain text. +// +// It takes two lexer as arguments: a root lexer and a language lexer. First everything is scanned using the language +// lexer, which must return "Other" for unrecognised tokens. Then all "Other" tokens are lexed using the root lexer. +// Finally, these two sets of tokens are merged. +// +// The lexers from the template lexer package use this base lexer. +func DelegatingLexer(root Lexer, language Lexer) Lexer { + return &delegatingLexer{ + root: root, + language: language, + } +} + +func (d *delegatingLexer) AnalyseText(text string) float32 { + return d.root.AnalyseText(text) +} + +func (d *delegatingLexer) SetAnalyser(analyser func(text string) float32) Lexer { + d.root.SetAnalyser(analyser) + return d +} + +func (d *delegatingLexer) SetRegistry(r *LexerRegistry) Lexer { + d.root.SetRegistry(r) + d.language.SetRegistry(r) + return d +} + +func (d *delegatingLexer) Config() *Config { + return d.language.Config() +} + +// An insertion is the character range where language tokens should be inserted. +type insertion struct { + start, end int + tokens []Token +} + +func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit + tokens, err := Tokenise(Coalesce(d.language), options, text) + if err != nil { + return nil, err + } + // Compute insertions and gather "Other" tokens. + others := &bytes.Buffer{} + insertions := []*insertion{} + var insert *insertion + offset := 0 + var last Token + for _, t := range tokens { + if t.Type == Other { + if last != EOF && insert != nil && last.Type != Other { + insert.end = offset + } + others.WriteString(t.Value) + } else { + if last == EOF || last.Type == Other { + insert = &insertion{start: offset} + insertions = append(insertions, insert) + } + insert.tokens = append(insert.tokens, t) + } + last = t + offset += len(t.Value) + } + + if len(insertions) == 0 { + return d.root.Tokenise(options, text) + } + + // Lex the other tokens. + rootTokens, err := Tokenise(Coalesce(d.root), options, others.String()) + if err != nil { + return nil, err + } + + // Interleave the two sets of tokens. + var out []Token + offset = 0 // Offset into text. + tokenIndex := 0 + nextToken := func() Token { + if tokenIndex >= len(rootTokens) { + return EOF + } + t := rootTokens[tokenIndex] + tokenIndex++ + return t + } + insertionIndex := 0 + nextInsertion := func() *insertion { + if insertionIndex >= len(insertions) { + return nil + } + i := insertions[insertionIndex] + insertionIndex++ + return i + } + t := nextToken() + i := nextInsertion() + for t != EOF || i != nil { + // fmt.Printf("%d->%d:%q %d->%d:%q\n", offset, offset+len(t.Value), t.Value, i.start, i.end, Stringify(i.tokens...)) + if t == EOF || (i != nil && i.start < offset+len(t.Value)) { + var l Token + l, t = splitToken(t, i.start-offset) + if l != EOF { + out = append(out, l) + offset += len(l.Value) + } + out = append(out, i.tokens...) + offset += i.end - i.start + if t == EOF { + t = nextToken() + } + i = nextInsertion() + } else { + out = append(out, t) + offset += len(t.Value) + t = nextToken() + } + } + return Literator(out...), nil +} + +func splitToken(t Token, offset int) (l Token, r Token) { + if t == EOF { + return EOF, EOF + } + if offset == 0 { + return EOF, t + } + if offset == len(t.Value) { + return t, EOF + } + l = t.Clone() + r = t.Clone() + l.Value = l.Value[:offset] + r.Value = r.Value[offset:] + return +} diff --git a/delegate_test.go b/delegate_test.go new file mode 100644 index 0000000..9c4a09b --- /dev/null +++ b/delegate_test.go @@ -0,0 +1,111 @@ +package chroma + +import ( + "testing" + + "github.com/alecthomas/assert/v2" +) + +func makeDelegationTestLexers(t *testing.T) (lang Lexer, root Lexer) { + return mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + {`\<\?`, CommentPreproc, Push("inside")}, + {`.`, Other, nil}, + }, + "inside": { + {`\?\>`, CommentPreproc, Pop(1)}, + {`\bwhat\b`, Keyword, nil}, + {`\s+`, Whitespace, nil}, + }, + }), + mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + {`\bhello\b`, Keyword, nil}, + {`\b(world|there)\b`, Name, nil}, + {`\s+`, Whitespace, nil}, + }, + }) +} + +func TestDelegate(t *testing.T) { + testdata := []struct { + name string + source string + expected []Token + }{ + {"SourceInMiddle", `hello world <? what ?> there`, []Token{ + {Keyword, "hello"}, + {TextWhitespace, " "}, + {Name, "world"}, + {TextWhitespace, " "}, + // lang + {CommentPreproc, "<?"}, + {Whitespace, " "}, + {Keyword, "what"}, + {Whitespace, " "}, + {CommentPreproc, "?>"}, + // /lang + {TextWhitespace, " "}, + {Name, "there"}, + }}, + {"SourceBeginning", `<? what ?> hello world there`, []Token{ + {CommentPreproc, "<?"}, + {TextWhitespace, " "}, + {Keyword, "what"}, + {TextWhitespace, " "}, + {CommentPreproc, "?>"}, + {TextWhitespace, " "}, + {Keyword, "hello"}, + {TextWhitespace, " "}, + {Name, "world"}, + {TextWhitespace, " "}, + {Name, "there"}, + }}, + {"SourceEnd", `hello world <? what there`, []Token{ + {Keyword, "hello"}, + {TextWhitespace, " "}, + {Name, "world"}, + {TextWhitespace, " "}, + // lang + {CommentPreproc, "<?"}, + {Whitespace, " "}, + {Keyword, "what"}, + {TextWhitespace, " "}, + {Error, "there"}, + }}, + {"SourceMultiple", "hello world <? what ?> hello there <? what ?> hello", []Token{ + {Keyword, "hello"}, + {TextWhitespace, " "}, + {Name, "world"}, + {TextWhitespace, " "}, + {CommentPreproc, "<?"}, + {TextWhitespace, " "}, + {Keyword, "what"}, + {TextWhitespace, " "}, + {CommentPreproc, "?>"}, + {TextWhitespace, " "}, + {Keyword, "hello"}, + {TextWhitespace, " "}, + {Name, "there"}, + {TextWhitespace, " "}, + {CommentPreproc, "<?"}, + {TextWhitespace, " "}, + {Keyword, "what"}, + {TextWhitespace, " "}, + {CommentPreproc, "?>"}, + {TextWhitespace, " "}, + {Keyword, "hello"}, + }}, + } + lang, root := makeDelegationTestLexers(t) + delegate := DelegatingLexer(root, lang) + for _, test := range testdata { + // nolint: scopelint + t.Run(test.name, func(t *testing.T) { + it, err := delegate.Tokenise(nil, test.source) + assert.NoError(t, err) + actual := it.Tokens() + assert.Equal(t, test.expected, actual) + }) + } +} diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..4dde77c --- /dev/null +++ b/doc.go @@ -0,0 +1,7 @@ +// Package chroma takes source code and other structured text and converts it into syntax highlighted HTML, ANSI- +// coloured text, etc. +// +// Chroma is based heavily on Pygments, and includes translators for Pygments lexers and styles. +// +// For more information, go here: https://github.com/alecthomas/chroma +package chroma diff --git a/emitters.go b/emitters.go new file mode 100644 index 0000000..0788b5b --- /dev/null +++ b/emitters.go @@ -0,0 +1,218 @@ +package chroma + +import ( + "fmt" +) + +// An Emitter takes group matches and returns tokens. +type Emitter interface { + // Emit tokens for the given regex groups. + Emit(groups []string, state *LexerState) Iterator +} + +// SerialisableEmitter is an Emitter that can be serialised and deserialised to/from JSON. +type SerialisableEmitter interface { + Emitter + EmitterKind() string +} + +// EmitterFunc is a function that is an Emitter. +type EmitterFunc func(groups []string, state *LexerState) Iterator + +// Emit tokens for groups. +func (e EmitterFunc) Emit(groups []string, state *LexerState) Iterator { + return e(groups, state) +} + +type Emitters []Emitter + +type byGroupsEmitter struct { + Emitters +} + +// ByGroups emits a token for each matching group in the rule's regex. +func ByGroups(emitters ...Emitter) Emitter { + return &byGroupsEmitter{Emitters: emitters} +} + +func (b *byGroupsEmitter) EmitterKind() string { return "bygroups" } + +func (b *byGroupsEmitter) Emit(groups []string, state *LexerState) Iterator { + iterators := make([]Iterator, 0, len(groups)-1) + if len(b.Emitters) != len(groups)-1 { + iterators = append(iterators, Error.Emit(groups, state)) + // panic(errors.Errorf("number of groups %q does not match number of emitters %v", groups, emitters)) + } else { + for i, group := range groups[1:] { + if b.Emitters[i] != nil { + iterators = append(iterators, b.Emitters[i].Emit([]string{group}, state)) + } + } + } + return Concaterator(iterators...) +} + +// ByGroupNames emits a token for each named matching group in the rule's regex. +func ByGroupNames(emitters map[string]Emitter) Emitter { + return EmitterFunc(func(groups []string, state *LexerState) Iterator { + iterators := make([]Iterator, 0, len(state.NamedGroups)-1) + if len(state.NamedGroups)-1 == 0 { + if emitter, ok := emitters[`0`]; ok { + iterators = append(iterators, emitter.Emit(groups, state)) + } else { + iterators = append(iterators, Error.Emit(groups, state)) + } + } else { + ruleRegex := state.Rules[state.State][state.Rule].Regexp + for i := 1; i < len(state.NamedGroups); i++ { + groupName := ruleRegex.GroupNameFromNumber(i) + group := state.NamedGroups[groupName] + if emitter, ok := emitters[groupName]; ok { + if emitter != nil { + iterators = append(iterators, emitter.Emit([]string{group}, state)) + } + } else { + iterators = append(iterators, Error.Emit([]string{group}, state)) + } + } + } + return Concaterator(iterators...) + }) +} + +// UsingByGroup emits tokens for the matched groups in the regex using a +// sublexer. Used when lexing code blocks where the name of a sublexer is +// contained within the block, for example on a Markdown text block or SQL +// language block. +// +// An attempt to load the sublexer will be made using the captured value from +// the text of the matched sublexerNameGroup. If a sublexer matching the +// sublexerNameGroup is available, then tokens for the matched codeGroup will +// be emitted using the sublexer. Otherwise, if no sublexer is available, then +// tokens will be emitted from the passed emitter. +// +// Example: +// +// var Markdown = internal.Register(MustNewLexer( +// &Config{ +// Name: "markdown", +// Aliases: []string{"md", "mkd"}, +// Filenames: []string{"*.md", "*.mkd", "*.markdown"}, +// MimeTypes: []string{"text/x-markdown"}, +// }, +// Rules{ +// "root": { +// {"^(```)(\\w+)(\\n)([\\w\\W]*?)(^```$)", +// UsingByGroup( +// 2, 4, +// String, String, String, Text, String, +// ), +// nil, +// }, +// }, +// }, +// )) +// +// See the lexers/markdown.go for the complete example. +// +// Note: panic's if the number of emitters does not equal the number of matched +// groups in the regex. +func UsingByGroup(sublexerNameGroup, codeGroup int, emitters ...Emitter) Emitter { + return &usingByGroup{ + SublexerNameGroup: sublexerNameGroup, + CodeGroup: codeGroup, + Emitters: emitters, + } +} + +type usingByGroup struct { + SublexerNameGroup int `xml:"sublexer_name_group"` + CodeGroup int `xml:"code_group"` + Emitters Emitters `xml:"emitters"` +} + +func (u *usingByGroup) EmitterKind() string { return "usingbygroup" } +func (u *usingByGroup) Emit(groups []string, state *LexerState) Iterator { + // bounds check + if len(u.Emitters) != len(groups)-1 { + panic("UsingByGroup expects number of emitters to be the same as len(groups)-1") + } + + // grab sublexer + sublexer := state.Registry.Get(groups[u.SublexerNameGroup]) + + // build iterators + iterators := make([]Iterator, len(groups)-1) + for i, group := range groups[1:] { + if i == u.CodeGroup-1 && sublexer != nil { + var err error + iterators[i], err = sublexer.Tokenise(nil, groups[u.CodeGroup]) + if err != nil { + panic(err) + } + } else if u.Emitters[i] != nil { + iterators[i] = u.Emitters[i].Emit([]string{group}, state) + } + } + return Concaterator(iterators...) +} + +// UsingLexer returns an Emitter that uses a given Lexer for parsing and emitting. +// +// This Emitter is not serialisable. +func UsingLexer(lexer Lexer) Emitter { + return EmitterFunc(func(groups []string, _ *LexerState) Iterator { + it, err := lexer.Tokenise(&TokeniseOptions{State: "root", Nested: true}, groups[0]) + if err != nil { + panic(err) + } + return it + }) +} + +type usingEmitter struct { + Lexer string `xml:"lexer,attr"` +} + +func (u *usingEmitter) EmitterKind() string { return "using" } + +func (u *usingEmitter) Emit(groups []string, state *LexerState) Iterator { + if state.Registry == nil { + panic(fmt.Sprintf("no LexerRegistry available for Using(%q)", u.Lexer)) + } + lexer := state.Registry.Get(u.Lexer) + if lexer == nil { + panic(fmt.Sprintf("no such lexer %q", u.Lexer)) + } + it, err := lexer.Tokenise(&TokeniseOptions{State: "root", Nested: true}, groups[0]) + if err != nil { + panic(err) + } + return it +} + +// Using returns an Emitter that uses a given Lexer reference for parsing and emitting. +// +// The referenced lexer must be stored in the same LexerRegistry. +func Using(lexer string) Emitter { + return &usingEmitter{Lexer: lexer} +} + +type usingSelfEmitter struct { + State string `xml:"state,attr"` +} + +func (u *usingSelfEmitter) EmitterKind() string { return "usingself" } + +func (u *usingSelfEmitter) Emit(groups []string, state *LexerState) Iterator { + it, err := state.Lexer.Tokenise(&TokeniseOptions{State: u.State, Nested: true}, groups[0]) + if err != nil { + panic(err) + } + return it +} + +// UsingSelf is like Using, but uses the current Lexer. +func UsingSelf(stateName string) Emitter { + return &usingSelfEmitter{stateName} +} diff --git a/formatter.go b/formatter.go new file mode 100644 index 0000000..00dd5d8 --- /dev/null +++ b/formatter.go @@ -0,0 +1,43 @@ +package chroma + +import ( + "io" +) + +// A Formatter for Chroma lexers. +type Formatter interface { + // Format returns a formatting function for tokens. + // + // If the iterator panics, the Formatter should recover. + Format(w io.Writer, style *Style, iterator Iterator) error +} + +// A FormatterFunc is a Formatter implemented as a function. +// +// Guards against iterator panics. +type FormatterFunc func(w io.Writer, style *Style, iterator Iterator) error + +func (f FormatterFunc) Format(w io.Writer, s *Style, it Iterator) (err error) { // nolint + defer func() { + if perr := recover(); perr != nil { + err = perr.(error) + } + }() + return f(w, s, it) +} + +type recoveringFormatter struct { + Formatter +} + +func (r recoveringFormatter) Format(w io.Writer, s *Style, it Iterator) (err error) { + defer func() { + if perr := recover(); perr != nil { + err = perr.(error) + } + }() + return r.Formatter.Format(w, s, it) +} + +// RecoveringFormatter wraps a formatter with panic recovery. +func RecoveringFormatter(formatter Formatter) Formatter { return recoveringFormatter{formatter} } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..06e3656 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module toastielab.dev/toastie-stuff/chroma/v2 + +go 1.24.1 + +require ( + github.com/alecthomas/assert/v2 v2.10.0 + github.com/alecthomas/repr v0.4.0 + github.com/dlclark/regexp2 v1.11.0 +) + +require github.com/hexops/gotextdiff v1.0.3 // indirect \ No newline at end of file diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4bd5c9d --- /dev/null +++ b/go.sum @@ -0,0 +1,5 @@ +github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= diff --git a/iterator.go b/iterator.go new file mode 100644 index 0000000..d5175de --- /dev/null +++ b/iterator.go @@ -0,0 +1,76 @@ +package chroma + +import "strings" + +// An Iterator across tokens. +// +// EOF will be returned at the end of the Token stream. +// +// If an error occurs within an Iterator, it may propagate this in a panic. Formatters should recover. +type Iterator func() Token + +// Tokens consumes all tokens from the iterator and returns them as a slice. +func (i Iterator) Tokens() []Token { + var out []Token + for t := i(); t != EOF; t = i() { + out = append(out, t) + } + return out +} + +// Concaterator concatenates tokens from a series of iterators. +func Concaterator(iterators ...Iterator) Iterator { + return func() Token { + for len(iterators) > 0 { + t := iterators[0]() + if t != EOF { + return t + } + iterators = iterators[1:] + } + return EOF + } +} + +// Literator converts a sequence of literal Tokens into an Iterator. +func Literator(tokens ...Token) Iterator { + return func() Token { + if len(tokens) == 0 { + return EOF + } + token := tokens[0] + tokens = tokens[1:] + return token + } +} + +// SplitTokensIntoLines splits tokens containing newlines in two. +func SplitTokensIntoLines(tokens []Token) (out [][]Token) { + var line []Token // nolint: prealloc + for _, token := range tokens { + for strings.Contains(token.Value, "\n") { + parts := strings.SplitAfterN(token.Value, "\n", 2) + // Token becomes the tail. + token.Value = parts[1] + + // Append the head to the line and flush the line. + clone := token.Clone() + clone.Value = parts[0] + line = append(line, clone) + out = append(out, line) + line = nil + } + line = append(line, token) + } + if len(line) > 0 { + out = append(out, line) + } + // Strip empty trailing token line. + if len(out) > 0 { + last := out[len(out)-1] + if len(last) == 1 && last[0].Value == "" { + out = out[:len(out)-1] + } + } + return +} diff --git a/lexer.go b/lexer.go new file mode 100644 index 0000000..eb027bf --- /dev/null +++ b/lexer.go @@ -0,0 +1,162 @@ +package chroma + +import ( + "fmt" + "strings" +) + +var ( + defaultOptions = &TokeniseOptions{ + State: "root", + EnsureLF: true, + } +) + +// Config for a lexer. +type Config struct { + // Name of the lexer. + Name string `xml:"name,omitempty"` + + // Shortcuts for the lexer + Aliases []string `xml:"alias,omitempty"` + + // File name globs + Filenames []string `xml:"filename,omitempty"` + + // Secondary file name globs + AliasFilenames []string `xml:"alias_filename,omitempty"` + + // MIME types + MimeTypes []string `xml:"mime_type,omitempty"` + + // Regex matching is case-insensitive. + CaseInsensitive bool `xml:"case_insensitive,omitempty"` + + // Regex matches all characters. + DotAll bool `xml:"dot_all,omitempty"` + + // Regex does not match across lines ($ matches EOL). + // + // Defaults to multiline. + NotMultiline bool `xml:"not_multiline,omitempty"` + + // Don't strip leading and trailing newlines from the input. + // DontStripNL bool + + // Strip all leading and trailing whitespace from the input + // StripAll bool + + // Make sure that the input ends with a newline. This + // is required for some lexers that consume input linewise. + EnsureNL bool `xml:"ensure_nl,omitempty"` + + // If given and greater than 0, expand tabs in the input. + // TabSize int + + // Priority of lexer. + // + // If this is 0 it will be treated as a default of 1. + Priority float32 `xml:"priority,omitempty"` + + // Analyse is a list of regexes to match against the input. + // + // If a match is found, the score is returned if single attribute is set to true, + // otherwise the sum of all the score of matching patterns will be + // used as the final score. + Analyse *AnalyseConfig `xml:"analyse,omitempty"` +} + +// AnalyseConfig defines the list of regexes analysers. +type AnalyseConfig struct { + Regexes []RegexConfig `xml:"regex,omitempty"` + // If true, the first matching score is returned. + First bool `xml:"first,attr"` +} + +// RegexConfig defines a single regex pattern and its score in case of match. +type RegexConfig struct { + Pattern string `xml:"pattern,attr"` + Score float32 `xml:"score,attr"` +} + +// Token output to formatter. +type Token struct { + Type TokenType `json:"type"` + Value string `json:"value"` +} + +func (t *Token) String() string { return t.Value } +func (t *Token) GoString() string { return fmt.Sprintf("&Token{%s, %q}", t.Type, t.Value) } + +// Clone returns a clone of the Token. +func (t *Token) Clone() Token { + return *t +} + +// EOF is returned by lexers at the end of input. +var EOF Token + +// TokeniseOptions contains options for tokenisers. +type TokeniseOptions struct { + // State to start tokenisation in. Defaults to "root". + State string + // Nested tokenisation. + Nested bool + + // If true, all EOLs are converted into LF + // by replacing CRLF and CR + EnsureLF bool +} + +// A Lexer for tokenising source code. +type Lexer interface { + // Config describing the features of the Lexer. + Config() *Config + // Tokenise returns an Iterator over tokens in text. + Tokenise(options *TokeniseOptions, text string) (Iterator, error) + // SetRegistry sets the registry this Lexer is associated with. + // + // The registry should be used by the Lexer if it needs to look up other + // lexers. + SetRegistry(registry *LexerRegistry) Lexer + // SetAnalyser sets a function the Lexer should use for scoring how + // likely a fragment of text is to match this lexer, between 0.0 and 1.0. + // A value of 1 indicates high confidence. + // + // Lexers may ignore this if they implement their own analysers. + SetAnalyser(analyser func(text string) float32) Lexer + // AnalyseText scores how likely a fragment of text is to match + // this lexer, between 0.0 and 1.0. A value of 1 indicates high confidence. + AnalyseText(text string) float32 +} + +// Lexers is a slice of lexers sortable by name. +type Lexers []Lexer + +func (l Lexers) Len() int { return len(l) } +func (l Lexers) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l Lexers) Less(i, j int) bool { + return strings.ToLower(l[i].Config().Name) < strings.ToLower(l[j].Config().Name) +} + +// PrioritisedLexers is a slice of lexers sortable by priority. +type PrioritisedLexers []Lexer + +func (l PrioritisedLexers) Len() int { return len(l) } +func (l PrioritisedLexers) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l PrioritisedLexers) Less(i, j int) bool { + ip := l[i].Config().Priority + if ip == 0 { + ip = 1 + } + jp := l[j].Config().Priority + if jp == 0 { + jp = 1 + } + return ip > jp +} + +// Analyser determines how appropriate this lexer is for the given text. +type Analyser interface { + AnalyseText(text string) float32 +} diff --git a/lexer_test.go b/lexer_test.go new file mode 100644 index 0000000..0f0ab5f --- /dev/null +++ b/lexer_test.go @@ -0,0 +1,48 @@ +package chroma + +import ( + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestTokenTypeClassifiers(t *testing.T) { + assert.True(t, GenericDeleted.InCategory(Generic)) + assert.True(t, LiteralStringBacktick.InSubCategory(String)) + assert.Equal(t, LiteralStringBacktick.String(), "LiteralStringBacktick") +} + +func TestSimpleLexer(t *testing.T) { + lexer := mustNewLexer(t, &Config{ + Name: "INI", + Aliases: []string{"ini", "cfg"}, + Filenames: []string{"*.ini", "*.cfg"}, + }, map[string][]Rule{ + "root": { + {`\s+`, Whitespace, nil}, + {`;.*?$`, Comment, nil}, + {`\[.*?\]$`, Keyword, nil}, + {`(.*?)(\s*)(=)(\s*)(.*?)$`, ByGroups(Name, Whitespace, Operator, Whitespace, String), nil}, + }, + }) + actual, err := Tokenise(lexer, nil, ` + ; this is a comment + [section] + a = 10 +`) + assert.NoError(t, err) + expected := []Token{ + {Whitespace, "\n\t"}, + {Comment, "; this is a comment"}, + {Whitespace, "\n\t"}, + {Keyword, "[section]"}, + {Whitespace, "\n\t"}, + {Name, "a"}, + {Whitespace, " "}, + {Operator, "="}, + {Whitespace, " "}, + {LiteralString, "10"}, + {Whitespace, "\n"}, + } + assert.Equal(t, expected, actual) +} diff --git a/mutator_test.go b/mutator_test.go new file mode 100644 index 0000000..6561fc4 --- /dev/null +++ b/mutator_test.go @@ -0,0 +1,57 @@ +package chroma + +import ( + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestInclude(t *testing.T) { + include := Include("other") + actual := CompiledRules{ + "root": {{Rule: include}}, + "other": { + {Rule: Rule{Pattern: "//.+", Type: Comment}}, + {Rule: Rule{Pattern: `"[^"]*"`, Type: String}}, + }, + } + lexer := &RegexLexer{rules: actual} + err := include.Mutator.(LexerMutator).MutateLexer(lexer.rules, "root", 0) + assert.NoError(t, err) + expected := CompiledRules{ + "root": { + {Rule: Rule{ + Pattern: "//.+", + Type: Comment, + }}, + {Rule: Rule{ + Pattern: `"[^"]*"`, + Type: String, + }}, + }, + "other": { + {Rule: Rule{ + Pattern: "//.+", + Type: Comment, + }}, + {Rule: Rule{ + Pattern: `"[^"]*"`, + Type: String, + }}, + }, + } + assert.Equal(t, expected, actual) +} + +func TestCombine(t *testing.T) { + l := mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": {{`hello`, String, Combined("world", "bye", "space")}}, + "world": {{`world`, Name, nil}}, + "bye": {{`bye`, Name, nil}}, + "space": {{`\s+`, Whitespace, nil}}, + }) + it, err := l.Tokenise(nil, "hello world") + assert.NoError(t, err) + expected := []Token{{String, `hello`}, {Whitespace, ` `}, {Name, `world`}} + assert.Equal(t, expected, it.Tokens()) +} diff --git a/mutators.go b/mutators.go new file mode 100644 index 0000000..e80ad97 --- /dev/null +++ b/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 "mutators" } + +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, "") +} diff --git a/regexp.go b/regexp.go new file mode 100644 index 0000000..0dcb077 --- /dev/null +++ b/regexp.go @@ -0,0 +1,483 @@ +package chroma + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + "sync" + "time" + "unicode/utf8" + + "github.com/dlclark/regexp2" +) + +// A Rule is the fundamental matching unit of the Regex lexer state machine. +type Rule struct { + Pattern string + Type Emitter + Mutator Mutator +} + +// Words creates a regex that matches any of the given literal words. +func Words(prefix, suffix string, words ...string) string { + sort.Slice(words, func(i, j int) bool { + return len(words[j]) < len(words[i]) + }) + for i, word := range words { + words[i] = regexp.QuoteMeta(word) + } + return prefix + `(` + strings.Join(words, `|`) + `)` + suffix +} + +// Tokenise text using lexer, returning tokens as a slice. +func Tokenise(lexer Lexer, options *TokeniseOptions, text string) ([]Token, error) { + var out []Token + it, err := lexer.Tokenise(options, text) + if err != nil { + return nil, err + } + for t := it(); t != EOF; t = it() { + out = append(out, t) + } + return out, nil +} + +// Rules maps from state to a sequence of Rules. +type Rules map[string][]Rule + +// Rename clones rules then a rule. +func (r Rules) Rename(oldRule, newRule string) Rules { + r = r.Clone() + r[newRule] = r[oldRule] + delete(r, oldRule) + return r +} + +// Clone returns a clone of the Rules. +func (r Rules) Clone() Rules { + out := map[string][]Rule{} + for key, rules := range r { + out[key] = make([]Rule, len(rules)) + copy(out[key], rules) + } + return out +} + +// Merge creates a clone of "r" then merges "rules" into the clone. +func (r Rules) Merge(rules Rules) Rules { + out := r.Clone() + for k, v := range rules.Clone() { + out[k] = v + } + return out +} + +// MustNewLexer creates a new Lexer with deferred rules generation or panics. +func MustNewLexer(config *Config, rules func() Rules) *RegexLexer { + lexer, err := NewLexer(config, rules) + if err != nil { + panic(err) + } + return lexer +} + +// NewLexer creates a new regex-based Lexer. +// +// "rules" is a state machine transition map. Each key is a state. Values are sets of rules +// that match input, optionally modify lexer state, and output tokens. +func NewLexer(config *Config, rulesFunc func() Rules) (*RegexLexer, error) { + if config == nil { + config = &Config{} + } + for _, glob := range append(config.Filenames, config.AliasFilenames...) { + _, err := filepath.Match(glob, "") + if err != nil { + return nil, fmt.Errorf("%s: %q is not a valid glob: %w", config.Name, glob, err) + } + } + r := &RegexLexer{ + config: config, + fetchRulesFunc: func() (Rules, error) { return rulesFunc(), nil }, + } + // One-off code to generate XML lexers in the Chroma source tree. + // var nameCleanRe = regexp.MustCompile(`[^-+A-Za-z0-9_]`) + // name := strings.ToLower(nameCleanRe.ReplaceAllString(config.Name, "_")) + // data, err := Marshal(r) + // if err != nil { + // if errors.Is(err, ErrNotSerialisable) { + // fmt.Fprintf(os.Stderr, "warning: %q: %s\n", name, err) + // return r, nil + // } + // return nil, err + // } + // _, file, _, ok := runtime.Caller(2) + // if !ok { + // panic("??") + // } + // fmt.Println(file) + // if strings.Contains(file, "/lexers/") { + // dir := filepath.Join(filepath.Dir(file), "embedded") + // err = os.MkdirAll(dir, 0700) + // if err != nil { + // return nil, err + // } + // filename := filepath.Join(dir, name) + ".xml" + // fmt.Println(filename) + // err = ioutil.WriteFile(filename, data, 0600) + // if err != nil { + // return nil, err + // } + // } + return r, nil +} + +// Trace enables debug tracing. +func (r *RegexLexer) Trace(trace bool) *RegexLexer { + r.trace = trace + return r +} + +// A CompiledRule is a Rule with a pre-compiled regex. +// +// Note that regular expressions are lazily compiled on first use of the lexer. +type CompiledRule struct { + Rule + Regexp *regexp2.Regexp + flags string +} + +// CompiledRules is a map of rule name to sequence of compiled rules in that rule. +type CompiledRules map[string][]*CompiledRule + +// LexerState contains the state for a single lex. +type LexerState struct { + Lexer *RegexLexer + Registry *LexerRegistry + Text []rune + Pos int + Rules CompiledRules + Stack []string + State string + Rule int + // Group matches. + Groups []string + // Named Group matches. + NamedGroups map[string]string + // Custum context for mutators. + MutatorContext map[interface{}]interface{} + iteratorStack []Iterator + options *TokeniseOptions + newlineAdded bool +} + +// Set mutator context. +func (l *LexerState) Set(key interface{}, value interface{}) { + l.MutatorContext[key] = value +} + +// Get mutator context. +func (l *LexerState) Get(key interface{}) interface{} { + return l.MutatorContext[key] +} + +// Iterator returns the next Token from the lexer. +func (l *LexerState) Iterator() Token { // nolint: gocognit + end := len(l.Text) + if l.newlineAdded { + end-- + } + for l.Pos < end && len(l.Stack) > 0 { + // Exhaust the iterator stack, if any. + for len(l.iteratorStack) > 0 { + n := len(l.iteratorStack) - 1 + t := l.iteratorStack[n]() + if t == EOF { + l.iteratorStack = l.iteratorStack[:n] + continue + } + return t + } + + l.State = l.Stack[len(l.Stack)-1] + if l.Lexer.trace { + fmt.Fprintf(os.Stderr, "%s: pos=%d, text=%q\n", l.State, l.Pos, string(l.Text[l.Pos:])) + } + selectedRule, ok := l.Rules[l.State] + if !ok { + panic("unknown state " + l.State) + } + ruleIndex, rule, groups, namedGroups := matchRules(l.Text, l.Pos, selectedRule) + // No match. + if groups == nil { + // From Pygments :\ + // + // If the RegexLexer encounters a newline that is flagged as an error token, the stack is + // emptied and the lexer continues scanning in the 'root' state. This can help producing + // error-tolerant highlighting for erroneous input, e.g. when a single-line string is not + // closed. + if l.Text[l.Pos] == '\n' && l.State != l.options.State { + l.Stack = []string{l.options.State} + continue + } + l.Pos++ + return Token{Error, string(l.Text[l.Pos-1 : l.Pos])} + } + l.Rule = ruleIndex + l.Groups = groups + l.NamedGroups = namedGroups + l.Pos += utf8.RuneCountInString(groups[0]) + if rule.Mutator != nil { + if err := rule.Mutator.Mutate(l); err != nil { + panic(err) + } + } + if rule.Type != nil { + l.iteratorStack = append(l.iteratorStack, rule.Type.Emit(l.Groups, l)) + } + } + // Exhaust the IteratorStack, if any. + // Duplicate code, but eh. + for len(l.iteratorStack) > 0 { + n := len(l.iteratorStack) - 1 + t := l.iteratorStack[n]() + if t == EOF { + l.iteratorStack = l.iteratorStack[:n] + continue + } + return t + } + + // If we get to here and we still have text, return it as an error. + if l.Pos != len(l.Text) && len(l.Stack) == 0 { + value := string(l.Text[l.Pos:]) + l.Pos = len(l.Text) + return Token{Type: Error, Value: value} + } + return EOF +} + +// RegexLexer is the default lexer implementation used in Chroma. +type RegexLexer struct { + registry *LexerRegistry // The LexerRegistry this Lexer is associated with, if any. + config *Config + analyser func(text string) float32 + trace bool + + mu sync.Mutex + compiled bool + rawRules Rules + rules map[string][]*CompiledRule + fetchRulesFunc func() (Rules, error) + compileOnce sync.Once +} + +func (r *RegexLexer) String() string { + return r.config.Name +} + +// Rules in the Lexer. +func (r *RegexLexer) Rules() (Rules, error) { + if err := r.needRules(); err != nil { + return nil, err + } + return r.rawRules, nil +} + +// SetRegistry the lexer will use to lookup other lexers if necessary. +func (r *RegexLexer) SetRegistry(registry *LexerRegistry) Lexer { + r.registry = registry + return r +} + +// SetAnalyser sets the analyser function used to perform content inspection. +func (r *RegexLexer) SetAnalyser(analyser func(text string) float32) Lexer { + r.analyser = analyser + return r +} + +// AnalyseText scores how likely a fragment of text is to match this lexer, between 0.0 and 1.0. +func (r *RegexLexer) AnalyseText(text string) float32 { + if r.analyser != nil { + return r.analyser(text) + } + return 0 +} + +// SetConfig replaces the Config for this Lexer. +func (r *RegexLexer) SetConfig(config *Config) *RegexLexer { + r.config = config + return r +} + +// Config returns the Config for this Lexer. +func (r *RegexLexer) Config() *Config { + return r.config +} + +// Regex compilation is deferred until the lexer is used. This is to avoid significant init() time costs. +func (r *RegexLexer) maybeCompile() (err error) { + r.mu.Lock() + defer r.mu.Unlock() + if r.compiled { + return nil + } + for state, rules := range r.rules { + for i, rule := range rules { + if rule.Regexp == nil { + pattern := "(?:" + rule.Pattern + ")" + if rule.flags != "" { + pattern = "(?" + rule.flags + ")" + pattern + } + pattern = `\G` + pattern + rule.Regexp, err = regexp2.Compile(pattern, 0) + if err != nil { + return fmt.Errorf("failed to compile rule %s.%d: %s", state, i, err) + } + rule.Regexp.MatchTimeout = time.Millisecond * 250 + } + } + } +restart: + seen := map[LexerMutator]bool{} + for state := range r.rules { + for i := 0; i < len(r.rules[state]); i++ { + rule := r.rules[state][i] + if compile, ok := rule.Mutator.(LexerMutator); ok { + if seen[compile] { + return fmt.Errorf("saw mutator %T twice; this should not happen", compile) + } + seen[compile] = true + if err := compile.MutateLexer(r.rules, state, i); err != nil { + return err + } + // Process the rules again in case the mutator added/removed rules. + // + // This sounds bad, but shouldn't be significant in practice. + goto restart + } + } + } + r.compiled = true + return nil +} + +func (r *RegexLexer) fetchRules() error { + rules, err := r.fetchRulesFunc() + if err != nil { + return fmt.Errorf("%s: failed to compile rules: %w", r.config.Name, err) + } + if _, ok := rules["root"]; !ok { + return fmt.Errorf("no \"root\" state") + } + compiledRules := map[string][]*CompiledRule{} + for state, rules := range rules { + compiledRules[state] = nil + for _, rule := range rules { + flags := "" + if !r.config.NotMultiline { + flags += "m" + } + if r.config.CaseInsensitive { + flags += "i" + } + if r.config.DotAll { + flags += "s" + } + compiledRules[state] = append(compiledRules[state], &CompiledRule{Rule: rule, flags: flags}) + } + } + + r.rawRules = rules + r.rules = compiledRules + return nil +} + +func (r *RegexLexer) needRules() error { + var err error + if r.fetchRulesFunc != nil { + r.compileOnce.Do(func() { + err = r.fetchRules() + }) + } + if err := r.maybeCompile(); err != nil { + return err + } + return err +} + +// Tokenise text using lexer, returning an iterator. +func (r *RegexLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { + err := r.needRules() + if err != nil { + return nil, err + } + if options == nil { + options = defaultOptions + } + if options.EnsureLF { + text = ensureLF(text) + } + newlineAdded := false + if !options.Nested && r.config.EnsureNL && !strings.HasSuffix(text, "\n") { + text += "\n" + newlineAdded = true + } + state := &LexerState{ + Registry: r.registry, + newlineAdded: newlineAdded, + options: options, + Lexer: r, + Text: []rune(text), + Stack: []string{options.State}, + Rules: r.rules, + MutatorContext: map[interface{}]interface{}{}, + } + return state.Iterator, nil +} + +// MustRules is like Rules() but will panic on error. +func (r *RegexLexer) MustRules() Rules { + rules, err := r.Rules() + if err != nil { + panic(err) + } + return rules +} + +func matchRules(text []rune, pos int, rules []*CompiledRule) (int, *CompiledRule, []string, map[string]string) { + for i, rule := range rules { + match, err := rule.Regexp.FindRunesMatchStartingAt(text, pos) + if match != nil && err == nil && match.Index == pos { + groups := []string{} + namedGroups := make(map[string]string) + for _, g := range match.Groups() { + namedGroups[g.Name] = g.String() + groups = append(groups, g.String()) + } + return i, rule, groups, namedGroups + } + } + return 0, &CompiledRule{}, nil, nil +} + +// replace \r and \r\n with \n +// same as strings.ReplaceAll but more efficient +func ensureLF(text string) string { + buf := make([]byte, len(text)) + var j int + for i := 0; i < len(text); i++ { + c := text[i] + if c == '\r' { + if i < len(text)-1 && text[i+1] == '\n' { + continue + } + c = '\n' + } + buf[j] = c + j++ + } + return string(buf[:j]) +} diff --git a/regexp_test.go b/regexp_test.go new file mode 100644 index 0000000..6a22c20 --- /dev/null +++ b/regexp_test.go @@ -0,0 +1,194 @@ +package chroma + +import ( + "testing" + + "github.com/alecthomas/assert/v2" +) + +func mustNewLexer(t *testing.T, config *Config, rules Rules) *RegexLexer { // nolint: forbidigo + lexer, err := NewLexer(config, func() Rules { + return rules + }) + assert.NoError(t, err) + return lexer +} + +func TestNewlineAtEndOfFile(t *testing.T) { + l := Coalesce(mustNewLexer(t, &Config{EnsureNL: true}, Rules{ // nolint: forbidigo + "root": { + {`(\w+)(\n)`, ByGroups(Keyword, Whitespace), nil}, + }, + })) + it, err := l.Tokenise(nil, `hello`) + assert.NoError(t, err) + assert.Equal(t, []Token{{Keyword, "hello"}, {Whitespace, "\n"}}, it.Tokens()) + + l = Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + {`(\w+)(\n)`, ByGroups(Keyword, Whitespace), nil}, + }, + })) + it, err = l.Tokenise(nil, `hello`) + assert.NoError(t, err) + assert.Equal(t, []Token{{Error, "hello"}}, it.Tokens()) +} + +func TestMatchingAtStart(t *testing.T) { + l := Coalesce(mustNewLexer(t, &Config{}, Rules{ // nolint: forbidigo + "root": { + {`\s+`, Whitespace, nil}, + {`^-`, Punctuation, Push("directive")}, + {`->`, Operator, nil}, + }, + "directive": { + {"module", NameEntity, Pop(1)}, + }, + })) + it, err := l.Tokenise(nil, `-module ->`) + assert.NoError(t, err) + assert.Equal(t, + []Token{{Punctuation, "-"}, {NameEntity, "module"}, {Whitespace, " "}, {Operator, "->"}}, + it.Tokens()) +} + +func TestEnsureLFOption(t *testing.T) { + l := Coalesce(mustNewLexer(t, &Config{}, Rules{ // nolint: forbidigo + "root": { + {`(\w+)(\r?\n|\r)`, ByGroups(Keyword, Whitespace), nil}, + }, + })) + it, err := l.Tokenise(&TokeniseOptions{ + State: "root", + EnsureLF: true, + }, "hello\r\nworld\r") + assert.NoError(t, err) + assert.Equal(t, []Token{ + {Keyword, "hello"}, + {Whitespace, "\n"}, + {Keyword, "world"}, + {Whitespace, "\n"}, + }, it.Tokens()) + + l = Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + {`(\w+)(\r?\n|\r)`, ByGroups(Keyword, Whitespace), nil}, + }, + })) + it, err = l.Tokenise(&TokeniseOptions{ + State: "root", + EnsureLF: false, + }, "hello\r\nworld\r") + assert.NoError(t, err) + assert.Equal(t, []Token{ + {Keyword, "hello"}, + {Whitespace, "\r\n"}, + {Keyword, "world"}, + {Whitespace, "\r"}, + }, it.Tokens()) +} + +func TestEnsureLFFunc(t *testing.T) { + tests := []struct{ in, out string }{ + {in: "", out: ""}, + {in: "abc", out: "abc"}, + {in: "\r", out: "\n"}, + {in: "a\r", out: "a\n"}, + {in: "\rb", out: "\nb"}, + {in: "a\rb", out: "a\nb"}, + {in: "\r\n", out: "\n"}, + {in: "a\r\n", out: "a\n"}, + {in: "\r\nb", out: "\nb"}, + {in: "a\r\nb", out: "a\nb"}, + {in: "\r\r\r\n\r", out: "\n\n\n\n"}, + } + for _, test := range tests { + out := ensureLF(test.in) + assert.Equal(t, out, test.out) + } +} + +func TestByGroupNames(t *testing.T) { + l := Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + { + `(?<key>\w+)(?<operator>=)(?<value>\w+)`, + ByGroupNames(map[string]Emitter{ + `key`: String, + `operator`: Operator, + `value`: String, + }), + nil, + }, + }, + })) + it, err := l.Tokenise(nil, `abc=123`) + assert.NoError(t, err) + assert.Equal(t, []Token{{String, `abc`}, {Operator, `=`}, {String, `123`}}, it.Tokens()) + + l = Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + { + `(?<key>\w+)(?<operator>=)(?<value>\w+)`, + ByGroupNames(map[string]Emitter{ + `key`: String, + `value`: String, + }), + nil, + }, + }, + })) + it, err = l.Tokenise(nil, `abc=123`) + assert.NoError(t, err) + assert.Equal(t, []Token{{String, `abc`}, {Error, `=`}, {String, `123`}}, it.Tokens()) + + l = Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + { + `(?<key>\w+)=(?<value>\w+)`, + ByGroupNames(map[string]Emitter{ + `key`: String, + `value`: String, + }), + nil, + }, + }, + })) + it, err = l.Tokenise(nil, `abc=123`) + assert.NoError(t, err) + assert.Equal(t, []Token{{String, `abc123`}}, it.Tokens()) + + l = Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + { + `(?<key>\w+)(?<op>=)(?<value>\w+)`, + ByGroupNames(map[string]Emitter{ + `key`: String, + `operator`: Operator, + `value`: String, + }), + nil, + }, + }, + })) + it, err = l.Tokenise(nil, `abc=123`) + assert.NoError(t, err) + assert.Equal(t, []Token{{String, `abc`}, {Error, `=`}, {String, `123`}}, it.Tokens()) + + l = Coalesce(mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + { + `\w+=\w+`, + ByGroupNames(map[string]Emitter{ + `key`: String, + `operator`: Operator, + `value`: String, + }), + nil, + }, + }, + })) + it, err = l.Tokenise(nil, `abc=123`) + assert.NoError(t, err) + assert.Equal(t, []Token{{Error, `abc=123`}}, it.Tokens()) +} diff --git a/registry.go b/registry.go new file mode 100644 index 0000000..4742e8c --- /dev/null +++ b/registry.go @@ -0,0 +1,210 @@ +package chroma + +import ( + "path/filepath" + "sort" + "strings" +) + +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", + } +) + +// LexerRegistry is a registry of Lexers. +type LexerRegistry struct { + Lexers Lexers + byName map[string]Lexer + byAlias map[string]Lexer +} + +// NewLexerRegistry creates a new LexerRegistry of Lexers. +func NewLexerRegistry() *LexerRegistry { + return &LexerRegistry{ + byName: map[string]Lexer{}, + byAlias: map[string]Lexer{}, + } +} + +// Names of all lexers, optionally including aliases. +func (l *LexerRegistry) Names(withAliases bool) []string { + out := []string{} + for _, lexer := range l.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 (l *LexerRegistry) Get(name string) Lexer { + if lexer := l.byName[name]; lexer != nil { + return lexer + } + if lexer := l.byAlias[name]; lexer != nil { + return lexer + } + if lexer := l.byName[strings.ToLower(name)]; lexer != nil { + return lexer + } + if lexer := l.byAlias[strings.ToLower(name)]; lexer != nil { + return lexer + } + + candidates := PrioritisedLexers{} + // Try file extension. + if lexer := l.Match("filename." + name); lexer != nil { + candidates = append(candidates, lexer) + } + // Try exact filename. + if lexer := l.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 (l *LexerRegistry) MatchMimeType(mimeType string) Lexer { + matched := PrioritisedLexers{} + for _, l := range l.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. +// +// Note that this iterates over all file patterns in all lexers, so is not fast. +func (l *LexerRegistry) Match(filename string) Lexer { + filename = filepath.Base(filename) + matched := PrioritisedLexers{} + // First, try primary filename matches. + for _, lexer := range l.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 l.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 (l *LexerRegistry) Analyse(text string) Lexer { + var picked Lexer + highest := float32(0.0) + for _, lexer := range l.Lexers { + if analyser, ok := lexer.(Analyser); ok { + weight := analyser.AnalyseText(text) + if weight > highest { + picked = lexer + highest = weight + } + } + } + return picked +} + +// Register a Lexer with the LexerRegistry. If the lexer is already registered +// it will be replaced. +func (l *LexerRegistry) Register(lexer Lexer) Lexer { + lexer.SetRegistry(l) + config := lexer.Config() + + l.byName[config.Name] = lexer + l.byName[strings.ToLower(config.Name)] = lexer + + for _, alias := range config.Aliases { + l.byAlias[alias] = lexer + l.byAlias[strings.ToLower(alias)] = lexer + } + + l.Lexers = add(l.Lexers, lexer) + + return lexer +} + +// add adds a lexer to a slice of lexers if it doesn't already exist, or if found will replace it. +func add(lexers Lexers, lexer Lexer) Lexers { + for i, val := range lexers { + if val == nil { + continue + } + + if val.Config().Name == lexer.Config().Name { + lexers[i] = lexer + return lexers + } + } + + return append(lexers, lexer) +} diff --git a/remap.go b/remap.go new file mode 100644 index 0000000..bcf5e66 --- /dev/null +++ b/remap.go @@ -0,0 +1,94 @@ +package chroma + +type remappingLexer struct { + lexer Lexer + mapper func(Token) []Token +} + +// RemappingLexer remaps a token to a set of, potentially empty, tokens. +func RemappingLexer(lexer Lexer, mapper func(Token) []Token) Lexer { + return &remappingLexer{lexer, mapper} +} + +func (r *remappingLexer) AnalyseText(text string) float32 { + return r.lexer.AnalyseText(text) +} + +func (r *remappingLexer) SetAnalyser(analyser func(text string) float32) Lexer { + r.lexer.SetAnalyser(analyser) + return r +} + +func (r *remappingLexer) SetRegistry(registry *LexerRegistry) Lexer { + r.lexer.SetRegistry(registry) + return r +} + +func (r *remappingLexer) Config() *Config { + return r.lexer.Config() +} + +func (r *remappingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { + it, err := r.lexer.Tokenise(options, text) + if err != nil { + return nil, err + } + var buffer []Token + return func() Token { + for { + if len(buffer) > 0 { + t := buffer[0] + buffer = buffer[1:] + return t + } + t := it() + if t == EOF { + return t + } + buffer = r.mapper(t) + } + }, nil +} + +// TypeMapping defines type maps for the TypeRemappingLexer. +type TypeMapping []struct { + From, To TokenType + Words []string +} + +// TypeRemappingLexer remaps types of tokens coming from a parent Lexer. +// +// eg. Map "defvaralias" tokens of type NameVariable to NameFunction: +// +// mapping := TypeMapping{ +// {NameVariable, NameFunction, []string{"defvaralias"}, +// } +// lexer = TypeRemappingLexer(lexer, mapping) +func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer { + // Lookup table for fast remapping. + lut := map[TokenType]map[string]TokenType{} + for _, rt := range mapping { + km, ok := lut[rt.From] + if !ok { + km = map[string]TokenType{} + lut[rt.From] = km + } + if len(rt.Words) == 0 { + km[""] = rt.To + } else { + for _, k := range rt.Words { + km[k] = rt.To + } + } + } + return RemappingLexer(lexer, func(t Token) []Token { + if k, ok := lut[t.Type]; ok { + if tt, ok := k[t.Value]; ok { + t.Type = tt + } else if tt, ok := k[""]; ok { + t.Type = tt + } + } + return []Token{t} + }) +} diff --git a/remap_test.go b/remap_test.go new file mode 100644 index 0000000..80d74ef --- /dev/null +++ b/remap_test.go @@ -0,0 +1,29 @@ +package chroma + +import ( + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestRemappingLexer(t *testing.T) { + var lexer Lexer = mustNewLexer(t, nil, Rules{ // nolint: forbidigo + "root": { + {`\s+`, Whitespace, nil}, + {`\w+`, Name, nil}, + }, + }) + lexer = TypeRemappingLexer(lexer, TypeMapping{ + {Name, Keyword, []string{"if", "else"}}, + }) + + it, err := lexer.Tokenise(nil, `if true then print else end`) + assert.NoError(t, err) + expected := []Token{ + {Keyword, "if"}, {TextWhitespace, " "}, {Name, "true"}, {TextWhitespace, " "}, {Name, "then"}, + {TextWhitespace, " "}, {Name, "print"}, {TextWhitespace, " "}, {Keyword, "else"}, + {TextWhitespace, " "}, {Name, "end"}, + } + actual := it.Tokens() + assert.Equal(t, expected, actual) +} diff --git a/serialise.go b/serialise.go new file mode 100644 index 0000000..645a5fa --- /dev/null +++ b/serialise.go @@ -0,0 +1,479 @@ +package chroma + +import ( + "compress/gzip" + "encoding/xml" + "errors" + "fmt" + "io" + "io/fs" + "math" + "path/filepath" + "reflect" + "regexp" + "strings" + + "github.com/dlclark/regexp2" +) + +// Serialisation of Chroma rules to XML. The format is: +// +// <rules> +// <state name="$STATE"> +// <rule [pattern="$PATTERN"]> +// [<$EMITTER ...>] +// [<$MUTATOR ...>] +// </rule> +// </state> +// </rules> +// +// eg. Include("String") would become: +// +// <rule> +// <include state="String" /> +// </rule> +// +// [null, null, {"kind": "include", "state": "String"}] +// +// eg. Rule{`\d+`, Text, nil} would become: +// +// <rule pattern="\\d+"> +// <token type="Text"/> +// </rule> +// +// eg. Rule{`"`, String, Push("String")} +// +// <rule pattern="\""> +// <token type="String" /> +// <push state="String" /> +// </rule> +// +// eg. Rule{`(\w+)(\n)`, ByGroups(Keyword, Whitespace), nil}, +// +// <rule pattern="(\\w+)(\\n)"> +// <bygroups token="Keyword" token="Whitespace" /> +// <push state="String" /> +// </rule> +var ( + // ErrNotSerialisable is returned if a lexer contains Rules that cannot be serialised. + ErrNotSerialisable = fmt.Errorf("not serialisable") + emitterTemplates = func() map[string]SerialisableEmitter { + out := map[string]SerialisableEmitter{} + for _, emitter := range []SerialisableEmitter{ + &byGroupsEmitter{}, + &usingSelfEmitter{}, + TokenType(0), + &usingEmitter{}, + &usingByGroup{}, + } { + out[emitter.EmitterKind()] = emitter + } + return out + }() + mutatorTemplates = func() map[string]SerialisableMutator { + out := map[string]SerialisableMutator{} + for _, mutator := range []SerialisableMutator{ + &includeMutator{}, + &combinedMutator{}, + &multiMutator{}, + &pushMutator{}, + &popMutator{}, + } { + out[mutator.MutatorKind()] = mutator + } + return out + }() +) + +// fastUnmarshalConfig unmarshals only the Config from a serialised lexer. +func fastUnmarshalConfig(from fs.FS, path string) (*Config, error) { + r, err := from.Open(path) + if err != nil { + return nil, err + } + defer r.Close() + dec := xml.NewDecoder(r) + for { + token, err := dec.Token() + if err != nil { + if errors.Is(err, io.EOF) { + return nil, fmt.Errorf("could not find <config> element") + } + return nil, err + } + switch se := token.(type) { + case xml.StartElement: + if se.Name.Local != "config" { + break + } + + var config Config + err = dec.DecodeElement(&config, &se) + if err != nil { + return nil, fmt.Errorf("%s: %w", path, err) + } + return &config, nil + } + } +} + +// MustNewXMLLexer constructs a new RegexLexer from an XML file or panics. +func MustNewXMLLexer(from fs.FS, path string) *RegexLexer { + lex, err := NewXMLLexer(from, path) + if err != nil { + panic(err) + } + return lex +} + +// NewXMLLexer creates a new RegexLexer from a serialised RegexLexer. +func NewXMLLexer(from fs.FS, path string) (*RegexLexer, error) { + config, err := fastUnmarshalConfig(from, path) + if err != nil { + return nil, err + } + + for _, glob := range append(config.Filenames, config.AliasFilenames...) { + _, err := filepath.Match(glob, "") + if err != nil { + return nil, fmt.Errorf("%s: %q is not a valid glob: %w", config.Name, glob, err) + } + } + + var analyserFn func(string) float32 + + if config.Analyse != nil { + type regexAnalyse struct { + re *regexp2.Regexp + score float32 + } + + regexAnalysers := make([]regexAnalyse, 0, len(config.Analyse.Regexes)) + + for _, ra := range config.Analyse.Regexes { + re, err := regexp2.Compile(ra.Pattern, regexp2.None) + if err != nil { + return nil, fmt.Errorf("%s: %q is not a valid analyser regex: %w", config.Name, ra.Pattern, err) + } + + regexAnalysers = append(regexAnalysers, regexAnalyse{re, ra.Score}) + } + + analyserFn = func(text string) float32 { + var score float32 + + for _, ra := range regexAnalysers { + ok, err := ra.re.MatchString(text) + if err != nil { + return 0 + } + + if ok && config.Analyse.First { + return float32(math.Min(float64(ra.score), 1.0)) + } + + if ok { + score += ra.score + } + } + + return float32(math.Min(float64(score), 1.0)) + } + } + + return &RegexLexer{ + config: config, + analyser: analyserFn, + fetchRulesFunc: func() (Rules, error) { + var lexer struct { + Config + Rules Rules `xml:"rules"` + } + // Try to open .xml fallback to .xml.gz + fr, err := from.Open(path) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + path += ".gz" + fr, err = from.Open(path) + if err != nil { + return nil, err + } + } else { + return nil, err + } + } + defer fr.Close() + var r io.Reader = fr + if strings.HasSuffix(path, ".gz") { + r, err = gzip.NewReader(r) + if err != nil { + return nil, fmt.Errorf("%s: %w", path, err) + } + } + err = xml.NewDecoder(r).Decode(&lexer) + if err != nil { + return nil, fmt.Errorf("%s: %w", path, err) + } + return lexer.Rules, nil + }, + }, nil +} + +// Marshal a RegexLexer to XML. +func Marshal(l *RegexLexer) ([]byte, error) { + type lexer struct { + Config Config `xml:"config"` + Rules Rules `xml:"rules"` + } + + rules, err := l.Rules() + if err != nil { + return nil, err + } + root := &lexer{ + Config: *l.Config(), + Rules: rules, + } + data, err := xml.MarshalIndent(root, "", " ") + if err != nil { + return nil, err + } + re := regexp.MustCompile(`></[a-zA-Z]+>`) + data = re.ReplaceAll(data, []byte(`/>`)) + return data, nil +} + +// Unmarshal a RegexLexer from XML. +func Unmarshal(data []byte) (*RegexLexer, error) { + type lexer struct { + Config Config `xml:"config"` + Rules Rules `xml:"rules"` + } + root := &lexer{} + err := xml.Unmarshal(data, root) + if err != nil { + return nil, fmt.Errorf("invalid Lexer XML: %w", err) + } + lex, err := NewLexer(&root.Config, func() Rules { return root.Rules }) + if err != nil { + return nil, err + } + return lex, nil +} + +func marshalMutator(e *xml.Encoder, mutator Mutator) error { + if mutator == nil { + return nil + } + smutator, ok := mutator.(SerialisableMutator) + if !ok { + return fmt.Errorf("unsupported mutator: %w", ErrNotSerialisable) + } + return e.EncodeElement(mutator, xml.StartElement{Name: xml.Name{Local: smutator.MutatorKind()}}) +} + +func unmarshalMutator(d *xml.Decoder, start xml.StartElement) (Mutator, error) { + kind := start.Name.Local + mutator, ok := mutatorTemplates[kind] + if !ok { + return nil, fmt.Errorf("unknown mutator %q: %w", kind, ErrNotSerialisable) + } + value, target := newFromTemplate(mutator) + if err := d.DecodeElement(target, &start); err != nil { + return nil, err + } + return value().(SerialisableMutator), nil +} + +func marshalEmitter(e *xml.Encoder, emitter Emitter) error { + if emitter == nil { + return nil + } + semitter, ok := emitter.(SerialisableEmitter) + if !ok { + return fmt.Errorf("unsupported emitter %T: %w", emitter, ErrNotSerialisable) + } + return e.EncodeElement(emitter, xml.StartElement{ + Name: xml.Name{Local: semitter.EmitterKind()}, + }) +} + +func unmarshalEmitter(d *xml.Decoder, start xml.StartElement) (Emitter, error) { + kind := start.Name.Local + mutator, ok := emitterTemplates[kind] + if !ok { + return nil, fmt.Errorf("unknown emitter %q: %w", kind, ErrNotSerialisable) + } + value, target := newFromTemplate(mutator) + if err := d.DecodeElement(target, &start); err != nil { + return nil, err + } + return value().(SerialisableEmitter), nil +} + +func (r Rule) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { + start := xml.StartElement{ + Name: xml.Name{Local: "rule"}, + } + if r.Pattern != "" { + start.Attr = append(start.Attr, xml.Attr{ + Name: xml.Name{Local: "pattern"}, + Value: r.Pattern, + }) + } + if err := e.EncodeToken(start); err != nil { + return err + } + if err := marshalEmitter(e, r.Type); err != nil { + return err + } + if err := marshalMutator(e, r.Mutator); err != nil { + return err + } + return e.EncodeToken(xml.EndElement{Name: start.Name}) +} + +func (r *Rule) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for _, attr := range start.Attr { + if attr.Name.Local == "pattern" { + r.Pattern = attr.Value + break + } + } + 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 && !errors.Is(err, ErrNotSerialisable) { + return err + } else if err == nil { + if r.Mutator != nil { + return fmt.Errorf("duplicate mutator") + } + r.Mutator = mutator + continue + } + emitter, err := unmarshalEmitter(d, token) + if err != nil && !errors.Is(err, ErrNotSerialisable) { // nolint: gocritic + return err + } else if err == nil { + if r.Type != nil { + return fmt.Errorf("duplicate emitter") + } + r.Type = emitter + continue + } else { + return err + } + + case xml.EndElement: + return nil + } + } +} + +type xmlRuleState struct { + Name string `xml:"name,attr"` + Rules []Rule `xml:"rule"` +} + +type xmlRules struct { + States []xmlRuleState `xml:"state"` +} + +func (r Rules) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { + xr := xmlRules{} + for state, rules := range r { + xr.States = append(xr.States, xmlRuleState{ + Name: state, + Rules: rules, + }) + } + return e.EncodeElement(xr, xml.StartElement{Name: xml.Name{Local: "rules"}}) +} + +func (r *Rules) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + xr := xmlRules{} + if err := d.DecodeElement(&xr, &start); err != nil { + return err + } + if *r == nil { + *r = Rules{} + } + for _, state := range xr.States { + (*r)[state.Name] = state.Rules + } + return nil +} + +type xmlTokenType struct { + Type string `xml:"type,attr"` +} + +func (t *TokenType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + el := xmlTokenType{} + if err := d.DecodeElement(&el, &start); err != nil { + return err + } + tt, err := TokenTypeString(el.Type) + if err != nil { + return err + } + *t = tt + return nil +} + +func (t TokenType) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "type"}, Value: t.String()}) + if err := e.EncodeToken(start); err != nil { + return err + } + return e.EncodeToken(xml.EndElement{Name: start.Name}) +} + +// This hijinks is a bit unfortunate but without it we can't deserialise into TokenType. +func newFromTemplate(template interface{}) (value func() interface{}, target interface{}) { + t := reflect.TypeOf(template) + if t.Kind() == reflect.Ptr { + v := reflect.New(t.Elem()) + return v.Interface, v.Interface() + } + v := reflect.New(t) + return func() interface{} { return v.Elem().Interface() }, v.Interface() +} + +func (b *Emitters) 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: + emitter, err := unmarshalEmitter(d, token) + if err != nil { + return err + } + *b = append(*b, emitter) + + case xml.EndElement: + return nil + } + } +} + +func (b Emitters) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if err := e.EncodeToken(start); err != nil { + return err + } + for _, m := range b { + if err := marshalEmitter(e, m); err != nil { + return err + } + } + return e.EncodeToken(xml.EndElement{Name: start.Name}) +} diff --git a/serialise_test.go b/serialise_test.go new file mode 100644 index 0000000..9177b54 --- /dev/null +++ b/serialise_test.go @@ -0,0 +1,166 @@ +package chroma + +import ( + "bytes" + "compress/gzip" + "encoding/xml" + "fmt" + "regexp" + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestEmitterSerialisationRoundTrip(t *testing.T) { + tests := []struct { + name string + emitter Emitter + }{ + {"ByGroups", ByGroups(Name, Using("Go"))}, + {"UsingSelf", UsingSelf("root")}, + {"Using", Using("Go")}, + {"UsingByGroup", UsingByGroup(1, 2, Name)}, + {"TokenType", Name}, + } + for _, test := range tests { + // nolint: scopelint + t.Run(test.name, func(t *testing.T) { + data, err := xml.Marshal(test.emitter) + assert.NoError(t, err) + t.Logf("%s", data) + value, target := newFromTemplate(test.emitter) + err = xml.Unmarshal(data, target) + assert.NoError(t, err) + assert.Equal(t, test.emitter, value().(Emitter)) + }) + } +} + +func TestMutatorSerialisationRoundTrip(t *testing.T) { + tests := []struct { + name string + mutator Mutator + }{ + {"Include", Include("string").Mutator}, + {"Combined", Combined("a", "b", "c")}, + {"Multi", Mutators(Include("string").Mutator, Push("quote"))}, + {"Push", Push("include")}, + {"Pop", Pop(1)}, + } + for _, test := range tests { + // nolint: scopelint + t.Run(test.name, func(t *testing.T) { + data, err := xml.Marshal(test.mutator) + assert.NoError(t, err) + t.Logf("%s", data) + value, target := newFromTemplate(test.mutator) + err = xml.Unmarshal(data, target) + assert.NoError(t, err) + assert.Equal(t, test.mutator, value().(Mutator)) + }) + } +} + +func TestMarshal(t *testing.T) { + actual := MustNewLexer(&Config{ + Name: "PkgConfig", + Aliases: []string{"pkgconfig"}, + Filenames: []string{"*.pc"}, + }, func() Rules { + return Rules{ + "root": { + {`#.*$`, CommentSingle, nil}, + {`^(\w+)(=)`, ByGroups(NameAttribute, Operator), nil}, + {`^([\w.]+)(:)`, ByGroups(NameTag, Punctuation), Push("spvalue")}, + Include("interp"), + {`[^${}#=:\n.]+`, Text, nil}, + {`.`, Text, nil}, + }, + "interp": { + {`\$\$`, Text, nil}, + {`\$\{`, LiteralStringInterpol, Push("curly")}, + }, + "curly": { + {`\}`, LiteralStringInterpol, Pop(1)}, + {`\w+`, NameAttribute, nil}, + }, + "spvalue": { + Include("interp"), + {`#.*$`, CommentSingle, Pop(1)}, + {`\n`, Text, Pop(1)}, + {`[^${}#\n]+`, Text, nil}, + {`.`, Text, nil}, + }, + } + }) + data, err := Marshal(actual) + assert.NoError(t, err) + expected, err := Unmarshal(data) + assert.NoError(t, err) + assert.Equal(t, expected.Config(), actual.Config()) + assert.Equal(t, mustRules(t, expected), mustRules(t, actual)) +} + +func mustRules(t testing.TB, r *RegexLexer) Rules { + t.Helper() + rules, err := r.Rules() + assert.NoError(t, err) + return rules +} + +func TestRuleSerialisation(t *testing.T) { + tests := []Rule{ + Include("String"), + {`\d+`, Text, nil}, + {`"`, String, Push("String")}, + } + for _, test := range tests { + data, err := xml.Marshal(test) + assert.NoError(t, err) + t.Log(string(data)) + actual := Rule{} + err = xml.Unmarshal(data, &actual) + assert.NoError(t, err) + assert.Equal(t, test, actual) + } +} + +func TestRulesSerialisation(t *testing.T) { + expected := Rules{ + "root": { + {`#.*$`, CommentSingle, nil}, + {`^(\w+)(=)`, ByGroups(NameAttribute, Operator), nil}, + {`^([\w.]+)(:)`, ByGroups(NameTag, Punctuation), Push("spvalue")}, + Include("interp"), + {`[^${}#=:\n.]+`, Text, nil}, + {`.`, Text, nil}, + }, + "interp": { + {`\$\$`, Text, nil}, + {`\$\{`, LiteralStringInterpol, Push("curly")}, + }, + "curly": { + {`\}`, LiteralStringInterpol, Pop(1)}, + {`\w+`, NameAttribute, nil}, + }, + "spvalue": { + Include("interp"), + {`#.*$`, CommentSingle, Pop(1)}, + {`\n`, Text, Pop(1)}, + {`[^${}#\n]+`, Text, nil}, + {`.`, Text, nil}, + }, + } + data, err := xml.MarshalIndent(expected, " ", " ") + assert.NoError(t, err) + re := regexp.MustCompile(`></[a-zA-Z]+>`) + data = re.ReplaceAll(data, []byte(`/>`)) + b := &bytes.Buffer{} + w := gzip.NewWriter(b) + fmt.Fprintln(w, string(data)) + w.Close() + actual := Rules{} + err = xml.Unmarshal(data, &actual) + assert.NoError(t, err) + assert.Equal(t, expected, actual) +} diff --git a/style.go b/style.go new file mode 100644 index 0000000..8cadaec --- /dev/null +++ b/style.go @@ -0,0 +1,493 @@ +package chroma + +import ( + "encoding/xml" + "fmt" + "io" + "sort" + "strings" +) + +// Trilean value for StyleEntry value inheritance. +type Trilean uint8 + +// Trilean states. +const ( + Pass Trilean = iota + Yes + No +) + +func (t Trilean) String() string { + switch t { + case Yes: + return "Yes" + case No: + return "No" + default: + return "Pass" + } +} + +// Prefix returns s with "no" as a prefix if Trilean is no. +func (t Trilean) Prefix(s string) string { + if t == Yes { + return s + } else if t == No { + return "no" + s + } + return "" +} + +// A StyleEntry in the Style map. +type StyleEntry struct { + // Hex colours. + Colour Colour + Background Colour + Border Colour + + Bold Trilean + Italic Trilean + Underline Trilean + NoInherit bool +} + +func (s StyleEntry) MarshalText() ([]byte, error) { + return []byte(s.String()), nil +} + +func (s StyleEntry) String() string { + out := []string{} + if s.Bold != Pass { + out = append(out, s.Bold.Prefix("bold")) + } + if s.Italic != Pass { + out = append(out, s.Italic.Prefix("italic")) + } + if s.Underline != Pass { + out = append(out, s.Underline.Prefix("underline")) + } + if s.NoInherit { + out = append(out, "noinherit") + } + if s.Colour.IsSet() { + out = append(out, s.Colour.String()) + } + if s.Background.IsSet() { + out = append(out, "bg:"+s.Background.String()) + } + if s.Border.IsSet() { + out = append(out, "border:"+s.Border.String()) + } + return strings.Join(out, " ") +} + +// Sub subtracts e from s where elements match. +func (s StyleEntry) Sub(e StyleEntry) StyleEntry { + out := StyleEntry{} + if e.Colour != s.Colour { + out.Colour = s.Colour + } + if e.Background != s.Background { + out.Background = s.Background + } + if e.Bold != s.Bold { + out.Bold = s.Bold + } + if e.Italic != s.Italic { + out.Italic = s.Italic + } + if e.Underline != s.Underline { + out.Underline = s.Underline + } + if e.Border != s.Border { + out.Border = s.Border + } + return out +} + +// Inherit styles from ancestors. +// +// Ancestors should be provided from oldest to newest. +func (s StyleEntry) Inherit(ancestors ...StyleEntry) StyleEntry { + out := s + for i := len(ancestors) - 1; i >= 0; i-- { + if out.NoInherit { + return out + } + ancestor := ancestors[i] + if !out.Colour.IsSet() { + out.Colour = ancestor.Colour + } + if !out.Background.IsSet() { + out.Background = ancestor.Background + } + if !out.Border.IsSet() { + out.Border = ancestor.Border + } + if out.Bold == Pass { + out.Bold = ancestor.Bold + } + if out.Italic == Pass { + out.Italic = ancestor.Italic + } + if out.Underline == Pass { + out.Underline = ancestor.Underline + } + } + return out +} + +func (s StyleEntry) IsZero() bool { + return s.Colour == 0 && s.Background == 0 && s.Border == 0 && s.Bold == Pass && s.Italic == Pass && + s.Underline == Pass && !s.NoInherit +} + +// A StyleBuilder is a mutable structure for building styles. +// +// Once built, a Style is immutable. +type StyleBuilder struct { + entries map[TokenType]string + name string + theme string + parent *Style +} + +func NewStyleBuilder(name string, theme string) *StyleBuilder { + return &StyleBuilder{name: name, theme: theme, entries: map[TokenType]string{}} +} + +func (s *StyleBuilder) AddAll(entries StyleEntries) *StyleBuilder { + for ttype, entry := range entries { + s.entries[ttype] = entry + } + return s +} + +func (s *StyleBuilder) Get(ttype TokenType) StyleEntry { + // This is less than ideal, but it's the price for not having to check errors on each Add(). + entry, _ := ParseStyleEntry(s.entries[ttype]) + if s.parent != nil { + entry = entry.Inherit(s.parent.Get(ttype)) + } + return entry +} + +// Add an entry to the Style map. +// +// See http://pygments.org/docs/styles/#style-rules for details. +func (s *StyleBuilder) Add(ttype TokenType, entry string) *StyleBuilder { // nolint: gocyclo + s.entries[ttype] = entry + return s +} + +func (s *StyleBuilder) AddEntry(ttype TokenType, entry StyleEntry) *StyleBuilder { + s.entries[ttype] = entry.String() + return s +} + +// Transform passes each style entry currently defined in the builder to the supplied +// function and saves the returned value. This can be used to adjust a style's colours; +// see Colour's ClampBrightness function, for example. +func (s *StyleBuilder) Transform(transform func(StyleEntry) StyleEntry) *StyleBuilder { + types := make(map[TokenType]struct{}) + for tt := range s.entries { + types[tt] = struct{}{} + } + if s.parent != nil { + for _, tt := range s.parent.Types() { + types[tt] = struct{}{} + } + } + for tt := range types { + s.AddEntry(tt, transform(s.Get(tt))) + } + return s +} + +func (s *StyleBuilder) Build() (*Style, error) { + style := &Style{ + Name: s.name, + Theme: s.theme, + entries: map[TokenType]StyleEntry{}, + parent: s.parent, + } + for ttype, descriptor := range s.entries { + entry, err := ParseStyleEntry(descriptor) + if err != nil { + return nil, fmt.Errorf("invalid entry for %s: %s", ttype, err) + } + style.entries[ttype] = entry + } + return style, nil +} + +// StyleEntries mapping TokenType to colour definition. +type StyleEntries map[TokenType]string + +// NewXMLStyle parses an XML style definition. +func NewXMLStyle(r io.Reader) (*Style, error) { + dec := xml.NewDecoder(r) + style := &Style{} + return style, dec.Decode(style) +} + +// MustNewXMLStyle is like NewXMLStyle but panics on error. +func MustNewXMLStyle(r io.Reader) *Style { + style, err := NewXMLStyle(r) + if err != nil { + panic(err) + } + return style +} + +// NewStyle creates a new style definition. +func NewStyle(name string, theme string, entries StyleEntries) (*Style, error) { + return NewStyleBuilder(name, theme).AddAll(entries).Build() +} + +// MustNewStyle creates a new style or panics. +func MustNewStyle(name string, theme string, entries StyleEntries) *Style { + style, err := NewStyle(name, theme, entries) + if err != nil { + panic(err) + } + return style +} + +// A Style definition. +// +// See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical. +type Style struct { + Name string + Theme string + entries map[TokenType]StyleEntry + parent *Style +} + +func (s *Style) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if s.parent != nil { + return fmt.Errorf("cannot marshal style with parent") + } + start.Name = xml.Name{Local: "style"} + start.Attr = []xml.Attr{ + {Name: xml.Name{Local: "name"}, Value: s.Name}, + {Name: xml.Name{Local: "theme"}, Value: s.Theme}, + } + if err := e.EncodeToken(start); err != nil { + return err + } + sorted := make([]TokenType, 0, len(s.entries)) + for ttype := range s.entries { + sorted = append(sorted, ttype) + } + sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) + for _, ttype := range sorted { + entry := s.entries[ttype] + el := xml.StartElement{Name: xml.Name{Local: "entry"}} + el.Attr = []xml.Attr{ + {Name: xml.Name{Local: "type"}, Value: ttype.String()}, + {Name: xml.Name{Local: "style"}, Value: entry.String()}, + } + if err := e.EncodeToken(el); err != nil { + return err + } + if err := e.EncodeToken(xml.EndElement{Name: el.Name}); err != nil { + return err + } + } + return e.EncodeToken(xml.EndElement{Name: start.Name}) +} + +func (s *Style) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for _, attr := range start.Attr { + if attr.Name.Local == "name" { + s.Name = attr.Value + } else if attr.Name.Local == "theme" { + s.Theme = attr.Value + } else { + return fmt.Errorf("unexpected attribute %s", attr.Name.Local) + } + } + if s.Name == "" { + return fmt.Errorf("missing style name attribute") + } + if s.Theme == "" { + return fmt.Errorf("missing style theme attribute") + } + s.entries = map[TokenType]StyleEntry{} + for { + tok, err := d.Token() + if err != nil { + return err + } + switch el := tok.(type) { + case xml.StartElement: + if el.Name.Local != "entry" { + return fmt.Errorf("unexpected element %s", el.Name.Local) + } + var ttype TokenType + var entry StyleEntry + for _, attr := range el.Attr { + switch attr.Name.Local { + case "type": + ttype, err = TokenTypeString(attr.Value) + if err != nil { + return err + } + + case "style": + entry, err = ParseStyleEntry(attr.Value) + if err != nil { + return err + } + + default: + return fmt.Errorf("unexpected attribute %s", attr.Name.Local) + } + } + s.entries[ttype] = entry + + case xml.EndElement: + if el.Name.Local == start.Name.Local { + return nil + } + } + } +} + +// Types that are styled. +func (s *Style) Types() []TokenType { + dedupe := map[TokenType]bool{} + for tt := range s.entries { + dedupe[tt] = true + } + if s.parent != nil { + for _, tt := range s.parent.Types() { + dedupe[tt] = true + } + } + out := make([]TokenType, 0, len(dedupe)) + for tt := range dedupe { + out = append(out, tt) + } + return out +} + +// Builder creates a mutable builder from this Style. +// +// The builder can then be safely modified. This is a cheap operation. +func (s *Style) Builder() *StyleBuilder { + return &StyleBuilder{ + name: s.Name, + theme: s.Theme, + entries: map[TokenType]string{}, + parent: s, + } +} + +// Has checks if an exact style entry match exists for a token type. +// +// This is distinct from Get() which will merge parent tokens. +func (s *Style) Has(ttype TokenType) bool { + return !s.get(ttype).IsZero() || s.synthesisable(ttype) +} + +// Get a style entry. Will try sub-category or category if an exact match is not found, and +// finally return the Background. +func (s *Style) Get(ttype TokenType) StyleEntry { + return s.get(ttype).Inherit( + s.get(Background), + s.get(Text), + s.get(ttype.Category()), + s.get(ttype.SubCategory())) +} + +func (s *Style) get(ttype TokenType) StyleEntry { + out := s.entries[ttype] + if out.IsZero() && s.parent != nil { + return s.parent.get(ttype) + } + if out.IsZero() && s.synthesisable(ttype) { + out = s.synthesise(ttype) + } + return out +} + +func (s *Style) synthesise(ttype TokenType) StyleEntry { + bg := s.get(Background) + text := StyleEntry{Colour: bg.Colour} + text.Colour = text.Colour.BrightenOrDarken(0.5) + + switch ttype { + // If we don't have a line highlight colour, make one that is 10% brighter/darker than the background. + case LineHighlight: + return StyleEntry{Background: bg.Background.BrightenOrDarken(0.1)} + + // If we don't have line numbers, use the text colour but 20% brighter/darker + case LineNumbers, LineNumbersTable: + return text + + default: + return StyleEntry{} + } +} + +func (s *Style) synthesisable(ttype TokenType) bool { + return ttype == LineHighlight || ttype == LineNumbers || ttype == LineNumbersTable +} + +// MustParseStyleEntry parses a Pygments style entry or panics. +func MustParseStyleEntry(entry string) StyleEntry { + out, err := ParseStyleEntry(entry) + if err != nil { + panic(err) + } + return out +} + +// ParseStyleEntry parses a Pygments style entry. +func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo + out := StyleEntry{} + parts := strings.Fields(entry) + for _, part := range parts { + switch { + case part == "italic": + out.Italic = Yes + case part == "noitalic": + out.Italic = No + case part == "bold": + out.Bold = Yes + case part == "nobold": + out.Bold = No + case part == "underline": + out.Underline = Yes + case part == "nounderline": + out.Underline = No + case part == "inherit": + out.NoInherit = false + case part == "noinherit": + out.NoInherit = true + case part == "bg:": + out.Background = 0 + case strings.HasPrefix(part, "bg:#"): + out.Background = ParseColour(part[3:]) + if !out.Background.IsSet() { + return StyleEntry{}, fmt.Errorf("invalid background colour %q", part) + } + case strings.HasPrefix(part, "border:#"): + out.Border = ParseColour(part[7:]) + if !out.Border.IsSet() { + return StyleEntry{}, fmt.Errorf("invalid border colour %q", part) + } + case strings.HasPrefix(part, "#"): + out.Colour = ParseColour(part) + if !out.Colour.IsSet() { + return StyleEntry{}, fmt.Errorf("invalid colour %q", part) + } + default: + return StyleEntry{}, fmt.Errorf("unknown style element %q", part) + } + } + return out, nil +} diff --git a/style_test.go b/style_test.go new file mode 100644 index 0000000..becf19d --- /dev/null +++ b/style_test.go @@ -0,0 +1,122 @@ +package chroma + +import ( + "encoding/xml" + "testing" + + "github.com/alecthomas/assert/v2" +) + +func TestStyleInherit(t *testing.T) { + s, err := NewStyle("test", "dark", StyleEntries{ + Name: "bold #f00", + NameVariable: "#fff", + }) + assert.NoError(t, err) + assert.Equal(t, StyleEntry{Colour: 0x1000000, Bold: Yes}, s.Get(NameVariable)) +} + +func TestStyleColours(t *testing.T) { + s, err := NewStyle("test", "dark", StyleEntries{ + Name: "#f00 bg:#001 border:#ansiblue", + }) + assert.NoError(t, err) + assert.Equal(t, StyleEntry{Colour: 0xff0001, Background: 0x000012, Border: 0x000100}, s.Get(Name)) +} + +func TestStyleClone(t *testing.T) { + parent, err := NewStyle("test", "dark", StyleEntries{ + Background: "bg:#ffffff", + }) + assert.NoError(t, err) + clone, err := parent.Builder().Add(Comment, "#0f0").Build() + assert.NoError(t, err) + + assert.Equal(t, "bg:#ffffff", clone.Get(Background).String()) + assert.Equal(t, "#00ff00 bg:#ffffff", clone.Get(Comment).String()) + assert.Equal(t, "bg:#ffffff", parent.Get(Comment).String()) +} + +func TestSynthesisedStyleEntries(t *testing.T) { + style, err := NewStyle("test", "dark", StyleEntries{ + Background: "bg:#ffffff", + }) + assert.NoError(t, err) + assert.True(t, style.Has(LineHighlight)) + assert.True(t, style.Has(LineNumbersTable)) + assert.True(t, style.Has(LineNumbers)) + assert.Equal(t, "bg:#e5e5e5", style.Get(LineHighlight).String()) + assert.Equal(t, "#7f7f7f bg:#ffffff", style.Get(LineNumbers).String()) + assert.Equal(t, "#7f7f7f bg:#ffffff", style.Get(LineNumbersTable).String()) +} + +func TestSynthesisedStyleClone(t *testing.T) { + style, err := NewStyle("test", "dark", StyleEntries{ + Background: "bg:#ffffff", + LineHighlight: "bg:#ffffff", + LineNumbers: "bg:#fffff1", + }) + assert.NoError(t, err) + style, err = style.Builder().Build() + assert.NoError(t, err) + assert.True(t, style.Has(LineHighlight)) + assert.True(t, style.Has(LineNumbers)) + assert.Equal(t, "bg:#ffffff", style.Get(LineHighlight).String()) + assert.Equal(t, "bg:#fffff1", style.Get(LineNumbers).String()) +} + +func TestStyleBuilderTransform(t *testing.T) { + orig, err := NewStyle("test", "dark", StyleEntries{ + Name: "#000", + NameVariable: "bold #f00", + }) + assert.NoError(t, err) + + // Derive a style that inherits entries from orig. + builder := orig.Builder() + builder.Add(NameVariableGlobal, "#f30") + deriv, err := builder.Build() + assert.NoError(t, err) + + // Use Transform to brighten or darken all of the colours in the derived style. + light, err := deriv.Builder().Transform(func(se StyleEntry) StyleEntry { + se.Colour = se.Colour.ClampBrightness(0.9, 1) + return se + }).Build() + assert.NoError(t, err, "Transform failed: %v", err) + assert.True(t, light.Get(Name).Colour.Brightness() >= 0.89) + assert.True(t, light.Get(NameVariable).Colour.Brightness() >= 0.89) + assert.True(t, light.Get(NameVariableGlobal).Colour.Brightness() >= 0.89) + + dark, err := deriv.Builder().Transform(func(se StyleEntry) StyleEntry { + se.Colour = se.Colour.ClampBrightness(0, 0.1) + return se + }).Build() + assert.NoError(t, err, "Transform failed: %v", err) + assert.True(t, dark.Get(Name).Colour.Brightness() <= 0.11) + assert.True(t, dark.Get(NameVariable).Colour.Brightness() <= 0.11) + assert.True(t, dark.Get(NameVariableGlobal).Colour.Brightness() <= 0.11) + + // The original styles should be unchanged. + assert.Equal(t, "#000000", orig.Get(Name).Colour.String()) + assert.Equal(t, "#ff0000", orig.Get(NameVariable).Colour.String()) + assert.Equal(t, "#ff3300", deriv.Get(NameVariableGlobal).Colour.String()) +} + +func TestStyleMarshaller(t *testing.T) { + expected, err := NewStyle("test", "dark", StyleEntries{ + Whitespace: "bg:#ffffff", + Text: "#000000 underline", + }) + assert.NoError(t, err) + data, err := xml.MarshalIndent(expected, "", " ") + assert.NoError(t, err) + assert.Equal(t, `<style name="test"> + <entry type="Text" style="underline #000000"></entry> + <entry type="TextWhitespace" style="bg:#ffffff"></entry> +</style>`, string(data)) + actual := &Style{} + err = xml.Unmarshal(data, actual) + assert.NoError(t, err) + assert.Equal(t, expected, actual) +} diff --git a/styles/api.go b/styles/api.go new file mode 100644 index 0000000..2936aeb --- /dev/null +++ b/styles/api.go @@ -0,0 +1,93 @@ +package styles + +import ( + "embed" + "io/fs" + "path/filepath" + "sort" + + "toastielab.dev/toastie-stuff/chroma/v2" + "toastielab.dev/toastie-stuff/chroma/v2/base16" +) + +//go:embed embedded +var embedded embed.FS + +// Registry of Styles. +var Registry = func() map[string]*chroma.Style { + registry := map[string]*chroma.Style{} + // Register all embedded styles. + embeddedSub, err := fs.Sub(embedded, "embedded") + if err != nil { + panic(err) + } + styles, err := LoadFromFS(embeddedSub) + if err != nil { + panic(err) + } + for _, style := range styles { + registry[style.Name] = style + } + return registry +}() + +// Fallback style. Reassign to change the default fallback style. +var Fallback = Registry["swapoff"] + +func LoadFromFS(fsys fs.FS) ([]*chroma.Style, error) { + files, err := fs.ReadDir(fsys, ".") + if err != nil { + return nil, err + } + + styles := make([]*chroma.Style, 0, len(files)) + for _, file := range files { + if file.IsDir() { + continue + } + + r, err := fsys.Open(file.Name()) + if err != nil { + return nil, err + } + + var style *chroma.Style + switch filepath.Ext(file.Name()) { + case ".xml": + style, err = chroma.NewXMLStyle(r) + case ".yaml", ".yml": + style, err = base16.NewStyle(r) + } + if err != nil { + return nil, err + } + + styles = append(styles, style) + } + + return styles, nil +} + +// Register a chroma.Style. +func Register(style *chroma.Style) *chroma.Style { + Registry[style.Name] = style + return style +} + +// Names of all available styles. +func Names() []string { + out := []string{} + for name := range Registry { + out = append(out, name) + } + sort.Strings(out) + return out +} + +// Get named style, or Fallback. +func Get(name string) *chroma.Style { + if style, ok := Registry[name]; ok { + return style + } + return Fallback +} diff --git a/styles/embedded/abap.xml b/styles/embedded/abap.xml new file mode 100644 index 0000000..8f0f1d3 --- /dev/null +++ b/styles/embedded/abap.xml @@ -0,0 +1,11 @@ +<style name="abap" theme="light"> + <entry type="Error" style="#ff0000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#0000ff"/> + <entry type="Name" style="#000000"/> + <entry type="LiteralString" style="#55aa22"/> + <entry type="LiteralNumber" style="#33aaff"/> + <entry type="OperatorWord" style="#0000ff"/> + <entry type="Comment" style="italic #888888"/> + <entry type="CommentSpecial" style="#888888"/> +</style> \ No newline at end of file diff --git a/styles/embedded/algol.xml b/styles/embedded/algol.xml new file mode 100644 index 0000000..8abc640 --- /dev/null +++ b/styles/embedded/algol.xml @@ -0,0 +1,18 @@ +<style name="algol" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold underline"/> + <entry type="KeywordDeclaration" style="italic"/> + <entry type="NameBuiltin" style="bold italic"/> + <entry type="NameBuiltinPseudo" style="bold italic"/> + <entry type="NameClass" style="bold italic #666666"/> + <entry type="NameConstant" style="bold italic #666666"/> + <entry type="NameFunction" style="bold italic #666666"/> + <entry type="NameNamespace" style="bold italic #666666"/> + <entry type="NameVariable" style="bold italic #666666"/> + <entry type="LiteralString" style="italic #666666"/> + <entry type="OperatorWord" style="bold"/> + <entry type="Comment" style="italic #888888"/> + <entry type="CommentSpecial" style="bold noitalic #888888"/> + <entry type="CommentPreproc" style="bold noitalic #888888"/> +</style> \ No newline at end of file diff --git a/styles/embedded/algol_nu.xml b/styles/embedded/algol_nu.xml new file mode 100644 index 0000000..ad296ca --- /dev/null +++ b/styles/embedded/algol_nu.xml @@ -0,0 +1,18 @@ +<style name="algol_nu" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold"/> + <entry type="KeywordDeclaration" style="italic"/> + <entry type="NameBuiltin" style="bold italic"/> + <entry type="NameBuiltinPseudo" style="bold italic"/> + <entry type="NameClass" style="bold italic #666666"/> + <entry type="NameConstant" style="bold italic #666666"/> + <entry type="NameFunction" style="bold italic #666666"/> + <entry type="NameNamespace" style="bold italic #666666"/> + <entry type="NameVariable" style="bold italic #666666"/> + <entry type="LiteralString" style="italic #666666"/> + <entry type="OperatorWord" style="bold"/> + <entry type="Comment" style="italic #888888"/> + <entry type="CommentSpecial" style="bold noitalic #888888"/> + <entry type="CommentPreproc" style="bold noitalic #888888"/> +</style> \ No newline at end of file diff --git a/styles/embedded/arduino.xml b/styles/embedded/arduino.xml new file mode 100644 index 0000000..bbf6197 --- /dev/null +++ b/styles/embedded/arduino.xml @@ -0,0 +1,18 @@ +<style name="arduino" theme="light"> + <entry type="Error" style="#a61717"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#728e00"/> + <entry type="KeywordConstant" style="#00979d"/> + <entry type="KeywordPseudo" style="#00979d"/> + <entry type="KeywordReserved" style="#00979d"/> + <entry type="KeywordType" style="#00979d"/> + <entry type="Name" style="#434f54"/> + <entry type="NameBuiltin" style="#728e00"/> + <entry type="NameFunction" style="#d35400"/> + <entry type="NameOther" style="#728e00"/> + <entry type="LiteralString" style="#7f8c8d"/> + <entry type="LiteralNumber" style="#8a7b52"/> + <entry type="Operator" style="#728e00"/> + <entry type="Comment" style="#95a5a6"/> + <entry type="CommentPreproc" style="#728e00"/> +</style> \ No newline at end of file diff --git a/styles/embedded/autumn.xml b/styles/embedded/autumn.xml new file mode 100644 index 0000000..453e407 --- /dev/null +++ b/styles/embedded/autumn.xml @@ -0,0 +1,36 @@ +<style name="autumn" theme="light"> + <entry type="Error" style="#ff0000 bg:#ffaaaa"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#0000aa"/> + <entry type="KeywordType" style="#00aaaa"/> + <entry type="NameAttribute" style="#1e90ff"/> + <entry type="NameBuiltin" style="#00aaaa"/> + <entry type="NameClass" style="underline #00aa00"/> + <entry type="NameConstant" style="#aa0000"/> + <entry type="NameDecorator" style="#888888"/> + <entry type="NameEntity" style="bold #880000"/> + <entry type="NameFunction" style="#00aa00"/> + <entry type="NameNamespace" style="underline #00aaaa"/> + <entry type="NameTag" style="bold #1e90ff"/> + <entry type="NameVariable" style="#aa0000"/> + <entry type="LiteralString" style="#aa5500"/> + <entry type="LiteralStringRegex" style="#009999"/> + <entry type="LiteralStringSymbol" style="#0000aa"/> + <entry type="LiteralNumber" style="#009999"/> + <entry type="OperatorWord" style="#0000aa"/> + <entry type="Comment" style="italic #aaaaaa"/> + <entry type="CommentSpecial" style="italic #0000aa"/> + <entry type="CommentPreproc" style="noitalic #4c8317"/> + <entry type="GenericDeleted" style="#aa0000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#aa0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00aa00"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="#555555"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#aa0000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/average.xml b/styles/embedded/average.xml new file mode 100644 index 0000000..65502fa --- /dev/null +++ b/styles/embedded/average.xml @@ -0,0 +1,74 @@ +<style name="average" theme="dark"> + <entry type="Other" style="#757575"/> + <entry type="Error" style="#ec0000"/> + <entry type="Background" style="bg:#000000"/> + <entry type="Keyword" style="#ec0000"/> + <entry type="KeywordConstant" style="#ec0000"/> + <entry type="KeywordDeclaration" style="#ec0000"/> + <entry type="KeywordNamespace" style="#ec0000"/> + <entry type="KeywordPseudo" style="#ec0000"/> + <entry type="KeywordReserved" style="#ec0000"/> + <entry type="KeywordType" style="#5f5fff"/> + <entry type="Name" style="#757575"/> + <entry type="NameAttribute" style="#5f5fff"/> + <entry type="NameBuiltin" style="#ec0000"/> + <entry type="NameBuiltinPseudo" style="#757575"/> + <entry type="NameClass" style="#5f5fff"/> + <entry type="NameConstant" style="#008900"/> + <entry type="NameDecorator" style="#008900"/> + <entry type="NameEntity" style="#757575"/> + <entry type="NameException" style="#757575"/> + <entry type="NameFunction" style="#5f5fff"/> + <entry type="NameLabel" style="#ec0000"/> + <entry type="NameNamespace" style="#757575"/> + <entry type="NameOther" style="#757575"/> + <entry type="NameTag" style="#ec0000"/> + <entry type="NameVariable" style="#ec0000"/> + <entry type="NameVariableClass" style="#ec0000"/> + <entry type="NameVariableGlobal" style="#ec0000"/> + <entry type="NameVariableInstance" style="#ec0000"/> + <entry type="Literal" style="#757575"/> + <entry type="LiteralDate" style="#757575"/> + <entry type="LiteralString" style="#008900"/> + <entry type="LiteralStringBacktick" style="#008900"/> + <entry type="LiteralStringChar" style="#008900"/> + <entry type="LiteralStringDoc" style="#008900"/> + <entry type="LiteralStringDouble" style="#008900"/> + <entry type="LiteralStringEscape" style="#008900"/> + <entry type="LiteralStringHeredoc" style="#008900"/> + <entry type="LiteralStringInterpol" style="#008900"/> + <entry type="LiteralStringOther" style="#008900"/> + <entry type="LiteralStringRegex" style="#008900"/> + <entry type="LiteralStringSingle" style="#008900"/> + <entry type="LiteralStringSymbol" style="#008900"/> + <entry type="LiteralNumber" style="#008900"/> + <entry type="LiteralNumberBin" style="#008900"/> + <entry type="LiteralNumberFloat" style="#008900"/> + <entry type="LiteralNumberHex" style="#008900"/> + <entry type="LiteralNumberInteger" style="#008900"/> + <entry type="LiteralNumberIntegerLong" style="#008900"/> + <entry type="LiteralNumberOct" style="#008900"/> + <entry type="Operator" style="#ec0000"/> + <entry type="OperatorWord" style="#ec0000"/> + <entry type="Punctuation" style="#757575"/> + <entry type="Comment" style="#757575"/> + <entry type="CommentHashbang" style="#757575"/> + <entry type="CommentMultiline" style="#757575"/> + <entry type="CommentSingle" style="#757575"/> + <entry type="CommentSpecial" style="#757575"/> + <entry type="CommentPreproc" style="#757575"/> + <entry type="Generic" style="#757575"/> + <entry type="GenericDeleted" style="#ec0000"/> + <entry type="GenericEmph" style="underline #757575"/> + <entry type="GenericError" style="#ec0000"/> + <entry type="GenericHeading" style="bold #757575"/> + <entry type="GenericInserted" style="bold #757575"/> + <entry type="GenericOutput" style="#757575"/> + <entry type="GenericPrompt" style="#757575"/> + <entry type="GenericStrong" style="italic #757575"/> + <entry type="GenericSubheading" style="bold #757575"/> + <entry type="GenericTraceback" style="#757575"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#757575"/> + <entry type="TextWhitespace" style="#757575"/> +</style> \ No newline at end of file diff --git a/styles/embedded/base16-snazzy.xml b/styles/embedded/base16-snazzy.xml new file mode 100644 index 0000000..d4a5c0a --- /dev/null +++ b/styles/embedded/base16-snazzy.xml @@ -0,0 +1,74 @@ +<style name="base16-snazzy" theme="dark"> + <entry type="Other" style="#e2e4e5"/> + <entry type="Error" style="#ff5c57"/> + <entry type="Background" style="bg:#282a36"/> + <entry type="Keyword" style="#ff6ac1"/> + <entry type="KeywordConstant" style="#ff6ac1"/> + <entry type="KeywordDeclaration" style="#ff5c57"/> + <entry type="KeywordNamespace" style="#ff6ac1"/> + <entry type="KeywordPseudo" style="#ff6ac1"/> + <entry type="KeywordReserved" style="#ff6ac1"/> + <entry type="KeywordType" style="#9aedfe"/> + <entry type="Name" style="#e2e4e5"/> + <entry type="NameAttribute" style="#57c7ff"/> + <entry type="NameBuiltin" style="#ff5c57"/> + <entry type="NameBuiltinPseudo" style="#e2e4e5"/> + <entry type="NameClass" style="#f3f99d"/> + <entry type="NameConstant" style="#ff9f43"/> + <entry type="NameDecorator" style="#ff9f43"/> + <entry type="NameEntity" style="#e2e4e5"/> + <entry type="NameException" style="#e2e4e5"/> + <entry type="NameFunction" style="#57c7ff"/> + <entry type="NameLabel" style="#ff5c57"/> + <entry type="NameNamespace" style="#e2e4e5"/> + <entry type="NameOther" style="#e2e4e5"/> + <entry type="NameTag" style="#ff6ac1"/> + <entry type="NameVariable" style="#ff5c57"/> + <entry type="NameVariableClass" style="#ff5c57"/> + <entry type="NameVariableGlobal" style="#ff5c57"/> + <entry type="NameVariableInstance" style="#ff5c57"/> + <entry type="Literal" style="#e2e4e5"/> + <entry type="LiteralDate" style="#e2e4e5"/> + <entry type="LiteralString" style="#5af78e"/> + <entry type="LiteralStringBacktick" style="#5af78e"/> + <entry type="LiteralStringChar" style="#5af78e"/> + <entry type="LiteralStringDoc" style="#5af78e"/> + <entry type="LiteralStringDouble" style="#5af78e"/> + <entry type="LiteralStringEscape" style="#5af78e"/> + <entry type="LiteralStringHeredoc" style="#5af78e"/> + <entry type="LiteralStringInterpol" style="#5af78e"/> + <entry type="LiteralStringOther" style="#5af78e"/> + <entry type="LiteralStringRegex" style="#5af78e"/> + <entry type="LiteralStringSingle" style="#5af78e"/> + <entry type="LiteralStringSymbol" style="#5af78e"/> + <entry type="LiteralNumber" style="#ff9f43"/> + <entry type="LiteralNumberBin" style="#ff9f43"/> + <entry type="LiteralNumberFloat" style="#ff9f43"/> + <entry type="LiteralNumberHex" style="#ff9f43"/> + <entry type="LiteralNumberInteger" style="#ff9f43"/> + <entry type="LiteralNumberIntegerLong" style="#ff9f43"/> + <entry type="LiteralNumberOct" style="#ff9f43"/> + <entry type="Operator" style="#ff6ac1"/> + <entry type="OperatorWord" style="#ff6ac1"/> + <entry type="Punctuation" style="#e2e4e5"/> + <entry type="Comment" style="#78787e"/> + <entry type="CommentHashbang" style="#78787e"/> + <entry type="CommentMultiline" style="#78787e"/> + <entry type="CommentSingle" style="#78787e"/> + <entry type="CommentSpecial" style="#78787e"/> + <entry type="CommentPreproc" style="#78787e"/> + <entry type="Generic" style="#e2e4e5"/> + <entry type="GenericDeleted" style="#ff5c57"/> + <entry type="GenericEmph" style="underline #e2e4e5"/> + <entry type="GenericError" style="#ff5c57"/> + <entry type="GenericHeading" style="bold #e2e4e5"/> + <entry type="GenericInserted" style="bold #e2e4e5"/> + <entry type="GenericOutput" style="#43454f"/> + <entry type="GenericPrompt" style="#e2e4e5"/> + <entry type="GenericStrong" style="italic #e2e4e5"/> + <entry type="GenericSubheading" style="bold #e2e4e5"/> + <entry type="GenericTraceback" style="#e2e4e5"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#e2e4e5"/> + <entry type="TextWhitespace" style="#e2e4e5"/> +</style> \ No newline at end of file diff --git a/styles/embedded/borland.xml b/styles/embedded/borland.xml new file mode 100644 index 0000000..0c1d4e9 --- /dev/null +++ b/styles/embedded/borland.xml @@ -0,0 +1,26 @@ +<style name="borland" theme="light"> + <entry type="Error" style="#a61717 bg:#e3d2d2"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold #000080"/> + <entry type="NameAttribute" style="#ff0000"/> + <entry type="NameTag" style="bold #000080"/> + <entry type="LiteralString" style="#0000ff"/> + <entry type="LiteralStringChar" style="#800080"/> + <entry type="LiteralNumber" style="#0000ff"/> + <entry type="OperatorWord" style="bold"/> + <entry type="Comment" style="italic #008800"/> + <entry type="CommentSpecial" style="bold noitalic"/> + <entry type="CommentPreproc" style="noitalic #008080"/> + <entry type="GenericDeleted" style="#000000 bg:#ffdddd"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#aa0000"/> + <entry type="GenericHeading" style="#999999"/> + <entry type="GenericInserted" style="#000000 bg:#ddffdd"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="#555555"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#aaaaaa"/> + <entry type="GenericTraceback" style="#aa0000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/bw.xml b/styles/embedded/bw.xml new file mode 100644 index 0000000..e454f61 --- /dev/null +++ b/styles/embedded/bw.xml @@ -0,0 +1,23 @@ +<style name="bw" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="nobold"/> + <entry type="NameClass" style="bold"/> + <entry type="NameEntity" style="bold"/> + <entry type="NameException" style="bold"/> + <entry type="NameNamespace" style="bold"/> + <entry type="NameTag" style="bold"/> + <entry type="LiteralString" style="italic"/> + <entry type="LiteralStringEscape" style="bold"/> + <entry type="LiteralStringInterpol" style="bold"/> + <entry type="OperatorWord" style="bold"/> + <entry type="Comment" style="italic"/> + <entry type="CommentPreproc" style="noitalic"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericHeading" style="bold"/> + <entry type="GenericPrompt" style="bold"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold"/> +</style> \ No newline at end of file diff --git a/styles/embedded/catppuccin-frappe.xml b/styles/embedded/catppuccin-frappe.xml new file mode 100644 index 0000000..b3827a3 --- /dev/null +++ b/styles/embedded/catppuccin-frappe.xml @@ -0,0 +1,83 @@ +<style name="catppuccin-frappe" theme="dark"> + <entry type="Background" style="bg:#303446 #c6d0f5"/> + <entry type="CodeLine" style="#c6d0f5"/> + <entry type="Error" style="#e78284"/> + <entry type="Other" style="#c6d0f5"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#51576d"/> + <entry type="LineNumbersTable" style="#838ba7"/> + <entry type="LineNumbers" style="#838ba7"/> + <entry type="Keyword" style="#ca9ee6"/> + <entry type="KeywordReserved" style="#ca9ee6"/> + <entry type="KeywordPseudo" style="#ca9ee6"/> + <entry type="KeywordConstant" style="#ef9f76"/> + <entry type="KeywordDeclaration" style="#e78284"/> + <entry type="KeywordNamespace" style="#81c8be"/> + <entry type="KeywordType" style="#e78284"/> + <entry type="Name" style="#c6d0f5"/> + <entry type="NameClass" style="#e5c890"/> + <entry type="NameConstant" style="#e5c890"/> + <entry type="NameDecorator" style="bold #8caaee"/> + <entry type="NameEntity" style="#81c8be"/> + <entry type="NameException" style="#ef9f76"/> + <entry type="NameFunction" style="#8caaee"/> + <entry type="NameFunctionMagic" style="#8caaee"/> + <entry type="NameLabel" style="#99d1db"/> + <entry type="NameNamespace" style="#ef9f76"/> + <entry type="NameProperty" style="#ef9f76"/> + <entry type="NameTag" style="#ca9ee6"/> + <entry type="NameVariable" style="#f2d5cf"/> + <entry type="NameVariableClass" style="#f2d5cf"/> + <entry type="NameVariableGlobal" style="#f2d5cf"/> + <entry type="NameVariableInstance" style="#f2d5cf"/> + <entry type="NameVariableMagic" style="#f2d5cf"/> + <entry type="NameAttribute" style="#8caaee"/> + <entry type="NameBuiltin" style="#99d1db"/> + <entry type="NameBuiltinPseudo" style="#99d1db"/> + <entry type="NameOther" style="#c6d0f5"/> + <entry type="Literal" style="#c6d0f5"/> + <entry type="LiteralDate" style="#c6d0f5"/> + <entry type="LiteralString" style="#a6d189"/> + <entry type="LiteralStringChar" style="#a6d189"/> + <entry type="LiteralStringSingle" style="#a6d189"/> + <entry type="LiteralStringDouble" style="#a6d189"/> + <entry type="LiteralStringBacktick" style="#a6d189"/> + <entry type="LiteralStringOther" style="#a6d189"/> + <entry type="LiteralStringSymbol" style="#a6d189"/> + <entry type="LiteralStringInterpol" style="#a6d189"/> + <entry type="LiteralStringAffix" style="#e78284"/> + <entry type="LiteralStringDelimiter" style="#8caaee"/> + <entry type="LiteralStringEscape" style="#8caaee"/> + <entry type="LiteralStringRegex" style="#81c8be"/> + <entry type="LiteralStringDoc" style="#737994"/> + <entry type="LiteralStringHeredoc" style="#737994"/> + <entry type="LiteralNumber" style="#ef9f76"/> + <entry type="LiteralNumberBin" style="#ef9f76"/> + <entry type="LiteralNumberHex" style="#ef9f76"/> + <entry type="LiteralNumberInteger" style="#ef9f76"/> + <entry type="LiteralNumberFloat" style="#ef9f76"/> + <entry type="LiteralNumberIntegerLong" style="#ef9f76"/> + <entry type="LiteralNumberOct" style="#ef9f76"/> + <entry type="Operator" style="bold #99d1db"/> + <entry type="OperatorWord" style="bold #99d1db"/> + <entry type="Comment" style="italic #737994"/> + <entry type="CommentSingle" style="italic #737994"/> + <entry type="CommentMultiline" style="italic #737994"/> + <entry type="CommentSpecial" style="italic #737994"/> + <entry type="CommentHashbang" style="italic #737994"/> + <entry type="CommentPreproc" style="italic #737994"/> + <entry type="CommentPreprocFile" style="bold #737994"/> + <entry type="Generic" style="#c6d0f5"/> + <entry type="GenericInserted" style="bg:#414559 #a6d189"/> + <entry type="GenericDeleted" style="#e78284 bg:#414559"/> + <entry type="GenericEmph" style="italic #c6d0f5"/> + <entry type="GenericStrong" style="bold #c6d0f5"/> + <entry type="GenericUnderline" style="underline #c6d0f5"/> + <entry type="GenericHeading" style="bold #ef9f76"/> + <entry type="GenericSubheading" style="bold #ef9f76"/> + <entry type="GenericOutput" style="#c6d0f5"/> + <entry type="GenericPrompt" style="#c6d0f5"/> + <entry type="GenericError" style="#e78284"/> + <entry type="GenericTraceback" style="#e78284"/> +</style> \ No newline at end of file diff --git a/styles/embedded/catppuccin-latte.xml b/styles/embedded/catppuccin-latte.xml new file mode 100644 index 0000000..48187f2 --- /dev/null +++ b/styles/embedded/catppuccin-latte.xml @@ -0,0 +1,83 @@ +<style name="catppuccin-latte" theme="light"> + <entry type="Background" style="bg:#eff1f5 #4c4f69"/> + <entry type="CodeLine" style="#4c4f69"/> + <entry type="Error" style="#d20f39"/> + <entry type="Other" style="#4c4f69"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#bcc0cc"/> + <entry type="LineNumbersTable" style="#8c8fa1"/> + <entry type="LineNumbers" style="#8c8fa1"/> + <entry type="Keyword" style="#8839ef"/> + <entry type="KeywordReserved" style="#8839ef"/> + <entry type="KeywordPseudo" style="#8839ef"/> + <entry type="KeywordConstant" style="#fe640b"/> + <entry type="KeywordDeclaration" style="#d20f39"/> + <entry type="KeywordNamespace" style="#179299"/> + <entry type="KeywordType" style="#d20f39"/> + <entry type="Name" style="#4c4f69"/> + <entry type="NameClass" style="#df8e1d"/> + <entry type="NameConstant" style="#df8e1d"/> + <entry type="NameDecorator" style="bold #1e66f5"/> + <entry type="NameEntity" style="#179299"/> + <entry type="NameException" style="#fe640b"/> + <entry type="NameFunction" style="#1e66f5"/> + <entry type="NameFunctionMagic" style="#1e66f5"/> + <entry type="NameLabel" style="#04a5e5"/> + <entry type="NameNamespace" style="#fe640b"/> + <entry type="NameProperty" style="#fe640b"/> + <entry type="NameTag" style="#8839ef"/> + <entry type="NameVariable" style="#dc8a78"/> + <entry type="NameVariableClass" style="#dc8a78"/> + <entry type="NameVariableGlobal" style="#dc8a78"/> + <entry type="NameVariableInstance" style="#dc8a78"/> + <entry type="NameVariableMagic" style="#dc8a78"/> + <entry type="NameAttribute" style="#1e66f5"/> + <entry type="NameBuiltin" style="#04a5e5"/> + <entry type="NameBuiltinPseudo" style="#04a5e5"/> + <entry type="NameOther" style="#4c4f69"/> + <entry type="Literal" style="#4c4f69"/> + <entry type="LiteralDate" style="#4c4f69"/> + <entry type="LiteralString" style="#40a02b"/> + <entry type="LiteralStringChar" style="#40a02b"/> + <entry type="LiteralStringSingle" style="#40a02b"/> + <entry type="LiteralStringDouble" style="#40a02b"/> + <entry type="LiteralStringBacktick" style="#40a02b"/> + <entry type="LiteralStringOther" style="#40a02b"/> + <entry type="LiteralStringSymbol" style="#40a02b"/> + <entry type="LiteralStringInterpol" style="#40a02b"/> + <entry type="LiteralStringAffix" style="#d20f39"/> + <entry type="LiteralStringDelimiter" style="#1e66f5"/> + <entry type="LiteralStringEscape" style="#1e66f5"/> + <entry type="LiteralStringRegex" style="#179299"/> + <entry type="LiteralStringDoc" style="#9ca0b0"/> + <entry type="LiteralStringHeredoc" style="#9ca0b0"/> + <entry type="LiteralNumber" style="#fe640b"/> + <entry type="LiteralNumberBin" style="#fe640b"/> + <entry type="LiteralNumberHex" style="#fe640b"/> + <entry type="LiteralNumberInteger" style="#fe640b"/> + <entry type="LiteralNumberFloat" style="#fe640b"/> + <entry type="LiteralNumberIntegerLong" style="#fe640b"/> + <entry type="LiteralNumberOct" style="#fe640b"/> + <entry type="Operator" style="bold #04a5e5"/> + <entry type="OperatorWord" style="bold #04a5e5"/> + <entry type="Comment" style="italic #9ca0b0"/> + <entry type="CommentSingle" style="italic #9ca0b0"/> + <entry type="CommentMultiline" style="italic #9ca0b0"/> + <entry type="CommentSpecial" style="italic #9ca0b0"/> + <entry type="CommentHashbang" style="italic #9ca0b0"/> + <entry type="CommentPreproc" style="italic #9ca0b0"/> + <entry type="CommentPreprocFile" style="bold #9ca0b0"/> + <entry type="Generic" style="#4c4f69"/> + <entry type="GenericInserted" style="bg:#ccd0da #40a02b"/> + <entry type="GenericDeleted" style="#d20f39 bg:#ccd0da"/> + <entry type="GenericEmph" style="italic #4c4f69"/> + <entry type="GenericStrong" style="bold #4c4f69"/> + <entry type="GenericUnderline" style="underline #4c4f69"/> + <entry type="GenericHeading" style="bold #fe640b"/> + <entry type="GenericSubheading" style="bold #fe640b"/> + <entry type="GenericOutput" style="#4c4f69"/> + <entry type="GenericPrompt" style="#4c4f69"/> + <entry type="GenericError" style="#d20f39"/> + <entry type="GenericTraceback" style="#d20f39"/> +</style> \ No newline at end of file diff --git a/styles/embedded/catppuccin-macchiato.xml b/styles/embedded/catppuccin-macchiato.xml new file mode 100644 index 0000000..ca53113 --- /dev/null +++ b/styles/embedded/catppuccin-macchiato.xml @@ -0,0 +1,83 @@ +<style name="catppuccin-macchiato" theme="dark"> + <entry type="Background" style="bg:#24273a #cad3f5"/> + <entry type="CodeLine" style="#cad3f5"/> + <entry type="Error" style="#ed8796"/> + <entry type="Other" style="#cad3f5"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#494d64"/> + <entry type="LineNumbersTable" style="#8087a2"/> + <entry type="LineNumbers" style="#8087a2"/> + <entry type="Keyword" style="#c6a0f6"/> + <entry type="KeywordReserved" style="#c6a0f6"/> + <entry type="KeywordPseudo" style="#c6a0f6"/> + <entry type="KeywordConstant" style="#f5a97f"/> + <entry type="KeywordDeclaration" style="#ed8796"/> + <entry type="KeywordNamespace" style="#8bd5ca"/> + <entry type="KeywordType" style="#ed8796"/> + <entry type="Name" style="#cad3f5"/> + <entry type="NameClass" style="#eed49f"/> + <entry type="NameConstant" style="#eed49f"/> + <entry type="NameDecorator" style="bold #8aadf4"/> + <entry type="NameEntity" style="#8bd5ca"/> + <entry type="NameException" style="#f5a97f"/> + <entry type="NameFunction" style="#8aadf4"/> + <entry type="NameFunctionMagic" style="#8aadf4"/> + <entry type="NameLabel" style="#91d7e3"/> + <entry type="NameNamespace" style="#f5a97f"/> + <entry type="NameProperty" style="#f5a97f"/> + <entry type="NameTag" style="#c6a0f6"/> + <entry type="NameVariable" style="#f4dbd6"/> + <entry type="NameVariableClass" style="#f4dbd6"/> + <entry type="NameVariableGlobal" style="#f4dbd6"/> + <entry type="NameVariableInstance" style="#f4dbd6"/> + <entry type="NameVariableMagic" style="#f4dbd6"/> + <entry type="NameAttribute" style="#8aadf4"/> + <entry type="NameBuiltin" style="#91d7e3"/> + <entry type="NameBuiltinPseudo" style="#91d7e3"/> + <entry type="NameOther" style="#cad3f5"/> + <entry type="Literal" style="#cad3f5"/> + <entry type="LiteralDate" style="#cad3f5"/> + <entry type="LiteralString" style="#a6da95"/> + <entry type="LiteralStringChar" style="#a6da95"/> + <entry type="LiteralStringSingle" style="#a6da95"/> + <entry type="LiteralStringDouble" style="#a6da95"/> + <entry type="LiteralStringBacktick" style="#a6da95"/> + <entry type="LiteralStringOther" style="#a6da95"/> + <entry type="LiteralStringSymbol" style="#a6da95"/> + <entry type="LiteralStringInterpol" style="#a6da95"/> + <entry type="LiteralStringAffix" style="#ed8796"/> + <entry type="LiteralStringDelimiter" style="#8aadf4"/> + <entry type="LiteralStringEscape" style="#8aadf4"/> + <entry type="LiteralStringRegex" style="#8bd5ca"/> + <entry type="LiteralStringDoc" style="#6e738d"/> + <entry type="LiteralStringHeredoc" style="#6e738d"/> + <entry type="LiteralNumber" style="#f5a97f"/> + <entry type="LiteralNumberBin" style="#f5a97f"/> + <entry type="LiteralNumberHex" style="#f5a97f"/> + <entry type="LiteralNumberInteger" style="#f5a97f"/> + <entry type="LiteralNumberFloat" style="#f5a97f"/> + <entry type="LiteralNumberIntegerLong" style="#f5a97f"/> + <entry type="LiteralNumberOct" style="#f5a97f"/> + <entry type="Operator" style="bold #91d7e3"/> + <entry type="OperatorWord" style="bold #91d7e3"/> + <entry type="Comment" style="italic #6e738d"/> + <entry type="CommentSingle" style="italic #6e738d"/> + <entry type="CommentMultiline" style="italic #6e738d"/> + <entry type="CommentSpecial" style="italic #6e738d"/> + <entry type="CommentHashbang" style="italic #6e738d"/> + <entry type="CommentPreproc" style="italic #6e738d"/> + <entry type="CommentPreprocFile" style="bold #6e738d"/> + <entry type="Generic" style="#cad3f5"/> + <entry type="GenericInserted" style="bg:#363a4f #a6da95"/> + <entry type="GenericDeleted" style="#ed8796 bg:#363a4f"/> + <entry type="GenericEmph" style="italic #cad3f5"/> + <entry type="GenericStrong" style="bold #cad3f5"/> + <entry type="GenericUnderline" style="underline #cad3f5"/> + <entry type="GenericHeading" style="bold #f5a97f"/> + <entry type="GenericSubheading" style="bold #f5a97f"/> + <entry type="GenericOutput" style="#cad3f5"/> + <entry type="GenericPrompt" style="#cad3f5"/> + <entry type="GenericError" style="#ed8796"/> + <entry type="GenericTraceback" style="#ed8796"/> +</style> \ No newline at end of file diff --git a/styles/embedded/catppuccin-mocha.xml b/styles/embedded/catppuccin-mocha.xml new file mode 100644 index 0000000..2ece4e5 --- /dev/null +++ b/styles/embedded/catppuccin-mocha.xml @@ -0,0 +1,83 @@ +<style name="catppuccin-mocha" theme="dark"> + <entry type="Background" style="bg:#1e1e2e #cdd6f4"/> + <entry type="CodeLine" style="#cdd6f4"/> + <entry type="Error" style="#f38ba8"/> + <entry type="Other" style="#cdd6f4"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#45475a"/> + <entry type="LineNumbersTable" style="#7f849c"/> + <entry type="LineNumbers" style="#7f849c"/> + <entry type="Keyword" style="#cba6f7"/> + <entry type="KeywordReserved" style="#cba6f7"/> + <entry type="KeywordPseudo" style="#cba6f7"/> + <entry type="KeywordConstant" style="#fab387"/> + <entry type="KeywordDeclaration" style="#f38ba8"/> + <entry type="KeywordNamespace" style="#94e2d5"/> + <entry type="KeywordType" style="#f38ba8"/> + <entry type="Name" style="#cdd6f4"/> + <entry type="NameClass" style="#f9e2af"/> + <entry type="NameConstant" style="#f9e2af"/> + <entry type="NameDecorator" style="bold #89b4fa"/> + <entry type="NameEntity" style="#94e2d5"/> + <entry type="NameException" style="#fab387"/> + <entry type="NameFunction" style="#89b4fa"/> + <entry type="NameFunctionMagic" style="#89b4fa"/> + <entry type="NameLabel" style="#89dceb"/> + <entry type="NameNamespace" style="#fab387"/> + <entry type="NameProperty" style="#fab387"/> + <entry type="NameTag" style="#cba6f7"/> + <entry type="NameVariable" style="#f5e0dc"/> + <entry type="NameVariableClass" style="#f5e0dc"/> + <entry type="NameVariableGlobal" style="#f5e0dc"/> + <entry type="NameVariableInstance" style="#f5e0dc"/> + <entry type="NameVariableMagic" style="#f5e0dc"/> + <entry type="NameAttribute" style="#89b4fa"/> + <entry type="NameBuiltin" style="#89dceb"/> + <entry type="NameBuiltinPseudo" style="#89dceb"/> + <entry type="NameOther" style="#cdd6f4"/> + <entry type="Literal" style="#cdd6f4"/> + <entry type="LiteralDate" style="#cdd6f4"/> + <entry type="LiteralString" style="#a6e3a1"/> + <entry type="LiteralStringChar" style="#a6e3a1"/> + <entry type="LiteralStringSingle" style="#a6e3a1"/> + <entry type="LiteralStringDouble" style="#a6e3a1"/> + <entry type="LiteralStringBacktick" style="#a6e3a1"/> + <entry type="LiteralStringOther" style="#a6e3a1"/> + <entry type="LiteralStringSymbol" style="#a6e3a1"/> + <entry type="LiteralStringInterpol" style="#a6e3a1"/> + <entry type="LiteralStringAffix" style="#f38ba8"/> + <entry type="LiteralStringDelimiter" style="#89b4fa"/> + <entry type="LiteralStringEscape" style="#89b4fa"/> + <entry type="LiteralStringRegex" style="#94e2d5"/> + <entry type="LiteralStringDoc" style="#6c7086"/> + <entry type="LiteralStringHeredoc" style="#6c7086"/> + <entry type="LiteralNumber" style="#fab387"/> + <entry type="LiteralNumberBin" style="#fab387"/> + <entry type="LiteralNumberHex" style="#fab387"/> + <entry type="LiteralNumberInteger" style="#fab387"/> + <entry type="LiteralNumberFloat" style="#fab387"/> + <entry type="LiteralNumberIntegerLong" style="#fab387"/> + <entry type="LiteralNumberOct" style="#fab387"/> + <entry type="Operator" style="bold #89dceb"/> + <entry type="OperatorWord" style="bold #89dceb"/> + <entry type="Comment" style="italic #6c7086"/> + <entry type="CommentSingle" style="italic #6c7086"/> + <entry type="CommentMultiline" style="italic #6c7086"/> + <entry type="CommentSpecial" style="italic #6c7086"/> + <entry type="CommentHashbang" style="italic #6c7086"/> + <entry type="CommentPreproc" style="italic #6c7086"/> + <entry type="CommentPreprocFile" style="bold #6c7086"/> + <entry type="Generic" style="#cdd6f4"/> + <entry type="GenericInserted" style="bg:#313244 #a6e3a1"/> + <entry type="GenericDeleted" style="#f38ba8 bg:#313244"/> + <entry type="GenericEmph" style="italic #cdd6f4"/> + <entry type="GenericStrong" style="bold #cdd6f4"/> + <entry type="GenericUnderline" style="underline #cdd6f4"/> + <entry type="GenericHeading" style="bold #fab387"/> + <entry type="GenericSubheading" style="bold #fab387"/> + <entry type="GenericOutput" style="#cdd6f4"/> + <entry type="GenericPrompt" style="#cdd6f4"/> + <entry type="GenericError" style="#f38ba8"/> + <entry type="GenericTraceback" style="#f38ba8"/> +</style> \ No newline at end of file diff --git a/styles/embedded/colorful.xml b/styles/embedded/colorful.xml new file mode 100644 index 0000000..dc74e09 --- /dev/null +++ b/styles/embedded/colorful.xml @@ -0,0 +1,52 @@ +<style name="colorful" theme="light"> + <entry type="Error" style="#ff0000 bg:#ffaaaa"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold #008800"/> + <entry type="KeywordPseudo" style="#003388"/> + <entry type="KeywordType" style="#333399"/> + <entry type="NameAttribute" style="#0000cc"/> + <entry type="NameBuiltin" style="#007020"/> + <entry type="NameClass" style="bold #bb0066"/> + <entry type="NameConstant" style="bold #003366"/> + <entry type="NameDecorator" style="bold #555555"/> + <entry type="NameEntity" style="bold #880000"/> + <entry type="NameException" style="bold #ff0000"/> + <entry type="NameFunction" style="bold #0066bb"/> + <entry type="NameLabel" style="bold #997700"/> + <entry type="NameNamespace" style="bold #0e84b5"/> + <entry type="NameTag" style="#007700"/> + <entry type="NameVariable" style="#996633"/> + <entry type="NameVariableClass" style="#336699"/> + <entry type="NameVariableGlobal" style="bold #dd7700"/> + <entry type="NameVariableInstance" style="#3333bb"/> + <entry type="LiteralString" style="bg:#fff0f0"/> + <entry type="LiteralStringChar" style="#0044dd"/> + <entry type="LiteralStringDoc" style="#dd4422"/> + <entry type="LiteralStringEscape" style="bold #666666"/> + <entry type="LiteralStringInterpol" style="bg:#eeeeee"/> + <entry type="LiteralStringOther" style="#dd2200"/> + <entry type="LiteralStringRegex" style="#000000 bg:#fff0ff"/> + <entry type="LiteralStringSymbol" style="#aa6600"/> + <entry type="LiteralNumber" style="bold #6600ee"/> + <entry type="LiteralNumberFloat" style="bold #6600ee"/> + <entry type="LiteralNumberHex" style="bold #005588"/> + <entry type="LiteralNumberInteger" style="bold #0000dd"/> + <entry type="LiteralNumberOct" style="bold #4400ee"/> + <entry type="Operator" style="#333333"/> + <entry type="OperatorWord" style="bold #000000"/> + <entry type="Comment" style="#888888"/> + <entry type="CommentSpecial" style="bold #cc0000"/> + <entry type="CommentPreproc" style="#557799"/> + <entry type="GenericDeleted" style="#a00000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00a000"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="bold #c65d09"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#0044dd"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/doom-one.xml b/styles/embedded/doom-one.xml new file mode 100644 index 0000000..f5a910a --- /dev/null +++ b/styles/embedded/doom-one.xml @@ -0,0 +1,51 @@ +<style name="doom-one" theme="dark"> + <entry type="Error" style="#b0c4de"/> + <entry type="Background" style="#b0c4de bg:#282c34"/> + <entry type="Keyword" style="#c678dd"/> + <entry type="KeywordConstant" style="bold #b756ff"/> + <entry type="KeywordType" style="#ef8383"/> + <entry type="Name" style="#c1abea"/> + <entry type="NameAttribute" style="#b3d23c"/> + <entry type="NameBuiltin" style="#ef8383"/> + <entry type="NameClass" style="#76a9f9"/> + <entry type="NameConstant" style="bold #b756ff"/> + <entry type="NameDecorator" style="#e5c07b"/> + <entry type="NameEntity" style="#bda26f"/> + <entry type="NameException" style="bold #fd7474"/> + <entry type="NameFunction" style="#00b1f7"/> + <entry type="NameLabel" style="#f5a40d"/> + <entry type="NameNamespace" style="#76a9f9"/> + <entry type="NameProperty" style="#cebc3a"/> + <entry type="NameTag" style="#e06c75"/> + <entry type="NameVariable" style="#dcaeea"/> + <entry type="NameVariableGlobal" style="bold #dcaeea"/> + <entry type="NameVariableInstance" style="#e06c75"/> + <entry type="Literal" style="#98c379"/> + <entry type="LiteralString" style="#98c379"/> + <entry type="LiteralStringDoc" style="#7e97c3"/> + <entry type="LiteralStringDouble" style="#63c381"/> + <entry type="LiteralStringEscape" style="bold #d26464"/> + <entry type="LiteralStringHeredoc" style="#98c379"/> + <entry type="LiteralStringInterpol" style="#98c379"/> + <entry type="LiteralStringOther" style="#70b33f"/> + <entry type="LiteralStringRegex" style="#56b6c2"/> + <entry type="LiteralStringSingle" style="#98c379"/> + <entry type="LiteralStringSymbol" style="#56b6c2"/> + <entry type="LiteralNumber" style="#d19a66"/> + <entry type="Operator" style="#c7bf54"/> + <entry type="OperatorWord" style="bold #b756ff"/> + <entry type="Punctuation" style="#b0c4de"/> + <entry type="Comment" style="italic #8a93a5"/> + <entry type="CommentHashbang" style="bold"/> + <entry type="Generic" style="#b0c4de"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericHeading" style="bold #a2cbff"/> + <entry type="GenericInserted" style="#a6e22e"/> + <entry type="GenericOutput" style="#a6e22e"/> + <entry type="GenericPrompt" style="#a6e22e"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#a2cbff"/> + <entry type="GenericTraceback" style="#a2cbff"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#b0c4de"/> +</style> \ No newline at end of file diff --git a/styles/embedded/doom-one2.xml b/styles/embedded/doom-one2.xml new file mode 100644 index 0000000..d6863f3 --- /dev/null +++ b/styles/embedded/doom-one2.xml @@ -0,0 +1,64 @@ +<style name="doom-one2" theme="dark"> + <entry type="Error" style="#b0c4de"/> + <entry type="Background" style="#b0c4de bg:#282c34"/> + <entry type="Keyword" style="#76a9f9"/> + <entry type="KeywordConstant" style="#e5c07b"/> + <entry type="KeywordType" style="#e5c07b"/> + <entry type="Name" style="#aa89ea"/> + <entry type="NameAttribute" style="#cebc3a"/> + <entry type="NameBuiltin" style="#e5c07b"/> + <entry type="NameClass" style="#ca72ff"/> + <entry type="NameConstant" style="bold"/> + <entry type="NameDecorator" style="#e5c07b"/> + <entry type="NameEntity" style="#bda26f"/> + <entry type="NameException" style="bold #fd7474"/> + <entry type="NameFunction" style="#00b1f7"/> + <entry type="NameLabel" style="#f5a40d"/> + <entry type="NameNamespace" style="#ca72ff"/> + <entry type="NameProperty" style="#cebc3a"/> + <entry type="NameTag" style="#76a9f9"/> + <entry type="NameVariable" style="#dcaeea"/> + <entry type="NameVariableClass" style="#dcaeea"/> + <entry type="NameVariableGlobal" style="bold #dcaeea"/> + <entry type="NameVariableInstance" style="#e06c75"/> + <entry type="NameVariableMagic" style="#dcaeea"/> + <entry type="Literal" style="#98c379"/> + <entry type="LiteralDate" style="#98c379"/> + <entry type="LiteralString" style="#98c379"/> + <entry type="LiteralStringAffix" style="#98c379"/> + <entry type="LiteralStringBacktick" style="#98c379"/> + <entry type="LiteralStringDelimiter" style="#98c379"/> + <entry type="LiteralStringDoc" style="#7e97c3"/> + <entry type="LiteralStringDouble" style="#63c381"/> + <entry type="LiteralStringEscape" style="bold #d26464"/> + <entry type="LiteralStringHeredoc" style="#98c379"/> + <entry type="LiteralStringInterpol" style="#98c379"/> + <entry type="LiteralStringOther" style="#70b33f"/> + <entry type="LiteralStringRegex" style="#56b6c2"/> + <entry type="LiteralStringSingle" style="#98c379"/> + <entry type="LiteralStringSymbol" style="#56b6c2"/> + <entry type="LiteralNumber" style="#d19a66"/> + <entry type="LiteralNumberBin" style="#d19a66"/> + <entry type="LiteralNumberFloat" style="#d19a66"/> + <entry type="LiteralNumberHex" style="#d19a66"/> + <entry type="LiteralNumberInteger" style="#d19a66"/> + <entry type="LiteralNumberIntegerLong" style="#d19a66"/> + <entry type="LiteralNumberOct" style="#d19a66"/> + <entry type="Operator" style="#54b1c7"/> + <entry type="OperatorWord" style="bold #b756ff"/> + <entry type="Punctuation" style="#abb2bf"/> + <entry type="Comment" style="italic #8a93a5"/> + <entry type="CommentHashbang" style="bold"/> + <entry type="Generic" style="#b0c4de"/> + <entry type="GenericDeleted" style="#b0c4de"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericHeading" style="bold #a2cbff"/> + <entry type="GenericInserted" style="#a6e22e"/> + <entry type="GenericOutput" style="#a6e22e"/> + <entry type="GenericPrompt" style="#a6e22e"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#a2cbff"/> + <entry type="GenericTraceback" style="#a2cbff"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#b0c4de"/> +</style> \ No newline at end of file diff --git a/styles/embedded/dracula.xml b/styles/embedded/dracula.xml new file mode 100644 index 0000000..da436b3 --- /dev/null +++ b/styles/embedded/dracula.xml @@ -0,0 +1,74 @@ +<style name="dracula" theme="dark"> + <entry type="Other" style="#f8f8f2"/> + <entry type="Error" style="#f8f8f2"/> + <entry type="Background" style="bg:#282a36"/> + <entry type="Keyword" style="#ff79c6"/> + <entry type="KeywordConstant" style="#ff79c6"/> + <entry type="KeywordDeclaration" style="italic #8be9fd"/> + <entry type="KeywordNamespace" style="#ff79c6"/> + <entry type="KeywordPseudo" style="#ff79c6"/> + <entry type="KeywordReserved" style="#ff79c6"/> + <entry type="KeywordType" style="#8be9fd"/> + <entry type="Name" style="#f8f8f2"/> + <entry type="NameAttribute" style="#50fa7b"/> + <entry type="NameBuiltin" style="italic #8be9fd"/> + <entry type="NameBuiltinPseudo" style="#f8f8f2"/> + <entry type="NameClass" style="#50fa7b"/> + <entry type="NameConstant" style="#f8f8f2"/> + <entry type="NameDecorator" style="#f8f8f2"/> + <entry type="NameEntity" style="#f8f8f2"/> + <entry type="NameException" style="#f8f8f2"/> + <entry type="NameFunction" style="#50fa7b"/> + <entry type="NameLabel" style="italic #8be9fd"/> + <entry type="NameNamespace" style="#f8f8f2"/> + <entry type="NameOther" style="#f8f8f2"/> + <entry type="NameTag" style="#ff79c6"/> + <entry type="NameVariable" style="italic #8be9fd"/> + <entry type="NameVariableClass" style="italic #8be9fd"/> + <entry type="NameVariableGlobal" style="italic #8be9fd"/> + <entry type="NameVariableInstance" style="italic #8be9fd"/> + <entry type="Literal" style="#f8f8f2"/> + <entry type="LiteralDate" style="#f8f8f2"/> + <entry type="LiteralString" style="#f1fa8c"/> + <entry type="LiteralStringBacktick" style="#f1fa8c"/> + <entry type="LiteralStringChar" style="#f1fa8c"/> + <entry type="LiteralStringDoc" style="#f1fa8c"/> + <entry type="LiteralStringDouble" style="#f1fa8c"/> + <entry type="LiteralStringEscape" style="#f1fa8c"/> + <entry type="LiteralStringHeredoc" style="#f1fa8c"/> + <entry type="LiteralStringInterpol" style="#f1fa8c"/> + <entry type="LiteralStringOther" style="#f1fa8c"/> + <entry type="LiteralStringRegex" style="#f1fa8c"/> + <entry type="LiteralStringSingle" style="#f1fa8c"/> + <entry type="LiteralStringSymbol" style="#f1fa8c"/> + <entry type="LiteralNumber" style="#bd93f9"/> + <entry type="LiteralNumberBin" style="#bd93f9"/> + <entry type="LiteralNumberFloat" style="#bd93f9"/> + <entry type="LiteralNumberHex" style="#bd93f9"/> + <entry type="LiteralNumberInteger" style="#bd93f9"/> + <entry type="LiteralNumberIntegerLong" style="#bd93f9"/> + <entry type="LiteralNumberOct" style="#bd93f9"/> + <entry type="Operator" style="#ff79c6"/> + <entry type="OperatorWord" style="#ff79c6"/> + <entry type="Punctuation" style="#f8f8f2"/> + <entry type="Comment" style="#6272a4"/> + <entry type="CommentHashbang" style="#6272a4"/> + <entry type="CommentMultiline" style="#6272a4"/> + <entry type="CommentSingle" style="#6272a4"/> + <entry type="CommentSpecial" style="#6272a4"/> + <entry type="CommentPreproc" style="#ff79c6"/> + <entry type="Generic" style="#f8f8f2"/> + <entry type="GenericDeleted" style="#ff5555"/> + <entry type="GenericEmph" style="underline #f8f8f2"/> + <entry type="GenericError" style="#f8f8f2"/> + <entry type="GenericHeading" style="bold #f8f8f2"/> + <entry type="GenericInserted" style="bold #50fa7b"/> + <entry type="GenericOutput" style="#44475a"/> + <entry type="GenericPrompt" style="#f8f8f2"/> + <entry type="GenericStrong" style="#f8f8f2"/> + <entry type="GenericSubheading" style="bold #f8f8f2"/> + <entry type="GenericTraceback" style="#f8f8f2"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#f8f8f2"/> + <entry type="TextWhitespace" style="#f8f8f2"/> +</style> \ No newline at end of file diff --git a/styles/embedded/emacs.xml b/styles/embedded/emacs.xml new file mode 100644 index 0000000..dd276f2 --- /dev/null +++ b/styles/embedded/emacs.xml @@ -0,0 +1,44 @@ +<style name="emacs" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="bg:#f8f8f8"/> + <entry type="Keyword" style="bold #aa22ff"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="bold #00bb00"/> + <entry type="NameAttribute" style="#bb4444"/> + <entry type="NameBuiltin" style="#aa22ff"/> + <entry type="NameClass" style="#0000ff"/> + <entry type="NameConstant" style="#880000"/> + <entry type="NameDecorator" style="#aa22ff"/> + <entry type="NameEntity" style="bold #999999"/> + <entry type="NameException" style="bold #d2413a"/> + <entry type="NameFunction" style="#00a000"/> + <entry type="NameLabel" style="#a0a000"/> + <entry type="NameNamespace" style="bold #0000ff"/> + <entry type="NameTag" style="bold #008000"/> + <entry type="NameVariable" style="#b8860b"/> + <entry type="LiteralString" style="#bb4444"/> + <entry type="LiteralStringDoc" style="italic"/> + <entry type="LiteralStringEscape" style="bold #bb6622"/> + <entry type="LiteralStringInterpol" style="bold #bb6688"/> + <entry type="LiteralStringOther" style="#008000"/> + <entry type="LiteralStringRegex" style="#bb6688"/> + <entry type="LiteralStringSymbol" style="#b8860b"/> + <entry type="LiteralNumber" style="#666666"/> + <entry type="Operator" style="#666666"/> + <entry type="OperatorWord" style="bold #aa22ff"/> + <entry type="Comment" style="italic #008800"/> + <entry type="CommentSpecial" style="bold noitalic"/> + <entry type="CommentPreproc" style="noitalic"/> + <entry type="GenericDeleted" style="#a00000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00a000"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="bold #000080"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#0044dd"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/evergarden.xml b/styles/embedded/evergarden.xml new file mode 100644 index 0000000..826435d --- /dev/null +++ b/styles/embedded/evergarden.xml @@ -0,0 +1,33 @@ +<style name="evergarden" theme="dark"> + <entry type="Background" style="noinherit #D6CBB4 bg:#252B2E"/> + <entry type="Keyword" style="noinherit #E67E80"/> + <entry type="KeywordType" style="noinherit #DBBC7F"/> + <entry type="Name" style="#D6CBB4"/> + <entry type="NameAttribute" style="bold #D699B6"/> + <entry type="NameBuiltin" style="#D699B6"/> + <entry type="NameConstant" style="noinherit #D699B6"/> + <entry type="NameEntity" style="noinherit #DBBC7F"/> + <entry type="NameException" style="noinherit #E67E80"/> + <entry type="NameFunction" style="#B2C98F"/> + <entry type="NameLabel" style="noinherit #E67E80"/> + <entry type="NameTag" style="noinherit #7a8478"/> + <entry type="NameVariable" style="noinherit #D6CBB4"/> + <entry type="LiteralString" style="noinherit #B2C98F"/> + <entry type="LiteralStringSymbol" style="#E69875"/> + <entry type="LiteralNumber" style="noinherit #D699B6"/> + <entry type="LiteralNumberFloat" style="noinherit #D699B6"/> + <entry type="Operator" style="#7a8478"/> + <entry type="Comment" style="italic #859289"/> + <entry type="CommentPreproc" style="noinherit #E67E80"/> + <entry type="Generic" style="#D6CBB4"/> + <entry type="GenericDeleted" style="noinherit #252B2E bg:#E67E80"/> + <entry type="GenericEmph" style="#6E8585"/> + <entry type="GenericError" style="bold bg:#E67E80"/> + <entry type="GenericHeading" style="bold #D699B6"/> + <entry type="GenericInserted" style="noinherit #252B2E bg:#B2C98F"/> + <entry type="GenericOutput" style="noinherit #6E8585"/> + <entry type="GenericPrompt" style="#D6CBB4"/> + <entry type="GenericStrong" style="#D6CBB4"/> + <entry type="GenericSubheading" style="bold #B2C98F"/> + <entry type="GenericTraceback" style="bold bg:#E67E80"/> +</style> \ No newline at end of file diff --git a/styles/embedded/friendly.xml b/styles/embedded/friendly.xml new file mode 100644 index 0000000..cd583c2 --- /dev/null +++ b/styles/embedded/friendly.xml @@ -0,0 +1,44 @@ +<style name="friendly" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="bg:#f0f0f0"/> + <entry type="Keyword" style="bold #007020"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="nobold #902000"/> + <entry type="NameAttribute" style="#4070a0"/> + <entry type="NameBuiltin" style="#007020"/> + <entry type="NameClass" style="bold #0e84b5"/> + <entry type="NameConstant" style="#60add5"/> + <entry type="NameDecorator" style="bold #555555"/> + <entry type="NameEntity" style="bold #d55537"/> + <entry type="NameException" style="#007020"/> + <entry type="NameFunction" style="#06287e"/> + <entry type="NameLabel" style="bold #002070"/> + <entry type="NameNamespace" style="bold #0e84b5"/> + <entry type="NameTag" style="bold #062873"/> + <entry type="NameVariable" style="#bb60d5"/> + <entry type="LiteralString" style="#4070a0"/> + <entry type="LiteralStringDoc" style="italic"/> + <entry type="LiteralStringEscape" style="bold #4070a0"/> + <entry type="LiteralStringInterpol" style="#70a0d0"/> + <entry type="LiteralStringOther" style="#c65d09"/> + <entry type="LiteralStringRegex" style="#235388"/> + <entry type="LiteralStringSymbol" style="#517918"/> + <entry type="LiteralNumber" style="#40a070"/> + <entry type="Operator" style="#666666"/> + <entry type="OperatorWord" style="bold #007020"/> + <entry type="Comment" style="italic #60a0b0"/> + <entry type="CommentSpecial" style="noitalic bg:#fff0f0"/> + <entry type="CommentPreproc" style="noitalic #007020"/> + <entry type="GenericDeleted" style="#a00000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00a000"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="bold #c65d09"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#0044dd"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/fruity.xml b/styles/embedded/fruity.xml new file mode 100644 index 0000000..00b048d --- /dev/null +++ b/styles/embedded/fruity.xml @@ -0,0 +1,19 @@ +<style name="fruity" theme="dark"> + <entry type="Background" style="#ffffff bg:#111111"/> + <entry type="Keyword" style="bold #fb660a"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="bold #cdcaa9"/> + <entry type="NameAttribute" style="bold #ff0086"/> + <entry type="NameConstant" style="#0086d2"/> + <entry type="NameFunction" style="bold #ff0086"/> + <entry type="NameTag" style="bold #fb660a"/> + <entry type="NameVariable" style="#fb660a"/> + <entry type="LiteralString" style="#0086d2"/> + <entry type="LiteralNumber" style="bold #0086f7"/> + <entry type="Comment" style="italic #008800 bg:#0f140f"/> + <entry type="CommentPreproc" style="bold #ff0007"/> + <entry type="GenericHeading" style="bold #ffffff"/> + <entry type="GenericOutput" style="#444444 bg:#222222"/> + <entry type="GenericSubheading" style="bold #ffffff"/> + <entry type="TextWhitespace" style="#888888"/> +</style> \ No newline at end of file diff --git a/styles/embedded/github-dark.xml b/styles/embedded/github-dark.xml new file mode 100644 index 0000000..85b3fc9 --- /dev/null +++ b/styles/embedded/github-dark.xml @@ -0,0 +1,45 @@ +<style name="github-dark" theme="dark"> + <entry type="Error" style="#f85149"/> + <entry type="LineHighlight" style="bg:#6e7681"/> + <entry type="LineNumbers" style="#6e7681"/> + <entry type="Background" style="#e6edf3 bg:#0d1117"/> + <entry type="Keyword" style="#ff7b72"/> + <entry type="KeywordConstant" style="#79c0ff"/> + <entry type="KeywordPseudo" style="#79c0ff"/> + <entry type="Name" style="#e6edf3"/> + <entry type="NameClass" style="bold #f0883e"/> + <entry type="NameConstant" style="bold #79c0ff"/> + <entry type="NameDecorator" style="bold #d2a8ff"/> + <entry type="NameEntity" style="#ffa657"/> + <entry type="NameException" style="bold #f0883e"/> + <entry type="NameFunction" style="bold #d2a8ff"/> + <entry type="NameLabel" style="bold #79c0ff"/> + <entry type="NameNamespace" style="#ff7b72"/> + <entry type="NameProperty" style="#79c0ff"/> + <entry type="NameTag" style="#7ee787"/> + <entry type="NameVariable" style="#79c0ff"/> + <entry type="Literal" style="#a5d6ff"/> + <entry type="LiteralDate" style="#79c0ff"/> + <entry type="LiteralStringAffix" style="#79c0ff"/> + <entry type="LiteralStringDelimiter" style="#79c0ff"/> + <entry type="LiteralStringEscape" style="#79c0ff"/> + <entry type="LiteralStringHeredoc" style="#79c0ff"/> + <entry type="LiteralStringRegex" style="#79c0ff"/> + <entry type="Operator" style="bold #ff7b72"/> + <entry type="Comment" style="italic #8b949e"/> + <entry type="CommentSpecial" style="bold italic #8b949e"/> + <entry type="CommentPreproc" style="bold #8b949e"/> + <entry type="Generic" style="#e6edf3"/> + <entry type="GenericDeleted" style="#ffa198 bg:#490202"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ffa198"/> + <entry type="GenericHeading" style="bold #79c0ff"/> + <entry type="GenericInserted" style="#56d364 bg:#0f5323"/> + <entry type="GenericOutput" style="#8b949e"/> + <entry type="GenericPrompt" style="#8b949e"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#79c0ff"/> + <entry type="GenericTraceback" style="#ff7b72"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#6e7681"/> +</style> \ No newline at end of file diff --git a/styles/embedded/github.xml b/styles/embedded/github.xml new file mode 100644 index 0000000..06e043a --- /dev/null +++ b/styles/embedded/github.xml @@ -0,0 +1,44 @@ +<style name="github" theme="light"> + <entry type="Error" style="#a61717 bg:#e3d2d2"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold #000000"/> + <entry type="KeywordType" style="bold #445588"/> + <entry type="NameAttribute" style="#008080"/> + <entry type="NameBuiltin" style="#0086b3"/> + <entry type="NameBuiltinPseudo" style="#999999"/> + <entry type="NameClass" style="bold #445588"/> + <entry type="NameConstant" style="#008080"/> + <entry type="NameDecorator" style="bold #3c5d5d"/> + <entry type="NameEntity" style="#800080"/> + <entry type="NameException" style="bold #990000"/> + <entry type="NameFunction" style="bold #990000"/> + <entry type="NameLabel" style="bold #990000"/> + <entry type="NameNamespace" style="#555555"/> + <entry type="NameTag" style="#000080"/> + <entry type="NameVariable" style="#008080"/> + <entry type="NameVariableClass" style="#008080"/> + <entry type="NameVariableGlobal" style="#008080"/> + <entry type="NameVariableInstance" style="#008080"/> + <entry type="LiteralString" style="#dd1144"/> + <entry type="LiteralStringRegex" style="#009926"/> + <entry type="LiteralStringSymbol" style="#990073"/> + <entry type="LiteralNumber" style="#009999"/> + <entry type="Operator" style="bold #000000"/> + <entry type="Comment" style="italic #999988"/> + <entry type="CommentMultiline" style="italic #999988"/> + <entry type="CommentSingle" style="italic #999988"/> + <entry type="CommentSpecial" style="bold italic #999999"/> + <entry type="CommentPreproc" style="bold #999999"/> + <entry type="GenericDeleted" style="#000000 bg:#ffdddd"/> + <entry type="GenericEmph" style="italic #000000"/> + <entry type="GenericError" style="#aa0000"/> + <entry type="GenericHeading" style="#999999"/> + <entry type="GenericInserted" style="#000000 bg:#ddffdd"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="#555555"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#aaaaaa"/> + <entry type="GenericTraceback" style="#aa0000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/gruvbox-light.xml b/styles/embedded/gruvbox-light.xml new file mode 100644 index 0000000..c1293c8 --- /dev/null +++ b/styles/embedded/gruvbox-light.xml @@ -0,0 +1,33 @@ +<style name="gruvbox-light" theme="light"> + <entry type="Background" style="noinherit #3c3836 bg:#fbf1c7"/> + <entry type="Keyword" style="noinherit #af3a03"/> + <entry type="KeywordType" style="noinherit #b57614"/> + <entry type="Name" style="#3c3836"/> + <entry type="NameAttribute" style="bold #79740e"/> + <entry type="NameBuiltin" style="#b57614"/> + <entry type="NameConstant" style="noinherit #d3869b"/> + <entry type="NameEntity" style="noinherit #b57614"/> + <entry type="NameException" style="noinherit #fb4934"/> + <entry type="NameFunction" style="#b57614"/> + <entry type="NameLabel" style="noinherit #9d0006"/> + <entry type="NameTag" style="noinherit #9d0006"/> + <entry type="NameVariable" style="noinherit #3c3836"/> + <entry type="LiteralString" style="noinherit #79740e"/> + <entry type="LiteralStringSymbol" style="#076678"/> + <entry type="LiteralNumber" style="noinherit #8f3f71"/> + <entry type="LiteralNumberFloat" style="noinherit #8f3f71"/> + <entry type="Operator" style="#af3a03"/> + <entry type="Comment" style="italic #928374"/> + <entry type="CommentPreproc" style="noinherit #427b58"/> + <entry type="Generic" style="#3c3836"/> + <entry type="GenericDeleted" style="noinherit #282828 bg:#9d0006"/> + <entry type="GenericEmph" style="underline #076678"/> + <entry type="GenericError" style="bold bg:#9d0006"/> + <entry type="GenericHeading" style="bold #79740e"/> + <entry type="GenericInserted" style="noinherit #282828 bg:#79740e"/> + <entry type="GenericOutput" style="noinherit #504945"/> + <entry type="GenericPrompt" style="#3c3836"/> + <entry type="GenericStrong" style="#3c3836"/> + <entry type="GenericSubheading" style="bold #79740e"/> + <entry type="GenericTraceback" style="bold bg:#3c3836"/> +</style> \ No newline at end of file diff --git a/styles/embedded/gruvbox.xml b/styles/embedded/gruvbox.xml new file mode 100644 index 0000000..9cb974d --- /dev/null +++ b/styles/embedded/gruvbox.xml @@ -0,0 +1,33 @@ +<style name="gruvbox" theme="dark"> + <entry type="Background" style="noinherit #ebdbb2 bg:#282828"/> + <entry type="Keyword" style="noinherit #fe8019"/> + <entry type="KeywordType" style="noinherit #fabd2f"/> + <entry type="Name" style="#ebdbb2"/> + <entry type="NameAttribute" style="bold #b8bb26"/> + <entry type="NameBuiltin" style="#fabd2f"/> + <entry type="NameConstant" style="noinherit #d3869b"/> + <entry type="NameEntity" style="noinherit #fabd2f"/> + <entry type="NameException" style="noinherit #fb4934"/> + <entry type="NameFunction" style="#fabd2f"/> + <entry type="NameLabel" style="noinherit #fb4934"/> + <entry type="NameTag" style="noinherit #fb4934"/> + <entry type="NameVariable" style="noinherit #ebdbb2"/> + <entry type="LiteralString" style="noinherit #b8bb26"/> + <entry type="LiteralStringSymbol" style="#83a598"/> + <entry type="LiteralNumber" style="noinherit #d3869b"/> + <entry type="LiteralNumberFloat" style="noinherit #d3869b"/> + <entry type="Operator" style="#fe8019"/> + <entry type="Comment" style="italic #928374"/> + <entry type="CommentPreproc" style="noinherit #8ec07c"/> + <entry type="Generic" style="#ebdbb2"/> + <entry type="GenericDeleted" style="noinherit #282828 bg:#fb4934"/> + <entry type="GenericEmph" style="underline #83a598"/> + <entry type="GenericError" style="bold bg:#fb4934"/> + <entry type="GenericHeading" style="bold #b8bb26"/> + <entry type="GenericInserted" style="noinherit #282828 bg:#b8bb26"/> + <entry type="GenericOutput" style="noinherit #504945"/> + <entry type="GenericPrompt" style="#ebdbb2"/> + <entry type="GenericStrong" style="#ebdbb2"/> + <entry type="GenericSubheading" style="bold #b8bb26"/> + <entry type="GenericTraceback" style="bold bg:#fb4934"/> +</style> \ No newline at end of file diff --git a/styles/embedded/hr_high_contrast.xml b/styles/embedded/hr_high_contrast.xml new file mode 100644 index 0000000..811d5eb --- /dev/null +++ b/styles/embedded/hr_high_contrast.xml @@ -0,0 +1,12 @@ +<style name="hr_high_contrast" theme="light"> + <entry type="Other" style="#d5d500"/> + <entry type="Background" style="#000000"/> + <entry type="Keyword" style="#467faf"/> + <entry type="Name" style="#ffffff"/> + <entry type="LiteralString" style="#a87662"/> + <entry type="LiteralStringBoolean" style="#467faf"/> + <entry type="LiteralNumber" style="#ffffff"/> + <entry type="Operator" style="#e4e400"/> + <entry type="OperatorWord" style="#467faf"/> + <entry type="Comment" style="#5a8349"/> +</style> \ No newline at end of file diff --git a/styles/embedded/hrdark.xml b/styles/embedded/hrdark.xml new file mode 100644 index 0000000..418e713 --- /dev/null +++ b/styles/embedded/hrdark.xml @@ -0,0 +1,10 @@ +<style name="hrdark" theme="light"> + <entry type="Other" style="#ffffff"/> + <entry type="Background" style="#1d2432"/> + <entry type="Keyword" style="#ff636f"/> + <entry type="Name" style="#58a1dd"/> + <entry type="Literal" style="#a6be9d"/> + <entry type="Operator" style="#ff636f"/> + <entry type="OperatorWord" style="#ff636f"/> + <entry type="Comment" style="italic #828b96"/> +</style> \ No newline at end of file diff --git a/styles/embedded/igor.xml b/styles/embedded/igor.xml new file mode 100644 index 0000000..6957562 --- /dev/null +++ b/styles/embedded/igor.xml @@ -0,0 +1,9 @@ +<style name="igor" theme="light"> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#0000ff"/> + <entry type="NameClass" style="#007575"/> + <entry type="NameDecorator" style="#cc00a3"/> + <entry type="NameFunction" style="#c34e00"/> + <entry type="LiteralString" style="#009c00"/> + <entry type="Comment" style="italic #ff0000"/> +</style> \ No newline at end of file diff --git a/styles/embedded/lovelace.xml b/styles/embedded/lovelace.xml new file mode 100644 index 0000000..d4f9954 --- /dev/null +++ b/styles/embedded/lovelace.xml @@ -0,0 +1,53 @@ +<style name="lovelace" theme="light"> + <entry type="Error" style="bg:#a848a8"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#2838b0"/> + <entry type="KeywordConstant" style="italic #444444"/> + <entry type="KeywordDeclaration" style="italic"/> + <entry type="KeywordType" style="italic"/> + <entry type="NameAttribute" style="#388038"/> + <entry type="NameBuiltin" style="#388038"/> + <entry type="NameBuiltinPseudo" style="italic"/> + <entry type="NameClass" style="#287088"/> + <entry type="NameConstant" style="#b85820"/> + <entry type="NameDecorator" style="#287088"/> + <entry type="NameEntity" style="#709030"/> + <entry type="NameException" style="#908828"/> + <entry type="NameFunction" style="#785840"/> + <entry type="NameFunctionMagic" style="#b85820"/> + <entry type="NameLabel" style="#289870"/> + <entry type="NameNamespace" style="#289870"/> + <entry type="NameTag" style="#2838b0"/> + <entry type="NameVariable" style="#b04040"/> + <entry type="NameVariableGlobal" style="#908828"/> + <entry type="NameVariableMagic" style="#b85820"/> + <entry type="LiteralString" style="#b83838"/> + <entry type="LiteralStringAffix" style="#444444"/> + <entry type="LiteralStringChar" style="#a848a8"/> + <entry type="LiteralStringDelimiter" style="#b85820"/> + <entry type="LiteralStringDoc" style="italic #b85820"/> + <entry type="LiteralStringEscape" style="#709030"/> + <entry type="LiteralStringInterpol" style="underline"/> + <entry type="LiteralStringOther" style="#a848a8"/> + <entry type="LiteralStringRegex" style="#a848a8"/> + <entry type="LiteralNumber" style="#444444"/> + <entry type="Operator" style="#666666"/> + <entry type="OperatorWord" style="#a848a8"/> + <entry type="Punctuation" style="#888888"/> + <entry type="Comment" style="italic #888888"/> + <entry type="CommentHashbang" style="#287088"/> + <entry type="CommentMultiline" style="#888888"/> + <entry type="CommentPreproc" style="noitalic #289870"/> + <entry type="GenericDeleted" style="#c02828"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#c02828"/> + <entry type="GenericHeading" style="#666666"/> + <entry type="GenericInserted" style="#388038"/> + <entry type="GenericOutput" style="#666666"/> + <entry type="GenericPrompt" style="#444444"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#444444"/> + <entry type="GenericTraceback" style="#2838b0"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#a89028"/> +</style> \ No newline at end of file diff --git a/styles/embedded/manni.xml b/styles/embedded/manni.xml new file mode 100644 index 0000000..b1c5f88 --- /dev/null +++ b/styles/embedded/manni.xml @@ -0,0 +1,44 @@ +<style name="manni" theme="light"> + <entry type="Error" style="#aa0000 bg:#ffaaaa"/> + <entry type="Background" style="bg:#f0f3f3"/> + <entry type="Keyword" style="bold #006699"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="#007788"/> + <entry type="NameAttribute" style="#330099"/> + <entry type="NameBuiltin" style="#336666"/> + <entry type="NameClass" style="bold #00aa88"/> + <entry type="NameConstant" style="#336600"/> + <entry type="NameDecorator" style="#9999ff"/> + <entry type="NameEntity" style="bold #999999"/> + <entry type="NameException" style="bold #cc0000"/> + <entry type="NameFunction" style="#cc00ff"/> + <entry type="NameLabel" style="#9999ff"/> + <entry type="NameNamespace" style="bold #00ccff"/> + <entry type="NameTag" style="bold #330099"/> + <entry type="NameVariable" style="#003333"/> + <entry type="LiteralString" style="#cc3300"/> + <entry type="LiteralStringDoc" style="italic"/> + <entry type="LiteralStringEscape" style="bold #cc3300"/> + <entry type="LiteralStringInterpol" style="#aa0000"/> + <entry type="LiteralStringOther" style="#cc3300"/> + <entry type="LiteralStringRegex" style="#33aaaa"/> + <entry type="LiteralStringSymbol" style="#ffcc33"/> + <entry type="LiteralNumber" style="#ff6600"/> + <entry type="Operator" style="#555555"/> + <entry type="OperatorWord" style="bold #000000"/> + <entry type="Comment" style="italic #0099ff"/> + <entry type="CommentSpecial" style="bold"/> + <entry type="CommentPreproc" style="noitalic #009999"/> + <entry type="GenericDeleted" style="bg:#ffcccc border:#cc0000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #003300"/> + <entry type="GenericInserted" style="bg:#ccffcc border:#00cc00"/> + <entry type="GenericOutput" style="#aaaaaa"/> + <entry type="GenericPrompt" style="bold #000099"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #003300"/> + <entry type="GenericTraceback" style="#99cc66"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/modus-operandi.xml b/styles/embedded/modus-operandi.xml new file mode 100644 index 0000000..7fa72d9 --- /dev/null +++ b/styles/embedded/modus-operandi.xml @@ -0,0 +1,13 @@ +<style name="modus-operandi" theme="light"> + <entry type="Background" style="#000000 bg:#ffffff"/> + <entry type="Keyword" style="#5317ac"/> + <entry type="KeywordConstant" style="#0000c0"/> + <entry type="KeywordType" style="#005a5f"/> + <entry type="NameBuiltin" style="#8f0075"/> + <entry type="NameFunction" style="#721045"/> + <entry type="NameVariable" style="#00538b"/> + <entry type="Literal" style="#0000c0"/> + <entry type="LiteralString" style="#2544bb"/> + <entry type="Operator" style="#00538b"/> + <entry type="Comment" style="#505050"/> +</style> \ No newline at end of file diff --git a/styles/embedded/modus-vivendi.xml b/styles/embedded/modus-vivendi.xml new file mode 100644 index 0000000..62fff97 --- /dev/null +++ b/styles/embedded/modus-vivendi.xml @@ -0,0 +1,13 @@ +<style name="modus-vivendi" theme="dark"> + <entry type="Background" style="#ffffff bg:#000000"/> + <entry type="Keyword" style="#b6a0ff"/> + <entry type="KeywordConstant" style="#00bcff"/> + <entry type="KeywordType" style="#6ae4b9"/> + <entry type="NameBuiltin" style="#f78fe7"/> + <entry type="NameFunction" style="#feacd0"/> + <entry type="NameVariable" style="#00d3d0"/> + <entry type="Literal" style="#00bcff"/> + <entry type="LiteralString" style="#79a8ff"/> + <entry type="Operator" style="#00d3d0"/> + <entry type="Comment" style="#a8a8a8"/> +</style> \ No newline at end of file diff --git a/styles/embedded/monokai.xml b/styles/embedded/monokai.xml new file mode 100644 index 0000000..e5ce083 --- /dev/null +++ b/styles/embedded/monokai.xml @@ -0,0 +1,29 @@ +<style name="monokai" theme="dark"> + <entry type="Error" style="#960050 bg:#1e0010"/> + <entry type="Background" style="bg:#272822"/> + <entry type="Keyword" style="#66d9ef"/> + <entry type="KeywordNamespace" style="#f92672"/> + <entry type="Name" style="#f8f8f2"/> + <entry type="NameAttribute" style="#a6e22e"/> + <entry type="NameClass" style="#a6e22e"/> + <entry type="NameConstant" style="#66d9ef"/> + <entry type="NameDecorator" style="#a6e22e"/> + <entry type="NameException" style="#a6e22e"/> + <entry type="NameFunction" style="#a6e22e"/> + <entry type="NameOther" style="#a6e22e"/> + <entry type="NameTag" style="#f92672"/> + <entry type="Literal" style="#ae81ff"/> + <entry type="LiteralDate" style="#e6db74"/> + <entry type="LiteralString" style="#e6db74"/> + <entry type="LiteralStringEscape" style="#ae81ff"/> + <entry type="LiteralNumber" style="#ae81ff"/> + <entry type="Operator" style="#f92672"/> + <entry type="Punctuation" style="#f8f8f2"/> + <entry type="Comment" style="#75715e"/> + <entry type="GenericDeleted" style="#f92672"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericInserted" style="#a6e22e"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#75715e"/> + <entry type="Text" style="#f8f8f2"/> +</style> \ No newline at end of file diff --git a/styles/embedded/monokailight.xml b/styles/embedded/monokailight.xml new file mode 100644 index 0000000..27bb8f0 --- /dev/null +++ b/styles/embedded/monokailight.xml @@ -0,0 +1,26 @@ +<style name="monokailight" theme="light"> + <entry type="Error" style="#960050 bg:#1e0010"/> + <entry type="Background" style="bg:#fafafa"/> + <entry type="Keyword" style="#00a8c8"/> + <entry type="KeywordNamespace" style="#f92672"/> + <entry type="Name" style="#111111"/> + <entry type="NameAttribute" style="#75af00"/> + <entry type="NameClass" style="#75af00"/> + <entry type="NameConstant" style="#00a8c8"/> + <entry type="NameDecorator" style="#75af00"/> + <entry type="NameException" style="#75af00"/> + <entry type="NameFunction" style="#75af00"/> + <entry type="NameOther" style="#75af00"/> + <entry type="NameTag" style="#f92672"/> + <entry type="Literal" style="#ae81ff"/> + <entry type="LiteralDate" style="#d88200"/> + <entry type="LiteralString" style="#d88200"/> + <entry type="LiteralStringEscape" style="#8045ff"/> + <entry type="LiteralNumber" style="#ae81ff"/> + <entry type="Operator" style="#f92672"/> + <entry type="Punctuation" style="#111111"/> + <entry type="Comment" style="#75715e"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericStrong" style="bold"/> + <entry type="Text" style="#272822"/> +</style> \ No newline at end of file diff --git a/styles/embedded/murphy.xml b/styles/embedded/murphy.xml new file mode 100644 index 0000000..867d9ee --- /dev/null +++ b/styles/embedded/murphy.xml @@ -0,0 +1,52 @@ +<style name="murphy" theme="light"> + <entry type="Error" style="#ff0000 bg:#ffaaaa"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold #228899"/> + <entry type="KeywordPseudo" style="#0088ff"/> + <entry type="KeywordType" style="#6666ff"/> + <entry type="NameAttribute" style="#000077"/> + <entry type="NameBuiltin" style="#007722"/> + <entry type="NameClass" style="bold #ee99ee"/> + <entry type="NameConstant" style="bold #55eedd"/> + <entry type="NameDecorator" style="bold #555555"/> + <entry type="NameEntity" style="#880000"/> + <entry type="NameException" style="bold #ff0000"/> + <entry type="NameFunction" style="bold #55eedd"/> + <entry type="NameLabel" style="bold #997700"/> + <entry type="NameNamespace" style="bold #0e84b5"/> + <entry type="NameTag" style="#007700"/> + <entry type="NameVariable" style="#003366"/> + <entry type="NameVariableClass" style="#ccccff"/> + <entry type="NameVariableGlobal" style="#ff8844"/> + <entry type="NameVariableInstance" style="#aaaaff"/> + <entry type="LiteralString" style="bg:#e0e0ff"/> + <entry type="LiteralStringChar" style="#8888ff"/> + <entry type="LiteralStringDoc" style="#dd4422"/> + <entry type="LiteralStringEscape" style="bold #666666"/> + <entry type="LiteralStringInterpol" style="bg:#eeeeee"/> + <entry type="LiteralStringOther" style="#ff8888"/> + <entry type="LiteralStringRegex" style="#000000 bg:#e0e0ff"/> + <entry type="LiteralStringSymbol" style="#ffcc88"/> + <entry type="LiteralNumber" style="bold #6600ee"/> + <entry type="LiteralNumberFloat" style="bold #6600ee"/> + <entry type="LiteralNumberHex" style="bold #005588"/> + <entry type="LiteralNumberInteger" style="bold #6666ff"/> + <entry type="LiteralNumberOct" style="bold #4400ee"/> + <entry type="Operator" style="#333333"/> + <entry type="OperatorWord" style="bold #000000"/> + <entry type="Comment" style="italic #666666"/> + <entry type="CommentSpecial" style="bold #cc0000"/> + <entry type="CommentPreproc" style="noitalic #557799"/> + <entry type="GenericDeleted" style="#a00000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00a000"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="bold #c65d09"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#0044dd"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/native.xml b/styles/embedded/native.xml new file mode 100644 index 0000000..e60fb3a --- /dev/null +++ b/styles/embedded/native.xml @@ -0,0 +1,35 @@ +<style name="native" theme="dark"> + <entry type="Error" style="#a61717 bg:#e3d2d2"/> + <entry type="Background" style="#d0d0d0 bg:#202020"/> + <entry type="Keyword" style="bold #6ab825"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="NameAttribute" style="#bbbbbb"/> + <entry type="NameBuiltin" style="#24909d"/> + <entry type="NameClass" style="underline #447fcf"/> + <entry type="NameConstant" style="#40ffff"/> + <entry type="NameDecorator" style="#ffa500"/> + <entry type="NameException" style="#bbbbbb"/> + <entry type="NameFunction" style="#447fcf"/> + <entry type="NameNamespace" style="underline #447fcf"/> + <entry type="NameTag" style="bold #6ab825"/> + <entry type="NameVariable" style="#40ffff"/> + <entry type="LiteralString" style="#ed9d13"/> + <entry type="LiteralStringOther" style="#ffa500"/> + <entry type="LiteralNumber" style="#3677a9"/> + <entry type="OperatorWord" style="bold #6ab825"/> + <entry type="Comment" style="italic #999999"/> + <entry type="CommentSpecial" style="bold noitalic #e50808 bg:#520000"/> + <entry type="CommentPreproc" style="bold noitalic #cd2828"/> + <entry type="GenericDeleted" style="#d22323"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#d22323"/> + <entry type="GenericHeading" style="bold #ffffff"/> + <entry type="GenericInserted" style="#589819"/> + <entry type="GenericOutput" style="#cccccc"/> + <entry type="GenericPrompt" style="#aaaaaa"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="underline #ffffff"/> + <entry type="GenericTraceback" style="#d22323"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#666666"/> +</style> \ No newline at end of file diff --git a/styles/embedded/nord.xml b/styles/embedded/nord.xml new file mode 100644 index 0000000..0004fd7 --- /dev/null +++ b/styles/embedded/nord.xml @@ -0,0 +1,46 @@ +<style name="nord" theme="dark"> + <entry type="Error" style="#bf616a"/> + <entry type="Background" style="#d8dee9 bg:#2e3440"/> + <entry type="Keyword" style="bold #81a1c1"/> + <entry type="KeywordPseudo" style="nobold #81a1c1"/> + <entry type="KeywordType" style="nobold #81a1c1"/> + <entry type="Name" style="#d8dee9"/> + <entry type="NameAttribute" style="#8fbcbb"/> + <entry type="NameBuiltin" style="#81a1c1"/> + <entry type="NameClass" style="#8fbcbb"/> + <entry type="NameConstant" style="#8fbcbb"/> + <entry type="NameDecorator" style="#d08770"/> + <entry type="NameEntity" style="#d08770"/> + <entry type="NameException" style="#bf616a"/> + <entry type="NameFunction" style="#88c0d0"/> + <entry type="NameLabel" style="#8fbcbb"/> + <entry type="NameNamespace" style="#8fbcbb"/> + <entry type="NameOther" style="#d8dee9"/> + <entry type="NameTag" style="#81a1c1"/> + <entry type="NameVariable" style="#d8dee9"/> + <entry type="NameProperty" style="#8fbcbb"/> + <entry type="LiteralString" style="#a3be8c"/> + <entry type="LiteralStringDoc" style="#616e87"/> + <entry type="LiteralStringEscape" style="#ebcb8b"/> + <entry type="LiteralStringInterpol" style="#a3be8c"/> + <entry type="LiteralStringOther" style="#a3be8c"/> + <entry type="LiteralStringRegex" style="#ebcb8b"/> + <entry type="LiteralStringSymbol" style="#a3be8c"/> + <entry type="LiteralNumber" style="#b48ead"/> + <entry type="Operator" style="#81a1c1"/> + <entry type="OperatorWord" style="bold #81a1c1"/> + <entry type="Punctuation" style="#eceff4"/> + <entry type="Comment" style="italic #616e87"/> + <entry type="CommentPreproc" style="#5e81ac"/> + <entry type="GenericDeleted" style="#bf616a"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#bf616a"/> + <entry type="GenericHeading" style="bold #88c0d0"/> + <entry type="GenericInserted" style="#a3be8c"/> + <entry type="GenericOutput" style="#d8dee9"/> + <entry type="GenericPrompt" style="bold #4c566a"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #88c0d0"/> + <entry type="GenericTraceback" style="#bf616a"/> + <entry type="TextWhitespace" style="#d8dee9"/> +</style> diff --git a/styles/embedded/onedark.xml b/styles/embedded/onedark.xml new file mode 100644 index 0000000..9ce9d17 --- /dev/null +++ b/styles/embedded/onedark.xml @@ -0,0 +1,25 @@ +<style name="onedark" theme="dark"> + <entry type="Background" style="#ABB2BF bg:#282C34"/> + <entry type="Punctuation" style="#ABB2BF"/> + <entry type="Keyword" style="#C678DD"/> + <entry type="KeywordConstant" style="#E5C07B"/> + <entry type="KeywordDeclaration" style="#C678DD"/> + <entry type="KeywordNamespace" style="#C678DD"/> + <entry type="KeywordReserved" style="#C678DD"/> + <entry type="KeywordType" style="#E5C07B"/> + <entry type="Name" style="#E06C75"/> + <entry type="NameAttribute" style="#E06C75"/> + <entry type="NameBuiltin" style="#E5C07B"/> + <entry type="NameClass" style="#E5C07B"/> + <entry type="NameFunction" style="bold #61AFEF"/> + <entry type="NameFunctionMagic" style="bold #56B6C2"/> + <entry type="NameOther" style="#E06C75"/> + <entry type="NameTag" style="#E06C75"/> + <entry type="NameDecorator" style="#61AFEF"/> + <entry type="LiteralString" style="#98C379"/> + <entry type="LiteralNumber" style="#D19A66"/> + <entry type="Operator" style="#56B6C2"/> + <entry type="Comment" style="#7F848E"/> + <entry type="GenericDeleted" style="#E06C75"/> + <entry type="GenericInserted" style="bold #98C379"/> +</style> diff --git a/styles/embedded/onesenterprise.xml b/styles/embedded/onesenterprise.xml new file mode 100644 index 0000000..efe93b8 --- /dev/null +++ b/styles/embedded/onesenterprise.xml @@ -0,0 +1,10 @@ +<style name="onesenterprise" theme="light"> + <entry type="Keyword" style="#ff0000"/> + <entry type="Name" style="#0000ff"/> + <entry type="LiteralString" style="#000000"/> + <entry type="Operator" style="#ff0000"/> + <entry type="Punctuation" style="#ff0000"/> + <entry type="Comment" style="#008000"/> + <entry type="CommentPreproc" style="#963200"/> + <entry type="Text" style="#000000"/> +</style> \ No newline at end of file diff --git a/styles/embedded/paraiso-dark.xml b/styles/embedded/paraiso-dark.xml new file mode 100644 index 0000000..45e0aa0 --- /dev/null +++ b/styles/embedded/paraiso-dark.xml @@ -0,0 +1,37 @@ +<style name="paraiso-dark" theme="dark"> + <entry type="Error" style="#ef6155"/> + <entry type="Background" style="bg:#2f1e2e"/> + <entry type="Keyword" style="#815ba4"/> + <entry type="KeywordNamespace" style="#5bc4bf"/> + <entry type="KeywordType" style="#fec418"/> + <entry type="Name" style="#e7e9db"/> + <entry type="NameAttribute" style="#06b6ef"/> + <entry type="NameClass" style="#fec418"/> + <entry type="NameConstant" style="#ef6155"/> + <entry type="NameDecorator" style="#5bc4bf"/> + <entry type="NameException" style="#ef6155"/> + <entry type="NameFunction" style="#06b6ef"/> + <entry type="NameNamespace" style="#fec418"/> + <entry type="NameOther" style="#06b6ef"/> + <entry type="NameTag" style="#5bc4bf"/> + <entry type="NameVariable" style="#ef6155"/> + <entry type="Literal" style="#f99b15"/> + <entry type="LiteralDate" style="#48b685"/> + <entry type="LiteralString" style="#48b685"/> + <entry type="LiteralStringChar" style="#e7e9db"/> + <entry type="LiteralStringDoc" style="#776e71"/> + <entry type="LiteralStringEscape" style="#f99b15"/> + <entry type="LiteralStringInterpol" style="#f99b15"/> + <entry type="LiteralNumber" style="#f99b15"/> + <entry type="Operator" style="#5bc4bf"/> + <entry type="Punctuation" style="#e7e9db"/> + <entry type="Comment" style="#776e71"/> + <entry type="GenericDeleted" style="#ef6155"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericHeading" style="bold #e7e9db"/> + <entry type="GenericInserted" style="#48b685"/> + <entry type="GenericPrompt" style="bold #776e71"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #5bc4bf"/> + <entry type="Text" style="#e7e9db"/> +</style> \ No newline at end of file diff --git a/styles/embedded/paraiso-light.xml b/styles/embedded/paraiso-light.xml new file mode 100644 index 0000000..f4e7ef6 --- /dev/null +++ b/styles/embedded/paraiso-light.xml @@ -0,0 +1,37 @@ +<style name="paraiso-light" theme="light"> + <entry type="Error" style="#ef6155"/> + <entry type="Background" style="bg:#e7e9db"/> + <entry type="Keyword" style="#815ba4"/> + <entry type="KeywordNamespace" style="#5bc4bf"/> + <entry type="KeywordType" style="#fec418"/> + <entry type="Name" style="#2f1e2e"/> + <entry type="NameAttribute" style="#06b6ef"/> + <entry type="NameClass" style="#fec418"/> + <entry type="NameConstant" style="#ef6155"/> + <entry type="NameDecorator" style="#5bc4bf"/> + <entry type="NameException" style="#ef6155"/> + <entry type="NameFunction" style="#06b6ef"/> + <entry type="NameNamespace" style="#fec418"/> + <entry type="NameOther" style="#06b6ef"/> + <entry type="NameTag" style="#5bc4bf"/> + <entry type="NameVariable" style="#ef6155"/> + <entry type="Literal" style="#f99b15"/> + <entry type="LiteralDate" style="#48b685"/> + <entry type="LiteralString" style="#48b685"/> + <entry type="LiteralStringChar" style="#2f1e2e"/> + <entry type="LiteralStringDoc" style="#8d8687"/> + <entry type="LiteralStringEscape" style="#f99b15"/> + <entry type="LiteralStringInterpol" style="#f99b15"/> + <entry type="LiteralNumber" style="#f99b15"/> + <entry type="Operator" style="#5bc4bf"/> + <entry type="Punctuation" style="#2f1e2e"/> + <entry type="Comment" style="#8d8687"/> + <entry type="GenericDeleted" style="#ef6155"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericHeading" style="bold #2f1e2e"/> + <entry type="GenericInserted" style="#48b685"/> + <entry type="GenericPrompt" style="bold #8d8687"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #5bc4bf"/> + <entry type="Text" style="#2f1e2e"/> +</style> \ No newline at end of file diff --git a/styles/embedded/pastie.xml b/styles/embedded/pastie.xml new file mode 100644 index 0000000..56297b1 --- /dev/null +++ b/styles/embedded/pastie.xml @@ -0,0 +1,45 @@ +<style name="pastie" theme="light"> + <entry type="Error" style="#a61717 bg:#e3d2d2"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold #008800"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="#888888"/> + <entry type="NameAttribute" style="#336699"/> + <entry type="NameBuiltin" style="#003388"/> + <entry type="NameClass" style="bold #bb0066"/> + <entry type="NameConstant" style="bold #003366"/> + <entry type="NameDecorator" style="#555555"/> + <entry type="NameException" style="bold #bb0066"/> + <entry type="NameFunction" style="bold #0066bb"/> + <entry type="NameLabel" style="italic #336699"/> + <entry type="NameNamespace" style="bold #bb0066"/> + <entry type="NameProperty" style="bold #336699"/> + <entry type="NameTag" style="bold #bb0066"/> + <entry type="NameVariable" style="#336699"/> + <entry type="NameVariableClass" style="#336699"/> + <entry type="NameVariableGlobal" style="#dd7700"/> + <entry type="NameVariableInstance" style="#3333bb"/> + <entry type="LiteralString" style="#dd2200 bg:#fff0f0"/> + <entry type="LiteralStringEscape" style="#0044dd"/> + <entry type="LiteralStringInterpol" style="#3333bb"/> + <entry type="LiteralStringOther" style="#22bb22 bg:#f0fff0"/> + <entry type="LiteralStringRegex" style="#008800 bg:#fff0ff"/> + <entry type="LiteralStringSymbol" style="#aa6600"/> + <entry type="LiteralNumber" style="bold #0000dd"/> + <entry type="OperatorWord" style="#008800"/> + <entry type="Comment" style="#888888"/> + <entry type="CommentSpecial" style="bold #cc0000 bg:#fff0f0"/> + <entry type="CommentPreproc" style="bold #cc0000"/> + <entry type="GenericDeleted" style="#000000 bg:#ffdddd"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#aa0000"/> + <entry type="GenericHeading" style="#333333"/> + <entry type="GenericInserted" style="#000000 bg:#ddffdd"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="#555555"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#666666"/> + <entry type="GenericTraceback" style="#aa0000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/perldoc.xml b/styles/embedded/perldoc.xml new file mode 100644 index 0000000..6521246 --- /dev/null +++ b/styles/embedded/perldoc.xml @@ -0,0 +1,37 @@ +<style name="perldoc" theme="light"> + <entry type="Error" style="#a61717 bg:#e3d2d2"/> + <entry type="Background" style="bg:#eeeedd"/> + <entry type="Keyword" style="bold #8b008b"/> + <entry type="KeywordType" style="#00688b"/> + <entry type="NameAttribute" style="#658b00"/> + <entry type="NameBuiltin" style="#658b00"/> + <entry type="NameClass" style="bold #008b45"/> + <entry type="NameConstant" style="#00688b"/> + <entry type="NameDecorator" style="#707a7c"/> + <entry type="NameException" style="bold #008b45"/> + <entry type="NameFunction" style="#008b45"/> + <entry type="NameNamespace" style="underline #008b45"/> + <entry type="NameTag" style="bold #8b008b"/> + <entry type="NameVariable" style="#00688b"/> + <entry type="LiteralString" style="#cd5555"/> + <entry type="LiteralStringHeredoc" style="italic #1c7e71"/> + <entry type="LiteralStringOther" style="#cb6c20"/> + <entry type="LiteralStringRegex" style="#1c7e71"/> + <entry type="LiteralNumber" style="#b452cd"/> + <entry type="OperatorWord" style="#8b008b"/> + <entry type="Comment" style="#228b22"/> + <entry type="CommentSpecial" style="bold #8b008b"/> + <entry type="CommentPreproc" style="#1e889b"/> + <entry type="GenericDeleted" style="#aa0000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#aa0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00aa00"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="#555555"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#aa0000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/pygments.xml b/styles/embedded/pygments.xml new file mode 100644 index 0000000..ffbd782 --- /dev/null +++ b/styles/embedded/pygments.xml @@ -0,0 +1,42 @@ +<style name="pygments" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Keyword" style="bold #008000"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="nobold #b00040"/> + <entry type="NameAttribute" style="#7d9029"/> + <entry type="NameBuiltin" style="#008000"/> + <entry type="NameClass" style="bold #0000ff"/> + <entry type="NameConstant" style="#880000"/> + <entry type="NameDecorator" style="#aa22ff"/> + <entry type="NameEntity" style="bold #999999"/> + <entry type="NameException" style="bold #d2413a"/> + <entry type="NameFunction" style="#0000ff"/> + <entry type="NameLabel" style="#a0a000"/> + <entry type="NameNamespace" style="bold #0000ff"/> + <entry type="NameTag" style="bold #008000"/> + <entry type="NameVariable" style="#19177c"/> + <entry type="LiteralString" style="#ba2121"/> + <entry type="LiteralStringDoc" style="italic"/> + <entry type="LiteralStringEscape" style="bold #bb6622"/> + <entry type="LiteralStringInterpol" style="bold #bb6688"/> + <entry type="LiteralStringOther" style="#008000"/> + <entry type="LiteralStringRegex" style="#bb6688"/> + <entry type="LiteralStringSymbol" style="#19177c"/> + <entry type="LiteralNumber" style="#666666"/> + <entry type="Operator" style="#666666"/> + <entry type="OperatorWord" style="bold #aa22ff"/> + <entry type="Comment" style="italic #408080"/> + <entry type="CommentPreproc" style="noitalic #bc7a00"/> + <entry type="GenericDeleted" style="#a00000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00a000"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="bold #000080"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#0044dd"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/rainbow_dash.xml b/styles/embedded/rainbow_dash.xml new file mode 100644 index 0000000..ffe6463 --- /dev/null +++ b/styles/embedded/rainbow_dash.xml @@ -0,0 +1,40 @@ +<style name="rainbow_dash" theme="light"> + <entry type="Error" style="#ffffff bg:#cc0000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold #2c5dcd"/> + <entry type="KeywordPseudo" style="nobold"/> + <entry type="KeywordType" style="#5918bb"/> + <entry type="NameAttribute" style="italic #2c5dcd"/> + <entry type="NameBuiltin" style="bold #5918bb"/> + <entry type="NameClass" style="underline"/> + <entry type="NameConstant" style="#318495"/> + <entry type="NameDecorator" style="bold #ff8000"/> + <entry type="NameEntity" style="bold #5918bb"/> + <entry type="NameException" style="bold #5918bb"/> + <entry type="NameFunction" style="bold #ff8000"/> + <entry type="NameTag" style="bold #2c5dcd"/> + <entry type="LiteralString" style="#00cc66"/> + <entry type="LiteralStringDoc" style="italic"/> + <entry type="LiteralStringEscape" style="bold #c5060b"/> + <entry type="LiteralStringOther" style="#318495"/> + <entry type="LiteralStringSymbol" style="bold #c5060b"/> + <entry type="LiteralNumber" style="bold #5918bb"/> + <entry type="Operator" style="#2c5dcd"/> + <entry type="OperatorWord" style="bold"/> + <entry type="Comment" style="italic #0080ff"/> + <entry type="CommentSpecial" style="bold"/> + <entry type="CommentPreproc" style="noitalic"/> + <entry type="GenericDeleted" style="bg:#ffcccc border:#c5060b"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #2c5dcd"/> + <entry type="GenericInserted" style="bg:#ccffcc border:#00cc00"/> + <entry type="GenericOutput" style="#aaaaaa"/> + <entry type="GenericPrompt" style="bold #2c5dcd"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #2c5dcd"/> + <entry type="GenericTraceback" style="#c5060b"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#4d4d4d"/> + <entry type="TextWhitespace" style="#cbcbcb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/rose-pine-dawn.xml b/styles/embedded/rose-pine-dawn.xml new file mode 100644 index 0000000..f2fa25d --- /dev/null +++ b/styles/embedded/rose-pine-dawn.xml @@ -0,0 +1,29 @@ +<style name="rose-pine-dawn" theme="light"> + <entry type="Error" style="#b4637a"/> + <entry type="Background" style="bg:#faf4ed"/> + <entry type="Keyword" style="#286983"/> + <entry type="KeywordNamespace" style="#907aa9"/> + <entry type="Name" style="#d7827e"/> + <entry type="NameAttribute" style="#d7827e"/> + <entry type="NameClass" style="#56949f"/> + <entry type="NameConstant" style="#ea9d34"/> + <entry type="NameDecorator" style="#797593"/> + <entry type="NameException" style="#286983"/> + <entry type="NameFunction" style="#d7827e"/> + <entry type="NameOther" style="#575279"/> + <entry type="NameTag" style="#d7827e"/> + <entry type="Literal" style="#ea9d34"/> + <entry type="LiteralDate" style="#ea9d34"/> + <entry type="LiteralString" style="#ea9d34"/> + <entry type="LiteralStringEscape" style="#286983"/> + <entry type="LiteralNumber" style="#ea9d34"/> + <entry type="Operator" style="#797593"/> + <entry type="Punctuation" style="#797593"/> + <entry type="Comment" style="#9893a5"/> + <entry type="GenericDeleted" style="#b4637a"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericInserted" style="#56949f"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#907aa9"/> + <entry type="Text" style="#575279"/> +</style> diff --git a/styles/embedded/rose-pine-moon.xml b/styles/embedded/rose-pine-moon.xml new file mode 100644 index 0000000..9df4245 --- /dev/null +++ b/styles/embedded/rose-pine-moon.xml @@ -0,0 +1,29 @@ +<style name="rose-pine-moon" theme="dark"> + <entry type="Error" style="#eb6f92"/> + <entry type="Background" style="bg:#232136"/> + <entry type="Keyword" style="#3e8fb0"/> + <entry type="KeywordNamespace" style="#c4a7e7"/> + <entry type="Name" style="#ea9a97"/> + <entry type="NameAttribute" style="#ea9a97"/> + <entry type="NameClass" style="#9ccfd8"/> + <entry type="NameConstant" style="#f6c177"/> + <entry type="NameDecorator" style="#908caa"/> + <entry type="NameException" style="#3e8fb0"/> + <entry type="NameFunction" style="#ea9a97"/> + <entry type="NameOther" style="#e0def4"/> + <entry type="NameTag" style="#ea9a97"/> + <entry type="Literal" style="#f6c177"/> + <entry type="LiteralDate" style="#f6c177"/> + <entry type="LiteralString" style="#f6c177"/> + <entry type="LiteralStringEscape" style="#3e8fb0"/> + <entry type="LiteralNumber" style="#f6c177"/> + <entry type="Operator" style="#908caa"/> + <entry type="Punctuation" style="#908caa"/> + <entry type="Comment" style="#6e6a86"/> + <entry type="GenericDeleted" style="#eb6f92"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericInserted" style="#9ccfd8"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#c4a7e7"/> + <entry type="Text" style="#e0def4"/> +</style> diff --git a/styles/embedded/rose-pine.xml b/styles/embedded/rose-pine.xml new file mode 100644 index 0000000..80bb45e --- /dev/null +++ b/styles/embedded/rose-pine.xml @@ -0,0 +1,29 @@ +<style name="rose-pine" theme="dark"> + <entry type="Error" style="#eb6f92"/> + <entry type="Background" style="bg:#191724"/> + <entry type="Keyword" style="#31748f"/> + <entry type="KeywordNamespace" style="#c4a7e7"/> + <entry type="Name" style="#ebbcba"/> + <entry type="NameAttribute" style="#ebbcba"/> + <entry type="NameClass" style="#9ccfd8"/> + <entry type="NameConstant" style="#f6c177"/> + <entry type="NameDecorator" style="#908caa"/> + <entry type="NameException" style="#31748f"/> + <entry type="NameFunction" style="#ebbcba"/> + <entry type="NameOther" style="#e0def4"/> + <entry type="NameTag" style="#ebbcba"/> + <entry type="Literal" style="#f6c177"/> + <entry type="LiteralDate" style="#f6c177"/> + <entry type="LiteralString" style="#f6c177"/> + <entry type="LiteralStringEscape" style="#31748f"/> + <entry type="LiteralNumber" style="#f6c177"/> + <entry type="Operator" style="#908caa"/> + <entry type="Punctuation" style="#908caa"/> + <entry type="Comment" style="#6e6a86"/> + <entry type="GenericDeleted" style="#eb6f92"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericInserted" style="#9ccfd8"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#c4a7e7"/> + <entry type="Text" style="#e0def4"/> +</style> diff --git a/styles/embedded/rrt.xml b/styles/embedded/rrt.xml new file mode 100644 index 0000000..063e66d --- /dev/null +++ b/styles/embedded/rrt.xml @@ -0,0 +1,13 @@ +<style name="rrt" theme="dark"> + <entry type="Background" style="#f8f8f2 bg:#000000"/> + <entry type="Keyword" style="#ff0000"/> + <entry type="KeywordType" style="#ee82ee"/> + <entry type="NameConstant" style="#7fffd4"/> + <entry type="NameFunction" style="#ffff00"/> + <entry type="NameVariable" style="#eedd82"/> + <entry type="LiteralString" style="#87ceeb"/> + <entry type="LiteralStringSymbol" style="#ff6600"/> + <entry type="LiteralNumber" style="#ff6600"/> + <entry type="Comment" style="#00ff00"/> + <entry type="CommentPreproc" style="#e5e5e5"/> +</style> \ No newline at end of file diff --git a/styles/embedded/solarized-dark.xml b/styles/embedded/solarized-dark.xml new file mode 100644 index 0000000..ae157ee --- /dev/null +++ b/styles/embedded/solarized-dark.xml @@ -0,0 +1,39 @@ +<style name="solarized-dark" theme="dark"> + <entry type="Other" style="#cb4b16"/> + <entry type="Background" style="#93a1a1 bg:#002b36"/> + <entry type="Keyword" style="#719e07"/> + <entry type="KeywordConstant" style="#cb4b16"/> + <entry type="KeywordDeclaration" style="#268bd2"/> + <entry type="KeywordReserved" style="#268bd2"/> + <entry type="KeywordType" style="#dc322f"/> + <entry type="NameAttribute" style="#93a1a1"/> + <entry type="NameBuiltin" style="#b58900"/> + <entry type="NameBuiltinPseudo" style="#268bd2"/> + <entry type="NameClass" style="#268bd2"/> + <entry type="NameConstant" style="#cb4b16"/> + <entry type="NameDecorator" style="#268bd2"/> + <entry type="NameEntity" style="#cb4b16"/> + <entry type="NameException" style="#cb4b16"/> + <entry type="NameFunction" style="#268bd2"/> + <entry type="NameTag" style="#268bd2"/> + <entry type="NameVariable" style="#268bd2"/> + <entry type="LiteralString" style="#2aa198"/> + <entry type="LiteralStringBacktick" style="#586e75"/> + <entry type="LiteralStringChar" style="#2aa198"/> + <entry type="LiteralStringDoc" style="#93a1a1"/> + <entry type="LiteralStringEscape" style="#cb4b16"/> + <entry type="LiteralStringHeredoc" style="#93a1a1"/> + <entry type="LiteralStringRegex" style="#dc322f"/> + <entry type="LiteralNumber" style="#2aa198"/> + <entry type="Operator" style="#719e07"/> + <entry type="Comment" style="#586e75"/> + <entry type="CommentSpecial" style="#719e07"/> + <entry type="CommentPreproc" style="#719e07"/> + <entry type="GenericDeleted" style="#dc322f"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="bold #dc322f"/> + <entry type="GenericHeading" style="#cb4b16"/> + <entry type="GenericInserted" style="#719e07"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#268bd2"/> +</style> \ No newline at end of file diff --git a/styles/embedded/solarized-dark256.xml b/styles/embedded/solarized-dark256.xml new file mode 100644 index 0000000..1693861 --- /dev/null +++ b/styles/embedded/solarized-dark256.xml @@ -0,0 +1,41 @@ +<style name="solarized-dark256" theme="dark"> + <entry type="Other" style="#d75f00"/> + <entry type="Background" style="#8a8a8a bg:#1c1c1c"/> + <entry type="Keyword" style="#5f8700"/> + <entry type="KeywordConstant" style="#d75f00"/> + <entry type="KeywordDeclaration" style="#0087ff"/> + <entry type="KeywordNamespace" style="#d75f00"/> + <entry type="KeywordReserved" style="#0087ff"/> + <entry type="KeywordType" style="#af0000"/> + <entry type="NameAttribute" style="#8a8a8a"/> + <entry type="NameBuiltin" style="#0087ff"/> + <entry type="NameBuiltinPseudo" style="#0087ff"/> + <entry type="NameClass" style="#0087ff"/> + <entry type="NameConstant" style="#d75f00"/> + <entry type="NameDecorator" style="#0087ff"/> + <entry type="NameEntity" style="#d75f00"/> + <entry type="NameException" style="#af8700"/> + <entry type="NameFunction" style="#0087ff"/> + <entry type="NameTag" style="#0087ff"/> + <entry type="NameVariable" style="#0087ff"/> + <entry type="LiteralString" style="#00afaf"/> + <entry type="LiteralStringBacktick" style="#4e4e4e"/> + <entry type="LiteralStringChar" style="#00afaf"/> + <entry type="LiteralStringDoc" style="#00afaf"/> + <entry type="LiteralStringEscape" style="#af0000"/> + <entry type="LiteralStringHeredoc" style="#00afaf"/> + <entry type="LiteralStringRegex" style="#af0000"/> + <entry type="LiteralNumber" style="#00afaf"/> + <entry type="Operator" style="#8a8a8a"/> + <entry type="OperatorWord" style="#5f8700"/> + <entry type="Comment" style="#4e4e4e"/> + <entry type="CommentSpecial" style="#5f8700"/> + <entry type="CommentPreproc" style="#5f8700"/> + <entry type="GenericDeleted" style="#af0000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="bold #af0000"/> + <entry type="GenericHeading" style="#d75f00"/> + <entry type="GenericInserted" style="#5f8700"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#0087ff"/> +</style> \ No newline at end of file diff --git a/styles/embedded/solarized-light.xml b/styles/embedded/solarized-light.xml new file mode 100644 index 0000000..67f2475 --- /dev/null +++ b/styles/embedded/solarized-light.xml @@ -0,0 +1,17 @@ +<style name="solarized-light" theme="light"> + <entry type="Background" style="bg:#eee8d5"/> + <entry type="Keyword" style="#859900"/> + <entry type="KeywordConstant" style="bold"/> + <entry type="KeywordNamespace" style="bold #dc322f"/> + <entry type="KeywordType" style="bold"/> + <entry type="Name" style="#268bd2"/> + <entry type="NameBuiltin" style="#cb4b16"/> + <entry type="NameClass" style="#cb4b16"/> + <entry type="NameTag" style="bold"/> + <entry type="Literal" style="#2aa198"/> + <entry type="LiteralNumber" style="bold"/> + <entry type="OperatorWord" style="#859900"/> + <entry type="Comment" style="italic #93a1a1"/> + <entry type="Generic" style="#d33682"/> + <entry type="Text" style="#586e75"/> +</style> \ No newline at end of file diff --git a/styles/embedded/swapoff.xml b/styles/embedded/swapoff.xml new file mode 100644 index 0000000..c396008 --- /dev/null +++ b/styles/embedded/swapoff.xml @@ -0,0 +1,18 @@ +<style name="swapoff" theme="dark"> + <entry type="Error" style="#ff0000"/> + <entry type="Background" style="#e5e5e5 bg:#000000"/> + <entry type="Keyword" style="bold #ffffff"/> + <entry type="NameAttribute" style="#007f7f"/> + <entry type="NameBuiltin" style="bold #ffffff"/> + <entry type="NameKeyword" style="bold #ffffff"/> + <entry type="NameTag" style="bold"/> + <entry type="LiteralDate" style="bold #ffff00"/> + <entry type="LiteralString" style="bold #00ffff"/> + <entry type="LiteralNumber" style="bold #ffff00"/> + <entry type="Comment" style="#007f7f"/> + <entry type="CommentPreproc" style="bold #00ff00"/> + <entry type="GenericHeading" style="bold"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold"/> + <entry type="GenericUnderline" style="underline"/> +</style> \ No newline at end of file diff --git a/styles/embedded/tango.xml b/styles/embedded/tango.xml new file mode 100644 index 0000000..431fe10 --- /dev/null +++ b/styles/embedded/tango.xml @@ -0,0 +1,72 @@ +<style name="tango" theme="light"> + <entry type="Other" style="#000000"/> + <entry type="Error" style="#a40000 border:#ef2929"/> + <entry type="Background" style="bg:#f8f8f8"/> + <entry type="Keyword" style="bold #204a87"/> + <entry type="KeywordConstant" style="bold #204a87"/> + <entry type="KeywordDeclaration" style="bold #204a87"/> + <entry type="KeywordNamespace" style="bold #204a87"/> + <entry type="KeywordPseudo" style="bold #204a87"/> + <entry type="KeywordReserved" style="bold #204a87"/> + <entry type="KeywordType" style="bold #204a87"/> + <entry type="Name" style="#000000"/> + <entry type="NameAttribute" style="#c4a000"/> + <entry type="NameBuiltin" style="#204a87"/> + <entry type="NameBuiltinPseudo" style="#3465a4"/> + <entry type="NameClass" style="#000000"/> + <entry type="NameConstant" style="#000000"/> + <entry type="NameDecorator" style="bold #5c35cc"/> + <entry type="NameEntity" style="#ce5c00"/> + <entry type="NameException" style="bold #cc0000"/> + <entry type="NameFunction" style="#000000"/> + <entry type="NameLabel" style="#f57900"/> + <entry type="NameNamespace" style="#000000"/> + <entry type="NameOther" style="#000000"/> + <entry type="NameProperty" style="#000000"/> + <entry type="NameTag" style="bold #204a87"/> + <entry type="NameVariable" style="#000000"/> + <entry type="NameVariableClass" style="#000000"/> + <entry type="NameVariableGlobal" style="#000000"/> + <entry type="NameVariableInstance" style="#000000"/> + <entry type="Literal" style="#000000"/> + <entry type="LiteralDate" style="#000000"/> + <entry type="LiteralString" style="#4e9a06"/> + <entry type="LiteralStringBacktick" style="#4e9a06"/> + <entry type="LiteralStringChar" style="#4e9a06"/> + <entry type="LiteralStringDoc" style="italic #8f5902"/> + <entry type="LiteralStringDouble" style="#4e9a06"/> + <entry type="LiteralStringEscape" style="#4e9a06"/> + <entry type="LiteralStringHeredoc" style="#4e9a06"/> + <entry type="LiteralStringInterpol" style="#4e9a06"/> + <entry type="LiteralStringOther" style="#4e9a06"/> + <entry type="LiteralStringRegex" style="#4e9a06"/> + <entry type="LiteralStringSingle" style="#4e9a06"/> + <entry type="LiteralStringSymbol" style="#4e9a06"/> + <entry type="LiteralNumber" style="bold #0000cf"/> + <entry type="LiteralNumberFloat" style="bold #0000cf"/> + <entry type="LiteralNumberHex" style="bold #0000cf"/> + <entry type="LiteralNumberInteger" style="bold #0000cf"/> + <entry type="LiteralNumberIntegerLong" style="bold #0000cf"/> + <entry type="LiteralNumberOct" style="bold #0000cf"/> + <entry type="Operator" style="bold #ce5c00"/> + <entry type="OperatorWord" style="bold #204a87"/> + <entry type="Punctuation" style="bold #000000"/> + <entry type="Comment" style="italic #8f5902"/> + <entry type="CommentMultiline" style="italic #8f5902"/> + <entry type="CommentSingle" style="italic #8f5902"/> + <entry type="CommentSpecial" style="italic #8f5902"/> + <entry type="CommentPreproc" style="italic #8f5902"/> + <entry type="Generic" style="#000000"/> + <entry type="GenericDeleted" style="#a40000"/> + <entry type="GenericEmph" style="italic #000000"/> + <entry type="GenericError" style="#ef2929"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00a000"/> + <entry type="GenericOutput" style="italic #000000"/> + <entry type="GenericPrompt" style="#8f5902"/> + <entry type="GenericStrong" style="bold #000000"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="bold #a40000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="underline #f8f8f8"/> +</style> \ No newline at end of file diff --git a/styles/embedded/tokyonight-day.xml b/styles/embedded/tokyonight-day.xml new file mode 100644 index 0000000..a146a18 --- /dev/null +++ b/styles/embedded/tokyonight-day.xml @@ -0,0 +1,83 @@ +<style name="tokyonight-day" theme="light"> + <entry type="Background" style="bg:#e1e2e7 #3760bf"/> + <entry type="CodeLine" style="#3760bf"/> + <entry type="Error" style="#c64343"/> + <entry type="Other" style="#3760bf"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#a1a6c5"/> + <entry type="LineNumbersTable" style="#6172b0"/> + <entry type="LineNumbers" style="#6172b0"/> + <entry type="Keyword" style="#9854f1"/> + <entry type="KeywordReserved" style="#9854f1"/> + <entry type="KeywordPseudo" style="#9854f1"/> + <entry type="KeywordConstant" style="#8c6c3e"/> + <entry type="KeywordDeclaration" style="#9d7cd8"/> + <entry type="KeywordNamespace" style="#007197"/> + <entry type="KeywordType" style="#0db9d7"/> + <entry type="Name" style="#3760bf"/> + <entry type="NameClass" style="#b15c00"/> + <entry type="NameConstant" style="#b15c00"/> + <entry type="NameDecorator" style="bold #2e7de9"/> + <entry type="NameEntity" style="#007197"/> + <entry type="NameException" style="#8c6c3e"/> + <entry type="NameFunction" style="#2e7de9"/> + <entry type="NameFunctionMagic" style="#2e7de9"/> + <entry type="NameLabel" style="#587539"/> + <entry type="NameNamespace" style="#8c6c3e"/> + <entry type="NameProperty" style="#8c6c3e"/> + <entry type="NameTag" style="#9854f1"/> + <entry type="NameVariable" style="#3760bf"/> + <entry type="NameVariableClass" style="#3760bf"/> + <entry type="NameVariableGlobal" style="#3760bf"/> + <entry type="NameVariableInstance" style="#3760bf"/> + <entry type="NameVariableMagic" style="#3760bf"/> + <entry type="NameAttribute" style="#2e7de9"/> + <entry type="NameBuiltin" style="#587539"/> + <entry type="NameBuiltinPseudo" style="#587539"/> + <entry type="NameOther" style="#3760bf"/> + <entry type="Literal" style="#3760bf"/> + <entry type="LiteralDate" style="#3760bf"/> + <entry type="LiteralString" style="#587539"/> + <entry type="LiteralStringChar" style="#587539"/> + <entry type="LiteralStringSingle" style="#587539"/> + <entry type="LiteralStringDouble" style="#587539"/> + <entry type="LiteralStringBacktick" style="#587539"/> + <entry type="LiteralStringOther" style="#587539"/> + <entry type="LiteralStringSymbol" style="#587539"/> + <entry type="LiteralStringInterpol" style="#587539"/> + <entry type="LiteralStringAffix" style="#9d7cd8"/> + <entry type="LiteralStringDelimiter" style="#2e7de9"/> + <entry type="LiteralStringEscape" style="#2e7de9"/> + <entry type="LiteralStringRegex" style="#007197"/> + <entry type="LiteralStringDoc" style="#a1a6c5"/> + <entry type="LiteralStringHeredoc" style="#a1a6c5"/> + <entry type="LiteralNumber" style="#8c6c3e"/> + <entry type="LiteralNumberBin" style="#8c6c3e"/> + <entry type="LiteralNumberHex" style="#8c6c3e"/> + <entry type="LiteralNumberInteger" style="#8c6c3e"/> + <entry type="LiteralNumberFloat" style="#8c6c3e"/> + <entry type="LiteralNumberIntegerLong" style="#8c6c3e"/> + <entry type="LiteralNumberOct" style="#8c6c3e"/> + <entry type="Operator" style="bold #587539"/> + <entry type="OperatorWord" style="bold #587539"/> + <entry type="Comment" style="italic #a1a6c5"/> + <entry type="CommentSingle" style="italic #a1a6c5"/> + <entry type="CommentMultiline" style="italic #a1a6c5"/> + <entry type="CommentSpecial" style="italic #a1a6c5"/> + <entry type="CommentHashbang" style="italic #a1a6c5"/> + <entry type="CommentPreproc" style="italic #a1a6c5"/> + <entry type="CommentPreprocFile" style="bold #a1a6c5"/> + <entry type="Generic" style="#3760bf"/> + <entry type="GenericInserted" style="bg:#e9e9ed #587539"/> + <entry type="GenericDeleted" style="#c64343 bg:#e9e9ed"/> + <entry type="GenericEmph" style="italic #3760bf"/> + <entry type="GenericStrong" style="bold #3760bf"/> + <entry type="GenericUnderline" style="underline #3760bf"/> + <entry type="GenericHeading" style="bold #8c6c3e"/> + <entry type="GenericSubheading" style="bold #8c6c3e"/> + <entry type="GenericOutput" style="#3760bf"/> + <entry type="GenericPrompt" style="#3760bf"/> + <entry type="GenericError" style="#c64343"/> + <entry type="GenericTraceback" style="#c64343"/> +</style> \ No newline at end of file diff --git a/styles/embedded/tokyonight-moon.xml b/styles/embedded/tokyonight-moon.xml new file mode 100644 index 0000000..0af8992 --- /dev/null +++ b/styles/embedded/tokyonight-moon.xml @@ -0,0 +1,83 @@ +<style name="tokyonight-moon" theme="dark"> + <entry type="Background" style="bg:#222436 #c8d3f5"/> + <entry type="CodeLine" style="#c8d3f5"/> + <entry type="Error" style="#c53b53"/> + <entry type="Other" style="#c8d3f5"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#444a73"/> + <entry type="LineNumbersTable" style="#828bb8"/> + <entry type="LineNumbers" style="#828bb8"/> + <entry type="Keyword" style="#c099ff"/> + <entry type="KeywordReserved" style="#c099ff"/> + <entry type="KeywordPseudo" style="#c099ff"/> + <entry type="KeywordConstant" style="#ffc777"/> + <entry type="KeywordDeclaration" style="#c099ff"/> + <entry type="KeywordNamespace" style="#86e1fc"/> + <entry type="KeywordType" style="#4fd6be"/> + <entry type="Name" style="#c8d3f5"/> + <entry type="NameClass" style="#ff966c"/> + <entry type="NameConstant" style="#ff966c"/> + <entry type="NameDecorator" style="bold #82aaff"/> + <entry type="NameEntity" style="#86e1fc"/> + <entry type="NameException" style="#ffc777"/> + <entry type="NameFunction" style="#82aaff"/> + <entry type="NameFunctionMagic" style="#82aaff"/> + <entry type="NameLabel" style="#c3e88d"/> + <entry type="NameNamespace" style="#ffc777"/> + <entry type="NameProperty" style="#ffc777"/> + <entry type="NameTag" style="#c099ff"/> + <entry type="NameVariable" style="#c8d3f5"/> + <entry type="NameVariableClass" style="#c8d3f5"/> + <entry type="NameVariableGlobal" style="#c8d3f5"/> + <entry type="NameVariableInstance" style="#c8d3f5"/> + <entry type="NameVariableMagic" style="#c8d3f5"/> + <entry type="NameAttribute" style="#82aaff"/> + <entry type="NameBuiltin" style="#c3e88d"/> + <entry type="NameBuiltinPseudo" style="#c3e88d"/> + <entry type="NameOther" style="#c8d3f5"/> + <entry type="Literal" style="#c8d3f5"/> + <entry type="LiteralDate" style="#c8d3f5"/> + <entry type="LiteralString" style="#c3e88d"/> + <entry type="LiteralStringChar" style="#c3e88d"/> + <entry type="LiteralStringSingle" style="#c3e88d"/> + <entry type="LiteralStringDouble" style="#c3e88d"/> + <entry type="LiteralStringBacktick" style="#c3e88d"/> + <entry type="LiteralStringOther" style="#c3e88d"/> + <entry type="LiteralStringSymbol" style="#c3e88d"/> + <entry type="LiteralStringInterpol" style="#c3e88d"/> + <entry type="LiteralStringAffix" style="#c099ff"/> + <entry type="LiteralStringDelimiter" style="#82aaff"/> + <entry type="LiteralStringEscape" style="#82aaff"/> + <entry type="LiteralStringRegex" style="#86e1fc"/> + <entry type="LiteralStringDoc" style="#444a73"/> + <entry type="LiteralStringHeredoc" style="#444a73"/> + <entry type="LiteralNumber" style="#ffc777"/> + <entry type="LiteralNumberBin" style="#ffc777"/> + <entry type="LiteralNumberHex" style="#ffc777"/> + <entry type="LiteralNumberInteger" style="#ffc777"/> + <entry type="LiteralNumberFloat" style="#ffc777"/> + <entry type="LiteralNumberIntegerLong" style="#ffc777"/> + <entry type="LiteralNumberOct" style="#ffc777"/> + <entry type="Operator" style="bold #c3e88d"/> + <entry type="OperatorWord" style="bold #c3e88d"/> + <entry type="Comment" style="italic #444a73"/> + <entry type="CommentSingle" style="italic #444a73"/> + <entry type="CommentMultiline" style="italic #444a73"/> + <entry type="CommentSpecial" style="italic #444a73"/> + <entry type="CommentHashbang" style="italic #444a73"/> + <entry type="CommentPreproc" style="italic #444a73"/> + <entry type="CommentPreprocFile" style="bold #444a73"/> + <entry type="Generic" style="#c8d3f5"/> + <entry type="GenericInserted" style="bg:#1b1d2b #c3e88d"/> + <entry type="GenericDeleted" style="#c53b53 bg:#1b1d2b"/> + <entry type="GenericEmph" style="italic #c8d3f5"/> + <entry type="GenericStrong" style="bold #c8d3f5"/> + <entry type="GenericUnderline" style="underline #c8d3f5"/> + <entry type="GenericHeading" style="bold #ffc777"/> + <entry type="GenericSubheading" style="bold #ffc777"/> + <entry type="GenericOutput" style="#c8d3f5"/> + <entry type="GenericPrompt" style="#c8d3f5"/> + <entry type="GenericError" style="#c53b53"/> + <entry type="GenericTraceback" style="#c53b53"/> +</style> diff --git a/styles/embedded/tokyonight-night.xml b/styles/embedded/tokyonight-night.xml new file mode 100644 index 0000000..a82ed38 --- /dev/null +++ b/styles/embedded/tokyonight-night.xml @@ -0,0 +1,83 @@ +<style name="tokyonight-night" theme="dark"> + <entry type="Background" style="bg:#1a1b26 #c0caf5"/> + <entry type="CodeLine" style="#c0caf5"/> + <entry type="Error" style="#db4b4b"/> + <entry type="Other" style="#c0caf5"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#414868"/> + <entry type="LineNumbersTable" style="#a9b1d6"/> + <entry type="LineNumbers" style="#a9b1d6"/> + <entry type="Keyword" style="#bb9af7"/> + <entry type="KeywordReserved" style="#bb9af7"/> + <entry type="KeywordPseudo" style="#bb9af7"/> + <entry type="KeywordConstant" style="#e0af68"/> + <entry type="KeywordDeclaration" style="#9d7cd8"/> + <entry type="KeywordNamespace" style="#7dcfff"/> + <entry type="KeywordType" style="#41a6b5"/> + <entry type="Name" style="#c0caf5"/> + <entry type="NameClass" style="#ff9e64"/> + <entry type="NameConstant" style="#ff9e64"/> + <entry type="NameDecorator" style="bold #7aa2f7"/> + <entry type="NameEntity" style="#7dcfff"/> + <entry type="NameException" style="#e0af68"/> + <entry type="NameFunction" style="#7aa2f7"/> + <entry type="NameFunctionMagic" style="#7aa2f7"/> + <entry type="NameLabel" style="#9ece6a"/> + <entry type="NameNamespace" style="#e0af68"/> + <entry type="NameProperty" style="#e0af68"/> + <entry type="NameTag" style="#bb9af7"/> + <entry type="NameVariable" style="#c0caf5"/> + <entry type="NameVariableClass" style="#c0caf5"/> + <entry type="NameVariableGlobal" style="#c0caf5"/> + <entry type="NameVariableInstance" style="#c0caf5"/> + <entry type="NameVariableMagic" style="#c0caf5"/> + <entry type="NameAttribute" style="#7aa2f7"/> + <entry type="NameBuiltin" style="#9ece6a"/> + <entry type="NameBuiltinPseudo" style="#9ece6a"/> + <entry type="NameOther" style="#c0caf5"/> + <entry type="Literal" style="#c0caf5"/> + <entry type="LiteralDate" style="#c0caf5"/> + <entry type="LiteralString" style="#9ece6a"/> + <entry type="LiteralStringChar" style="#9ece6a"/> + <entry type="LiteralStringSingle" style="#9ece6a"/> + <entry type="LiteralStringDouble" style="#9ece6a"/> + <entry type="LiteralStringBacktick" style="#9ece6a"/> + <entry type="LiteralStringOther" style="#9ece6a"/> + <entry type="LiteralStringSymbol" style="#9ece6a"/> + <entry type="LiteralStringInterpol" style="#9ece6a"/> + <entry type="LiteralStringAffix" style="#9d7cd8"/> + <entry type="LiteralStringDelimiter" style="#7aa2f7"/> + <entry type="LiteralStringEscape" style="#7aa2f7"/> + <entry type="LiteralStringRegex" style="#7dcfff"/> + <entry type="LiteralStringDoc" style="#414868"/> + <entry type="LiteralStringHeredoc" style="#414868"/> + <entry type="LiteralNumber" style="#e0af68"/> + <entry type="LiteralNumberBin" style="#e0af68"/> + <entry type="LiteralNumberHex" style="#e0af68"/> + <entry type="LiteralNumberInteger" style="#e0af68"/> + <entry type="LiteralNumberFloat" style="#e0af68"/> + <entry type="LiteralNumberIntegerLong" style="#e0af68"/> + <entry type="LiteralNumberOct" style="#e0af68"/> + <entry type="Operator" style="bold #9ece6a"/> + <entry type="OperatorWord" style="bold #9ece6a"/> + <entry type="Comment" style="italic #414868"/> + <entry type="CommentSingle" style="italic #414868"/> + <entry type="CommentMultiline" style="italic #414868"/> + <entry type="CommentSpecial" style="italic #414868"/> + <entry type="CommentHashbang" style="italic #414868"/> + <entry type="CommentPreproc" style="italic #414868"/> + <entry type="CommentPreprocFile" style="bold #414868"/> + <entry type="Generic" style="#c0caf5"/> + <entry type="GenericInserted" style="bg:#15161e #9ece6a"/> + <entry type="GenericDeleted" style="#db4b4b bg:#15161e"/> + <entry type="GenericEmph" style="italic #c0caf5"/> + <entry type="GenericStrong" style="bold #c0caf5"/> + <entry type="GenericUnderline" style="underline #c0caf5"/> + <entry type="GenericHeading" style="bold #e0af68"/> + <entry type="GenericSubheading" style="bold #e0af68"/> + <entry type="GenericOutput" style="#c0caf5"/> + <entry type="GenericPrompt" style="#c0caf5"/> + <entry type="GenericError" style="#db4b4b"/> + <entry type="GenericTraceback" style="#db4b4b"/> +</style> \ No newline at end of file diff --git a/styles/embedded/tokyonight-storm.xml b/styles/embedded/tokyonight-storm.xml new file mode 100644 index 0000000..3c3773a --- /dev/null +++ b/styles/embedded/tokyonight-storm.xml @@ -0,0 +1,83 @@ +<style name="tokyonight-storm" theme="dark"> + <entry type="Background" style="bg:#1a1b26 #c0caf5"/> + <entry type="CodeLine" style="#c0caf5"/> + <entry type="Error" style="#db4b4b"/> + <entry type="Other" style="#c0caf5"/> + <entry type="LineTableTD" style=""/> + <entry type="LineTable" style=""/> + <entry type="LineHighlight" style="bg:#414868"/> + <entry type="LineNumbersTable" style="#a9b1d6"/> + <entry type="LineNumbers" style="#a9b1d6"/> + <entry type="Keyword" style="#bb9af7"/> + <entry type="KeywordReserved" style="#bb9af7"/> + <entry type="KeywordPseudo" style="#bb9af7"/> + <entry type="KeywordConstant" style="#e0af68"/> + <entry type="KeywordDeclaration" style="#9d7cd8"/> + <entry type="KeywordNamespace" style="#7dcfff"/> + <entry type="KeywordType" style="#41a6b5"/> + <entry type="Name" style="#c0caf5"/> + <entry type="NameClass" style="#ff9e64"/> + <entry type="NameConstant" style="#ff9e64"/> + <entry type="NameDecorator" style="bold #7aa2f7"/> + <entry type="NameEntity" style="#7dcfff"/> + <entry type="NameException" style="#e0af68"/> + <entry type="NameFunction" style="#7aa2f7"/> + <entry type="NameFunctionMagic" style="#7aa2f7"/> + <entry type="NameLabel" style="#9ece6a"/> + <entry type="NameNamespace" style="#e0af68"/> + <entry type="NameProperty" style="#e0af68"/> + <entry type="NameTag" style="#bb9af7"/> + <entry type="NameVariable" style="#c0caf5"/> + <entry type="NameVariableClass" style="#c0caf5"/> + <entry type="NameVariableGlobal" style="#c0caf5"/> + <entry type="NameVariableInstance" style="#c0caf5"/> + <entry type="NameVariableMagic" style="#c0caf5"/> + <entry type="NameAttribute" style="#7aa2f7"/> + <entry type="NameBuiltin" style="#9ece6a"/> + <entry type="NameBuiltinPseudo" style="#9ece6a"/> + <entry type="NameOther" style="#c0caf5"/> + <entry type="Literal" style="#c0caf5"/> + <entry type="LiteralDate" style="#c0caf5"/> + <entry type="LiteralString" style="#9ece6a"/> + <entry type="LiteralStringChar" style="#9ece6a"/> + <entry type="LiteralStringSingle" style="#9ece6a"/> + <entry type="LiteralStringDouble" style="#9ece6a"/> + <entry type="LiteralStringBacktick" style="#9ece6a"/> + <entry type="LiteralStringOther" style="#9ece6a"/> + <entry type="LiteralStringSymbol" style="#9ece6a"/> + <entry type="LiteralStringInterpol" style="#9ece6a"/> + <entry type="LiteralStringAffix" style="#9d7cd8"/> + <entry type="LiteralStringDelimiter" style="#7aa2f7"/> + <entry type="LiteralStringEscape" style="#7aa2f7"/> + <entry type="LiteralStringRegex" style="#7dcfff"/> + <entry type="LiteralStringDoc" style="#414868"/> + <entry type="LiteralStringHeredoc" style="#414868"/> + <entry type="LiteralNumber" style="#e0af68"/> + <entry type="LiteralNumberBin" style="#e0af68"/> + <entry type="LiteralNumberHex" style="#e0af68"/> + <entry type="LiteralNumberInteger" style="#e0af68"/> + <entry type="LiteralNumberFloat" style="#e0af68"/> + <entry type="LiteralNumberIntegerLong" style="#e0af68"/> + <entry type="LiteralNumberOct" style="#e0af68"/> + <entry type="Operator" style="bold #9ece6a"/> + <entry type="OperatorWord" style="bold #9ece6a"/> + <entry type="Comment" style="italic #414868"/> + <entry type="CommentSingle" style="italic #414868"/> + <entry type="CommentMultiline" style="italic #414868"/> + <entry type="CommentSpecial" style="italic #414868"/> + <entry type="CommentHashbang" style="italic #414868"/> + <entry type="CommentPreproc" style="italic #414868"/> + <entry type="CommentPreprocFile" style="bold #414868"/> + <entry type="Generic" style="#c0caf5"/> + <entry type="GenericInserted" style="bg:#15161e #9ece6a"/> + <entry type="GenericDeleted" style="#db4b4b bg:#15161e"/> + <entry type="GenericEmph" style="italic #c0caf5"/> + <entry type="GenericStrong" style="bold #c0caf5"/> + <entry type="GenericUnderline" style="underline #c0caf5"/> + <entry type="GenericHeading" style="bold #e0af68"/> + <entry type="GenericSubheading" style="bold #e0af68"/> + <entry type="GenericOutput" style="#c0caf5"/> + <entry type="GenericPrompt" style="#c0caf5"/> + <entry type="GenericError" style="#db4b4b"/> + <entry type="GenericTraceback" style="#db4b4b"/> +</style> \ No newline at end of file diff --git a/styles/embedded/trac.xml b/styles/embedded/trac.xml new file mode 100644 index 0000000..377989c --- /dev/null +++ b/styles/embedded/trac.xml @@ -0,0 +1,35 @@ +<style name="trac" theme="light"> + <entry type="Error" style="#a61717 bg:#e3d2d2"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="bold"/> + <entry type="KeywordType" style="#445588"/> + <entry type="NameAttribute" style="#008080"/> + <entry type="NameBuiltin" style="#999999"/> + <entry type="NameClass" style="bold #445588"/> + <entry type="NameConstant" style="#008080"/> + <entry type="NameEntity" style="#800080"/> + <entry type="NameException" style="bold #990000"/> + <entry type="NameFunction" style="bold #990000"/> + <entry type="NameNamespace" style="#555555"/> + <entry type="NameTag" style="#000080"/> + <entry type="NameVariable" style="#008080"/> + <entry type="LiteralString" style="#bb8844"/> + <entry type="LiteralStringRegex" style="#808000"/> + <entry type="LiteralNumber" style="#009999"/> + <entry type="Operator" style="bold"/> + <entry type="Comment" style="italic #999988"/> + <entry type="CommentSpecial" style="bold #999999"/> + <entry type="CommentPreproc" style="bold noitalic #999999"/> + <entry type="GenericDeleted" style="#000000 bg:#ffdddd"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#aa0000"/> + <entry type="GenericHeading" style="#999999"/> + <entry type="GenericInserted" style="#000000 bg:#ddffdd"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="#555555"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#aaaaaa"/> + <entry type="GenericTraceback" style="#aa0000"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="TextWhitespace" style="#bbbbbb"/> +</style> \ No newline at end of file diff --git a/styles/embedded/vim.xml b/styles/embedded/vim.xml new file mode 100644 index 0000000..2920512 --- /dev/null +++ b/styles/embedded/vim.xml @@ -0,0 +1,29 @@ +<style name="vim" theme="dark"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="#cccccc bg:#000000"/> + <entry type="Keyword" style="#cdcd00"/> + <entry type="KeywordDeclaration" style="#00cd00"/> + <entry type="KeywordNamespace" style="#cd00cd"/> + <entry type="KeywordType" style="#00cd00"/> + <entry type="NameBuiltin" style="#cd00cd"/> + <entry type="NameClass" style="#00cdcd"/> + <entry type="NameException" style="bold #666699"/> + <entry type="NameVariable" style="#00cdcd"/> + <entry type="LiteralString" style="#cd0000"/> + <entry type="LiteralNumber" style="#cd00cd"/> + <entry type="Operator" style="#3399cc"/> + <entry type="OperatorWord" style="#cdcd00"/> + <entry type="Comment" style="#000080"/> + <entry type="CommentSpecial" style="bold #cd0000"/> + <entry type="GenericDeleted" style="#cd0000"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericError" style="#ff0000"/> + <entry type="GenericHeading" style="bold #000080"/> + <entry type="GenericInserted" style="#00cd00"/> + <entry type="GenericOutput" style="#888888"/> + <entry type="GenericPrompt" style="bold #000080"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold #800080"/> + <entry type="GenericTraceback" style="#0044dd"/> + <entry type="GenericUnderline" style="underline"/> +</style> \ No newline at end of file diff --git a/styles/embedded/vs.xml b/styles/embedded/vs.xml new file mode 100644 index 0000000..b9fa734 --- /dev/null +++ b/styles/embedded/vs.xml @@ -0,0 +1,16 @@ +<style name="vs" theme="light"> + <entry type="Error" style="border:#ff0000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#0000ff"/> + <entry type="KeywordType" style="#2b91af"/> + <entry type="NameClass" style="#2b91af"/> + <entry type="LiteralString" style="#a31515"/> + <entry type="OperatorWord" style="#0000ff"/> + <entry type="Comment" style="#008000"/> + <entry type="CommentPreproc" style="#0000ff"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericHeading" style="bold"/> + <entry type="GenericPrompt" style="bold"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="bold"/> +</style> \ No newline at end of file diff --git a/styles/embedded/vulcan.xml b/styles/embedded/vulcan.xml new file mode 100644 index 0000000..717ffd2 --- /dev/null +++ b/styles/embedded/vulcan.xml @@ -0,0 +1,74 @@ +<style name="vulcan" theme="dark"> + <entry type="Other" style="#c9c9c9"/> + <entry type="Error" style="#cf5967"/> + <entry type="Background" style="bg:#282c34"/> + <entry type="Keyword" style="#7fbaf5"/> + <entry type="KeywordConstant" style="#cf5967 bg:#43454f"/> + <entry type="KeywordDeclaration" style="#7fbaf5"/> + <entry type="KeywordNamespace" style="#bc74c4"/> + <entry type="KeywordPseudo" style="#bc74c4"/> + <entry type="KeywordReserved" style="#7fbaf5"/> + <entry type="KeywordType" style="bold #57c7ff"/> + <entry type="Name" style="#c9c9c9"/> + <entry type="NameAttribute" style="#bc74c4"/> + <entry type="NameBuiltin" style="#7fbaf5"/> + <entry type="NameBuiltinPseudo" style="#7fbaf5"/> + <entry type="NameClass" style="#ecbe7b"/> + <entry type="NameConstant" style="#ecbe7b"/> + <entry type="NameDecorator" style="#ecbe7b"/> + <entry type="NameEntity" style="#c9c9c9"/> + <entry type="NameException" style="#cf5967"/> + <entry type="NameFunction" style="#57c7ff"/> + <entry type="NameLabel" style="#cf5967"/> + <entry type="NameNamespace" style="#c9c9c9"/> + <entry type="NameOther" style="#c9c9c9"/> + <entry type="NameTag" style="#bc74c4"/> + <entry type="NameVariable" style="italic #bc74c4"/> + <entry type="NameVariableClass" style="bold #57c7ff"/> + <entry type="NameVariableGlobal" style="#ecbe7b"/> + <entry type="NameVariableInstance" style="#57c7ff"/> + <entry type="Literal" style="#c9c9c9"/> + <entry type="LiteralDate" style="#57c7ff"/> + <entry type="LiteralString" style="#82cc6a"/> + <entry type="LiteralStringBacktick" style="#57c7ff"/> + <entry type="LiteralStringChar" style="#57c7ff"/> + <entry type="LiteralStringDoc" style="#82cc6a"/> + <entry type="LiteralStringDouble" style="#82cc6a"/> + <entry type="LiteralStringEscape" style="#56b6c2"/> + <entry type="LiteralStringHeredoc" style="#56b6c2"/> + <entry type="LiteralStringInterpol" style="#82cc6a"/> + <entry type="LiteralStringOther" style="#82cc6a"/> + <entry type="LiteralStringRegex" style="#57c7ff"/> + <entry type="LiteralStringSingle" style="#82cc6a"/> + <entry type="LiteralStringSymbol" style="#82cc6a"/> + <entry type="LiteralNumber" style="#56b6c2"/> + <entry type="LiteralNumberBin" style="#57c7ff"/> + <entry type="LiteralNumberFloat" style="#56b6c2"/> + <entry type="LiteralNumberHex" style="#57c7ff"/> + <entry type="LiteralNumberInteger" style="#56b6c2"/> + <entry type="LiteralNumberIntegerLong" style="#56b6c2"/> + <entry type="LiteralNumberOct" style="#57c7ff"/> + <entry type="Operator" style="#bc74c4"/> + <entry type="OperatorWord" style="#bc74c4"/> + <entry type="Punctuation" style="#56b6c2"/> + <entry type="Comment" style="#3e4460"/> + <entry type="CommentHashbang" style="italic #3e4460"/> + <entry type="CommentMultiline" style="#3e4460"/> + <entry type="CommentSingle" style="#3e4460"/> + <entry type="CommentSpecial" style="italic #bc74c4"/> + <entry type="CommentPreproc" style="#7fbaf5"/> + <entry type="Generic" style="#c9c9c9"/> + <entry type="GenericDeleted" style="#cf5967"/> + <entry type="GenericEmph" style="underline #c9c9c9"/> + <entry type="GenericError" style="bold #cf5967"/> + <entry type="GenericHeading" style="bold #ecbe7b"/> + <entry type="GenericInserted" style="#ecbe7b"/> + <entry type="GenericOutput" style="#43454f"/> + <entry type="GenericPrompt" style="#c9c9c9"/> + <entry type="GenericStrong" style="bold #cf5967"/> + <entry type="GenericSubheading" style="italic #cf5967"/> + <entry type="GenericTraceback" style="#c9c9c9"/> + <entry type="GenericUnderline" style="underline"/> + <entry type="Text" style="#c9c9c9"/> + <entry type="TextWhitespace" style="#c9c9c9"/> +</style> diff --git a/styles/embedded/witchhazel.xml b/styles/embedded/witchhazel.xml new file mode 100644 index 0000000..4c175c9 --- /dev/null +++ b/styles/embedded/witchhazel.xml @@ -0,0 +1,31 @@ +<style name="witchhazel" theme="dark"> + <entry type="Error" style="#960050 bg:#1e0010"/> + <entry type="Background" style="bg:#433e56"/> + <entry type="Keyword" style="#c2ffdf"/> + <entry type="KeywordNamespace" style="#ffb8d1"/> + <entry type="Name" style="#f8f8f2"/> + <entry type="NameAttribute" style="#ceb1ff"/> + <entry type="NameBuiltinPseudo" style="#80cbc4"/> + <entry type="NameClass" style="#ceb1ff"/> + <entry type="NameConstant" style="#c5a3ff"/> + <entry type="NameDecorator" style="#ceb1ff"/> + <entry type="NameException" style="#ceb1ff"/> + <entry type="NameFunction" style="#ceb1ff"/> + <entry type="NameProperty" style="#f8f8f2"/> + <entry type="NameTag" style="#ffb8d1"/> + <entry type="NameVariable" style="#f8f8f2"/> + <entry type="Literal" style="#ae81ff"/> + <entry type="LiteralDate" style="#e6db74"/> + <entry type="LiteralString" style="#1bc5e0"/> + <entry type="LiteralNumber" style="#c5a3ff"/> + <entry type="Operator" style="#ffb8d1"/> + <entry type="Punctuation" style="#f8f8f2"/> + <entry type="Comment" style="#b0bec5"/> + <entry type="GenericDeleted" style="#f92672"/> + <entry type="GenericEmph" style="italic"/> + <entry type="GenericInserted" style="#a6e22e"/> + <entry type="GenericStrong" style="bold"/> + <entry type="GenericSubheading" style="#75715e"/> + <entry type="Text" style="#f8f8f2"/> + <entry type="TextWhitespace" style="#a8757b"/> +</style> \ No newline at end of file diff --git a/styles/embedded/xcode-dark.xml b/styles/embedded/xcode-dark.xml new file mode 100644 index 0000000..d2ba679 --- /dev/null +++ b/styles/embedded/xcode-dark.xml @@ -0,0 +1,31 @@ +<style name="xcode-dark" theme="dark"> + <entry type="Error" style="#960050"/> + <entry type="Background" style="#ffffff bg:#1f1f24"/> + <entry type="Keyword" style="#fc5fa3"/> + <entry type="KeywordConstant" style="#fc5fa3"/> + <entry type="KeywordDeclaration" style="#fc5fa3"/> + <entry type="KeywordReserved" style="#fc5fa3"/> + <entry type="Name" style="#ffffff"/> + <entry type="NameBuiltin" style="#d0a8ff"/> + <entry type="NameBuiltinPseudo" style="#a167e6"/> + <entry type="NameClass" style="#5dd8ff"/> + <entry type="NameFunction" style="#41a1c0"/> + <entry type="NameVariable" style="#41a1c0"/> + <entry type="LiteralString" style="#fc6a5d"/> + <entry type="LiteralStringEscape" style="#fc6a5d"/> + <entry type="LiteralStringInterpol" style="#ffffff"/> + <entry type="LiteralNumber" style="#d0bf69"/> + <entry type="LiteralNumberBin" style="#d0bf69"/> + <entry type="LiteralNumberFloat" style="#d0bf69"/> + <entry type="LiteralNumberHex" style="#d0bf69"/> + <entry type="LiteralNumberInteger" style="#d0bf69"/> + <entry type="LiteralNumberOct" style="#d0bf69"/> + <entry type="Operator" style="#ffffff"/> + <entry type="Punctuation" style="#ffffff"/> + <entry type="Comment" style="#6c7986"/> + <entry type="CommentMultiline" style="#6c7986"/> + <entry type="CommentSingle" style="#6c7986"/> + <entry type="CommentSpecial" style="italic #6c7986"/> + <entry type="CommentPreproc" style="#fd8f3f"/> + <entry type="Text" style="#ffffff"/> +</style> \ No newline at end of file diff --git a/styles/embedded/xcode.xml b/styles/embedded/xcode.xml new file mode 100644 index 0000000..9bfa0d1 --- /dev/null +++ b/styles/embedded/xcode.xml @@ -0,0 +1,22 @@ +<style name="xcode" theme="light"> + <entry type="Error" style="#000000"/> + <entry type="Background" style="bg:#ffffff"/> + <entry type="Keyword" style="#a90d91"/> + <entry type="Name" style="#000000"/> + <entry type="NameAttribute" style="#836c28"/> + <entry type="NameBuiltin" style="#a90d91"/> + <entry type="NameBuiltinPseudo" style="#5b269a"/> + <entry type="NameClass" style="#3f6e75"/> + <entry type="NameDecorator" style="#000000"/> + <entry type="NameFunction" style="#000000"/> + <entry type="NameLabel" style="#000000"/> + <entry type="NameTag" style="#000000"/> + <entry type="NameVariable" style="#000000"/> + <entry type="Literal" style="#1c01ce"/> + <entry type="LiteralString" style="#c41a16"/> + <entry type="LiteralStringChar" style="#2300ce"/> + <entry type="LiteralNumber" style="#1c01ce"/> + <entry type="Operator" style="#000000"/> + <entry type="Comment" style="#177500"/> + <entry type="CommentPreproc" style="#633820"/> +</style> \ No newline at end of file diff --git a/tokentype_enumer.go b/tokentype_enumer.go new file mode 100644 index 0000000..696e9ce --- /dev/null +++ b/tokentype_enumer.go @@ -0,0 +1,573 @@ +// Code generated by "enumer -text -type TokenType"; DO NOT EDIT. + +package chroma + +import ( + "fmt" + "strings" +) + +const _TokenTypeName = "NoneOtherErrorCodeLineLineLinkLineTableTDLineTableLineHighlightLineNumbersTableLineNumbersLinePreWrapperBackgroundEOFTypeKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameBuiltinNameBuiltinPseudoNameClassNameConstantNameDecoratorNameEntityNameExceptionNameFunctionNameFunctionMagicNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation" +const _TokenTypeLowerName = "noneothererrorcodelinelinelinklinetabletdlinetablelinehighlightlinenumberstablelinenumberslineprewrapperbackgroundeoftypekeywordkeywordconstantkeyworddeclarationkeywordnamespacekeywordpseudokeywordreservedkeywordtypenamenameattributenamebuiltinnamebuiltinpseudonameclassnameconstantnamedecoratornameentitynameexceptionnamefunctionnamefunctionmagicnamekeywordnamelabelnamenamespacenameoperatornameothernamepseudonamepropertynametagnamevariablenamevariableanonymousnamevariableclassnamevariableglobalnamevariableinstancenamevariablemagicliteralliteraldateliteralotherliteralstringliteralstringaffixliteralstringatomliteralstringbacktickliteralstringbooleanliteralstringcharliteralstringdelimiterliteralstringdocliteralstringdoubleliteralstringescapeliteralstringheredocliteralstringinterpolliteralstringnameliteralstringotherliteralstringregexliteralstringsingleliteralstringsymbolliteralnumberliteralnumberbinliteralnumberfloatliteralnumberhexliteralnumberintegerliteralnumberintegerlongliteralnumberoctoperatoroperatorwordpunctuationcommentcommenthashbangcommentmultilinecommentsinglecommentspecialcommentpreproccommentpreprocfilegenericgenericdeletedgenericemphgenericerrorgenericheadinggenericinsertedgenericoutputgenericpromptgenericstronggenericsubheadinggenerictracebackgenericunderlinetexttextwhitespacetextsymboltextpunctuation" + +var _TokenTypeMap = map[TokenType]string{ + -13: _TokenTypeName[0:4], + -12: _TokenTypeName[4:9], + -11: _TokenTypeName[9:14], + -10: _TokenTypeName[14:22], + -9: _TokenTypeName[22:30], + -8: _TokenTypeName[30:41], + -7: _TokenTypeName[41:50], + -6: _TokenTypeName[50:63], + -5: _TokenTypeName[63:79], + -4: _TokenTypeName[79:90], + -3: _TokenTypeName[90:94], + -2: _TokenTypeName[94:104], + -1: _TokenTypeName[104:114], + 0: _TokenTypeName[114:121], + 1000: _TokenTypeName[121:128], + 1001: _TokenTypeName[128:143], + 1002: _TokenTypeName[143:161], + 1003: _TokenTypeName[161:177], + 1004: _TokenTypeName[177:190], + 1005: _TokenTypeName[190:205], + 1006: _TokenTypeName[205:216], + 2000: _TokenTypeName[216:220], + 2001: _TokenTypeName[220:233], + 2002: _TokenTypeName[233:244], + 2003: _TokenTypeName[244:261], + 2004: _TokenTypeName[261:270], + 2005: _TokenTypeName[270:282], + 2006: _TokenTypeName[282:295], + 2007: _TokenTypeName[295:305], + 2008: _TokenTypeName[305:318], + 2009: _TokenTypeName[318:330], + 2010: _TokenTypeName[330:347], + 2011: _TokenTypeName[347:358], + 2012: _TokenTypeName[358:367], + 2013: _TokenTypeName[367:380], + 2014: _TokenTypeName[380:392], + 2015: _TokenTypeName[392:401], + 2016: _TokenTypeName[401:411], + 2017: _TokenTypeName[411:423], + 2018: _TokenTypeName[423:430], + 2019: _TokenTypeName[430:442], + 2020: _TokenTypeName[442:463], + 2021: _TokenTypeName[463:480], + 2022: _TokenTypeName[480:498], + 2023: _TokenTypeName[498:518], + 2024: _TokenTypeName[518:535], + 3000: _TokenTypeName[535:542], + 3001: _TokenTypeName[542:553], + 3002: _TokenTypeName[553:565], + 3100: _TokenTypeName[565:578], + 3101: _TokenTypeName[578:596], + 3102: _TokenTypeName[596:613], + 3103: _TokenTypeName[613:634], + 3104: _TokenTypeName[634:654], + 3105: _TokenTypeName[654:671], + 3106: _TokenTypeName[671:693], + 3107: _TokenTypeName[693:709], + 3108: _TokenTypeName[709:728], + 3109: _TokenTypeName[728:747], + 3110: _TokenTypeName[747:767], + 3111: _TokenTypeName[767:788], + 3112: _TokenTypeName[788:805], + 3113: _TokenTypeName[805:823], + 3114: _TokenTypeName[823:841], + 3115: _TokenTypeName[841:860], + 3116: _TokenTypeName[860:879], + 3200: _TokenTypeName[879:892], + 3201: _TokenTypeName[892:908], + 3202: _TokenTypeName[908:926], + 3203: _TokenTypeName[926:942], + 3204: _TokenTypeName[942:962], + 3205: _TokenTypeName[962:986], + 3206: _TokenTypeName[986:1002], + 4000: _TokenTypeName[1002:1010], + 4001: _TokenTypeName[1010:1022], + 5000: _TokenTypeName[1022:1033], + 6000: _TokenTypeName[1033:1040], + 6001: _TokenTypeName[1040:1055], + 6002: _TokenTypeName[1055:1071], + 6003: _TokenTypeName[1071:1084], + 6004: _TokenTypeName[1084:1098], + 6100: _TokenTypeName[1098:1112], + 6101: _TokenTypeName[1112:1130], + 7000: _TokenTypeName[1130:1137], + 7001: _TokenTypeName[1137:1151], + 7002: _TokenTypeName[1151:1162], + 7003: _TokenTypeName[1162:1174], + 7004: _TokenTypeName[1174:1188], + 7005: _TokenTypeName[1188:1203], + 7006: _TokenTypeName[1203:1216], + 7007: _TokenTypeName[1216:1229], + 7008: _TokenTypeName[1229:1242], + 7009: _TokenTypeName[1242:1259], + 7010: _TokenTypeName[1259:1275], + 7011: _TokenTypeName[1275:1291], + 8000: _TokenTypeName[1291:1295], + 8001: _TokenTypeName[1295:1309], + 8002: _TokenTypeName[1309:1319], + 8003: _TokenTypeName[1319:1334], +} + +func (i TokenType) String() string { + if str, ok := _TokenTypeMap[i]; ok { + return str + } + return fmt.Sprintf("TokenType(%d)", i) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _TokenTypeNoOp() { + var x [1]struct{} + _ = x[None-(-13)] + _ = x[Other-(-12)] + _ = x[Error-(-11)] + _ = x[CodeLine-(-10)] + _ = x[LineLink-(-9)] + _ = x[LineTableTD-(-8)] + _ = x[LineTable-(-7)] + _ = x[LineHighlight-(-6)] + _ = x[LineNumbersTable-(-5)] + _ = x[LineNumbers-(-4)] + _ = x[Line-(-3)] + _ = x[PreWrapper-(-2)] + _ = x[Background-(-1)] + _ = x[EOFType-(0)] + _ = x[Keyword-(1000)] + _ = x[KeywordConstant-(1001)] + _ = x[KeywordDeclaration-(1002)] + _ = x[KeywordNamespace-(1003)] + _ = x[KeywordPseudo-(1004)] + _ = x[KeywordReserved-(1005)] + _ = x[KeywordType-(1006)] + _ = x[Name-(2000)] + _ = x[NameAttribute-(2001)] + _ = x[NameBuiltin-(2002)] + _ = x[NameBuiltinPseudo-(2003)] + _ = x[NameClass-(2004)] + _ = x[NameConstant-(2005)] + _ = x[NameDecorator-(2006)] + _ = x[NameEntity-(2007)] + _ = x[NameException-(2008)] + _ = x[NameFunction-(2009)] + _ = x[NameFunctionMagic-(2010)] + _ = x[NameKeyword-(2011)] + _ = x[NameLabel-(2012)] + _ = x[NameNamespace-(2013)] + _ = x[NameOperator-(2014)] + _ = x[NameOther-(2015)] + _ = x[NamePseudo-(2016)] + _ = x[NameProperty-(2017)] + _ = x[NameTag-(2018)] + _ = x[NameVariable-(2019)] + _ = x[NameVariableAnonymous-(2020)] + _ = x[NameVariableClass-(2021)] + _ = x[NameVariableGlobal-(2022)] + _ = x[NameVariableInstance-(2023)] + _ = x[NameVariableMagic-(2024)] + _ = x[Literal-(3000)] + _ = x[LiteralDate-(3001)] + _ = x[LiteralOther-(3002)] + _ = x[LiteralString-(3100)] + _ = x[LiteralStringAffix-(3101)] + _ = x[LiteralStringAtom-(3102)] + _ = x[LiteralStringBacktick-(3103)] + _ = x[LiteralStringBoolean-(3104)] + _ = x[LiteralStringChar-(3105)] + _ = x[LiteralStringDelimiter-(3106)] + _ = x[LiteralStringDoc-(3107)] + _ = x[LiteralStringDouble-(3108)] + _ = x[LiteralStringEscape-(3109)] + _ = x[LiteralStringHeredoc-(3110)] + _ = x[LiteralStringInterpol-(3111)] + _ = x[LiteralStringName-(3112)] + _ = x[LiteralStringOther-(3113)] + _ = x[LiteralStringRegex-(3114)] + _ = x[LiteralStringSingle-(3115)] + _ = x[LiteralStringSymbol-(3116)] + _ = x[LiteralNumber-(3200)] + _ = x[LiteralNumberBin-(3201)] + _ = x[LiteralNumberFloat-(3202)] + _ = x[LiteralNumberHex-(3203)] + _ = x[LiteralNumberInteger-(3204)] + _ = x[LiteralNumberIntegerLong-(3205)] + _ = x[LiteralNumberOct-(3206)] + _ = x[Operator-(4000)] + _ = x[OperatorWord-(4001)] + _ = x[Punctuation-(5000)] + _ = x[Comment-(6000)] + _ = x[CommentHashbang-(6001)] + _ = x[CommentMultiline-(6002)] + _ = x[CommentSingle-(6003)] + _ = x[CommentSpecial-(6004)] + _ = x[CommentPreproc-(6100)] + _ = x[CommentPreprocFile-(6101)] + _ = x[Generic-(7000)] + _ = x[GenericDeleted-(7001)] + _ = x[GenericEmph-(7002)] + _ = x[GenericError-(7003)] + _ = x[GenericHeading-(7004)] + _ = x[GenericInserted-(7005)] + _ = x[GenericOutput-(7006)] + _ = x[GenericPrompt-(7007)] + _ = x[GenericStrong-(7008)] + _ = x[GenericSubheading-(7009)] + _ = x[GenericTraceback-(7010)] + _ = x[GenericUnderline-(7011)] + _ = x[Text-(8000)] + _ = x[TextWhitespace-(8001)] + _ = x[TextSymbol-(8002)] + _ = x[TextPunctuation-(8003)] +} + +var _TokenTypeValues = []TokenType{None, Other, Error, CodeLine, LineLink, LineTableTD, LineTable, LineHighlight, LineNumbersTable, LineNumbers, Line, PreWrapper, Background, EOFType, Keyword, KeywordConstant, KeywordDeclaration, KeywordNamespace, KeywordPseudo, KeywordReserved, KeywordType, Name, NameAttribute, NameBuiltin, NameBuiltinPseudo, NameClass, NameConstant, NameDecorator, NameEntity, NameException, NameFunction, NameFunctionMagic, NameKeyword, NameLabel, NameNamespace, NameOperator, NameOther, NamePseudo, NameProperty, NameTag, NameVariable, NameVariableAnonymous, NameVariableClass, NameVariableGlobal, NameVariableInstance, NameVariableMagic, Literal, LiteralDate, LiteralOther, LiteralString, LiteralStringAffix, LiteralStringAtom, LiteralStringBacktick, LiteralStringBoolean, LiteralStringChar, LiteralStringDelimiter, LiteralStringDoc, LiteralStringDouble, LiteralStringEscape, LiteralStringHeredoc, LiteralStringInterpol, LiteralStringName, LiteralStringOther, LiteralStringRegex, LiteralStringSingle, LiteralStringSymbol, LiteralNumber, LiteralNumberBin, LiteralNumberFloat, LiteralNumberHex, LiteralNumberInteger, LiteralNumberIntegerLong, LiteralNumberOct, Operator, OperatorWord, Punctuation, Comment, CommentHashbang, CommentMultiline, CommentSingle, CommentSpecial, CommentPreproc, CommentPreprocFile, Generic, GenericDeleted, GenericEmph, GenericError, GenericHeading, GenericInserted, GenericOutput, GenericPrompt, GenericStrong, GenericSubheading, GenericTraceback, GenericUnderline, Text, TextWhitespace, TextSymbol, TextPunctuation} + +var _TokenTypeNameToValueMap = map[string]TokenType{ + _TokenTypeName[0:4]: None, + _TokenTypeLowerName[0:4]: None, + _TokenTypeName[4:9]: Other, + _TokenTypeLowerName[4:9]: Other, + _TokenTypeName[9:14]: Error, + _TokenTypeLowerName[9:14]: Error, + _TokenTypeName[14:22]: CodeLine, + _TokenTypeLowerName[14:22]: CodeLine, + _TokenTypeName[22:30]: LineLink, + _TokenTypeLowerName[22:30]: LineLink, + _TokenTypeName[30:41]: LineTableTD, + _TokenTypeLowerName[30:41]: LineTableTD, + _TokenTypeName[41:50]: LineTable, + _TokenTypeLowerName[41:50]: LineTable, + _TokenTypeName[50:63]: LineHighlight, + _TokenTypeLowerName[50:63]: LineHighlight, + _TokenTypeName[63:79]: LineNumbersTable, + _TokenTypeLowerName[63:79]: LineNumbersTable, + _TokenTypeName[79:90]: LineNumbers, + _TokenTypeLowerName[79:90]: LineNumbers, + _TokenTypeName[90:94]: Line, + _TokenTypeLowerName[90:94]: Line, + _TokenTypeName[94:104]: PreWrapper, + _TokenTypeLowerName[94:104]: PreWrapper, + _TokenTypeName[104:114]: Background, + _TokenTypeLowerName[104:114]: Background, + _TokenTypeName[114:121]: EOFType, + _TokenTypeLowerName[114:121]: EOFType, + _TokenTypeName[121:128]: Keyword, + _TokenTypeLowerName[121:128]: Keyword, + _TokenTypeName[128:143]: KeywordConstant, + _TokenTypeLowerName[128:143]: KeywordConstant, + _TokenTypeName[143:161]: KeywordDeclaration, + _TokenTypeLowerName[143:161]: KeywordDeclaration, + _TokenTypeName[161:177]: KeywordNamespace, + _TokenTypeLowerName[161:177]: KeywordNamespace, + _TokenTypeName[177:190]: KeywordPseudo, + _TokenTypeLowerName[177:190]: KeywordPseudo, + _TokenTypeName[190:205]: KeywordReserved, + _TokenTypeLowerName[190:205]: KeywordReserved, + _TokenTypeName[205:216]: KeywordType, + _TokenTypeLowerName[205:216]: KeywordType, + _TokenTypeName[216:220]: Name, + _TokenTypeLowerName[216:220]: Name, + _TokenTypeName[220:233]: NameAttribute, + _TokenTypeLowerName[220:233]: NameAttribute, + _TokenTypeName[233:244]: NameBuiltin, + _TokenTypeLowerName[233:244]: NameBuiltin, + _TokenTypeName[244:261]: NameBuiltinPseudo, + _TokenTypeLowerName[244:261]: NameBuiltinPseudo, + _TokenTypeName[261:270]: NameClass, + _TokenTypeLowerName[261:270]: NameClass, + _TokenTypeName[270:282]: NameConstant, + _TokenTypeLowerName[270:282]: NameConstant, + _TokenTypeName[282:295]: NameDecorator, + _TokenTypeLowerName[282:295]: NameDecorator, + _TokenTypeName[295:305]: NameEntity, + _TokenTypeLowerName[295:305]: NameEntity, + _TokenTypeName[305:318]: NameException, + _TokenTypeLowerName[305:318]: NameException, + _TokenTypeName[318:330]: NameFunction, + _TokenTypeLowerName[318:330]: NameFunction, + _TokenTypeName[330:347]: NameFunctionMagic, + _TokenTypeLowerName[330:347]: NameFunctionMagic, + _TokenTypeName[347:358]: NameKeyword, + _TokenTypeLowerName[347:358]: NameKeyword, + _TokenTypeName[358:367]: NameLabel, + _TokenTypeLowerName[358:367]: NameLabel, + _TokenTypeName[367:380]: NameNamespace, + _TokenTypeLowerName[367:380]: NameNamespace, + _TokenTypeName[380:392]: NameOperator, + _TokenTypeLowerName[380:392]: NameOperator, + _TokenTypeName[392:401]: NameOther, + _TokenTypeLowerName[392:401]: NameOther, + _TokenTypeName[401:411]: NamePseudo, + _TokenTypeLowerName[401:411]: NamePseudo, + _TokenTypeName[411:423]: NameProperty, + _TokenTypeLowerName[411:423]: NameProperty, + _TokenTypeName[423:430]: NameTag, + _TokenTypeLowerName[423:430]: NameTag, + _TokenTypeName[430:442]: NameVariable, + _TokenTypeLowerName[430:442]: NameVariable, + _TokenTypeName[442:463]: NameVariableAnonymous, + _TokenTypeLowerName[442:463]: NameVariableAnonymous, + _TokenTypeName[463:480]: NameVariableClass, + _TokenTypeLowerName[463:480]: NameVariableClass, + _TokenTypeName[480:498]: NameVariableGlobal, + _TokenTypeLowerName[480:498]: NameVariableGlobal, + _TokenTypeName[498:518]: NameVariableInstance, + _TokenTypeLowerName[498:518]: NameVariableInstance, + _TokenTypeName[518:535]: NameVariableMagic, + _TokenTypeLowerName[518:535]: NameVariableMagic, + _TokenTypeName[535:542]: Literal, + _TokenTypeLowerName[535:542]: Literal, + _TokenTypeName[542:553]: LiteralDate, + _TokenTypeLowerName[542:553]: LiteralDate, + _TokenTypeName[553:565]: LiteralOther, + _TokenTypeLowerName[553:565]: LiteralOther, + _TokenTypeName[565:578]: LiteralString, + _TokenTypeLowerName[565:578]: LiteralString, + _TokenTypeName[578:596]: LiteralStringAffix, + _TokenTypeLowerName[578:596]: LiteralStringAffix, + _TokenTypeName[596:613]: LiteralStringAtom, + _TokenTypeLowerName[596:613]: LiteralStringAtom, + _TokenTypeName[613:634]: LiteralStringBacktick, + _TokenTypeLowerName[613:634]: LiteralStringBacktick, + _TokenTypeName[634:654]: LiteralStringBoolean, + _TokenTypeLowerName[634:654]: LiteralStringBoolean, + _TokenTypeName[654:671]: LiteralStringChar, + _TokenTypeLowerName[654:671]: LiteralStringChar, + _TokenTypeName[671:693]: LiteralStringDelimiter, + _TokenTypeLowerName[671:693]: LiteralStringDelimiter, + _TokenTypeName[693:709]: LiteralStringDoc, + _TokenTypeLowerName[693:709]: LiteralStringDoc, + _TokenTypeName[709:728]: LiteralStringDouble, + _TokenTypeLowerName[709:728]: LiteralStringDouble, + _TokenTypeName[728:747]: LiteralStringEscape, + _TokenTypeLowerName[728:747]: LiteralStringEscape, + _TokenTypeName[747:767]: LiteralStringHeredoc, + _TokenTypeLowerName[747:767]: LiteralStringHeredoc, + _TokenTypeName[767:788]: LiteralStringInterpol, + _TokenTypeLowerName[767:788]: LiteralStringInterpol, + _TokenTypeName[788:805]: LiteralStringName, + _TokenTypeLowerName[788:805]: LiteralStringName, + _TokenTypeName[805:823]: LiteralStringOther, + _TokenTypeLowerName[805:823]: LiteralStringOther, + _TokenTypeName[823:841]: LiteralStringRegex, + _TokenTypeLowerName[823:841]: LiteralStringRegex, + _TokenTypeName[841:860]: LiteralStringSingle, + _TokenTypeLowerName[841:860]: LiteralStringSingle, + _TokenTypeName[860:879]: LiteralStringSymbol, + _TokenTypeLowerName[860:879]: LiteralStringSymbol, + _TokenTypeName[879:892]: LiteralNumber, + _TokenTypeLowerName[879:892]: LiteralNumber, + _TokenTypeName[892:908]: LiteralNumberBin, + _TokenTypeLowerName[892:908]: LiteralNumberBin, + _TokenTypeName[908:926]: LiteralNumberFloat, + _TokenTypeLowerName[908:926]: LiteralNumberFloat, + _TokenTypeName[926:942]: LiteralNumberHex, + _TokenTypeLowerName[926:942]: LiteralNumberHex, + _TokenTypeName[942:962]: LiteralNumberInteger, + _TokenTypeLowerName[942:962]: LiteralNumberInteger, + _TokenTypeName[962:986]: LiteralNumberIntegerLong, + _TokenTypeLowerName[962:986]: LiteralNumberIntegerLong, + _TokenTypeName[986:1002]: LiteralNumberOct, + _TokenTypeLowerName[986:1002]: LiteralNumberOct, + _TokenTypeName[1002:1010]: Operator, + _TokenTypeLowerName[1002:1010]: Operator, + _TokenTypeName[1010:1022]: OperatorWord, + _TokenTypeLowerName[1010:1022]: OperatorWord, + _TokenTypeName[1022:1033]: Punctuation, + _TokenTypeLowerName[1022:1033]: Punctuation, + _TokenTypeName[1033:1040]: Comment, + _TokenTypeLowerName[1033:1040]: Comment, + _TokenTypeName[1040:1055]: CommentHashbang, + _TokenTypeLowerName[1040:1055]: CommentHashbang, + _TokenTypeName[1055:1071]: CommentMultiline, + _TokenTypeLowerName[1055:1071]: CommentMultiline, + _TokenTypeName[1071:1084]: CommentSingle, + _TokenTypeLowerName[1071:1084]: CommentSingle, + _TokenTypeName[1084:1098]: CommentSpecial, + _TokenTypeLowerName[1084:1098]: CommentSpecial, + _TokenTypeName[1098:1112]: CommentPreproc, + _TokenTypeLowerName[1098:1112]: CommentPreproc, + _TokenTypeName[1112:1130]: CommentPreprocFile, + _TokenTypeLowerName[1112:1130]: CommentPreprocFile, + _TokenTypeName[1130:1137]: Generic, + _TokenTypeLowerName[1130:1137]: Generic, + _TokenTypeName[1137:1151]: GenericDeleted, + _TokenTypeLowerName[1137:1151]: GenericDeleted, + _TokenTypeName[1151:1162]: GenericEmph, + _TokenTypeLowerName[1151:1162]: GenericEmph, + _TokenTypeName[1162:1174]: GenericError, + _TokenTypeLowerName[1162:1174]: GenericError, + _TokenTypeName[1174:1188]: GenericHeading, + _TokenTypeLowerName[1174:1188]: GenericHeading, + _TokenTypeName[1188:1203]: GenericInserted, + _TokenTypeLowerName[1188:1203]: GenericInserted, + _TokenTypeName[1203:1216]: GenericOutput, + _TokenTypeLowerName[1203:1216]: GenericOutput, + _TokenTypeName[1216:1229]: GenericPrompt, + _TokenTypeLowerName[1216:1229]: GenericPrompt, + _TokenTypeName[1229:1242]: GenericStrong, + _TokenTypeLowerName[1229:1242]: GenericStrong, + _TokenTypeName[1242:1259]: GenericSubheading, + _TokenTypeLowerName[1242:1259]: GenericSubheading, + _TokenTypeName[1259:1275]: GenericTraceback, + _TokenTypeLowerName[1259:1275]: GenericTraceback, + _TokenTypeName[1275:1291]: GenericUnderline, + _TokenTypeLowerName[1275:1291]: GenericUnderline, + _TokenTypeName[1291:1295]: Text, + _TokenTypeLowerName[1291:1295]: Text, + _TokenTypeName[1295:1309]: TextWhitespace, + _TokenTypeLowerName[1295:1309]: TextWhitespace, + _TokenTypeName[1309:1319]: TextSymbol, + _TokenTypeLowerName[1309:1319]: TextSymbol, + _TokenTypeName[1319:1334]: TextPunctuation, + _TokenTypeLowerName[1319:1334]: TextPunctuation, +} + +var _TokenTypeNames = []string{ + _TokenTypeName[0:4], + _TokenTypeName[4:9], + _TokenTypeName[9:14], + _TokenTypeName[14:22], + _TokenTypeName[22:30], + _TokenTypeName[30:41], + _TokenTypeName[41:50], + _TokenTypeName[50:63], + _TokenTypeName[63:79], + _TokenTypeName[79:90], + _TokenTypeName[90:94], + _TokenTypeName[94:104], + _TokenTypeName[104:114], + _TokenTypeName[114:121], + _TokenTypeName[121:128], + _TokenTypeName[128:143], + _TokenTypeName[143:161], + _TokenTypeName[161:177], + _TokenTypeName[177:190], + _TokenTypeName[190:205], + _TokenTypeName[205:216], + _TokenTypeName[216:220], + _TokenTypeName[220:233], + _TokenTypeName[233:244], + _TokenTypeName[244:261], + _TokenTypeName[261:270], + _TokenTypeName[270:282], + _TokenTypeName[282:295], + _TokenTypeName[295:305], + _TokenTypeName[305:318], + _TokenTypeName[318:330], + _TokenTypeName[330:347], + _TokenTypeName[347:358], + _TokenTypeName[358:367], + _TokenTypeName[367:380], + _TokenTypeName[380:392], + _TokenTypeName[392:401], + _TokenTypeName[401:411], + _TokenTypeName[411:423], + _TokenTypeName[423:430], + _TokenTypeName[430:442], + _TokenTypeName[442:463], + _TokenTypeName[463:480], + _TokenTypeName[480:498], + _TokenTypeName[498:518], + _TokenTypeName[518:535], + _TokenTypeName[535:542], + _TokenTypeName[542:553], + _TokenTypeName[553:565], + _TokenTypeName[565:578], + _TokenTypeName[578:596], + _TokenTypeName[596:613], + _TokenTypeName[613:634], + _TokenTypeName[634:654], + _TokenTypeName[654:671], + _TokenTypeName[671:693], + _TokenTypeName[693:709], + _TokenTypeName[709:728], + _TokenTypeName[728:747], + _TokenTypeName[747:767], + _TokenTypeName[767:788], + _TokenTypeName[788:805], + _TokenTypeName[805:823], + _TokenTypeName[823:841], + _TokenTypeName[841:860], + _TokenTypeName[860:879], + _TokenTypeName[879:892], + _TokenTypeName[892:908], + _TokenTypeName[908:926], + _TokenTypeName[926:942], + _TokenTypeName[942:962], + _TokenTypeName[962:986], + _TokenTypeName[986:1002], + _TokenTypeName[1002:1010], + _TokenTypeName[1010:1022], + _TokenTypeName[1022:1033], + _TokenTypeName[1033:1040], + _TokenTypeName[1040:1055], + _TokenTypeName[1055:1071], + _TokenTypeName[1071:1084], + _TokenTypeName[1084:1098], + _TokenTypeName[1098:1112], + _TokenTypeName[1112:1130], + _TokenTypeName[1130:1137], + _TokenTypeName[1137:1151], + _TokenTypeName[1151:1162], + _TokenTypeName[1162:1174], + _TokenTypeName[1174:1188], + _TokenTypeName[1188:1203], + _TokenTypeName[1203:1216], + _TokenTypeName[1216:1229], + _TokenTypeName[1229:1242], + _TokenTypeName[1242:1259], + _TokenTypeName[1259:1275], + _TokenTypeName[1275:1291], + _TokenTypeName[1291:1295], + _TokenTypeName[1295:1309], + _TokenTypeName[1309:1319], + _TokenTypeName[1319:1334], +} + +// TokenTypeString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func TokenTypeString(s string) (TokenType, error) { + if val, ok := _TokenTypeNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _TokenTypeNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to TokenType values", s) +} + +// TokenTypeValues returns all values of the enum +func TokenTypeValues() []TokenType { + return _TokenTypeValues +} + +// TokenTypeStrings returns a slice of all String values of the enum +func TokenTypeStrings() []string { + strs := make([]string, len(_TokenTypeNames)) + copy(strs, _TokenTypeNames) + return strs +} + +// IsATokenType returns "true" if the value is listed in the enum definition. "false" otherwise +func (i TokenType) IsATokenType() bool { + _, ok := _TokenTypeMap[i] + return ok +} + +// MarshalText implements the encoding.TextMarshaler interface for TokenType +func (i TokenType) MarshalText() ([]byte, error) { + return []byte(i.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface for TokenType +func (i *TokenType) UnmarshalText(text []byte) error { + var err error + *i, err = TokenTypeString(string(text)) + return err +} diff --git a/types.go b/types.go new file mode 100644 index 0000000..3d12310 --- /dev/null +++ b/types.go @@ -0,0 +1,340 @@ +package chroma + +//go:generate enumer -text -type TokenType + +// TokenType is the type of token to highlight. +// +// It is also an Emitter, emitting a single token of itself +type TokenType int + +// Set of TokenTypes. +// +// Categories of types are grouped in ranges of 1000, while sub-categories are in ranges of 100. For +// example, the literal category is in the range 3000-3999. The sub-category for literal strings is +// in the range 3100-3199. + +// Meta token types. +const ( + // Default background style. + Background TokenType = -1 - iota + // PreWrapper style. + PreWrapper + // Line style. + Line + // Line numbers in output. + LineNumbers + // Line numbers in output when in table. + LineNumbersTable + // Line higlight style. + LineHighlight + // Line numbers table wrapper style. + LineTable + // Line numbers table TD wrapper style. + LineTableTD + // Line number links. + LineLink + // Code line wrapper style. + CodeLine + // Input that could not be tokenised. + Error + // Other is used by the Delegate lexer to indicate which tokens should be handled by the delegate. + Other + // No highlighting. + None + // Used as an EOF marker / nil token + EOFType TokenType = 0 +) + +// Keywords. +const ( + Keyword TokenType = 1000 + iota + KeywordConstant + KeywordDeclaration + KeywordNamespace + KeywordPseudo + KeywordReserved + KeywordType +) + +// Names. +const ( + Name TokenType = 2000 + iota + NameAttribute + NameBuiltin + NameBuiltinPseudo + NameClass + NameConstant + NameDecorator + NameEntity + NameException + NameFunction + NameFunctionMagic + NameKeyword + NameLabel + NameNamespace + NameOperator + NameOther + NamePseudo + NameProperty + NameTag + NameVariable + NameVariableAnonymous + NameVariableClass + NameVariableGlobal + NameVariableInstance + NameVariableMagic +) + +// Literals. +const ( + Literal TokenType = 3000 + iota + LiteralDate + LiteralOther +) + +// Strings. +const ( + LiteralString TokenType = 3100 + iota + LiteralStringAffix + LiteralStringAtom + LiteralStringBacktick + LiteralStringBoolean + LiteralStringChar + LiteralStringDelimiter + LiteralStringDoc + LiteralStringDouble + LiteralStringEscape + LiteralStringHeredoc + LiteralStringInterpol + LiteralStringName + LiteralStringOther + LiteralStringRegex + LiteralStringSingle + LiteralStringSymbol +) + +// Literals. +const ( + LiteralNumber TokenType = 3200 + iota + LiteralNumberBin + LiteralNumberFloat + LiteralNumberHex + LiteralNumberInteger + LiteralNumberIntegerLong + LiteralNumberOct +) + +// Operators. +const ( + Operator TokenType = 4000 + iota + OperatorWord +) + +// Punctuation. +const ( + Punctuation TokenType = 5000 + iota +) + +// Comments. +const ( + Comment TokenType = 6000 + iota + CommentHashbang + CommentMultiline + CommentSingle + CommentSpecial +) + +// Preprocessor "comments". +const ( + CommentPreproc TokenType = 6100 + iota + CommentPreprocFile +) + +// Generic tokens. +const ( + Generic TokenType = 7000 + iota + GenericDeleted + GenericEmph + GenericError + GenericHeading + GenericInserted + GenericOutput + GenericPrompt + GenericStrong + GenericSubheading + GenericTraceback + GenericUnderline +) + +// Text. +const ( + Text TokenType = 8000 + iota + TextWhitespace + TextSymbol + TextPunctuation +) + +// Aliases. +const ( + Whitespace = TextWhitespace + + Date = LiteralDate + + String = LiteralString + StringAffix = LiteralStringAffix + StringBacktick = LiteralStringBacktick + StringChar = LiteralStringChar + StringDelimiter = LiteralStringDelimiter + StringDoc = LiteralStringDoc + StringDouble = LiteralStringDouble + StringEscape = LiteralStringEscape + StringHeredoc = LiteralStringHeredoc + StringInterpol = LiteralStringInterpol + StringOther = LiteralStringOther + StringRegex = LiteralStringRegex + StringSingle = LiteralStringSingle + StringSymbol = LiteralStringSymbol + + Number = LiteralNumber + NumberBin = LiteralNumberBin + NumberFloat = LiteralNumberFloat + NumberHex = LiteralNumberHex + NumberInteger = LiteralNumberInteger + NumberIntegerLong = LiteralNumberIntegerLong + NumberOct = LiteralNumberOct +) + +var ( + StandardTypes = map[TokenType]string{ + Background: "bg", + PreWrapper: "chroma", + Line: "line", + LineNumbers: "ln", + LineNumbersTable: "lnt", + LineHighlight: "hl", + LineTable: "lntable", + LineTableTD: "lntd", + LineLink: "lnlinks", + CodeLine: "cl", + Text: "", + Whitespace: "w", + Error: "err", + Other: "x", + // I have no idea what this is used for... + // Escape: "esc", + + Keyword: "k", + KeywordConstant: "kc", + KeywordDeclaration: "kd", + KeywordNamespace: "kn", + KeywordPseudo: "kp", + KeywordReserved: "kr", + KeywordType: "kt", + + Name: "n", + NameAttribute: "na", + NameBuiltin: "nb", + NameBuiltinPseudo: "bp", + NameClass: "nc", + NameConstant: "no", + NameDecorator: "nd", + NameEntity: "ni", + NameException: "ne", + NameFunction: "nf", + NameFunctionMagic: "fm", + NameProperty: "py", + NameLabel: "nl", + NameNamespace: "nn", + NameOther: "nx", + NameTag: "nt", + NameVariable: "nv", + NameVariableClass: "vc", + NameVariableGlobal: "vg", + NameVariableInstance: "vi", + NameVariableMagic: "vm", + + Literal: "l", + LiteralDate: "ld", + + String: "s", + StringAffix: "sa", + StringBacktick: "sb", + StringChar: "sc", + StringDelimiter: "dl", + StringDoc: "sd", + StringDouble: "s2", + StringEscape: "se", + StringHeredoc: "sh", + StringInterpol: "si", + StringOther: "sx", + StringRegex: "sr", + StringSingle: "s1", + StringSymbol: "ss", + + Number: "m", + NumberBin: "mb", + NumberFloat: "mf", + NumberHex: "mh", + NumberInteger: "mi", + NumberIntegerLong: "il", + NumberOct: "mo", + + Operator: "o", + OperatorWord: "ow", + + Punctuation: "p", + + Comment: "c", + CommentHashbang: "ch", + CommentMultiline: "cm", + CommentPreproc: "cp", + CommentPreprocFile: "cpf", + CommentSingle: "c1", + CommentSpecial: "cs", + + Generic: "g", + GenericDeleted: "gd", + GenericEmph: "ge", + GenericError: "gr", + GenericHeading: "gh", + GenericInserted: "gi", + GenericOutput: "go", + GenericPrompt: "gp", + GenericStrong: "gs", + GenericSubheading: "gu", + GenericTraceback: "gt", + GenericUnderline: "gl", + } +) + +func (t TokenType) Parent() TokenType { + if t%100 != 0 { + return t / 100 * 100 + } + if t%1000 != 0 { + return t / 1000 * 1000 + } + return 0 +} + +func (t TokenType) Category() TokenType { + return t / 1000 * 1000 +} + +func (t TokenType) SubCategory() TokenType { + return t / 100 * 100 +} + +func (t TokenType) InCategory(other TokenType) bool { + return t/1000 == other/1000 +} + +func (t TokenType) InSubCategory(other TokenType) bool { + return t/100 == other/100 +} + +func (t TokenType) Emit(groups []string, _ *LexerState) Iterator { + return Literator(Token{Type: t, Value: groups[0]}) +} + +func (t TokenType) EmitterKind() string { return "token" }