| 🛟 Updated. 28d5985 k33g 19h ago | 1 | package syntax_test |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | |
| 6 | "codeberg.org/turbo-editors/turbo-core/syntax" |
| 7 | ) |
| 8 | |
| 9 | // Colouring a line of Markdown. |
| 10 | func ExampleHighlight() { |
| 11 | spans := syntax.Highlight(syntax.LanguageMarkdown, "# Title") |
| 12 | |
| 13 | for _, s := range spans[0] { |
| 14 | fmt.Printf("%d-%d %v\n", s.Start, s.End, s.Class) |
| 15 | } |
| 16 | // Output: |
| 17 | // 0-7 heading |
| 18 | } |
| 19 | |
| 20 | // The cache is what the editor draws from: it re-scans only when the buffer's |
| 21 | // revision has moved. |
| 22 | func ExampleCache() { |
| 23 | cache := syntax.NewCache(syntax.LanguageOf("settings.toml", "[editor]")) |
| 24 | |
| 25 | cache.Update("theme = \"turbo-dark\"", 1) |
| 26 | cache.Update("theme = \"turbo-dark\"", 1) // no work: same revision |
| 27 | |
| 28 | for _, s := range cache.Line(0) { |
| 29 | fmt.Println(s.Class) |
| 30 | } |
| 31 | // Output: |
| 32 | // identifier |
| 33 | // operator |
| 34 | // string |
| 35 | } |
| 36 | |
| 37 | // TOML is coloured with the classes every language here shares, so a theme |
| 38 | // needs no keys of its own for it: a table header reads as a type, a key as an |
| 39 | // identifier. |
| 40 | func ExampleHighlight_toml() { |
| 41 | spans := syntax.Highlight(syntax.LanguageTOML, "[editor]\ntheme = \"turbo-dark\" # ours\n") |
| 42 | |
| 43 | for _, s := range spans[1] { |
| 44 | fmt.Printf("%d-%d %v\n", s.Start, s.End, s.Class) |
| 45 | } |
| 46 | // Output: |
| 47 | // 0-5 identifier |
| 48 | // 6-7 operator |
| 49 | // 8-20 string |
| 50 | // 21-27 comment |
| 51 | } |
| 52 | |
| 53 | // A file is named by its extension, and only failing that by its first line. |
| 54 | // Go is absent from this list on purpose: this library colours the languages |
| 55 | // every editor built on it shares, and each editor registers the one it is for. |
| 56 | func ExampleLanguageOf() { |
| 57 | fmt.Println(syntax.LanguageOf(".turbo-go/settings.toml", "[editor]")) |
| 58 | fmt.Println(syntax.LanguageOf("README.md", "# Title")) |
| 59 | fmt.Println(syntax.LanguageOf("configure", "#!/bin/sh")) // no extension, so the shebang decides |
| 60 | fmt.Println(syntax.LanguageOf("photo.png", "")) |
| 61 | // Output: |
| 62 | // toml |
| 63 | // markdown |
| 64 | // bash |
| 65 | // none |
| 66 | } |
| 67 | |
| 68 | // Teaching the package a language of your own. This is what Turbo Rust does at |
| 69 | // start-up, with a scanner written against syntax.LineScanner. |
| 70 | func ExampleRegister() { |
| 71 | syntax.Register(syntax.Definition{ |
| 72 | Language: "rust", |
| 73 | Extensions: []string{".rs"}, |
| 74 | Highlight: func(src string) [][]syntax.Span { |
| 75 | return syntax.ScanLines(src, func(line []rune, carry struct{}) ([]syntax.Span, struct{}) { |
| 76 | s := syntax.NewLineScanner(line) |
| 77 | s.TakeRest(syntax.ClassComment) // a scanner worth the name does more |
| 78 | return s.Spans(), carry |
| 79 | }) |
| 80 | }, |
| 81 | }) |
| 82 | |
| 83 | fmt.Println(syntax.LanguageOf("main.rs", "")) |
| 84 | fmt.Println(syntax.Highlight("rust", "fn main() {}")[0][0].Class) |
| 85 | // Output: |
| 86 | // rust |
| 87 | // comment |
| 88 | } |