├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── UPGRADE-2.x.md ├── composer.json ├── package-lock.json ├── package.json ├── phpstan.neon ├── phpunit.xml ├── resources ├── grammars │ ├── abap.json │ ├── actionscript-3.json │ ├── ada.json │ ├── angular-expression.json │ ├── angular-html.json │ ├── angular-inline-style.json │ ├── angular-inline-template.json │ ├── angular-let-declaration.json │ ├── angular-template-blocks.json │ ├── angular-template.json │ ├── angular-ts.json │ ├── antlers.json │ ├── apache.json │ ├── apex.json │ ├── apl.json │ ├── applescript.json │ ├── ara.json │ ├── asciidoc.json │ ├── asm.json │ ├── astro.json │ ├── awk.json │ ├── ballerina.json │ ├── bat.json │ ├── beancount.json │ ├── berry.json │ ├── bibtex.json │ ├── bicep.json │ ├── blade.json │ ├── bsl.json │ ├── c.json │ ├── cadence.json │ ├── cairo.json │ ├── clarity.json │ ├── clojure.json │ ├── cmake.json │ ├── cobol.json │ ├── codeowners.json │ ├── codeql.json │ ├── coffee.json │ ├── common-lisp.json │ ├── coq.json │ ├── cpp-macro.json │ ├── cpp.json │ ├── crystal.json │ ├── csharp.json │ ├── css.json │ ├── csv.json │ ├── cue.json │ ├── cypher.json │ ├── d.json │ ├── dart.json │ ├── dax.json │ ├── desktop.json │ ├── diff.json │ ├── docker.json │ ├── dotenv.json │ ├── dream-maker.json │ ├── edge.json │ ├── elixir.json │ ├── elm.json │ ├── emacs-lisp.json │ ├── erb.json │ ├── erlang.json │ ├── es-tag-css.json │ ├── es-tag-glsl.json │ ├── es-tag-html.json │ ├── es-tag-sql.json │ ├── es-tag-xml.json │ ├── fennel.json │ ├── fish.json │ ├── fluent.json │ ├── fortran-fixed-form.json │ ├── fortran-free-form.json │ ├── fsharp.json │ ├── gdresource.json │ ├── gdscript.json │ ├── gdshader.json │ ├── genie.json │ ├── gherkin.json │ ├── git-commit.json │ ├── git-rebase.json │ ├── gleam.json │ ├── glimmer-js.json │ ├── glimmer-ts.json │ ├── glsl.json │ ├── gnuplot.json │ ├── go.json │ ├── graphql.json │ ├── groovy.json │ ├── hack.json │ ├── haml.json │ ├── handlebars.json │ ├── haskell.json │ ├── haxe.json │ ├── hcl.json │ ├── hjson.json │ ├── hlsl.json │ ├── html-derivative.json │ ├── html.json │ ├── http.json │ ├── hxml.json │ ├── hy.json │ ├── imba.json │ ├── ini.json │ ├── java.json │ ├── javascript.json │ ├── jinja-html.json │ ├── jinja.json │ ├── jison.json │ ├── json.json │ ├── json5.json │ ├── jsonc.json │ ├── jsonl.json │ ├── jsonnet.json │ ├── jssm.json │ ├── jsx.json │ ├── julia.json │ ├── kotlin.json │ ├── kusto.json │ ├── latex.json │ ├── lean.json │ ├── less.json │ ├── liquid.json │ ├── llvm.json │ ├── log.json │ ├── logo.json │ ├── lua.json │ ├── luau.json │ ├── make.json │ ├── markdown-vue.json │ ├── markdown.json │ ├── marko.json │ ├── matlab.json │ ├── mdc.json │ ├── mdx.json │ ├── mermaid.json │ ├── mipsasm.json │ ├── mojo.json │ ├── move.json │ ├── narrat.json │ ├── nextflow.json │ ├── nginx.json │ ├── nim.json │ ├── nix.json │ ├── nushell.json │ ├── objective-c.json │ ├── objective-cpp.json │ ├── ocaml.json │ ├── pascal.json │ ├── perl.json │ ├── php.json │ ├── plsql.json │ ├── po.json │ ├── polar.json │ ├── postcss.json │ ├── powerquery.json │ ├── powershell.json │ ├── prisma.json │ ├── prolog.json │ ├── proto.json │ ├── pug.json │ ├── puppet.json │ ├── purescript.json │ ├── python.json │ ├── qml.json │ ├── qmldir.json │ ├── qss.json │ ├── r.json │ ├── racket.json │ ├── raku.json │ ├── razor.json │ ├── reg.json │ ├── regexp.json │ ├── rel.json │ ├── riscv.json │ ├── rst.json │ ├── ruby.json │ ├── rust.json │ ├── sas.json │ ├── sass.json │ ├── scala.json │ ├── scheme.json │ ├── scss.json │ ├── sdbl.json │ ├── shaderlab.json │ ├── shellscript.json │ ├── shellsession.json │ ├── smalltalk.json │ ├── solidity.json │ ├── soy.json │ ├── sparql.json │ ├── splunk.json │ ├── sql.json │ ├── ssh-config.json │ ├── stata.json │ ├── stylus.json │ ├── svelte.json │ ├── swift.json │ ├── system-verilog.json │ ├── systemd.json │ ├── talonscript.json │ ├── tasl.json │ ├── tcl.json │ ├── templ.json │ ├── terraform.json │ ├── tex.json │ ├── toml.json │ ├── ts-tags.json │ ├── tsv.json │ ├── tsx.json │ ├── turtle.json │ ├── twig.json │ ├── txt.json │ ├── typescript.json │ ├── typespec.json │ ├── typst.json │ ├── v.json │ ├── vala.json │ ├── vb.json │ ├── verilog.json │ ├── vhdl.json │ ├── viml.json │ ├── vue-directives.json │ ├── vue-html.json │ ├── vue-interpolations.json │ ├── vue-sfc-style-variable-injection.json │ ├── vue-vine.json │ ├── vue.json │ ├── vyper.json │ ├── wasm.json │ ├── wenyan.json │ ├── wgsl.json │ ├── wikitext.json │ ├── wit.json │ ├── wolfram.json │ ├── xml.json │ ├── xsl.json │ ├── yaml.json │ ├── zenscript.json │ └── zig.json └── themes │ ├── andromeeda.json │ ├── aurora-x.json │ ├── ayu-dark.json │ ├── catppuccin-frappe.json │ ├── catppuccin-latte.json │ ├── catppuccin-macchiato.json │ ├── catppuccin-mocha.json │ ├── dark-plus.json │ ├── dracula-soft.json │ ├── dracula.json │ ├── everforest-dark.json │ ├── everforest-light.json │ ├── github-dark-default.json │ ├── github-dark-dimmed.json │ ├── github-dark-high-contrast.json │ ├── github-dark.json │ ├── github-light-default.json │ ├── github-light-high-contrast.json │ ├── github-light.json │ ├── gruvbox-dark-hard.json │ ├── gruvbox-dark-medium.json │ ├── gruvbox-dark-soft.json │ ├── gruvbox-light-hard.json │ ├── gruvbox-light-medium.json │ ├── gruvbox-light-soft.json │ ├── houston.json │ ├── kanagawa-dragon.json │ ├── kanagawa-lotus.json │ ├── kanagawa-wave.json │ ├── laserwave.json │ ├── light-plus.json │ ├── material-theme-darker.json │ ├── material-theme-lighter.json │ ├── material-theme-ocean.json │ ├── material-theme-palenight.json │ ├── material-theme.json │ ├── min-dark.json │ ├── min-light.json │ ├── monokai.json │ ├── night-owl.json │ ├── nord.json │ ├── one-dark-pro.json │ ├── one-light.json │ ├── plastic.json │ ├── poimandres.json │ ├── red.json │ ├── rose-pine-dawn.json │ ├── rose-pine-moon.json │ ├── rose-pine.json │ ├── slack-dark.json │ ├── slack-ochin.json │ ├── snazzy-light.json │ ├── solarized-dark.json │ ├── solarized-light.json │ ├── synthwave-84.json │ ├── tokyo-night.json │ ├── vesper.json │ ├── vitesse-black.json │ ├── vitesse-dark.json │ └── vitesse-light.json ├── src ├── Adapters │ ├── CommonMark │ │ ├── CodeBlockRenderer.php │ │ ├── PhikiExtension.php │ │ └── Transformers │ │ │ ├── Annotations │ │ │ ├── Annotation.php │ │ │ ├── AnnotationRange.php │ │ │ ├── AnnotationRangeKind.php │ │ │ └── AnnotationType.php │ │ │ ├── AnnotationsTransformer.php │ │ │ └── MetaTransformer.php │ └── Laravel │ │ ├── Components │ │ └── Code.php │ │ ├── Facades │ │ └── Phiki.php │ │ └── PhikiServiceProvider.php ├── Contracts │ ├── ExtensionInterface.php │ ├── GrammarRepositoryInterface.php │ ├── HasContentNameInterface.php │ ├── InjectionMatcherInterface.php │ ├── InjectionSelectorParserInputInterface.php │ ├── PatternInterface.php │ ├── RequiresGrammarInterface.php │ ├── RequiresThemesInterface.php │ ├── ThemeRepositoryInterface.php │ └── TransformerInterface.php ├── Environment.php ├── Exceptions │ ├── FailedToInitializePatternSearchException.php │ ├── FailedToSetSearchPositionException.php │ ├── GenericPatternException.php │ ├── InvalidThemeException.php │ ├── MissingRequiredGrammarKeyException.php │ ├── UnreachableException.php │ ├── UnrecognisedGrammarException.php │ ├── UnrecognisedReferenceException.php │ └── UnrecognisedThemeException.php ├── Grammar │ ├── BeginEndPattern.php │ ├── BeginWhilePattern.php │ ├── Capture.php │ ├── CollectionPattern.php │ ├── EndPattern.php │ ├── Grammar.php │ ├── GrammarParser.php │ ├── GrammarRepository.php │ ├── IncludePattern.php │ ├── Injections │ │ ├── Composite.php │ │ ├── Expression.php │ │ ├── Filter.php │ │ ├── Group.php │ │ ├── Injection.php │ │ ├── Operator.php │ │ ├── Path.php │ │ ├── Prefix.php │ │ ├── Scope.php │ │ └── Selector.php │ ├── MatchPattern.php │ ├── MatchedInjection.php │ ├── MatchedPattern.php │ ├── ParsedGrammar.php │ └── WhilePattern.php ├── Highlighting │ └── Highlighter.php ├── Output │ └── Html │ │ └── PendingHtmlOutput.php ├── Phast │ ├── ClassList.php │ ├── Element.php │ ├── Literal.php │ ├── Properties.php │ ├── Root.php │ └── Text.php ├── Phiki.php ├── Support │ ├── Arr.php │ ├── Regex.php │ └── Str.php ├── Tests │ └── Adapters │ │ └── Laravel │ │ └── TestCase.php ├── TextMate │ ├── AttributedScopeStack.php │ ├── LineTokens.php │ ├── LocalStackElement.php │ ├── PatternSearcher.php │ ├── ScopeStack.php │ ├── StateStack.php │ ├── Tokenizer.php │ └── WhileStackElement.php ├── Theme │ ├── ParsedTheme.php │ ├── Scope.php │ ├── ScopeMatchResult.php │ ├── Theme.php │ ├── ThemeParser.php │ ├── ThemeRepository.php │ ├── TokenColor.php │ ├── TokenColorMatchResult.php │ └── TokenSettings.php ├── Token │ ├── HighlightedToken.php │ └── Token.php └── Transformers │ ├── AbstractTransformer.php │ ├── AddClassesTransformer.php │ ├── Concerns │ ├── RequiresGrammar.php │ └── RequiresThemes.php │ ├── Decorations │ ├── CodeDecoration.php │ ├── DecorationTransformer.php │ ├── GutterDecoration.php │ ├── LineDecoration.php │ └── PreDecoration.php │ └── Meta.php └── testbench.yaml /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | All contributions to Phiki are welcome and greatly appreciated, regardless of their size or set of changes. 4 | 5 | To make sure your pull request is reviewed and treated fairly, please follow the rules below: 6 | * Keep your contribution small and self-contained. Don't make large changes to multiple parts of the project at the same time. 7 | * Keep your branch up-to-date with `main` to make it easier to review and merge. 8 | * Keep your commits clean and simple. Some reviewers will work through each commit to see what has changed and why. 9 | * Always check the "Issues" tab before working on something new. If there's an issue, it could contain valuable information or ideas for the contribution. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Ryan Chandler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Phiki](./art/banner.png) 2 | 3 | Phiki is a syntax highlighter written in PHP. It uses TextMate grammar files and Visual Studio Code themes to generate syntax highlighted code for the web. 4 | 5 | The name and public API of Phiki is heavily inspired by [Shiki](https://shiki.style/), a package that does more or less the same thing in the JavaScript ecosystem. The actual implementation of the package is also heavily inspired by [`vscode-textmate`](https://github.com/microsoft/vscode-textmate) which is the powerhouse of a package behind Visual Studio Code, Shiki, and others. 6 | 7 | ## Installation 8 | 9 | Install Phiki via Composer: 10 | 11 | ```sh 12 | composer require phiki/phiki 13 | ``` 14 | 15 | ## Documentation 16 | 17 | For more information on how to integrate Phiki into your application, please [visit the official documentation](https://phiki.dev). 18 | 19 | ## Support my work 20 | 21 | If you find Phiki useful, please consider supporting me through [GitHub Sponsors](https://github.com/sponsors/ryangjchandler) or [Buy me a Coffee](https://buymeacoffee.com/ryangjchandler). 22 | 23 | All sponsorships go towards the maintenance and continuous improvement of my open source projects. 24 | 25 | ## Credits 26 | 27 | * [Ryan Chandler](https://github.com/ryangjchandler) 28 | * [Shiki](https://shiki.style/) for API inspiration and TextMate grammar files via [`tm-grammars` and `tm-themes`](https://github.com/shikijs/textmate-grammars-themes). 29 | * [`vscode-textmate`](https://github.com/microsoft/vscode-textmate) for guiding the implementation of the internal tokenizer. 30 | -------------------------------------------------------------------------------- /UPGRADE-2.x.md: -------------------------------------------------------------------------------- 1 | # Upgrading from 1.x to 2.0 2 | 3 | To read more about the upgrade process from Phiki 1.x to v2.0, please [visit the official upgrade guide](https://phiki.dev/upgrade-2.0) on our website. 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phiki/phiki", 3 | "description": "Syntax highlighting using TextMate grammars in PHP.", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Ryan Chandler", 8 | "email": "support@ryangjchandler.co.uk", 9 | "role": "Developer", 10 | "homepage": "https://ryangjchandler.co.uk" 11 | } 12 | ], 13 | "require": { 14 | "php": "^8.2", 15 | "league/commonmark": "^2.5.3", 16 | "ext-mbstring": "*", 17 | "psr/simple-cache": "^3.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Phiki\\": "src/" 22 | } 23 | }, 24 | "autoload-dev": { 25 | "psr-4": { 26 | "Phiki\\Tests\\": "tests/" 27 | } 28 | }, 29 | "minimum-stability": "dev", 30 | "prefer-stable": true, 31 | "require-dev": { 32 | "symfony/var-dumper": "^7.1.6", 33 | "pestphp/pest": "^3.5.1", 34 | "laravel/pint": "^1.18.1", 35 | "phpstan/phpstan": "^2.0", 36 | "phpstan/extension-installer": "^1.4.3", 37 | "illuminate/support": "^11.45", 38 | "orchestra/testbench": "^9.15" 39 | }, 40 | "config": { 41 | "allow-plugins": { 42 | "pestphp/pest-plugin": true, 43 | "phpstan/extension-installer": true 44 | } 45 | }, 46 | "scripts": { 47 | "sample": [ 48 | "Composer\\Config::disableProcessTimeout", 49 | "@php -S 127.0.0.1:8080 ./meta/sample/index.php -d memory_limit=-1" 50 | ], 51 | "sample:debug": [ 52 | "Composer\\Config::disableProcessTimeout", 53 | "herd debug -S 127.0.0.1:8080 ./meta/sample/index.php" 54 | ], 55 | "vscode-textmate:tokens": "node meta/generate-vscode-textmate-tokens.js", 56 | "update-grammars-and-themes": [ 57 | "Composer\\Config::disableProcessTimeout", 58 | "npm update", 59 | "node meta/update-grammars-and-themes.js", 60 | "php meta/generate-vscode-token-dumps.php" 61 | ], 62 | "update-grammars-and-themes:only": [ 63 | "Composer\\Config::disableProcessTimeout", 64 | "node meta/update-grammars-and-themes.js" 65 | ], 66 | "test": [ 67 | "@php -dmemory_limit=-1 ./vendor/bin/pest --enforce-time-limit --default-time-limit=1" 68 | ], 69 | "lint": "@php vendor/bin/phpstan", 70 | "fmt": "@php vendor/bin/pint" 71 | }, 72 | "extra": { 73 | "laravel": { 74 | "providers": [ 75 | "Phiki\\Adapters\\Laravel\\PhikiServiceProvider" 76 | ] 77 | } 78 | }, 79 | "funding": [ 80 | { 81 | "type": "github", 82 | "url": "https://github.com/sponsors/ryangjchandler" 83 | }, 84 | { 85 | "type": "other", 86 | "url": "https://buymeacoffee.com/ryangjchandler" 87 | } 88 | ] 89 | } 90 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "devDependencies": { 5 | "change-case": "^5.4.4", 6 | "tablemark": "^3.1.0", 7 | "tm-grammars": "^1.22.10", 8 | "tm-themes": "^1.9.8", 9 | "vscode-oniguruma": "^2.0.1", 10 | "vscode-textmate": "^9.2.0" 11 | }, 12 | "version": "0.0.1" 13 | } 14 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 5 3 | 4 | excludePaths: 5 | - meta/stubs/* 6 | 7 | paths: 8 | - src 9 | - meta 10 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 10 | 11 | 12 | 13 | ./tests/Adapters 14 | 15 | 16 | 17 | 18 | ./app 19 | ./src 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /resources/grammars/angular-html.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Angular HTML","information_for_contributors":["This file has been converted from https://github.com/textmate/html.tmbundle/blob/master/Syntaxes/HTML%20%28Derivative%29.tmLanguage","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"injections":{"R:text.html - (comment.block, text.html meta.embedded, meta.tag.*.*.html, meta.tag.*.*.*.html, meta.tag.*.*.*.*.html)":{"comment":"Uses R: to ensure this matches after any other injections.","patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"angular-html","patterns":[{"include":"text.html.basic#core-minus-invalid"},{"begin":"(]*)(?)","endCaptures":{"1":{"name":"punctuation.definition.tag.end.html"}},"name":"meta.tag.other.unrecognized.html.derivative","patterns":[{"include":"text.html.basic#attribute"}]}],"scopeName":"text.html.derivative.ng","version":"https://github.com/textmate/html.tmbundle/commit/390c8870273a2ae80244dae6db6ba064a802f407"} 2 | -------------------------------------------------------------------------------- /resources/grammars/angular-inline-style.json: -------------------------------------------------------------------------------- 1 | {"injectTo":["source.ts.ng"],"injectionSelector":"L:source.ts#meta.decorator.ts -comment","name":"angular-inline-style","patterns":[{"include":"#inlineStyles"}],"repository":{"inlineStyles":{"begin":"(styles)\\s*(:)","beginCaptures":{"1":{"name":"meta.object-literal.key.ts"},"2":{"name":"meta.object-literal.key.ts punctuation.separator.key-value.ts"}},"end":"(?=,|})","patterns":[{"include":"#tsParenExpression"},{"include":"#tsBracketExpression"},{"include":"#style"}]},"style":{"begin":"\\s*([`|'|\"])","beginCaptures":{"1":{"name":"string"}},"contentName":"source.css.scss","end":"\\1","endCaptures":{"0":{"name":"string"}},"patterns":[{"include":"source.css.scss"}]},"tsBracketExpression":{"begin":"\\G\\s*(\\[)","beginCaptures":{"1":{"name":"meta.array.literal.ts meta.brace.square.ts"}},"end":"\\]","endCaptures":{"0":{"name":"meta.array.literal.ts meta.brace.square.ts"}},"patterns":[{"include":"#style"}]},"tsParenExpression":{"begin":"\\G\\s*(\\()","beginCaptures":{"1":{"name":"meta.brace.round.ts"}},"end":"\\)","endCaptures":{"0":{"name":"meta.brace.round.ts"}},"patterns":[{"include":"$self"},{"include":"#tsBracketExpression"},{"include":"#style"}]}},"scopeName":"inline-styles.ng"} 2 | -------------------------------------------------------------------------------- /resources/grammars/angular-inline-template.json: -------------------------------------------------------------------------------- 1 | {"injectTo":["source.ts.ng"],"injectionSelector":"L:meta.decorator.ts -comment -text.html","name":"angular-inline-template","patterns":[{"include":"#inlineTemplate"}],"repository":{"inlineTemplate":{"begin":"(template)\\s*(:)","beginCaptures":{"1":{"name":"meta.object-literal.key.ts"},"2":{"name":"meta.object-literal.key.ts punctuation.separator.key-value.ts"}},"end":"(?=,|})","patterns":[{"include":"#tsParenExpression"},{"include":"#ngTemplate"}]},"ngTemplate":{"begin":"\\G\\s*([`|'|\"])","beginCaptures":{"1":{"name":"string"}},"contentName":"text.html.derivative.ng","end":"\\1","endCaptures":{"0":{"name":"string"}},"patterns":[{"include":"text.html.derivative.ng"},{"include":"template.ng"}]},"tsParenExpression":{"begin":"\\G\\s*(\\()","beginCaptures":{"1":{"name":"meta.brace.round.ts"}},"end":"\\)","endCaptures":{"0":{"name":"meta.brace.round.ts"}},"patterns":[{"include":"#tsParenExpression"},{"include":"#ngTemplate"}]}},"scopeName":"inline-template.ng"} 2 | -------------------------------------------------------------------------------- /resources/grammars/angular-let-declaration.json: -------------------------------------------------------------------------------- 1 | {"injectTo":["text.html.derivative","text.html.derivative.ng","source.ts.ng"],"injectionSelector":"L:text.html -comment -expression.ng -meta.tag -source.css -source.js","name":"angular-let-declaration","patterns":[{"include":"#letDeclaration"}],"repository":{"letDeclaration":{"begin":"(@let)\\s+([_$[:alpha:]][_$[:alnum:]]*)\\s*(=)?","beginCaptures":{"1":{"name":"storage.type.ng"},"2":{"name":"variable.other.constant.ng"},"3":{"name":"keyword.operator.assignment.ng"}},"end":"(?<=;)","name":"meta.definition.variable.ng","patterns":[{"include":"#letInitializer"}]},"letInitializer":{"begin":"\\s*","beginCaptures":{"0":{"name":"keyword.operator.assignment.ng"}},"contentName":"meta.definition.variable.initializer.ng","end":";","endCaptures":{"0":{"name":"punctuation.terminator.statement.ng"}},"patterns":[{"include":"expression.ng"}]}},"scopeName":"template.let.ng"} 2 | -------------------------------------------------------------------------------- /resources/grammars/angular-template-blocks.json: -------------------------------------------------------------------------------- 1 | {"injectTo":["text.html.derivative","text.html.derivative.ng","source.ts.ng"],"injectionSelector":"L:text.html -comment -expression.ng -meta.tag -source.css -source.js","name":"angular-template-blocks","patterns":[{"include":"#block"}],"repository":{"block":{"begin":"(@)(if|else if|else|defer|placeholder|loading|error|switch|case|default|for|empty)(?:\\s*)","beginCaptures":{"1":{"patterns":[{"include":"#transition"}]},"2":{"name":"keyword.control.block.kind.ng"}},"end":"(?<=\\})","name":"control.block.ng","patterns":[{"include":"#blockExpression"},{"include":"#blockBody"}]},"blockBody":{"begin":"\\{","beginCaptures":{"0":{"name":"punctuation.definition.block.ts"}},"contentName":"control.block.body.ng","end":"\\}","endCaptures":{"0":{"name":"punctuation.definition.block.ts"}},"patterns":[{"include":"text.html.derivative.ng"},{"include":"template.ng"}]},"blockExpression":{"begin":"\\(","beginCaptures":{"0":{"name":"meta.brace.round.ts"}},"contentName":"control.block.expression.ng","end":"\\)","endCaptures":{"0":{"name":"meta.brace.round.ts"}},"patterns":[{"include":"#blockExpressionOfClause"},{"include":"#blockExpressionLetBinding"},{"include":"#blockExpressionTrackClause"},{"include":"expression.ng"}]},"blockExpressionLetBinding":{"begin":"\\blet\\b","beginCaptures":{"0":{"name":"storage.type.ng"}},"end":"(?=[$)])|(?<=;)","patterns":[{"include":"expression.ng"}]},"blockExpressionOfClause":{"begin":"([_$[:alpha:]][_$[:alnum:]]*)\\s+(of)\\b","beginCaptures":{"1":{"name":"variable.other.constant.ng"},"2":{"name":"keyword.operator.expression.of.ng"}},"end":"(?=[$)])|(?<=;)","patterns":[{"include":"expression.ng"}]},"blockExpressionTrackClause":{"begin":"\\btrack\\b","beginCaptures":{"0":{"name":"keyword.control.track.ng"}},"end":"(?=[$)])|(?<=;)","patterns":[{"include":"expression.ng"}]},"transition":{"match":"@","name":"keyword.control.block.transition.ng"}},"scopeName":"template.blocks.ng"} 2 | -------------------------------------------------------------------------------- /resources/grammars/angular-template.json: -------------------------------------------------------------------------------- 1 | {"injectTo":["text.html.derivative","text.html.derivative.ng","source.ts.ng"],"injectionSelector":"L:text.html -comment","name":"angular-template","patterns":[{"include":"#interpolation"}],"repository":{"interpolation":{"begin":"{{","beginCaptures":{"0":{"name":"punctuation.definition.block.ts"}},"contentName":"expression.ng","end":"}}","endCaptures":{"0":{"name":"punctuation.definition.block.ts"}},"patterns":[{"include":"expression.ng"}]}},"scopeName":"template.ng"} 2 | -------------------------------------------------------------------------------- /resources/grammars/berry.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Berry","name":"berry","patterns":[{"include":"#controls"},{"include":"#strings"},{"include":"#comment-block"},{"include":"#comments"},{"include":"#keywords"},{"include":"#function"},{"include":"#member"},{"include":"#identifier"},{"include":"#number"},{"include":"#operator"}],"repository":{"comment-block":{"begin":"\\#\\-","end":"\\-#","name":"comment.berry","patterns":[{}]},"comments":{"begin":"\\#","end":"\\n","name":"comment.line.berry","patterns":[{}]},"controls":{"patterns":[{"match":"\\b(if|elif|else|for|while|do|end|break|continue|return|try|except|raise)\\b","name":"keyword.control.berry"}]},"function":{"patterns":[{"match":"\\b([a-zA-Z_][a-zA-Z0-9_]*(?=\\s*\\())","name":"entity.name.function.berry"}]},"identifier":{"patterns":[{"match":"\\b[_A-Za-z]\\w+\\b","name":"identifier.berry"}]},"keywords":{"patterns":[{"match":"\\b(var|static|def|class|true|false|nil|self|super|import|as|_class)\\b","name":"keyword.berry"}]},"member":{"patterns":[{"captures":{"0":{"name":"entity.other.attribute-name.berry"}},"match":"\\.([a-zA-Z_][a-zA-Z0-9_]*)"}]},"number":{"patterns":[{"match":"0x[a-fA-F0-9]+|\\d+|(\\d+\\.?|\\.\\d)\\d*([eE][+-]?\\d+)?","name":"constant.numeric.berry"}]},"operator":{"patterns":[{"match":"\\(|\\)|\\[|\\]|\\.|-|\\!|~|\\*|/|%|\\+|&|\\^|\\||<|>|=|:","name":"keyword.operator.berry"}]},"strings":{"patterns":[{"begin":"(\"|')","end":"\\1","name":"string.quoted.double.berry","patterns":[{"match":"(\\\\x[\\h]{2})|(\\\\[0-7]{3})|(\\\\\\\\)|(\\\\\")|(\\\\')|(\\\\a)|(\\\\b)|(\\\\f)|(\\\\n)|(\\\\r)|(\\\\t)|(\\\\v)","name":"constant.character.escape.berry"}]},{"begin":"f(\"|')","end":"\\1","name":"string.quoted.other.berry","patterns":[{"match":"(\\\\x[\\h]{2})|(\\\\[0-7]{3})|(\\\\\\\\)|(\\\\\")|(\\\\')|(\\\\a)|(\\\\b)|(\\\\f)|(\\\\n)|(\\\\r)|(\\\\t)|(\\\\v)","name":"constant.character.escape.berry"},{"match":"\\{\\{[^\\}]*\\}\\}","name":"string.quoted.other.berry"},{"begin":"\\{","end":"\\}","name":"keyword.other.unit.berry","patterns":[{"include":"#keywords"},{"include":"#numbers"},{"include":"#identifier"},{"include":"#operator"},{"include":"#member"},{"include":"#function"}]}]}]}},"scopeName":"source.berry"} 2 | -------------------------------------------------------------------------------- /resources/grammars/cairo.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Cairo","name":"cairo","patterns":[{"begin":"\\b(if).*\\(","beginCaptures":{"1":{"name":"keyword.control.if"},"2":{"name":"entity.name.condition"}},"contentName":"source.cairo0","end":"\\}","endCaptures":{"0":{"name":"keyword.control.end"}},"name":"meta.control.if","patterns":[{"include":"source.cairo0"}]},{"begin":"\\b(with)\\s+(.+)\\s*\\{","beginCaptures":{"1":{"name":"keyword.control.with"},"2":{"name":"entity.name.identifiers"}},"contentName":"source.cairo0","end":"\\}","endCaptures":{"0":{"name":"keyword.control.end"}},"name":"meta.control.with","patterns":[{"include":"source.cairo0"}]},{"begin":"\\b(with_attr)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*[({]","beginCaptures":{"1":{"name":"keyword.control.with_attr"},"2":{"name":"entity.name.function"}},"contentName":"source.cairo0","end":"\\}","endCaptures":{"0":{"name":"keyword.control.end"}},"name":"meta.control.with_attr","patterns":[{"include":"source.cairo0"}]},{"match":"\\belse\\b","name":"keyword.control.else"},{"match":"\\b(call|jmp|ret|abs|rel|if)\\b","name":"keyword.other.opcode"},{"match":"\\b(ap|fp)\\b","name":"keyword.other.register"},{"match":"\\b(const|let|local|tempvar|felt|as|from|import|static_assert|return|assert|cast|alloc_locals|with|with_attr|nondet|dw|codeoffset|new|using|and)\\b","name":"keyword.other.meta"},{"match":"\\b(SIZEOF_LOCALS|SIZE)\\b","name":"markup.italic"},{"match":"//[^\n]*\n","name":"comment.line.sharp"},{"match":"\\b[a-zA-Z_][a-zA-Z0-9_]*:\\s*$","name":"entity.name.function"},{"begin":"\\b(func)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*[({]","beginCaptures":{"1":{"name":"storage.type.function.cairo"},"2":{"name":"entity.name.function"}},"contentName":"source.cairo0","end":"\\}","endCaptures":{"0":{"name":"storage.type.function.cairo"}},"name":"meta.function.cairo","patterns":[{"include":"source.cairo0"}]},{"begin":"\\b(struct|namespace)\\s+([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\{","beginCaptures":{"1":{"name":"storage.type.function.cairo"},"2":{"name":"entity.name.function"}},"contentName":"source.cairo0","end":"\\}","endCaptures":{"0":{"name":"storage.type.function.cairo"}},"name":"meta.function.cairo","patterns":[{"include":"source.cairo0"}]},{"match":"\\b[+-]?[0-9]+\\b","name":"constant.numeric.decimal"},{"match":"\\b[+-]?0x[0-9a-fA-F]+\\b","name":"constant.numeric.hexadecimal"},{"match":"'[^']*'","name":"string.quoted.single"},{"match":"\"[^\"]*\"","name":"string.quoted.double"},{"begin":"%{","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.python"}},"contentName":"source.python","end":"%}","endCaptures":{"0":{"name":"punctuation.section.embedded.end.python"},"1":{"name":"source.python"}},"name":"meta.embedded.block.python","patterns":[{"include":"source.python"}]}],"scopeName":"source.cairo0"} 2 | -------------------------------------------------------------------------------- /resources/grammars/codeowners.json: -------------------------------------------------------------------------------- 1 | {"displayName":"CODEOWNERS","name":"codeowners","patterns":[{"include":"#comment"},{"include":"#pattern"},{"include":"#owner"}],"repository":{"comment":{"patterns":[{"begin":"^\\s*#","captures":{"0":{"name":"punctuation.definition.comment.codeowners"}},"end":"$","name":"comment.line.codeowners"}]},"owner":{"match":"\\S*@\\S+","name":"storage.type.function.codeowners"},"pattern":{"match":"^\\s*(\\S+)","name":"variable.other.codeowners"}},"scopeName":"text.codeowners"} 2 | -------------------------------------------------------------------------------- /resources/grammars/csv.json: -------------------------------------------------------------------------------- 1 | {"displayName":"CSV","fileTypes":["csv"],"name":"csv","patterns":[{"captures":{"1":{"name":"rainbow1"},"10":{"name":"invalid.rainbow10"},"2":{"name":"keyword.rainbow2"},"3":{"name":"entity.name.function.rainbow3"},"4":{"name":"comment.rainbow4"},"5":{"name":"string.rainbow5"},"6":{"name":"variable.parameter.rainbow6"},"7":{"name":"constant.numeric.rainbow7"},"8":{"name":"entity.name.type.rainbow8"},"9":{"name":"markup.bold.rainbow9"}},"match":"((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?((?: *\"(?:[^\"]*\"\")*[^\"]*\" *(?:,|$))|(?:[^,]*(?:,|$)))?","name":"rainbowgroup"}],"scopeName":"text.csv","uuid":"ca03e352-04ef-4340-9a6b-9b99aae1c418"} 2 | -------------------------------------------------------------------------------- /resources/grammars/desktop.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Desktop","name":"desktop","patterns":[{"include":"#layout"},{"include":"#keywords"},{"include":"#values"},{"include":"#inCommands"},{"include":"#inCategories"}],"repository":{"inCategories":{"patterns":[{"match":"(?<=^Categories.*)AudioVideo|(?<=^Categories.*)Audio|(?<=^Categories.*)Video|(?<=^Categories.*)Development|(?<=^Categories.*)Education|(?<=^Categories.*)Game|(?<=^Categories.*)Graphics|(?<=^Categories.*)Network|(?<=^Categories.*)Office|(?<=^Categories.*)Science|(?<=^Categories.*)Settings|(?<=^Categories.*)System|(?<=^Categories.*)Utility","name":"markup.bold"}]},"inCommands":{"patterns":[{"match":"(?<=^Exec.*\\s)-+\\S+","name":"variable.parameter"},{"match":"(?<=^Exec.*)\\s\\%[fFuUick]\\s","name":"variable.language"},{"match":"\".*\"","name":"string"}]},"keywords":{"patterns":[{"match":"^Type\\b|^Version\\b|^Name\\b|^GenericName\\b|^NoDisplay\\b|^Comment\\b|^Icon\\b|^Hidden\\b|^OnlyShowIn\\b|^NotShowIn\\b|^DBusActivatable\\b|^TryExec\\b|^Exec\\b|^Path\\b|^Terminal\\b|^Actions\\b|^MimeType\\b|^Categories\\b|^Implements\\b|^Keywords\\b|^StartupNotify\\b|^StartupWMClass\\b|^URL\\b|^PrefersNonDefaultGPU\\b|^Encoding\\b","name":"keyword"},{"match":"^X-[A-z 0-9 -]*","name":"keyword.other"},{"match":"(?)( .*)?)|((\\+).*))$\\n?","name":"markup.inserted.diff"},{"captures":{"1":{"name":"punctuation.definition.changed.diff"}},"match":"^(!).*$\\n?","name":"markup.changed.diff"},{"captures":{"3":{"name":"punctuation.definition.deleted.diff"},"6":{"name":"punctuation.definition.deleted.diff"}},"match":"^(((<)( .*)?)|((-).*))$\\n?","name":"markup.deleted.diff"},{"begin":"^(#)","captures":{"1":{"name":"punctuation.definition.comment.diff"}},"comment":"Git produces unified diffs with embedded comments\"","end":"\\n","name":"comment.line.number-sign.diff"},{"match":"^index [0-9a-f]{7,40}\\.\\.[0-9a-f]{7,40}.*$\\n?","name":"meta.diff.index.git"},{"captures":{"1":{"name":"punctuation.separator.key-value.diff"},"2":{"name":"meta.toc-list.file-name.diff"}},"match":"^Index(:) (.+)$\\n?","name":"meta.diff.index"},{"match":"^Only in .*: .*$\\n?","name":"meta.diff.only-in"}],"scopeName":"source.diff","version":"https://github.com/textmate/diff.tmbundle/commit/0593bb775eab1824af97ef2172fd38822abd97d7"} 2 | -------------------------------------------------------------------------------- /resources/grammars/docker.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Dockerfile","information_for_contributors":["This file has been converted from https://github.com/moby/moby/blob/master/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"name":"docker","patterns":[{"captures":{"1":{"name":"keyword.other.special-method.dockerfile"},"2":{"name":"keyword.other.special-method.dockerfile"}},"match":"^\\s*\\b(?i:(FROM))\\b.*?\\b(?i:(AS))\\b"},{"captures":{"1":{"name":"keyword.control.dockerfile"},"2":{"name":"keyword.other.special-method.dockerfile"}},"match":"^\\s*(?i:(ONBUILD)\\s+)?(?i:(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR))\\s"},{"captures":{"1":{"name":"keyword.operator.dockerfile"},"2":{"name":"keyword.other.special-method.dockerfile"}},"match":"^\\s*(?i:(ONBUILD)\\s+)?(?i:(CMD|ENTRYPOINT))\\s"},{"include":"#string-character-escape"},{"begin":"\"","beginCaptures":{"1":{"name":"punctuation.definition.string.begin.dockerfile"}},"end":"\"","endCaptures":{"1":{"name":"punctuation.definition.string.end.dockerfile"}},"name":"string.quoted.double.dockerfile","patterns":[{"include":"#string-character-escape"}]},{"begin":"'","beginCaptures":{"1":{"name":"punctuation.definition.string.begin.dockerfile"}},"end":"'","endCaptures":{"1":{"name":"punctuation.definition.string.end.dockerfile"}},"name":"string.quoted.single.dockerfile","patterns":[{"include":"#string-character-escape"}]},{"captures":{"1":{"name":"punctuation.whitespace.comment.leading.dockerfile"},"2":{"name":"comment.line.number-sign.dockerfile"},"3":{"name":"punctuation.definition.comment.dockerfile"}},"comment":"comment.line","match":"^(\\s*)((#).*$\\n?)"}],"repository":{"string-character-escape":{"match":"\\\\.","name":"constant.character.escaped.dockerfile"}},"scopeName":"source.dockerfile","version":"https://github.com/moby/moby/commit/c2029cb2574647e4bc28ed58486b8e85883eedb9"} 2 | -------------------------------------------------------------------------------- /resources/grammars/dotenv.json: -------------------------------------------------------------------------------- 1 | {"displayName":"dotEnv","name":"dotenv","patterns":[{"captures":{"1":{"patterns":[{"include":"#line-comment"}]}},"comment":"Full Line Comment","match":"^\\s?(#.*$)\\n"},{"captures":{"1":{"patterns":[{"include":"#key"}]},"2":{"name":"keyword.operator.assignment.dotenv"},"3":{"name":"property.value.dotenv","patterns":[{"include":"#line-comment"},{"include":"#double-quoted-string"},{"include":"#single-quoted-string"},{"include":"#interpolation"}]}},"comment":"ENV entry","match":"^\\s?(.*?)\\s?(\\=)(.*)$"}],"repository":{"double-quoted-string":{"captures":{"1":{"patterns":[{"include":"#interpolation"},{"include":"#escape-characters"}]}},"comment":"Double Quoted String","match":"\"(.*)\"","name":"string.quoted.double.dotenv"},"escape-characters":{"comment":"Escape characters","match":"\\\\[nrtfb\"'\\\\]|\\\\u[0123456789ABCDEF]{4}","name":"constant.character.escape.dotenv"},"interpolation":{"captures":{"1":{"name":"keyword.interpolation.begin.dotenv"},"2":{"name":"variable.interpolation.dotenv"},"3":{"name":"keyword.interpolation.end.dotenv"}},"comment":"Interpolation (variable substitution)","match":"(\\$\\{)(.*)(\\})"},"key":{"captures":{"1":{"name":"keyword.key.export.dotenv"},"2":{"name":"variable.key.dotenv","patterns":[{"include":"#variable"}]}},"comment":"Key","match":"(export\\s)?(.*)"},"line-comment":{"comment":"Comment","match":"#.*$","name":"comment.line.dotenv"},"single-quoted-string":{"comment":"Single Quoted String","match":"'(.*)'","name":"string.quoted.single.dotenv"},"variable":{"comment":"env variable","match":"[a-zA-Z_]+[a-zA-Z0-9_]*"}},"scopeName":"source.dotenv"} 2 | -------------------------------------------------------------------------------- /resources/grammars/edge.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Edge","injections":{"text.html.edge - (meta.embedded | meta.tag | comment.block.edge), L:(text.html.edge meta.tag - (comment.block.edge | meta.embedded.block.edge)), L:(source.ts.embedded.html - (comment.block.edge | meta.embedded.block.edge))":{"patterns":[{"include":"#comment"},{"include":"#escapedMustache"},{"include":"#safeMustache"},{"include":"#mustache"},{"include":"#nonSeekableTag"},{"include":"#tag"}]}},"name":"edge","patterns":[{"include":"text.html.basic"},{"include":"text.html.derivative"}],"repository":{"comment":{"begin":"\\{{--","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.edge"}},"end":"\\--}}","endCaptures":{"0":{"name":"punctuation.definition.comment.end.edge"}},"name":"comment.block"},"escapedMustache":{"begin":"\\@{{","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.edge"}},"end":"\\}}","endCaptures":{"0":{"name":"punctuation.definition.comment.end.edge"}},"name":"comment.block"},"mustache":{"begin":"\\{{","beginCaptures":{"0":{"name":"punctuation.mustache.begin"}},"end":"\\}}","endCaptures":{"0":{"name":"punctuation.mustache.end"}},"name":"meta.embedded.block.javascript","patterns":[{"include":"source.ts#expression"}]},"nonSeekableTag":{"captures":{"2":{"name":"support.function.edge"}},"match":"^(\\s*)((@{1,2})(!)?([a-zA-Z._]+))(~)?$","name":"meta.embedded.block.javascript","patterns":[{"include":"source.ts#expression"}]},"safeMustache":{"begin":"\\{{{","beginCaptures":{"0":{"name":"punctuation.mustache.begin"}},"end":"\\}}}","endCaptures":{"0":{"name":"punctuation.mustache.end"}},"name":"meta.embedded.block.javascript","patterns":[{"include":"source.ts#expression"}]},"tag":{"begin":"^(\\s*)((@{1,2})(!)?([a-zA-Z._]+)(\\s{0,2}))(\\()","beginCaptures":{"2":{"name":"support.function.edge"},"7":{"name":"punctuation.paren.open"}},"end":"\\)","endCaptures":{"0":{"name":"punctuation.paren.close"}},"name":"meta.embedded.block.javascript","patterns":[{"include":"source.ts#expression"}]}},"scopeName":"text.html.edge"} 2 | -------------------------------------------------------------------------------- /resources/grammars/erb.json: -------------------------------------------------------------------------------- 1 | {"displayName":"ERB","fileTypes":["erb","rhtml","html.erb"],"injections":{"text.html.erb - (meta.embedded.block.erb | meta.embedded.line.erb | comment)":{"patterns":[{"begin":"(^\\s*)(?=<%+#(?![^%]*%>))","beginCaptures":{"0":{"name":"punctuation.whitespace.comment.leading.erb"}},"end":"(?!\\G)(\\s*$\\n)?","endCaptures":{"0":{"name":"punctuation.whitespace.comment.trailing.erb"}},"patterns":[{"include":"#comment"}]},{"begin":"(^\\s*)(?=<%(?![^%]*%>))","beginCaptures":{"0":{"name":"punctuation.whitespace.embedded.leading.erb"}},"end":"(?!\\G)(\\s*$\\n)?","endCaptures":{"0":{"name":"punctuation.whitespace.embedded.trailing.erb"}},"patterns":[{"include":"#tags"}]},{"include":"#comment"},{"include":"#tags"}]}},"keyEquivalent":"^~H","name":"erb","patterns":[{"include":"text.html.basic"}],"repository":{"comment":{"patterns":[{"begin":"<%+#","beginCaptures":{"0":{"name":"punctuation.definition.comment.begin.erb"}},"end":"%>","endCaptures":{"0":{"name":"punctuation.definition.comment.end.erb"}},"name":"comment.block.erb"}]},"tags":{"patterns":[{"begin":"<%+(?!>)[-=]?(?![^%]*%>)","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.erb"}},"contentName":"source.ruby","end":"(-?%)>","endCaptures":{"0":{"name":"punctuation.section.embedded.end.erb"},"1":{"name":"source.ruby"}},"name":"meta.embedded.block.erb","patterns":[{"captures":{"1":{"name":"punctuation.definition.comment.erb"}},"match":"(#).*?(?=-?%>)","name":"comment.line.number-sign.erb"},{"include":"source.ruby"}]},{"begin":"<%+(?!>)[-=]?","beginCaptures":{"0":{"name":"punctuation.section.embedded.begin.erb"}},"contentName":"source.ruby","end":"(-?%)>","endCaptures":{"0":{"name":"punctuation.section.embedded.end.erb"},"1":{"name":"source.ruby"}},"name":"meta.embedded.line.erb","patterns":[{"captures":{"1":{"name":"punctuation.definition.comment.erb"}},"match":"(#).*?(?=-?%>)","name":"comment.line.number-sign.erb"},{"include":"source.ruby"}]}]}},"scopeName":"text.html.erb","uuid":"13FF9439-15D0-4E74-9A8E-83ABF0BAA5E7"} 2 | -------------------------------------------------------------------------------- /resources/grammars/es-tag-css.json: -------------------------------------------------------------------------------- 1 | {"fileTypes":["js","jsx","ts","tsx","html","vue","svelte","php","res"],"injectTo":["source.ts","source.js"],"injectionSelector":"L:source.js -comment -string, L:source.js -comment -string, L:source.jsx -comment -string, L:source.js.jsx -comment -string, L:source.ts -comment -string, L:source.tsx -comment -string, L:source.rescript -comment -string, L:source.vue -comment -string, L:source.svelte -comment -string, L:source.php -comment -string, L:source.rescript -comment -string","injections":{"L:source":{"patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"es-tag-css","patterns":[{"begin":"(?i)(\\s?\\/\\*\\s?(css|inline-css)\\s?\\*\\/\\s?)(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.css"},{"include":"inline.es6-htmlx#template"}]},{"begin":"(?i)(\\s*(css|inline-css))(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.css"},{"include":"inline.es6-htmlx#template"},{"include":"string.quoted.other.template.js"}]},{"begin":"(?i)(?<=\\s|\\,|\\=|\\:|\\(|\\$\\()\\s{0,}(((\\/\\*)|(\\/\\/))\\s?(css|inline-css)[ ]{0,1000}\\*?\\/?)[ ]{0,1000}$","beginCaptures":{"1":{"name":"comment.line"}},"end":"(`).*","patterns":[{"begin":"(\\G)","end":"(`)"},{"include":"source.ts#template-substitution-element"},{"include":"source.css"}]},{"begin":"(\\${)","beginCaptures":{"1":{"name":"entity.name.tag"}},"end":"(})","endCaptures":{"1":{"name":"entity.name.tag"}},"patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.js"}]}],"scopeName":"inline.es6-css"} 2 | -------------------------------------------------------------------------------- /resources/grammars/es-tag-glsl.json: -------------------------------------------------------------------------------- 1 | {"fileTypes":["js","jsx","ts","tsx","html","vue","svelte","php","res"],"injectTo":["source.ts","source.js"],"injectionSelector":"L:source.js -comment -string, L:source.js -comment -string, L:source.jsx -comment -string, L:source.js.jsx -comment -string, L:source.ts -comment -string, L:source.tsx -comment -string, L:source.rescript -comment -string","injections":{"L:source":{"patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"es-tag-glsl","patterns":[{"begin":"(?i)(\\s?\\/\\*\\s?(glsl|inline-glsl)\\s?\\*\\/\\s?)(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.glsl"},{"include":"inline.es6-htmlx#template"}]},{"begin":"(?i)(\\s*(glsl|inline-glsl))(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.glsl"},{"include":"inline.es6-htmlx#template"},{"include":"string.quoted.other.template.js"}]},{"begin":"(?i)(?<=\\s|\\,|\\=|\\:|\\(|\\$\\()\\s{0,}(((\\/\\*)|(\\/\\/))\\s?(glsl|inline-glsl)[ ]{0,1000}\\*?\\/?)[ ]{0,1000}$","beginCaptures":{"1":{"name":"comment.line"}},"end":"(`).*","patterns":[{"begin":"(\\G)","end":"(`)"},{"include":"source.ts#template-substitution-element"},{"include":"source.glsl"}]},{"begin":"(\\${)","beginCaptures":{"1":{"name":"entity.name.tag"}},"end":"(})","endCaptures":{"1":{"name":"entity.name.tag"}},"patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.js"}]}],"scopeName":"inline.es6-glsl"} 2 | -------------------------------------------------------------------------------- /resources/grammars/es-tag-html.json: -------------------------------------------------------------------------------- 1 | {"fileTypes":["js","jsx","ts","tsx","html","vue","svelte","php","res"],"injectTo":["source.ts","source.js"],"injectionSelector":"L:source.js -comment -string, L:source.js -comment -string, L:source.jsx -comment -string, L:source.js.jsx -comment -string, L:source.ts -comment -string, L:source.tsx -comment -string, L:source.rescript -comment -string","injections":{"L:source":{"patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"es-tag-html","patterns":[{"begin":"(?i)(\\s?\\/\\*\\s?(html|template|inline-html|inline-template)\\s?\\*\\/\\s?)(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"text.html.basic"},{"include":"inline.es6-htmlx#template"}]},{"begin":"(?i)(\\s*(html|template|inline-html|inline-template))(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"text.html.basic"},{"include":"inline.es6-htmlx#template"},{"include":"string.quoted.other.template.js"}]},{"begin":"(?i)(?<=\\s|\\,|\\=|\\:|\\(|\\$\\()\\s{0,}(((\\/\\*)|(\\/\\/))\\s?(html|template|inline-html|inline-template)[ ]{0,1000}\\*?\\/?)[ ]{0,1000}$","beginCaptures":{"1":{"name":"comment.line"}},"end":"(`).*","patterns":[{"begin":"(\\G)","end":"(`)"},{"include":"source.ts#template-substitution-element"},{"include":"text.html.basic"}]},{"begin":"(\\${)","beginCaptures":{"1":{"name":"entity.name.tag"}},"end":"(})","endCaptures":{"1":{"name":"entity.name.tag"}},"patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.js"}]},{"begin":"(\\$\\(`)","beginCaptures":{"1":{"name":"entity.name.tag"}},"end":"(`\\))","endCaptures":{"1":{"name":"entity.name.tag"}},"patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.js"}]}],"scopeName":"inline.es6-html"} 2 | -------------------------------------------------------------------------------- /resources/grammars/es-tag-sql.json: -------------------------------------------------------------------------------- 1 | {"fileTypes":["js","jsx","ts","tsx","html","vue","svelte","php","res"],"injectTo":["source.ts","source.js"],"injectionSelector":"L:source.js -comment -string, L:source.jsx -comment -string, L:source.js.jsx -comment -string, L:source.ts -comment -string, L:source.tsx -comment -string, L:source.rescript -comment -string","injections":{"L:source":{"patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"es-tag-sql","patterns":[{"begin":"(?i)\\b(\\w+\\.sql)\\s*(`)","beginCaptures":{"1":{"name":"variable.parameter"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.ts#string-character-escape"},{"include":"source.sql"},{"include":"source.plpgsql.postgres"},{"match":"."}]},{"begin":"(?i)(\\s?\\/?\\*?\\s?(sql|inline-sql)\\s?\\*?\\/?\\s?)(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"source.ts#template-substitution-element"},{"include":"source.ts#string-character-escape"},{"include":"source.sql"},{"include":"source.plpgsql.postgres"},{"match":"."}]},{"begin":"(?i)(?<=\\s|\\,|\\=|\\:|\\(|\\$\\()\\s{0,}(((\\/\\*)|(\\/\\/))\\s?(sql|inline-sql)[ ]{0,1000}\\*?\\/?)[ ]{0,1000}$","beginCaptures":{"1":{"name":"comment.line"}},"end":"(`)","patterns":[{"begin":"(\\G)","end":"(`)"},{"include":"source.ts#template-substitution-element"},{"include":"source.ts#string-character-escape"},{"include":"source.sql"},{"include":"source.plpgsql.postgres"},{"match":"."}]}],"scopeName":"inline.es6-sql"} 2 | -------------------------------------------------------------------------------- /resources/grammars/es-tag-xml.json: -------------------------------------------------------------------------------- 1 | {"fileTypes":["js","jsx","ts","tsx","html","vue","svelte","php","res"],"injectTo":["source.ts","source.js"],"injectionSelector":"L:source.js -comment -string, L:source.js -comment -string, L:source.jsx -comment -string, L:source.js.jsx -comment -string, L:source.ts -comment -string, L:source.tsx -comment -string, L:source.rescript -comment -string","injections":{"L:source":{"patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"es-tag-xml","patterns":[{"begin":"(?i)(\\s?\\/\\*\\s?(xml|svg|inline-svg|inline-xml)\\s?\\*\\/\\s?)(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"text.xml"}]},{"begin":"(?i)(\\s*(xml|inline-xml))(`)","beginCaptures":{"1":{"name":"comment.block"}},"end":"(`)","patterns":[{"include":"text.xml"}]},{"begin":"(?i)(?<=\\s|\\,|\\=|\\:|\\(|\\$\\()\\s{0,}(((\\/\\*)|(\\/\\/))\\s?(xml|svg|inline-svg|inline-xml)[ ]{0,1000}\\*?\\/?)[ ]{0,1000}$","beginCaptures":{"1":{"name":"comment.line"}},"end":"(`).*","patterns":[{"begin":"(\\G)","end":"(`)"},{"include":"text.xml"}]}],"scopeName":"inline.es6-xml"} 2 | -------------------------------------------------------------------------------- /resources/grammars/fluent.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Fluent","name":"fluent","patterns":[{"include":"#comment"},{"include":"#message"},{"include":"#wrong-line"}],"repository":{"attributes":{"begin":"\\s*(\\.[a-zA-Z][a-zA-Z0-9_-]*\\s*=\\s*)","beginCaptures":{"1":{"name":"support.class.attribute-begin.fluent"}},"end":"^(?=\\s*[^\\.])","patterns":[{"include":"#placeable"}]},"comment":{"match":"^##?#?\\s.*$","name":"comment.fluent"},"function-comma":{"match":",","name":"support.function.function-comma.fluent"},"function-named-argument":{"begin":"([a-zA-Z0-9]+:)\\s*([\"a-zA-Z0-9]+)","beginCaptures":{"1":{"name":"support.function.named-argument.name.fluent"},"2":{"name":"variable.other.named-argument.value.fluent"}},"end":"(?=\\)|,|\\s)","name":"variable.other.named-argument.fluent"},"function-positional-argument":{"match":"\\$[a-zA-Z0-9_-]+","name":"variable.other.function.positional-argument.fluent"},"invalid-placeable-string-missing-end-quote":{"match":"\"[^\"]+$","name":"invalid.illegal.wrong-placeable-missing-end-quote.fluent"},"invalid-placeable-wrong-placeable-missing-end":{"match":"([^}A-Z]*$|[^-][^>]$)\\b","name":"invalid.illegal.wrong-placeable-missing-end.fluent"},"message":{"begin":"^(-?[a-zA-Z][a-zA-Z0-9_-]*\\s*=\\s*)","beginCaptures":{"1":{"name":"support.class.message-identifier.fluent"}},"contentName":"string.fluent","end":"^(?=\\S)","patterns":[{"include":"#attributes"},{"include":"#placeable"}]},"placeable":{"begin":"({)","beginCaptures":{"1":{"name":"keyword.placeable.begin.fluent"}},"contentName":"variable.other.placeable.content.fluent","end":"(})","endCaptures":{"1":{"name":"keyword.placeable.end.fluent"}},"patterns":[{"include":"#placeable-string"},{"include":"#placeable-function"},{"include":"#placeable-reference-or-number"},{"include":"#selector"},{"include":"#invalid-placeable-wrong-placeable-missing-end"},{"include":"#invalid-placeable-string-missing-end-quote"},{"include":"#invalid-placeable-wrong-function-name"}]},"placeable-function":{"begin":"([A-Z][A-Z0-9_-]*\\()","beginCaptures":{"1":{"name":"support.function.placeable-function.call.begin.fluent"}},"contentName":"string.placeable-function.fluent","end":"(\\))","endCaptures":{"1":{"name":"support.function.placeable-function.call.end.fluent"}},"patterns":[{"include":"#function-comma"},{"include":"#function-positional-argument"},{"include":"#function-named-argument"}]},"placeable-reference-or-number":{"match":"((-|\\$)[a-zA-Z0-9_-]+|[a-zA-Z][a-zA-Z0-9_-]*|[0-9]+)","name":"variable.other.placeable.reference-or-number.fluent"},"placeable-string":{"begin":"(\")(?=[^\\n]*\")","beginCaptures":{"1":{"name":"variable.other.placeable-string-begin.fluent"}},"contentName":"string.placeable-string-content.fluent","end":"(\")","endCaptures":{"1":{"name":"variable.other.placeable-string-end.fluent"}}},"selector":{"begin":"(->)","beginCaptures":{"1":{"name":"support.function.selector.begin.fluent"}},"contentName":"string.selector.content.fluent","end":"^(?=\\s*})","patterns":[{"include":"#selector-item"}]},"selector-item":{"begin":"(\\s*\\*?\\[)([a-zA-Z0-9_-]+)(\\]\\s*)","beginCaptures":{"1":{"name":"support.function.selector-item.begin.fluent"},"2":{"name":"variable.other.selector-item.begin.fluent"},"3":{"name":"support.function.selector-item.begin.fluent"}},"contentName":"string.selector-item.content.fluent","end":"^(?=(\\s*})|(\\s*\\[)|(\\s*\\*))","patterns":[{"include":"#placeable"}]},"wrong-line":{"match":".*","name":"invalid.illegal.wrong-line.fluent"}},"scopeName":"source.ftl"} 2 | -------------------------------------------------------------------------------- /resources/grammars/fortran-fixed-form.json: -------------------------------------------------------------------------------- 1 | {"comment":"Inherits rules from free form Fortran.","displayName":"Fortran (Fixed Form)","fileTypes":["f","F","f77","F77","for","FOR"],"injections":{"source.fortran.fixed - ( string | comment )":{"patterns":[{"include":"#line-header"},{"include":"#line-end-comment"}]}},"name":"fortran-fixed-form","patterns":[{"include":"#comments"},{"include":"#line-header"},{"include":"source.fortran.free"}],"repository":{"comments":{"patterns":[{"begin":"^[cC\\*]","end":"\\n","name":"comment.line.fortran"},{"begin":"^ *!","end":"\\n","name":"comment.line.fortran"}]},"line-end-comment":{"begin":"(?<=^.{72})(?!\\n)","end":"(?=\\n)","name":"comment.line-end.fortran"},"line-header":{"captures":{"1":{"name":"constant.numeric.fortran"},"2":{"name":"keyword.line-continuation-operator.fortran"},"3":{"name":"source.fortran.free"},"4":{"name":"invalid.error.fortran"}},"match":"^(?!\\s*[!#])(?:([ \\d]{5} )|( {5}.)|(\\t)|(.{1,5}))"}},"scopeName":"source.fortran.fixed"} 2 | -------------------------------------------------------------------------------- /resources/grammars/genie.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Genie","fileTypes":["gs"],"name":"genie","patterns":[{"include":"#code"}],"repository":{"code":{"patterns":[{"include":"#comments"},{"include":"#constants"},{"include":"#strings"},{"include":"#keywords"},{"include":"#types"},{"include":"#functions"},{"include":"#variables"}]},"comments":{"patterns":[{"captures":{"0":{"name":"punctuation.definition.comment.vala"}},"match":"/\\*\\*/","name":"comment.block.empty.vala"},{"include":"text.html.javadoc"},{"include":"#comments-inline"}]},"comments-inline":{"patterns":[{"begin":"/\\*","captures":{"0":{"name":"punctuation.definition.comment.vala"}},"end":"\\*/","name":"comment.block.vala"},{"captures":{"1":{"name":"comment.line.double-slash.vala"},"2":{"name":"punctuation.definition.comment.vala"}},"match":"\\s*((//).*$\\n?)"}]},"constants":{"patterns":[{"match":"\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)([LlFfUuDd]|UL|ul)?\\b","name":"constant.numeric.vala"},{"match":"\\b([A-Z][A-Z0-9_]+)\\b","name":"variable.other.constant.vala"}]},"functions":{"patterns":[{"match":"(\\w+)(?=\\s*(<[\\s\\w.]+>\\s*)?\\()","name":"entity.name.function.vala"}]},"keywords":{"patterns":[{"match":"(?<=^|[^@\\w\\.])(as|do|if|in|is|of|or|to|and|def|for|get|isa|new|not|out|ref|set|try|var|case|dict|else|enum|init|list|lock|null|pass|prop|self|true|uses|void|weak|when|array|async|break|class|const|event|false|final|owned|print|super|raise|while|yield|assert|delete|downto|except|extern|inline|params|public|raises|return|sealed|sizeof|static|struct|typeof|default|dynamic|ensures|finally|private|unowned|virtual|abstract|continue|delegate|internal|override|readonly|requires|volatile|construct|errordomain|interface|namespace|protected|implements)\\b","name":"keyword.vala"},{"match":"(?<=^|[^@\\w\\.])(bool|double|float|unichar|char|uchar|int|uint|long|ulong|short|ushort|size_t|ssize_t|string|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b","name":"keyword.vala"},{"match":"(#if|#elif|#else|#endif)","name":"keyword.vala"}]},"strings":{"patterns":[{"begin":"\"\"\"","end":"\"\"\"","name":"string.quoted.triple.vala"},{"begin":"@\"","end":"\"","name":"string.quoted.interpolated.vala","patterns":[{"match":"\\\\.","name":"constant.character.escape.vala"},{"match":"\\$\\w+","name":"constant.character.escape.vala"},{"match":"\\$\\(([^)(]|\\(([^)(]|\\([^)]*\\))*\\))*\\)","name":"constant.character.escape.vala"}]},{"begin":"\"","end":"\"","name":"string.quoted.double.vala","patterns":[{"match":"\\\\.","name":"constant.character.escape.vala"}]},{"begin":"'","end":"'","name":"string.quoted.single.vala","patterns":[{"match":"\\\\.","name":"constant.character.escape.vala"}]},{"match":"/((\\\\/)|([^/]))*/(?=\\s*[,;)\\.\\n])","name":"string.regexp.vala"}]},"types":{"patterns":[{"match":"(?<=^|[^@\\w\\.])(bool|double|float|unichar|char|uchar|int|uint|long|ulong|short|ushort|size_t|ssize_t|string|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b","name":"storage.type.primitive.vala"},{"match":"\\b([A-Z]+\\w*)\\b","name":"entity.name.type.vala"}]},"variables":{"patterns":[{"match":"\\b([_a-z]+\\w*)\\b","name":"variable.other.vala"}]}},"scopeName":"source.genie","uuid":"b1e902c2-7248-400a-a6e6-666f250eadb1"} 2 | -------------------------------------------------------------------------------- /resources/grammars/git-commit.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Git Commit Message","information_for_contributors":["This file has been converted from https://github.com/walles/git-commit-message-plus/blob/master/syntaxes/git-commit.tmLanguage.json","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"name":"git-commit","patterns":[{"begin":"(?=^diff\\ \\-\\-git)","comment":"diff presented at the end of the commit message when using commit -v.","contentName":"source.diff","end":"\\z","name":"meta.embedded.diff.git-commit","patterns":[{"include":"source.diff"}]},{"begin":"^(?!#)","comment":"User supplied message","end":"^(?=#)","name":"meta.scope.message.git-commit","patterns":[{"captures":{"1":{"name":"invalid.deprecated.line-too-long.git-commit"},"2":{"name":"invalid.illegal.line-too-long.git-commit"}},"comment":"Mark > 50 lines as deprecated, > 72 as illegal","match":"\\G.{0,50}(.{0,22}(.*))$","name":"meta.scope.subject.git-commit"}]},{"begin":"^(?=#)","comment":"Git supplied metadata in a number of lines starting with #","contentName":"comment.line.number-sign.git-commit","end":"^(?!#)","name":"meta.scope.metadata.git-commit","patterns":[{"captures":{"1":{"name":"markup.changed.git-commit"}},"match":"^#\\t((modified|renamed):.*)$"},{"captures":{"1":{"name":"markup.inserted.git-commit"}},"match":"^#\\t(new file:.*)$"},{"captures":{"1":{"name":"markup.deleted.git-commit"}},"match":"^#\\t(deleted.*)$"},{"captures":{"1":{"name":"keyword.other.file-type.git-commit"},"2":{"name":"string.unquoted.filename.git-commit"}},"comment":"Fallback for non-English git commit template","match":"^#\\t([^:]+): *(.*)$"}]}],"scopeName":"text.git-commit","version":"https://github.com/walles/git-commit-message-plus/commit/35a079dea5a91b087021b40c01a6bb4eb0337a87"} 2 | -------------------------------------------------------------------------------- /resources/grammars/git-rebase.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Git Rebase Message","information_for_contributors":["This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Rebase%20Message.tmLanguage","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"name":"git-rebase","patterns":[{"captures":{"1":{"name":"punctuation.definition.comment.git-rebase"}},"match":"^\\s*(#).*$\\n?","name":"comment.line.number-sign.git-rebase"},{"captures":{"1":{"name":"support.function.git-rebase"},"2":{"name":"constant.sha.git-rebase"},"3":{"name":"meta.commit-message.git-rebase"}},"match":"^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|drop|d)\\s+([0-9a-f]+)\\s+(.*)$","name":"meta.commit-command.git-rebase"},{"captures":{"1":{"name":"support.function.git-rebase"},"2":{"patterns":[{"include":"source.shell"}]}},"match":"^\\s*(exec|x)\\s+(.*)$","name":"meta.commit-command.git-rebase"},{"captures":{"1":{"name":"support.function.git-rebase"}},"match":"^\\s*(break|b)\\s*$","name":"meta.commit-command.git-rebase"}],"scopeName":"text.git-rebase","version":"https://github.com/textmate/git.tmbundle/commit/5870cf3f8abad3a6637bdf69250b5d2ded427dc4"} 2 | -------------------------------------------------------------------------------- /resources/grammars/gleam.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Gleam","fileTypes":["gleam"],"name":"gleam","patterns":[{"include":"#comments"},{"include":"#keywords"},{"include":"#strings"},{"include":"#constant"},{"include":"#entity"},{"include":"#discards"}],"repository":{"binary_number":{"match":"\\b0[bB][01_]*\\b","name":"constant.numeric.binary.gleam","patterns":[]},"comments":{"patterns":[{"match":"//.*","name":"comment.line.gleam"}]},"constant":{"patterns":[{"include":"#binary_number"},{"include":"#octal_number"},{"include":"#hexadecimal_number"},{"include":"#decimal_number"},{"match":"[[:upper:]][[:alnum:]]*","name":"entity.name.type.gleam"}]},"decimal_number":{"match":"\\b([0-9][0-9_]*)(\\.([0-9_]*)?(e-?[0-9]+)?)?\\b","name":"constant.numeric.decimal.gleam","patterns":[]},"discards":{"match":"\\b_(?:[[:word:]]+)?\\b","name":"comment.unused.gleam"},"entity":{"patterns":[{"begin":"\\b([[:lower:]][[:word:]]*)\\b[[:space:]]*\\(","captures":{"1":{"name":"entity.name.function.gleam"}},"end":"\\)","patterns":[{"include":"$self"}]},{"match":"\\b([[:lower:]][[:word:]]*):\\s","name":"variable.parameter.gleam"},{"match":"\\b([[:lower:]][[:word:]]*):","name":"entity.name.namespace.gleam"}]},"hexadecimal_number":{"match":"\\b0[xX][0-9a-fA-F_]+\\b","name":"constant.numeric.hexadecimal.gleam","patterns":[]},"keywords":{"patterns":[{"match":"\\b(as|use|case|if|fn|import|let|assert|pub|type|opaque|const|todo|panic|else|echo)\\b","name":"keyword.control.gleam"},{"match":"(<\\-|\\->)","name":"keyword.operator.arrow.gleam"},{"match":"\\|>","name":"keyword.operator.pipe.gleam"},{"match":"\\.\\.","name":"keyword.operator.splat.gleam"},{"match":"(==|!=)","name":"keyword.operator.comparison.gleam"},{"match":"(<=\\.|>=\\.|<\\.|>\\.)","name":"keyword.operator.comparison.float.gleam"},{"match":"(<=|>=|<|>)","name":"keyword.operator.comparison.int.gleam"},{"match":"(&&|\\|\\|)","name":"keyword.operator.logical.gleam"},{"match":"<>","name":"keyword.operator.string.gleam"},{"match":"\\|","name":"keyword.operator.other.gleam"},{"match":"(\\+\\.|\\-\\.|/\\.|\\*\\.)","name":"keyword.operator.arithmetic.float.gleam"},{"match":"(\\+|\\-|/|\\*|%)","name":"keyword.operator.arithmetic.int.gleam"},{"match":"=","name":"keyword.operator.assignment.gleam"}]},"octal_number":{"match":"\\b0[oO][0-7_]*\\b","name":"constant.numeric.octal.gleam","patterns":[]},"strings":{"begin":"\"","end":"\"","name":"string.quoted.double.gleam","patterns":[{"match":"\\\\.","name":"constant.character.escape.gleam"}]}},"scopeName":"source.gleam"} 2 | -------------------------------------------------------------------------------- /resources/grammars/html-derivative.json: -------------------------------------------------------------------------------- 1 | {"displayName":"HTML (Derivative)","information_for_contributors":["This file has been converted from https://github.com/textmate/html.tmbundle/blob/master/Syntaxes/HTML%20%28Derivative%29.tmLanguage","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"injections":{"R:text.html - (comment.block, text.html meta.embedded, meta.tag.*.*.html, meta.tag.*.*.*.html, meta.tag.*.*.*.*.html)":{"comment":"Uses R: to ensure this matches after any other injections.","patterns":[{"match":"<","name":"invalid.illegal.bad-angle-bracket.html"}]}},"name":"html-derivative","patterns":[{"include":"text.html.basic#core-minus-invalid"},{"begin":"(]*)(?)","endCaptures":{"1":{"name":"punctuation.definition.tag.end.html"}},"name":"meta.tag.other.unrecognized.html.derivative","patterns":[{"include":"text.html.basic#attribute"}]}],"scopeName":"text.html.derivative","version":"https://github.com/textmate/html.tmbundle/commit/390c8870273a2ae80244dae6db6ba064a802f407"} 2 | -------------------------------------------------------------------------------- /resources/grammars/hxml.json: -------------------------------------------------------------------------------- 1 | {"displayName":"HXML","fileTypes":["hxml"],"foldingStartMarker":"--next","foldingStopMarker":"\\n\\n","keyEquivalent":"^@H","name":"hxml","patterns":[{"captures":{"1":{"name":"punctuation.definition.comment.hxml"}},"match":"(#).*$\\n?","name":"comment.line.number-sign.hxml"},{"begin":"(?*])(abs|all|any|ascii|bin|breakpoint|callable|chr|compile|delattr|dir|divmod|eval|exec|format|getattr|globals|hasattr|hash|hex|id|input|isinstance|issubclass|iter|aiter|len|locals|max|min|next|anext|oct|ord|pow|print|repr|round|setattr|sorted|sum|vars|False|None|True|NotImplemented|bool|memoryview|bytearray|bytes|classmethod|complex|dict|enumerate|filter|float|frozenset|property|int|list|map|object|range|reversed|set|slice|staticmethod|str|super|tuple|type|zip|open|quit|exit|copyright|credits|help)(?![\\.:\\w_\\-=!@\\$%^&?/<>*])","name":"storage.builtin.hy"},{"match":"(?<=\\(\\s*)\\.\\.\\.(?![\\.:\\w_\\-=!@\\$%^&?/<>*])","name":"storage.builtin.dots.hy"}]},"comment":{"patterns":[{"match":"(;).*$","name":"comment.line.hy"}]},"constants":{"patterns":[{"match":"(?<=[\\{\\[\\(\\s])([0-9]+(\\.[0-9]+)?|(#x)[0-9a-fA-F]+|(#o)[0-7]+|(#b)[01]+)(?=[\\s;()'\",\\[\\]\\{\\}])","name":"constant.numeric.hy"}]},"keysym":{"match":"(?*]):[\\.:\\w_\\-=!@\\$%^&?\\/<>*]*","name":"variable.other.constant"},"keywords":{"patterns":[{"match":"(?*])(and|await|match|let|annotate|assert|break|chainc|cond|continue|deftype|do|except\\*?|finally|else|defreader|([dgls])?for|set[vx]|defclass|defmacro|del|export|eval-and-compile|eval-when-compile|get|global|if|import|(de)?fn|nonlocal|not-in|or|(quasi)?quote|require|return|cut|raise|try|unpack-iterable|unpack-mapping|unquote|unquote-splice|when|while|with|yield|local-macros|in|is|py(s)?|pragma|nonlocal|(is-)?not)(?![\\.:\\w_\\-=!@\\$%^&?/<>*])","name":"keyword.control.hy"},{"match":"(?<=\\(\\s*)\\.(?![\\.:\\w_\\-=!@\\$%^&?/<>*])","name":"keyword.control.dot.hy"}]},"operators":{"patterns":[{"match":"(?*])(\\+=?|\\/\\/?=?|\\*\\*?=?|--?=?|[!<>]?=|@=?|%=?|<>?=?|&=?|\\|=?|\\^|~@|~=?|#\\*\\*?)(?![\\.:\\w_\\-=!@\\$%^&?/<>*])","name":"keyword.control.hy"}]},"strings":{"begin":"(f?\"|}(?=[^\n]*?[{\"]))","end":"(\"|(?<=[\"}][^\n]*?){)","name":"string.quoted.double.hy","patterns":[{"match":"\\\\.","name":"constant.character.escape.hy"}]},"symbol":{"match":"(?*#])[\\.a-zA-ZΑ-Ωα-ω_\\-=!@\\$%^*#][\\.:\\w_\\-=!@\\$%^&?/<>*#]*","name":"variable.other.hy"}},"scopeName":"source.hy"} 2 | -------------------------------------------------------------------------------- /resources/grammars/ini.json: -------------------------------------------------------------------------------- 1 | {"displayName":"INI","information_for_contributors":["This file has been converted from https://github.com/textmate/ini.tmbundle/blob/master/Syntaxes/Ini.plist","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"name":"ini","patterns":[{"begin":"(^[ \\t]+)?(?=#)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.ini"}},"end":"(?!\\G)","patterns":[{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.ini"}},"end":"\\n","name":"comment.line.number-sign.ini"}]},{"begin":"(^[ \\t]+)?(?=;)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.ini"}},"end":"(?!\\G)","patterns":[{"begin":";","beginCaptures":{"0":{"name":"punctuation.definition.comment.ini"}},"end":"\\n","name":"comment.line.semicolon.ini"}]},{"captures":{"1":{"name":"keyword.other.definition.ini"},"2":{"name":"punctuation.separator.key-value.ini"}},"match":"\\b([a-zA-Z0-9_.-]+)\\b\\s*(=)"},{"captures":{"1":{"name":"punctuation.definition.entity.ini"},"3":{"name":"punctuation.definition.entity.ini"}},"match":"^(\\[)(.*?)(\\])","name":"entity.name.section.group-title.ini"},{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.ini"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.ini"}},"name":"string.quoted.single.ini","patterns":[{"match":"\\\\.","name":"constant.character.escape.ini"}]},{"begin":"\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.ini"}},"end":"\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.ini"}},"name":"string.quoted.double.ini"}],"scopeName":"source.ini","version":"https://github.com/textmate/ini.tmbundle/commit/2af0cbb0704940f967152616f2f1ff0aae6287a6"} 2 | -------------------------------------------------------------------------------- /resources/grammars/jinja-html.json: -------------------------------------------------------------------------------- 1 | {"comment":"Jinja HTML Templates","displayName":"jinja-html","firstLineMatch":"^{% extends [\"'][^\"']+[\"'] %}","foldingStartMarker":"(<(?i:(head|table|tr|div|style|script|ul|ol|form|dl))\\b.*?>|{%\\s*(block|filter|for|if|macro|raw))","foldingStopMarker":"(|{%\\s*(endblock|endfilter|endfor|endif|endmacro|endraw)\\s*%})","name":"jinja-html","patterns":[{"include":"source.jinja"},{"include":"text.html.basic"}],"scopeName":"text.html.jinja"} 2 | -------------------------------------------------------------------------------- /resources/grammars/jsonnet.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Jsonnet","name":"jsonnet","patterns":[{"include":"#expression"},{"include":"#keywords"}],"repository":{"builtin-functions":{"patterns":[{"match":"\\bstd[.](acos|asin|atan|ceil|char|codepoint|cos|exp|exponent)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](filter|floor|force|length|log|makeArray|mantissa)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](objectFields|objectHas|pow|sin|sqrt|tan|type|thisFile)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](acos|asin|atan|ceil|char|codepoint|cos|exp|exponent)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](abs|assertEqual|escapeString(Bash|Dollars|Json|Python))\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](filterMap|flattenArrays|foldl|foldr|format|join)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](lines|manifest(Ini|Python(Vars)?)|map|max|min|mod)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](set|set(Diff|Inter|Member|Union)|sort)\\b","name":"support.function.jsonnet"},{"match":"\\bstd[.](range|split|stringChars|substr|toString|uniq)\\b","name":"support.function.jsonnet"}]},"comment":{"patterns":[{"begin":"/\\*","end":"\\*/","name":"comment.block.jsonnet"},{"match":"//.*$","name":"comment.line.jsonnet"},{"match":"#.*$","name":"comment.block.jsonnet"}]},"double-quoted-strings":{"begin":"\"","end":"\"","name":"string.quoted.double.jsonnet","patterns":[{"match":"\\\\([\"\\\\/bfnrt]|(u[0-9a-fA-F]{4}))","name":"constant.character.escape.jsonnet"},{"match":"\\\\[^\"\\\\/bfnrtu]","name":"invalid.illegal.jsonnet"}]},"expression":{"patterns":[{"include":"#literals"},{"include":"#comment"},{"include":"#single-quoted-strings"},{"include":"#double-quoted-strings"},{"include":"#triple-quoted-strings"},{"include":"#builtin-functions"},{"include":"#functions"}]},"functions":{"patterns":[{"begin":"\\b([a-zA-Z_][a-z0-9A-Z_]*)\\s*\\(","beginCaptures":{"1":{"name":"entity.name.function.jsonnet"}},"end":"\\)","name":"meta.function","patterns":[{"include":"#expression"}]}]},"keywords":{"patterns":[{"match":"[!:~\\+\\-&\\|\\^=<>\\*\\/%]","name":"keyword.operator.jsonnet"},{"match":"\\$","name":"keyword.other.jsonnet"},{"match":"\\b(self|super|import|importstr|local|tailstrict)\\b","name":"keyword.other.jsonnet"},{"match":"\\b(if|then|else|for|in|error|assert)\\b","name":"keyword.control.jsonnet"},{"match":"\\b(function)\\b","name":"storage.type.jsonnet"},{"match":"[a-zA-Z_][a-z0-9A-Z_]*\\s*(:::|\\+:::)","name":"variable.parameter.jsonnet"},{"match":"[a-zA-Z_][a-z0-9A-Z_]*\\s*(::|\\+::)","name":"entity.name.type"},{"match":"[a-zA-Z_][a-z0-9A-Z_]*\\s*(:|\\+:)","name":"variable.parameter.jsonnet"}]},"literals":{"patterns":[{"match":"\\b(true|false|null)\\b","name":"constant.language.jsonnet"},{"match":"\\b(\\d+([Ee][+-]?\\d+)?)\\b","name":"constant.numeric.jsonnet"},{"match":"\\b\\d+[.]\\d*([Ee][+-]?\\d+)?\\b","name":"constant.numeric.jsonnet"},{"match":"\\b[.]\\d+([Ee][+-]?\\d+)?\\b","name":"constant.numeric.jsonnet"}]},"single-quoted-strings":{"begin":"'","end":"'","name":"string.quoted.double.jsonnet","patterns":[{"match":"\\\\(['\\\\/bfnrt]|(u[0-9a-fA-F]{4}))","name":"constant.character.escape.jsonnet"},{"match":"\\\\[^'\\\\/bfnrtu]","name":"invalid.illegal.jsonnet"}]},"triple-quoted-strings":{"patterns":[{"begin":"\\|\\|\\|","end":"\\|\\|\\|","name":"string.quoted.triple.jsonnet"}]}},"scopeName":"source.jsonnet"} 2 | -------------------------------------------------------------------------------- /resources/grammars/jssm.json: -------------------------------------------------------------------------------- 1 | {"displayName":"JSSM","fileTypes":["jssm","jssm_state"],"name":"jssm","patterns":[{"begin":"/\\*","captures":{"0":{"name":"punctuation.definition.comment.mn"}},"comment":"block comment","end":"\\*/","name":"comment.block.jssm"},{"begin":"//","comment":"block comment","end":"$","name":"comment.line.jssm"},{"begin":"\\${","captures":{"0":{"name":"entity.name.function"}},"comment":"js outcalls","end":"}","name":"keyword.other"},{"comment":"semver","match":"([0-9]*)(\\.)([0-9]*)(\\.)([0-9]*)","name":"constant.numeric"},{"comment":"jssm language tokens","match":"graph_layout(\\s*)(:)","name":"constant.language.jssmLanguage"},{"comment":"jssm language tokens","match":"machine_name(\\s*)(:)","name":"constant.language.jssmLanguage"},{"comment":"jssm language tokens","match":"machine_version(\\s*)(:)","name":"constant.language.jssmLanguage"},{"comment":"jssm language tokens","match":"jssm_version(\\s*)(:)","name":"constant.language.jssmLanguage"},{"comment":"transitions","match":"<->","name":"keyword.control.transition.jssmArrow.legal_legal"},{"comment":"transitions","match":"<-","name":"keyword.control.transition.jssmArrow.legal_none"},{"comment":"transitions","match":"->","name":"keyword.control.transition.jssmArrow.none_legal"},{"comment":"transitions","match":"<=>","name":"keyword.control.transition.jssmArrow.main_main"},{"comment":"transitions","match":"=>","name":"keyword.control.transition.jssmArrow.none_main"},{"comment":"transitions","match":"<=","name":"keyword.control.transition.jssmArrow.main_none"},{"comment":"transitions","match":"<~>","name":"keyword.control.transition.jssmArrow.forced_forced"},{"comment":"transitions","match":"~>","name":"keyword.control.transition.jssmArrow.none_forced"},{"comment":"transitions","match":"<~","name":"keyword.control.transition.jssmArrow.forced_none"},{"comment":"transitions","match":"<-=>","name":"keyword.control.transition.jssmArrow.legal_main"},{"comment":"transitions","match":"<=->","name":"keyword.control.transition.jssmArrow.main_legal"},{"comment":"transitions","match":"<-~>","name":"keyword.control.transition.jssmArrow.legal_forced"},{"comment":"transitions","match":"<~->","name":"keyword.control.transition.jssmArrow.forced_legal"},{"comment":"transitions","match":"<=~>","name":"keyword.control.transition.jssmArrow.main_forced"},{"comment":"transitions","match":"<~=>","name":"keyword.control.transition.jssmArrow.forced_main"},{"comment":"edge probability annotation","match":"([0-9]+)%","name":"constant.numeric.jssmProbability"},{"comment":"action annotation","match":"\\'[^']*\\'","name":"constant.character.jssmAction"},{"comment":"jssm label annotation","match":"\\\"[^\"]*\\\"","name":"entity.name.tag.jssmLabel.doublequoted"},{"comment":"jssm label annotation","match":"([a-zA-Z0-9_.+&()#@!?,])","name":"entity.name.tag.jssmLabel.atom"}],"scopeName":"source.jssm","uuid":"2bb22b55-e811-4383-9929-ae6d0ab92aca"} 2 | -------------------------------------------------------------------------------- /resources/grammars/log.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Log file","fileTypes":["log"],"name":"log","patterns":[{"match":"\\b([Tt]race|TRACE)\\b:?","name":"comment log.verbose"},{"match":"(?i)\\[(verbose|verb|vrb|vb|v)\\]","name":"comment log.verbose"},{"match":"(?<=^[\\s\\d\\p]*)\\bV\\b","name":"comment log.verbose"},{"match":"\\b(DEBUG|Debug)\\b|(?i)\\b(debug)\\:","name":"markup.changed log.debug"},{"match":"(?i)\\[(debug|dbug|dbg|de|d)\\]","name":"markup.changed log.debug"},{"match":"(?<=^[\\s\\d\\p]*)\\bD\\b","name":"markup.changed log.debug"},{"match":"\\b(HINT|INFO|INFORMATION|Info|NOTICE|II)\\b|(?i)\\b(info|information)\\:","name":"markup.inserted log.info"},{"match":"(?i)\\[(information|info|inf|in|i)\\]","name":"markup.inserted log.info"},{"match":"(?<=^[\\s\\d\\p]*)\\bI\\b","name":"markup.inserted log.info"},{"match":"\\b(WARNING|WARN|Warn|WW)\\b|(?i)\\b(warning)\\:","name":"markup.deleted log.warning"},{"match":"(?i)\\[(warning|warn|wrn|wn|w)\\]","name":"markup.deleted log.warning"},{"match":"(?<=^[\\s\\d\\p]*)\\bW\\b","name":"markup.deleted log.warning"},{"match":"\\b(ALERT|CRITICAL|EMERGENCY|ERROR|FAILURE|FAIL|Fatal|FATAL|Error|EE)\\b|(?i)\\b(error)\\:","name":"string.regexp, strong log.error"},{"match":"(?i)\\[(error|eror|err|er|e|fatal|fatl|ftl|fa|f)\\]","name":"string.regexp, strong log.error"},{"match":"(?<=^[\\s\\d\\p]*)\\bE\\b","name":"string.regexp, strong log.error"},{"match":"\\b\\d{4}-\\d{2}-\\d{2}(?=T|\\b)","name":"comment log.date"},{"match":"(?<=(^|\\s))\\d{2}[^\\w\\s]\\d{2}[^\\w\\s]\\d{4}\\b","name":"comment log.date"},{"match":"T?\\d{1,2}:\\d{2}(:\\d{2}([.,]\\d{1,})?)?(Z| ?[+-]\\d{1,2}:\\d{2})?\\b","name":"comment log.date"},{"match":"T\\d{2}\\d{2}(\\d{2}([.,]\\d{1,})?)?(Z| ?[+-]\\d{1,2}\\d{2})?\\b","name":"comment log.date"},{"match":"\\b([0-9a-fA-F]{40}|[0-9a-fA-F]{10}|[0-9a-fA-F]{7})\\b","name":"constant.language"},{"match":"\\b[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}\\b","name":"constant.language log.constant"},{"match":"\\b([0-9a-fA-F]{2,}[:-])+[0-9a-fA-F]{2,}+\\b","name":"constant.language log.constant"},{"match":"\\b([0-9]+|true|false|null)\\b","name":"constant.language log.constant"},{"match":"\\b(0x[a-fA-F0-9]+)\\b","name":"constant.language log.constant"},{"match":"\"[^\"]*\"","name":"string log.string"},{"match":"(?","displayName":"Logo","fileTypes":[],"keyEquivalent":"^~L","name":"logo","patterns":[{"match":"^to [\\w.]+","name":"entity.name.function.logo"},{"match":"continue|do\\.until|do\\.while|end|for(each)?|if(else|falsetrue|)|repeat|stop|until","name":"keyword.control.logo"},{"match":"\\b(\\.defmacro|\\.eq|\\.macro|\\.maybeoutput|\\.setbf|\\.setfirst|\\.setitem|\\.setsegmentsize|allopen|allowgetset|and|apply|arc|arctan|arity|array|arrayp|arraytolist|ascii|ashift|back|background|backslashedp|beforep|bitand|bitnot|bitor|bitxor|buried|buriedp|bury|buryall|buryname|butfirst|butfirsts|butlast|bye|cascade|case|caseignoredp|catch|char|clean|clearscreen|cleartext|close|closeall|combine|cond|contents|copydef|cos|count|crossmap|cursor|define|definedp|dequeue|difference|dribble|edall|edit|editfile|edn|edns|edpl|edpls|edps|emptyp|eofp|epspict|equalp|erall|erase|erasefile|ern|erns|erpl|erpls|erps|erract|error|exp|fence|filep|fill|filter|find|first|firsts|forever|form|forward|fput|fullprintp|fullscreen|fulltext|gc|gensym|global|goto|gprop|greaterp|heading|help|hideturtle|home|ignore|int|invoke|iseq|item|keyp|label|last|left|lessp|list|listp|listtoarray|ln|load|loadnoisily|loadpict|local|localmake|log10|lowercase|lput|lshift|macroexpand|macrop|make|map|map.se|mdarray|mditem|mdsetitem|member|memberp|minus|modulo|name|namelist|namep|names|nodes|nodribble|norefresh|not|numberp|openappend|openread|openupdate|openwrite|or|output|palette|parse|pause|pen|pencolor|pendown|pendownp|penerase|penmode|penpaint|penreverse|pensize|penup|pick|plist|plistp|plists|pllist|po|poall|pon|pons|pop|popl|popls|pops|pos|pot|pots|power|pprop|prefix|primitivep|print|printdepthlimit|printwidthlimit|procedurep|procedures|product|push|queue|quoted|quotient|radarctan|radcos|radsin|random|rawascii|readchar|readchars|reader|readlist|readpos|readrawline|readword|redefp|reduce|refresh|remainder|remdup|remove|remprop|repcount|rerandom|reverse|right|round|rseq|run|runparse|runresult|save|savel|savepict|screenmode|scrunch|sentence|setbackground|setcursor|seteditor|setheading|sethelploc|setitem|setlibloc|setmargins|setpalette|setpen|setpencolor|setpensize|setpos|setprefix|setread|setreadpos|setscrunch|settemploc|settextcolor|setwrite|setwritepos|setx|setxy|sety|shell|show|shownp|showturtle|sin|splitscreen|sqrt|standout|startup|step|stepped|steppedp|substringp|sum|tag|test|text|textscreen|thing|throw|towards|trace|traced|tracedp|transfer|turtlemode|type|unbury|unburyall|unburyname|unburyonedit|unstep|untrace|uppercase|usealternatenam|wait|while|window|word|wordp|wrap|writepos|writer|xcor|ycor)\\b","name":"keyword.other.logo"},{"captures":{"1":{"name":"punctuation.definition.variable.logo"}},"match":"(\\:)(?:\\|[^|]*\\||[-\\w.]*)+","name":"variable.parameter.logo"},{"match":"\"(?:\\|[^|]*\\||[-\\w.]*)+","name":"string.other.word.logo"},{"begin":"(^[ \\t]+)?(?=;)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.logo"}},"end":"(?!\\G)","patterns":[{"begin":";","beginCaptures":{"0":{"name":"punctuation.definition.comment.logo"}},"end":"\\n","name":"comment.line.semicolon.logo"}]}],"scopeName":"source.logo","uuid":"7613EC24-B0F9-4D01-8706-1D54098BFFD8"} 2 | -------------------------------------------------------------------------------- /resources/grammars/markdown-vue.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","fileTypes":[],"injectTo":["text.html.markdown"],"injectionSelector":"L:text.html.markdown","name":"markdown-vue","patterns":[{"include":"#vue-code-block"}],"repository":{"vue-code-block":{"begin":"(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(vue)((\\s+|:|,|\\{|\\?)[^`~]*)?$)","beginCaptures":{"3":{"name":"punctuation.definition.markdown"},"4":{"name":"fenced_code.block.language.markdown"},"5":{"name":"fenced_code.block.language.attributes.markdown","patterns":[]}},"end":"(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$","endCaptures":{"3":{"name":"punctuation.definition.markdown"}},"name":"markup.fenced_code.block.markdown","patterns":[{"include":"source.vue"}]}},"scopeName":"markdown.vue.codeblock"} 2 | -------------------------------------------------------------------------------- /resources/grammars/mipsasm.json: -------------------------------------------------------------------------------- 1 | {"displayName":"MIPS Assembly","fileTypes":["s","mips","spim","asm"],"keyEquivalent":"^~M","name":"mipsasm","patterns":[{"comment":"ok actually this are instructions, but one also could call them funtions…","match":"\\b(mul|abs|div|divu|mulo|mulou|neg|negu|not|rem|remu|rol|ror|li|seq|sge|sgeu|sgt|sgtu|sle|sleu|sne|b|beqz|bge|bgeu|bgt|bgtu|ble|bleu|blt|bltu|bnez|la|ld|ulh|ulhu|ulw|sd|ush|usw|move|mfc1\\.d|l\\.d|l\\.s|s\\.d|s\\.s)\\b","name":"support.function.pseudo.mips"},{"match":"\\b(abs\\.d|abs\\.s|add|add\\.d|add\\.s|addi|addiu|addu|and|andi|bc1f|bc1t|beq|bgez|bgezal|bgtz|blez|bltz|bltzal|bne|break|c\\.eq\\.d|c\\.eq\\.s|c\\.le\\.d|c\\.le\\.s|c\\.lt\\.d|c\\.lt\\.s|ceil\\.w\\.d|ceil\\.w\\.s|clo|clz|cvt\\.d\\.s|cvt\\.d\\.w|cvt\\.s\\.d|cvt\\.s\\.w|cvt\\.w\\.d|cvt\\.w\\.s|div|div\\.d|div\\.s|divu|eret|floor\\.w\\.d|floor\\.w\\.s|j|jal|jalr|jr|lb|lbu|lh|lhu|ll|lui|lw|lwc1|lwl|lwr|madd|maddu|mfc0|mfc1|mfhi|mflo|mov\\.d|mov\\.s|movf|movf\\.d|movf\\.s|movn|movn\\.d|movn\\.s|movt|movt\\.d|movt\\.s|movz|movz\\.d|movz\\.s|msub|mtc0|mtc1|mthi|mtlo|mul|mul\\.d|mul\\.s|mult|multu|neg\\.d|neg\\.s|nop|nor|or|ori|round\\.w\\.d|round\\.w\\.s|sb|sc|sdc1|sh|sll|sllv|slt|slti|sltiu|sltu|sqrt\\.d|sqrt\\.s|sra|srav|srl|srlv|sub|sub\\.d|sub\\.s|subu|sw|swc1|swl|swr|syscall|teq|teqi|tge|tgei|tgeiu|tgeu|tlt|tlti|tltiu|tltu|trunc\\.w\\.d|trunc\\.w\\.s|xor|xori)\\b","name":"support.function.mips"},{"match":"\\.(ascii|asciiz|byte|data|double|float|half|kdata|ktext|space|text|word|set\\s*(noat|at))\\b","name":"storage.type.mips"},{"match":"\\.(align|extern||globl)\\b","name":"storage.modifier.mips"},{"captures":{"1":{"name":"entity.name.function.label.mips"}},"match":"\\b([A-Za-z0-9_]+):","name":"meta.function.label.mips"},{"captures":{"1":{"name":"punctuation.definition.variable.mips"}},"match":"(\\$)(0|[2-9]|1[0-9]|2[0-5]|2[89]|3[0-1])\\b","name":"variable.other.register.usable.by-number.mips"},{"captures":{"1":{"name":"punctuation.definition.variable.mips"}},"match":"(\\$)(zero|v[01]|a[0-3]|t[0-9]|s[0-7]|gp|sp|fp|ra)\\b","name":"variable.other.register.usable.by-name.mips"},{"captures":{"1":{"name":"punctuation.definition.variable.mips"}},"match":"(\\$)(at|k[01]|1|2[67])\\b","name":"variable.other.register.reserved.mips"},{"captures":{"1":{"name":"punctuation.definition.variable.mips"}},"match":"(\\$)f([0-9]|1[0-9]|2[0-9]|3[0-1])\\b","name":"variable.other.register.usable.floating-point.mips"},{"match":"\\b\\d+\\.\\d+\\b","name":"constant.numeric.float.mips"},{"match":"\\b(\\d+|0(x|X)[a-fA-F0-9]+)\\b","name":"constant.numeric.integer.mips"},{"begin":"\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.mips"}},"end":"\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.mips"}},"name":"string.quoted.double.mips","patterns":[{"match":"\\\\[rnt\\\\\"]","name":"constant.character.escape.mips"}]},{"begin":"(^[ \\t]+)?(?=#)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.mips"}},"end":"(?!\\G)","patterns":[{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.mips"}},"end":"\\n","name":"comment.line.number-sign.mips"}]}],"scopeName":"source.mips","uuid":"7FD88C2E-6BE3-11D9-9A40-0011242E4184"} 2 | -------------------------------------------------------------------------------- /resources/grammars/po.json: -------------------------------------------------------------------------------- 1 | {"comment":"\nTODO: Command for copy original to untranslated, label as fuzzy, remove fuzzy, next fuzzy etc\nCreate meta scope for each entry\n","displayName":"Gettext PO","fileTypes":["po","pot","potx"],"keyEquivalent":"^~G","name":"po","patterns":[{"begin":"^(?=(msgid(_plural)?|msgctxt)\\s*\"[^\"])|^\\s*$","comment":"Start of body of document, after header","end":"\\z","patterns":[{"include":"#body"}]},{"include":"#comments"},{"match":"^msg(id|str)\\s+\"\"\\s*$\\n?","name":"comment.line.number-sign.po"},{"captures":{"1":{"name":"constant.language.po"},"2":{"name":"punctuation.separator.key-value.po"},"3":{"name":"string.other.po"}},"match":"^\"(?:([^\\s:]+)(:)\\s+)?([^\"]*)\"\\s*$\\n?","name":"meta.header.po"}],"repository":{"body":{"patterns":[{"begin":"^(msgid(_plural)?)\\s+","beginCaptures":{"1":{"name":"keyword.control.msgid.po"}},"end":"^(?!\")","name":"meta.scope.msgid.po","patterns":[{"begin":"(\\G|^)\"","end":"\"","name":"string.quoted.double.po","patterns":[{"match":"\\\\[\\\\\"]","name":"constant.character.escape.po"}]}]},{"begin":"^(msgstr)(?:(\\[)(\\d+)(\\]))?\\s+","beginCaptures":{"1":{"name":"keyword.control.msgstr.po"},"2":{"name":"keyword.control.msgstr.po"},"3":{"name":"constant.numeric.po"},"4":{"name":"keyword.control.msgstr.po"}},"end":"^(?!\")","name":"meta.scope.msgstr.po","patterns":[{"begin":"(\\G|^)\"","end":"\"","name":"string.quoted.double.po","patterns":[{"match":"\\\\[\\\\\"]","name":"constant.character.escape.po"}]}]},{"begin":"^(msgctxt)(?:(\\[)(\\d+)(\\]))?\\s+","beginCaptures":{"1":{"name":"keyword.control.msgctxt.po"},"2":{"name":"keyword.control.msgctxt.po"},"3":{"name":"constant.numeric.po"},"4":{"name":"keyword.control.msgctxt.po"}},"end":"^(?!\")","name":"meta.scope.msgctxt.po","patterns":[{"begin":"(\\G|^)\"","end":"\"","name":"string.quoted.double.po","patterns":[{"match":"\\\\[\\\\\"]","name":"constant.character.escape.po"}]}]},{"captures":{"1":{"name":"punctuation.definition.comment.po"}},"match":"^(#~).*$\\n?","name":"comment.line.number-sign.obsolete.po"},{"include":"#comments"},{"comment":"a line that does not begin with # or \". Could improve this regexp","match":"^(?!\\s*$)[^#\"].*$\\n?","name":"invalid.illegal.po"}]},"comments":{"patterns":[{"begin":"^(?=#)","end":"(?!\\G)","patterns":[{"begin":"(#,)\\s+","beginCaptures":{"1":{"name":"punctuation.definition.comment.po"}},"end":"\\n","name":"comment.line.number-sign.flag.po","patterns":[{"captures":{"1":{"name":"entity.name.type.flag.po"}},"match":"(?:\\G|,\\s*)((?:fuzzy)|(?:no-)?(?:c|objc|sh|lisp|elisp|librep|scheme|smalltalk|java|csharp|awk|object-pascal|ycp|tcl|perl|perl-brace|php|gcc-internal|qt|boost)-format)"}]},{"begin":"#\\.","beginCaptures":{"0":{"name":"punctuation.definition.comment.po"}},"end":"\\n","name":"comment.line.number-sign.extracted.po"},{"begin":"(#:)[ \\t]*","beginCaptures":{"1":{"name":"punctuation.definition.comment.po"}},"end":"\\n","name":"comment.line.number-sign.reference.po","patterns":[{"match":"(\\S+:)([\\d;]*)","name":"storage.type.class.po"}]},{"begin":"#\\|","beginCaptures":{"0":{"name":"punctuation.definition.comment.po"}},"end":"\\n","name":"comment.line.number-sign.previous.po"},{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.po"}},"end":"\\n","name":"comment.line.number-sign.po"}]}]}},"scopeName":"source.po","uuid":"F07730BD-59BC-41D0-AC3F-4AB2DCB6C54A"} 2 | -------------------------------------------------------------------------------- /resources/grammars/qmldir.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"QML Directory","name":"qmldir","patterns":[{"include":"#comment"},{"include":"#keywords"},{"include":"#version"},{"include":"#names"}],"repository":{"comment":{"patterns":[{"begin":"#","end":"$","name":"comment.line.number-sign.qmldir"}]},"file-name":{"patterns":[{"match":"\\b\\w+\\.(qmltypes|qml|js)\\b","name":"string.unquoted.qmldir"}]},"identifier":{"patterns":[{"match":"\\b\\w+\\b","name":"variable.parameter.qmldir"}]},"keywords":{"patterns":[{"match":"\\b(module|singleton|internal|plugin|classname|typeinfo|depends|designersupported)\\b","name":"keyword.other.qmldir"}]},"module-name":{"patterns":[{"match":"\\b[A-Z]\\w*\\b","name":"entity.name.type.qmldir"}]},"names":{"patterns":[{"include":"#file-name"},{"include":"#module-name"},{"include":"#identifier"}]},"version":{"patterns":[{"match":"\\b\\d+\\.\\d+\\b","name":"constant.numeric.qml"}]}},"scopeName":"source.qmldir"} 2 | -------------------------------------------------------------------------------- /resources/grammars/reg.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Windows Registry Script","fileTypes":["reg","REG"],"name":"reg","patterns":[{"match":"Windows Registry Editor Version 5\\.00|REGEDIT4","name":"keyword.control.import.reg"},{"captures":{"1":{"name":"punctuation.definition.comment.reg"}},"match":"(;).*$","name":"comment.line.semicolon.reg"},{"captures":{"1":{"name":"punctuation.definition.section.reg"},"2":{"name":"entity.section.reg"},"3":{"name":"punctuation.definition.section.reg"}},"match":"^\\s*(\\[(?!-))(.*?)(\\])","name":"entity.name.function.section.add.reg"},{"captures":{"1":{"name":"punctuation.definition.section.reg"},"2":{"name":"entity.section.reg"},"3":{"name":"punctuation.definition.section.reg"}},"match":"^\\s*(\\[-)(.*?)(\\])","name":"entity.name.function.section.delete.reg"},{"captures":{"10":{"name":"string.name.regdata.reg"},"11":{"name":"punctuation.definition.quote.reg"},"13":{"name":"support.type.dword.reg"},"14":{"name":"keyword.operator.arithmetic.colon.reg"},"15":{"name":"constant.numeric.dword.reg"},"17":{"name":"support.type.dword.reg"},"18":{"name":"keyword.operator.arithmetic.parenthesis.reg"},"19":{"name":"keyword.operator.arithmetic.parenthesis.reg"},"2":{"name":"punctuation.definition.quote.reg"},"20":{"name":"constant.numeric.hex.size.reg"},"21":{"name":"keyword.operator.arithmetic.parenthesis.reg"},"22":{"name":"keyword.operator.arithmetic.colon.reg"},"23":{"name":"constant.numeric.hex.reg"},"24":{"name":"keyword.operator.arithmetic.linecontinuation.reg"},"25":{"name":"comment.declarationline.semicolon.reg"},"3":{"name":"support.function.regname.ini"},"4":{"name":"punctuation.definition.quote.reg"},"5":{"name":"punctuation.definition.equals.reg"},"7":{"name":"keyword.operator.arithmetic.minus.reg"},"9":{"name":"punctuation.definition.quote.reg"}},"match":"^(\\s*([\"']?)(.+?)([\"']?)\\s*(=))?\\s*((-)|(([\"'])(.*?)([\"']))|(((?i:dword))(\\:)\\s*([\\dabcdefABCDEF]{1,8}))|(((?i:hex))((\\()([\\d]*)(\\)))?(\\:)(.*?)(\\\\?)))\\s*(;.*)?$","name":"meta.declaration.reg"},{"match":"[0-9]+","name":"constant.numeric.reg"},{"match":"[a-fA-F]+","name":"constant.numeric.hex.reg"},{"match":",+","name":"constant.numeric.hex.comma.reg"},{"match":"\\\\","name":"keyword.operator.arithmetic.linecontinuation.reg"}],"scopeName":"source.reg","uuid":"B7773F5B-C43A-4BB9-843A-4AC119250EBD"} 2 | -------------------------------------------------------------------------------- /resources/grammars/rel.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Rel","name":"rel","patterns":[{"include":"#strings"},{"include":"#comment"},{"include":"#single-line-comment-consuming-line-ending"},{"include":"#deprecated-temporary"},{"include":"#operators"},{"include":"#symbols"},{"include":"#keywords"},{"include":"#otherkeywords"},{"include":"#types"},{"include":"#constants"}],"repository":{"comment":{"patterns":[{"begin":"/\\*\\*(?!/)","beginCaptures":{"0":{"name":"punctuation.definition.comment.rel"}},"end":"\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.rel"}},"name":"comment.block.documentation.rel","patterns":[{"include":"#docblock"}]},{"begin":"(/\\*)(?:\\s*((@)internal)(?=\\s|(\\*/)))?","beginCaptures":{"1":{"name":"punctuation.definition.comment.rel"},"2":{"name":"storage.type.internaldeclaration.rel"},"3":{"name":"punctuation.decorator.internaldeclaration.rel"}},"end":"\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.rel"}},"name":"comment.block.rel"},{"begin":"doc\"\"\"","end":"\"\"\"","name":"comment.block.documentation.rel"},{"begin":"(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.rel"},"2":{"name":"comment.line.double-slash.rel"},"3":{"name":"punctuation.definition.comment.rel"},"4":{"name":"storage.type.internaldeclaration.rel"},"5":{"name":"punctuation.decorator.internaldeclaration.rel"}},"contentName":"comment.line.double-slash.rel","end":"(?=$)"}]},"constants":{"patterns":[{"match":"(\\b(true|false)\\b)","name":"constant.language.rel"}]},"deprecated-temporary":{"patterns":[{"match":"@inspect","name":"keyword.other.rel"}]},"keywords":{"patterns":[{"match":"(\\b(def|entity|bound|include|ic|forall|exists|∀|∃|return|module|^end)\\b)|(((\\<)?\\|(\\>)?)|∀|∃)","name":"keyword.control.rel"}]},"operators":{"patterns":[{"match":"(\\b(if|then|else|and|or|not|eq|neq|lt|lt_eq|gt|gt_eq)\\b)|(\\+|\\-|\\*|\\/|÷|\\^|\\%|\\=|\\!\\=|≠|\\<|\\<\\=|≤|\\>|\\>\\=|≥|\\&)|\\s+(end)","name":"keyword.other.rel"}]},"otherkeywords":{"patterns":[{"match":"\\s*(@inline)\\s*|\\s*(@auto_number)\\s*|\\s*(function)\\s|(\\b(implies|select|from|∈|where|for|in)\\b)|(((\\<)?\\|(\\>)?)|∈)","name":"keyword.other.rel"}]},"single-line-comment-consuming-line-ending":{"begin":"(^[ \\t]+)?((//)(?:\\s*((@)internal)(?=\\s|$))?)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.rel"},"2":{"name":"comment.line.double-slash.rel"},"3":{"name":"punctuation.definition.comment.rel"},"4":{"name":"storage.type.internaldeclaration.rel"},"5":{"name":"punctuation.decorator.internaldeclaration.rel"}},"contentName":"comment.line.double-slash.rel","end":"(?=^)"},"strings":{"begin":"\"","end":"\"","name":"string.quoted.double.rel","patterns":[{"match":"\\\\.","name":"constant.character.escape.rel"}]},"symbols":{"patterns":[{"match":"(:[\\[_$[:alpha:]](\\]|[_$[:alnum:]]*))","name":"variable.parameter.rel"}]},"types":{"patterns":[{"match":"(\\b(Symbol|Char|Bool|Rational|FixedDecimal|Float16|Float32|Float64|Int8|Int16|Int32|Int64|Int128|UInt8|UInt16|UInt32|UInt64|UInt128|Date|DateTime|Day|Week|Month|Year|Nanosecond|Microsecond|Millisecond|Second|Minute|Hour|FilePos|HashValue|AutoNumberValue)\\b)","name":"entity.name.type.rel"}]}},"scopeName":"source.rel"} 2 | -------------------------------------------------------------------------------- /resources/grammars/shellsession.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Shell Session","fileTypes":["sh-session"],"name":"shellsession","patterns":[{"captures":{"1":{"name":"entity.other.prompt-prefix.shell-session"},"2":{"name":"punctuation.separator.prompt.shell-session"},"3":{"name":"source.shell","patterns":[{"include":"source.shell"}]}},"match":"(?x) ^ (?: ( (?:\\(\\S+\\)\\s*)? (?: sh\\S*? | \\w+\\S+[@:]\\S+(?:\\s+\\S+)? | \\[\\S+?[@:][^\\n]+?\\].*? ) ) \\s* )? ( [>$#%❯➜] | \\p{Greek} ) \\s+ (.*) $"},{"match":"^.+$","name":"meta.output.shell-session"}],"scopeName":"text.shell-session"} 2 | -------------------------------------------------------------------------------- /resources/grammars/sparql.json: -------------------------------------------------------------------------------- 1 | {"displayName":"SPARQL","fileTypes":["rq","sparql","sq"],"name":"sparql","patterns":[{"include":"source.turtle"},{"include":"#query-keyword-operators"},{"include":"#functions"},{"include":"#variables"},{"include":"#expression-operators"}],"repository":{"expression-operators":{"match":"(?:\\|\\||&&|=|!=|<|>|<=|>=|\\*|/|\\+|-|\\||\\^|\\?|\\!)","name":"support.class.sparql"},"functions":{"match":"\\b(?i:concat|regex|asc|desc|bound|isiri|isuri|isblank|isliteral|isnumeric|str|lang|datatype|sameterm|langmatches|avg|count|group_concat|separator|max|min|sample|sum|iri|uri|bnode|strdt|uuid|struuid|strlang|strlen|substr|ucase|lcase|strstarts|strends|contains|strbefore|strafter|encode_for_uri|replace|abs|round|ceil|floor|rand|now|year|month|day|hours|minutes|seconds|timezone|tz|md5|sha1|sha256|sha384|sha512|coalesce|if)\\b","name":"support.function.sparql"},"query-keyword-operators":{"match":"\\b(?i:define|select|distinct|reduced|from|named|construct|ask|describe|where|graph|having|bind|as|filter|optional|union|order|by|group|limit|offset|values|insert data|delete data|with|delete|insert|clear|silent|default|all|create|drop|copy|move|add|to|using|service|not exists|exists|not in|in|minus|load)\\b","name":"keyword.control.sparql"},"variables":{"match":"(?","beginCaptures":{"0":{"name":"punctuation.separator.tasl.component"}},"end":"$","patterns":[{"include":"#expression"}]},"coproduct":{"begin":"\\[","beginCaptures":{"0":{"name":"punctuation.definition.block.tasl.coproduct"}},"end":"\\]","endCaptures":{"0":{"name":"punctuation.definition.block.tasl.coproduct"}},"patterns":[{"include":"#comment"},{"include":"#term"},{"include":"#option"}]},"datatype":{"match":"[a-zA-Z][a-zA-Z0-9]*:(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})+","name":"string.regexp"},"edge":{"begin":"(?:^\\s*)(edge)\\b","beginCaptures":{"1":{"name":"keyword.control.tasl.edge"}},"end":"$","patterns":[{"include":"#key"},{"include":"#export"},{"match":"=/","name":"punctuation.separator.tasl.edge.source"},{"match":"/=>","name":"punctuation.separator.tasl.edge.target"},{"match":"=>","name":"punctuation.separator.tasl.edge"},{"include":"#expression"}]},"export":{"match":"::","name":"keyword.operator.tasl.export"},"expression":{"patterns":[{"include":"#literal"},{"include":"#uri"},{"include":"#product"},{"include":"#coproduct"},{"include":"#reference"},{"include":"#optional"},{"include":"#identifier"}]},"identifier":{"captures":{"1":{"name":"variable"}},"match":"([a-zA-Z][a-zA-Z0-9]*)\\b"},"key":{"match":"[a-zA-Z][a-zA-Z0-9]*:(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})+","name":"markup.bold entity.name.class"},"literal":{"patterns":[{"include":"#datatype"}]},"namespace":{"captures":{"1":{"name":"keyword.control.tasl.namespace"},"2":{"patterns":[{"include":"#namespaceURI"},{"match":"[a-zA-Z][a-zA-Z0-9]*\\b","name":"entity.name"}]}},"match":"(?:^\\s*)(namespace)\\b(.*)"},"namespaceURI":{"match":"[a-z]+:[a-zA-Z0-9-._~:\\/?#\\[\\]@!$&'()*+,;%=]+","name":"markup.underline.link"},"option":{"begin":"<-","beginCaptures":{"0":{"name":"punctuation.separator.tasl.option"}},"end":"$","patterns":[{"include":"#expression"}]},"optional":{"begin":"\\?","beginCaptures":{"0":{"name":"keyword.operator"}},"end":"$","patterns":[{"include":"#expression"}]},"product":{"begin":"{","beginCaptures":{"0":{"name":"punctuation.definition.block.tasl.product"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.block.tasl.product"}},"patterns":[{"include":"#comment"},{"include":"#term"},{"include":"#component"}]},"reference":{"captures":{"1":{"name":"markup.bold keyword.operator"},"2":{"patterns":[{"include":"#key"}]}},"match":"(\\*)\\s*(.*)"},"term":{"match":"[a-zA-Z][a-zA-Z0-9]*:(?:[A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})+","name":"entity.other.tasl.key"},"type":{"begin":"(?:^\\s*)(type)\\b","beginCaptures":{"1":{"name":"keyword.control.tasl.type"}},"end":"$","patterns":[{"include":"#expression"}]},"uri":{"match":"<>","name":"variable.other.constant"}},"scopeName":"source.tasl"} 2 | -------------------------------------------------------------------------------- /resources/grammars/ts-tags.json: -------------------------------------------------------------------------------- 1 | {"displayName":"TypeScript with Tags","name":"ts-tags","patterns":[{"include":"source.ts"}],"scopeName":"source.ts.tags"} 2 | -------------------------------------------------------------------------------- /resources/grammars/tsv.json: -------------------------------------------------------------------------------- 1 | {"displayName":"TSV","fileTypes":["tsv","tab"],"name":"tsv","patterns":[{"captures":{"1":{"name":"rainbow1"},"10":{"name":"invalid.rainbow10"},"2":{"name":"keyword.rainbow2"},"3":{"name":"entity.name.function.rainbow3"},"4":{"name":"comment.rainbow4"},"5":{"name":"string.rainbow5"},"6":{"name":"variable.parameter.rainbow6"},"7":{"name":"constant.numeric.rainbow7"},"8":{"name":"entity.name.type.rainbow8"},"9":{"name":"markup.bold.rainbow9"}},"match":"([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)([^\\t]*\\t?)","name":"rainbowgroup"}],"scopeName":"text.tsv","uuid":"ca13e332-04ef-1340-9a6b-9b99aae1c418"} 2 | -------------------------------------------------------------------------------- /resources/grammars/turtle.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Turtle","fileTypes":["turtle","ttl","acl"],"name":"turtle","patterns":[{"include":"#rule-constraint"},{"include":"#iriref"},{"include":"#prefix"},{"include":"#prefixed-name"},{"include":"#comment"},{"include":"#special-predicate"},{"include":"#literals"},{"include":"#language-tag"}],"repository":{"boolean":{"match":"\\b(?i:true|false)\\b","name":"constant.language.sparql"},"comment":{"match":"#.*$","name":"comment.line.number-sign.turtle"},"integer":{"match":"[+-]?(?:\\d+|[0-9]+\\.[0-9]*|\\.[0-9]+(?:[eE][+-]?\\d+)?)","name":"constant.numeric.turtle"},"iriref":{"match":"<[^\\x20-\\x20<>\"{}|^`\\\\]*>","name":"entity.name.type.iriref.turtle"},"language-tag":{"captures":{"1":{"name":"entity.name.class.turtle"}},"match":"@(\\w+)","name":"meta.string-literal-language-tag.turtle"},"literals":{"patterns":[{"include":"#string"},{"include":"#numeric"},{"include":"#boolean"}]},"numeric":{"patterns":[{"include":"#integer"}]},"prefix":{"match":"(?i:@?base|@?prefix)\\s","name":"keyword.operator.turtle"},"prefixed-name":{"captures":{"1":{"name":"storage.type.PNAME_NS.turtle"},"2":{"name":"support.variable.PN_LOCAL.turtle"}},"match":"(\\w*:)(\\w*)","name":"constant.complex.turtle"},"rule-constraint":{"begin":"(rule:content) (\"\"\")","beginCaptures":{"1":{"patterns":[{"include":"#prefixed-name"}]},"2":{"name":"string.quoted.triple.turtle"}},"end":"\"\"\"","endCaptures":{"0":{"name":"string.quoted.triple.turtle"}},"name":"meta.rule-constraint.turtle","patterns":[{"include":"source.srs"}]},"single-dquote-string-literal":{"begin":"\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.turtle"}},"end":"\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.turtle"}},"name":"string.quoted.double.turtle","patterns":[{"include":"#string-character-escape"}]},"single-squote-string-literal":{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.turtle"}},"end":"'","endCaptures":{"1":{"name":"punctuation.definition.string.end.turtle"},"2":{"name":"invalid.illegal.newline.turtle"}},"name":"string.quoted.single.turtle","patterns":[{"include":"#string-character-escape"}]},"special-predicate":{"captures":{"1":{"name":"keyword.control.turtle"}},"match":"\\s(a)\\s","name":"meta.specialPredicate.turtle"},"string":{"patterns":[{"include":"#triple-squote-string-literal"},{"include":"#triple-dquote-string-literal"},{"include":"#single-squote-string-literal"},{"include":"#single-dquote-string-literal"},{"include":"#triple-tick-string-literal"}]},"string-character-escape":{"match":"\\\\(x\\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)","name":"constant.character.escape.turtle"},"triple-dquote-string-literal":{"begin":"\"\"\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.turtle"}},"end":"\"\"\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.turtle"}},"name":"string.quoted.triple.turtle","patterns":[{"include":"#string-character-escape"}]},"triple-squote-string-literal":{"begin":"'''","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.turtle"}},"end":"'''","endCaptures":{"0":{"name":"punctuation.definition.string.end.turtle"}},"name":"string.quoted.triple.turtle","patterns":[{"include":"#string-character-escape"}]},"triple-tick-string-literal":{"begin":"```","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.turtle"}},"end":"```","endCaptures":{"0":{"name":"punctuation.definition.string.end.turtle"}},"name":"string.quoted.triple.turtle","patterns":[{"include":"#string-character-escape"}]}},"scopeName":"source.turtle","uuid":"230498230498sdfkj8909-34df-23dfs"} 2 | -------------------------------------------------------------------------------- /resources/grammars/txt.json: -------------------------------------------------------------------------------- 1 | {"scopeName":"text.plain","patterns":[],"repository":{}} 2 | -------------------------------------------------------------------------------- /resources/grammars/vala.json: -------------------------------------------------------------------------------- 1 | {"displayName":"Vala","fileTypes":["vala","vapi","gs"],"name":"vala","patterns":[{"include":"#code"}],"repository":{"code":{"patterns":[{"include":"#comments"},{"include":"#constants"},{"include":"#strings"},{"include":"#keywords"},{"include":"#types"},{"include":"#functions"},{"include":"#variables"}]},"comments":{"patterns":[{"captures":{"0":{"name":"punctuation.definition.comment.vala"}},"match":"/\\*\\*/","name":"comment.block.empty.vala"},{"include":"text.html.javadoc"},{"include":"#comments-inline"}]},"comments-inline":{"patterns":[{"begin":"/\\*","captures":{"0":{"name":"punctuation.definition.comment.vala"}},"end":"\\*/","name":"comment.block.vala"},{"captures":{"1":{"name":"comment.line.double-slash.vala"},"2":{"name":"punctuation.definition.comment.vala"}},"match":"\\s*((//).*$\\n?)"}]},"constants":{"patterns":[{"match":"\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)([LlFfUuDd]|UL|ul)?\\b","name":"constant.numeric.vala"},{"match":"\\b([A-Z][A-Z0-9_]+)\\b","name":"variable.other.constant.vala"}]},"functions":{"patterns":[{"match":"(\\w+)(?=\\s*(<[\\s\\w.]+>\\s*)?\\()","name":"entity.name.function.vala"}]},"keywords":{"patterns":[{"match":"(?<=^|[^@\\w\\.])(as|do|if|in|is|not|or|and|for|get|new|out|ref|set|try|var|base|case|else|enum|lock|null|this|true|void|weak|async|break|catch|class|const|false|owned|throw|using|while|with|yield|delete|extern|inline|params|public|return|sealed|signal|sizeof|static|struct|switch|throws|typeof|unlock|default|dynamic|ensures|finally|foreach|private|unowned|virtual|abstract|continue|delegate|internal|override|requires|volatile|construct|interface|namespace|protected|errordomain)\\b","name":"keyword.vala"},{"match":"(?<=^|[^@\\w\\.])(bool|double|float|unichar|unichar2|char|uchar|int|uint|long|ulong|short|ushort|size_t|ssize_t|string|string16|string32|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64|va_list|time_t)\\b","name":"keyword.vala"},{"match":"(#if|#elif|#else|#endif)","name":"keyword.vala"}]},"strings":{"patterns":[{"begin":"\"\"\"","end":"\"\"\"","name":"string.quoted.triple.vala"},{"begin":"@\"","end":"\"","name":"string.quoted.interpolated.vala","patterns":[{"match":"\\\\.","name":"constant.character.escape.vala"},{"match":"\\$\\w+","name":"constant.character.escape.vala"},{"match":"\\$\\(([^)(]|\\(([^)(]|\\([^)]*\\))*\\))*\\)","name":"constant.character.escape.vala"}]},{"begin":"\"","end":"\"","name":"string.quoted.double.vala","patterns":[{"match":"\\\\.","name":"constant.character.escape.vala"}]},{"begin":"'","end":"'","name":"string.quoted.single.vala","patterns":[{"match":"\\\\.","name":"constant.character.escape.vala"}]},{"match":"/((\\\\/)|([^/]))*/(?=\\s*[,;)\\.\\n])","name":"string.regexp.vala"}]},"types":{"patterns":[{"match":"(?<=^|[^@\\w\\.])(bool|double|float|unichar|unichar2|char|uchar|int|uint|long|ulong|short|ushort|size_t|ssize_t|string|string16|string32|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64|va_list|time_t)\\b","name":"storage.type.primitive.vala"},{"match":"\\b([A-Z]+\\w*)\\b","name":"entity.name.type.vala"}]},"variables":{"patterns":[{"match":"\\b([_a-z]+\\w*)\\b","name":"variable.other.vala"}]}},"scopeName":"source.vala","uuid":"5fbc8212-3c2f-45ac-83d2-0c9195878913"} 2 | -------------------------------------------------------------------------------- /resources/grammars/vue-directives.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","fileTypes":[],"injectTo":["source.vue","text.html.markdown","text.html.derivative","text.pug"],"injectionSelector":"L:meta.tag -meta.attribute -meta.ng-binding -entity.name.tag.pug -attribute_value -source.tsx -source.js.jsx, L:meta.element -meta.attribute","name":"vue-directives","patterns":[{"include":"source.vue#vue-directives"}],"scopeName":"vue.directives"} 2 | -------------------------------------------------------------------------------- /resources/grammars/vue-interpolations.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","fileTypes":[],"injectTo":["source.vue","text.html.markdown","text.html.derivative","text.pug"],"injectionSelector":"L:text.pug -comment -string.comment, L:text.html.derivative -comment.block, L:text.html.markdown -comment.block","name":"vue-interpolations","patterns":[{"include":"source.vue#vue-interpolations"}],"scopeName":"vue.interpolations"} 2 | -------------------------------------------------------------------------------- /resources/grammars/vue-sfc-style-variable-injection.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","fileTypes":[],"injectTo":["source.vue"],"injectionSelector":"L:source.css -comment, L:source.postcss -comment, L:source.sass -comment, L:source.stylus -comment","name":"vue-sfc-style-variable-injection","patterns":[{"include":"#vue-sfc-style-variable-injection"}],"repository":{"vue-sfc-style-variable-injection":{"begin":"\\b(v-bind)\\s*\\(","beginCaptures":{"1":{"name":"entity.name.function"}},"end":"\\)","name":"vue.sfc.style.variable.injection.v-bind","patterns":[{"begin":"('|\")","beginCaptures":{"1":{"name":"punctuation.definition.tag.begin.html"}},"end":"(\\1)","endCaptures":{"1":{"name":"punctuation.definition.tag.end.html"}},"name":"source.ts.embedded.html.vue","patterns":[{"include":"source.js"}]},{"include":"source.js"}]}},"scopeName":"vue.sfc.style.variable.injection"} 2 | -------------------------------------------------------------------------------- /resources/grammars/wenyan.json: -------------------------------------------------------------------------------- 1 | {"$schema":"https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json","displayName":"Wenyan","name":"wenyan","patterns":[{"include":"#keywords"},{"include":"#constants"},{"include":"#operators"},{"include":"#symbols"},{"include":"#expression"},{"include":"#comment-blocks"},{"include":"#comment-lines"}],"repository":{"comment-blocks":{"begin":"(注曰|疏曰|批曰)。?(「「|『)","end":"(」」|』)","name":"comment.block","patterns":[{"match":"\\\\.","name":"constant.character"}]},"comment-lines":{"begin":"注曰|疏曰|批曰","end":"$","name":"comment.line","patterns":[{"match":"\\\\.","name":"constant.character"}]},"constants":{"patterns":[{"match":"負|·|又|零|〇|一|二|三|四|五|六|七|八|九|十|百|千|萬|億|兆|京|垓|秭|穰|溝|澗|正|載|極|分|釐|毫|絲|忽|微|纖|沙|塵|埃|渺|漠","name":"constant.numeric"},{"match":"其|陰|陽","name":"constant.language"},{"begin":"「「|『","end":"」」|』","name":"string.quoted","patterns":[{"match":"\\\\.","name":"constant.character"}]}]},"expression":{"patterns":[{"include":"#variables"}]},"keywords":{"patterns":[{"match":"數|列|言|術|爻|物|元","name":"storage.type"},{"match":"乃行是術曰|若其不然者|乃歸空無|欲行是術|乃止是遍|若其然者|其物如是|乃得矣|之術也|必先得|是術曰|恆為是|之物也|乃得|是謂|云云|中之|為是|乃止|若非|或若|之長|其餘","name":"keyword.control"},{"match":"或云|蓋謂","name":"keyword.control"},{"match":"中有陽乎|中無陰乎|所餘幾何|不等於|不大於|不小於|等於|大於|小於|加|減|乘|除|變|以|於","name":"keyword.operator"},{"match":"不知何禍歟|不復存矣|姑妄行此|如事不諧|名之曰|吾嘗觀|之禍歟|乃作罷|吾有|今有|物之|書之|以施|昔之|是矣|之書|方悟|之義|嗚呼|之禍|有|施|曰|噫|取|今|夫|中|豈","name":"keyword.other"},{"match":"也|凡|遍|若|者|之|充|銜","name":"keyword.control"}]},"symbols":{"patterns":[{"match":"。|、","name":"punctuation.separator"}]},"variables":{"begin":"「","end":"」","name":"variable.other","patterns":[{"match":"\\\\.","name":"constant.character"}]}},"scopeName":"source.wenyan"} 2 | -------------------------------------------------------------------------------- /resources/grammars/xsl.json: -------------------------------------------------------------------------------- 1 | {"displayName":"XSL","information_for_contributors":["This file has been converted from https://github.com/atom/language-xml/blob/master/grammars/xsl.cson","If you want to provide a fix or improvement, please create a pull request against the original repository.","Once accepted there, we are happy to receive an update request."],"name":"xsl","patterns":[{"begin":"(<)(xsl)((:))(template)","captures":{"1":{"name":"punctuation.definition.tag.xml"},"2":{"name":"entity.name.tag.namespace.xml"},"3":{"name":"entity.name.tag.xml"},"4":{"name":"punctuation.separator.namespace.xml"},"5":{"name":"entity.name.tag.localname.xml"}},"end":"(>)","name":"meta.tag.xml.template","patterns":[{"captures":{"1":{"name":"entity.other.attribute-name.namespace.xml"},"2":{"name":"entity.other.attribute-name.xml"},"3":{"name":"punctuation.separator.namespace.xml"},"4":{"name":"entity.other.attribute-name.localname.xml"}},"match":" (?:([-_a-zA-Z0-9]+)((:)))?([a-zA-Z-]+)"},{"include":"#doublequotedString"},{"include":"#singlequotedString"}]},{"include":"text.xml"}],"repository":{"doublequotedString":{"begin":"\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.double.xml"},"singlequotedString":{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.xml"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.xml"}},"name":"string.quoted.single.xml"}},"scopeName":"text.xml.xsl","version":"https://github.com/atom/language-xml/commit/507de2ee7daca60cf02e9e21fbeb92bbae73e280"} 2 | -------------------------------------------------------------------------------- /src/Adapters/CommonMark/CodeBlockRenderer.php: -------------------------------------------------------------------------------- 1 | getLiteral(), "\n"); 32 | $grammar = $this->detectGrammar($node); 33 | $meta = new Meta(markdownInfo: $node->getInfoWords()[1] ?? null); 34 | 35 | return $this->phiki->codeToHtml($code, $grammar, $this->theme) 36 | ->withGutter($this->withGutter) 37 | ->withMeta($meta) 38 | ->transformer(new MetaTransformer) 39 | ->transformer(new AnnotationsTransformer) 40 | ->toString(); 41 | } 42 | 43 | protected function detectGrammar(FencedCode $node): Grammar|string 44 | { 45 | if (! isset($node->getInfoWords()[0]) || $node->getInfoWords()[0] === '') { 46 | return Grammar::Txt; 47 | } 48 | 49 | preg_match('/[a-zA-Z]+/', $node->getInfoWords()[0], $matches); 50 | 51 | if (! $this->phiki->environment->grammars->has($matches[0])) { 52 | return Grammar::Txt; 53 | } 54 | 55 | return $matches[0]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Adapters/CommonMark/PhikiExtension.php: -------------------------------------------------------------------------------- 1 | addSchema('phiki', Expect::structure([ 27 | 'theme' => Expect::mixed()->default($this->theme), 28 | 'with_gutter' => Expect::bool()->default($this->withGutter), 29 | ])); 30 | } 31 | 32 | public function register(EnvironmentBuilderInterface $environment): void 33 | { 34 | $config = $environment->getConfiguration(); 35 | 36 | $theme = $config->get('phiki/theme'); 37 | $withGutter = $config->get('phiki/with_gutter'); 38 | 39 | $environment->addRenderer( 40 | FencedCode::class, 41 | new CodeBlockRenderer($theme, $this->phiki, $withGutter), 42 | 10, 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Adapters/CommonMark/Transformers/Annotations/Annotation.php: -------------------------------------------------------------------------------- 1 | properties->get('class')->add(...$this->type->getLineClasses()); 18 | } 19 | 20 | public function applyToPre(Element $pre): void 21 | { 22 | $pre->properties->get('class')->add(...$this->type->getPreClasses()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Adapters/CommonMark/Transformers/Annotations/AnnotationRange.php: -------------------------------------------------------------------------------- 1 | \d+),(?\d+)$/', $range, $matches) === 1) { 29 | return new AnnotationRange(AnnotationRangeKind::Fixed, $index + (int) $matches['offset'], $index + (int) $matches['offset'] + (int) $matches['and'] - 1); 30 | } 31 | 32 | // Start highlighting from $index - OFFSET for a total of AND lines. 33 | if (preg_match('/^(?-\d+),(?\d+)$/', $range, $matches) === 1) { 34 | return new AnnotationRange(AnnotationRangeKind::Fixed, $index + (int) $matches['offset'], $index + (int) $matches['offset'] + (int) $matches['and'] - 1); 35 | } 36 | 37 | // Start highlighting in an open-ended manner from the current line. 38 | if (preg_match('/^start$/i', $range) === 1) { 39 | return new AnnotationRange(AnnotationRangeKind::OpenEnded, $index, $index); 40 | } 41 | 42 | // Stop highlighting in an open-ended manner at the current line. 43 | if (preg_match('/^end$/i', $range) === 1) { 44 | return new AnnotationRange(AnnotationRangeKind::End, $index, $index); 45 | } 46 | 47 | return null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Adapters/CommonMark/Transformers/Annotations/AnnotationRangeKind.php: -------------------------------------------------------------------------------- 1 | ['highlight', 'hl', '~~'], 19 | self::Focus => ['focus', 'f', '**'], 20 | }; 21 | } 22 | 23 | /** 24 | * Get the CSS classes to apply to lines with this annotation. 25 | */ 26 | public function getLineClasses(): array 27 | { 28 | return match ($this) { 29 | self::Highlight => ['highlight'], 30 | self::Focus => ['focus'], 31 | }; 32 | } 33 | 34 | /** 35 | * Get the CSS classes to apply to the pre element. 36 | */ 37 | public function getPreClasses(): array 38 | { 39 | return match ($this) { 40 | self::Focus => ['focus'], 41 | default => [], 42 | }; 43 | } 44 | 45 | /** 46 | * Get the type from the given keyword. 47 | */ 48 | public static function fromKeyword(string $keyword): self 49 | { 50 | return match ($keyword) { 51 | 'highlight', 'hl', '~~' => self::Highlight, 52 | 'focus', 'f', '**' => self::Focus, 53 | default => throw new \InvalidArgumentException("Unknown annotation keyword: {$keyword}"), 54 | }; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Adapters/CommonMark/Transformers/MetaTransformer.php: -------------------------------------------------------------------------------- 1 | parse(); 17 | 18 | return $code; 19 | } 20 | 21 | public function pre(Element $pre): Element 22 | { 23 | if ($this->focuses !== []) { 24 | $pre->properties->get('class')->add('focus'); 25 | } 26 | 27 | return $pre; 28 | } 29 | 30 | public function line(Element $span, array $tokens, int $index): Element 31 | { 32 | if (in_array($index + 1, $this->highlights, true)) { 33 | $span->properties->get('class')->add('highlight'); 34 | } 35 | 36 | if (in_array($index + 1, $this->focuses, true)) { 37 | $span->properties->get('class')->add('focus'); 38 | } 39 | 40 | return $span; 41 | } 42 | 43 | protected function parse(): void 44 | { 45 | if (! $this->meta->markdownInfo) { 46 | return; 47 | } 48 | 49 | [$highlights, $focuses] = array_pad( 50 | explode( 51 | '}{', 52 | rtrim(ltrim($this->meta->markdownInfo, '{'), '}'), 53 | 2 54 | ), 55 | 2, 56 | null 57 | ); 58 | 59 | if (! $highlights && ! $focuses) { 60 | return; 61 | } 62 | 63 | $highlights = array_map( 64 | fn (array $part) => count($part) > 1 ? $part : $part[0], 65 | array_map( 66 | fn (string $part) => array_map(fn (string $number) => intval($number), explode('-', trim($part))), 67 | explode(',', $highlights) 68 | ) 69 | ); 70 | 71 | foreach ($highlights as $part) { 72 | if (is_array($part)) { 73 | $this->highlights = array_merge($this->highlights, range($part[0], $part[1])); 74 | } else { 75 | $this->highlights[] = $part; 76 | } 77 | } 78 | 79 | $this->highlights = array_unique($this->highlights); 80 | 81 | if (! $focuses) { 82 | return; 83 | } 84 | 85 | $focuses = array_map( 86 | fn (array $part) => count($part) > 1 ? $part : $part[0], 87 | array_map( 88 | fn (string $part) => array_map(fn (string $number) => intval($number), explode('-', trim($part))), 89 | explode(',', $focuses) 90 | ) 91 | ); 92 | 93 | foreach ($focuses as $part) { 94 | if (is_array($part)) { 95 | $this->focuses = array_merge($this->focuses, range($part[0], $part[1])); 96 | } else { 97 | $this->focuses[] = $part; 98 | } 99 | } 100 | 101 | $this->focuses = array_unique($this->focuses); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Adapters/Laravel/Components/Code.php: -------------------------------------------------------------------------------- 1 | __toString(), $grammar, $theme)->withGutter($gutter)->startingLine($startingLine) !!} 29 | BLADE; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Adapters/Laravel/Facades/Phiki.php: -------------------------------------------------------------------------------- 1 | > codeToTokens(string $code, string|\Phiki\Grammar\Grammar|\Phiki\Grammar\ParsedGrammar $grammar) 9 | * @method static array> tokensToHighlightedTokens(array> $tokens, string|array|\Phiki\Theme\Theme $theme) 10 | * @method static array> codeToHighlightedTokens(string $code, string|\Phiki\Grammar\Grammar $grammar, string|array|\Phiki\Theme\Theme $theme) 11 | * @method static \Phiki\Output\Html\PendingHtmlOutput codeToHtml(string $code, string|\Phiki\Grammar\Grammar $grammar, string|array|\Phiki\Theme\Theme $theme) 12 | * @method static \Phiki\Environment environment() 13 | * @method static \Phiki\Phiki extend(\Phiki\Contracts\ExtensionInterface $extension) 14 | * @method static \Phiki\Phiki grammar(string $name, string|\Phiki\Grammar\ParsedGrammar $pathOrGrammar) 15 | * @method static \Phiki\Phiki alias(string $alias, string | \Phiki\Grammar\Grammar $for) 16 | * @method static \Phiki\Phiki theme(string $name, string|\Phiki\Theme\ParsedTheme $pathOrTheme) 17 | * @method static \Phiki\Phiki cache(\Psr\SimpleCache\CacheInterface $cache) 18 | * 19 | * @see \Phiki\Phiki 20 | */ 21 | class Phiki extends Facade 22 | { 23 | /** 24 | * Get the registered name of the component. 25 | * 26 | * @return string 27 | */ 28 | protected static function getFacadeAccessor() 29 | { 30 | return \Phiki\Phiki::class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Adapters/Laravel/PhikiServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton(Phiki::class, static fn () => (new Phiki)->cache(Cache::store())); 18 | } 19 | 20 | /** 21 | * Bootstrap services. 22 | */ 23 | public function boot(): void 24 | { 25 | Blade::resolved(function ($blade) { 26 | $blade->componentNamespace('Phiki\\Adapters\\Laravel\\Components', 'phiki'); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Contracts/ExtensionInterface.php: -------------------------------------------------------------------------------- 1 | $captures 11 | */ 12 | public function getContentName(array $captures): ?string; 13 | } 14 | -------------------------------------------------------------------------------- /src/Contracts/InjectionMatcherInterface.php: -------------------------------------------------------------------------------- 1 | $captures 13 | */ 14 | public function getScopeName(array $captures): ?string; 15 | 16 | /** 17 | * Compile the pattern into a list of matchable patterns. 18 | * 19 | * @return array 20 | */ 21 | public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array; 22 | 23 | /** 24 | * Get the ID of the pattern. 25 | */ 26 | public function getId(): int; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contracts/RequiresGrammarInterface.php: -------------------------------------------------------------------------------- 1 | $themes 13 | */ 14 | public function withThemes(array $themes): void; 15 | } 16 | -------------------------------------------------------------------------------- /src/Contracts/ThemeRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | > $tokens 22 | */ 23 | public function tokens(array $tokens): array; 24 | 25 | /** 26 | * Modify the highlighted tokens before they are converted into the HTML AST. 27 | * 28 | * @param array> $tokens 29 | */ 30 | public function highlighted(array $tokens): array; 31 | 32 | /** 33 | * Modify the root HTML element. 34 | */ 35 | public function root(Root $root): Root; 36 | 37 | /** 38 | * Modify the
 tag.
39 |      */
40 |     public function pre(Element $pre): Element;
41 | 
42 |     /**
43 |      * Modify the  tag.
44 |      */
45 |     public function code(Element $code): Element;
46 | 
47 |     /**
48 |      * Modify the  for each line.
49 |      *
50 |      * @param  array  $line
51 |      */
52 |     public function line(Element $span, array $line, int $index): Element;
53 | 
54 |     /**
55 |      * Modify the  for each token.
56 |      */
57 |     public function token(Element $span, HighlightedToken $token, int $index, int $line): Element;
58 | 
59 |     /**
60 |      * Modify the  for each gutter element.
61 |      */
62 |     public function gutter(Element $span, int $lineNumber): Element;
63 | 
64 |     /**
65 |      * Modify the HTML output after the AST has been converted.
66 |      */
67 |     public function postprocess(string $html): string;
68 | 
69 |     /**
70 |      * Supply the meta object to the transformer.
71 |      */
72 |     public function withMeta(Meta $meta): void;
73 | }
74 | 


--------------------------------------------------------------------------------
/src/Environment.php:
--------------------------------------------------------------------------------
 1 | grammars = new GrammarRepository;
23 |         $this->themes = new ThemeRepository;
24 |     }
25 | 
26 |     public function extend(ExtensionInterface $extension): static
27 |     {
28 |         $extension->register($this);
29 | 
30 |         return $this;
31 |     }
32 | 
33 |     public function grammar(string $slug, string|ParsedGrammar $grammar): static
34 |     {
35 |         $this->grammars->register($slug, $grammar);
36 | 
37 |         return $this;
38 |     }
39 | 
40 |     public function theme(string $slug, string|ParsedTheme $theme): static
41 |     {
42 |         $this->themes->register($slug, $theme);
43 | 
44 |         return $this;
45 |     }
46 | 
47 |     public function cache(CacheInterface $cache): static
48 |     {
49 |         $this->cache = $cache;
50 | 
51 |         return $this;
52 |     }
53 | }
54 | 


--------------------------------------------------------------------------------
/src/Exceptions/FailedToInitializePatternSearchException.php:
--------------------------------------------------------------------------------
 1 | name === null) {
29 |             return null;
30 |         }
31 | 
32 |         return Str::replaceScopeNameCapture($this->name, $captures);
33 |     }
34 | 
35 |     public function captures(): array
36 |     {
37 |         return count(array_filter($this->beginCaptures)) > 0 ? $this->beginCaptures : $this->captures;
38 |     }
39 | 
40 |     public function getContentName(array $captures): ?string
41 |     {
42 |         if ($this->contentName === null) {
43 |             return null;
44 |         }
45 | 
46 |         return Str::replaceScopeNameCapture($this->contentName, $captures);
47 |     }
48 | 
49 |     /**
50 |      * Compile the pattern into a list of matchable patterns.
51 |      *
52 |      * @return array
53 |      */
54 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
55 |     {
56 |         return [
57 |             [$this, $this->begin->get($allowA, $allowG)],
58 |         ];
59 |     }
60 | 
61 |     /**
62 |      * Create the associated `EndPattern` for this `BeginEndPattern`.
63 |      */
64 |     public function createEndPattern(MatchedPattern $matched): EndPattern
65 |     {
66 |         return new EndPattern(
67 |             id: $this->id,
68 |             begin: $matched,
69 |             end: $this->end,
70 |             name: $this->name,
71 |             contentName: $this->contentName,
72 |             endCaptures: $this->endCaptures,
73 |             captures: $this->captures,
74 |             patterns: $this->patterns,
75 |             injection: $this->injection,
76 |         );
77 |     }
78 | 
79 |     public function getId(): int
80 |     {
81 |         return $this->id;
82 |     }
83 | }
84 | 


--------------------------------------------------------------------------------
/src/Grammar/BeginWhilePattern.php:
--------------------------------------------------------------------------------
 1 | name === null) {
29 |             return null;
30 |         }
31 | 
32 |         return Str::replaceScopeNameCapture($this->name, $captures);
33 |     }
34 | 
35 |     public function captures(): array
36 |     {
37 |         return count(array_filter($this->beginCaptures)) > 0 ? array_filter($this->beginCaptures) : $this->captures;
38 |     }
39 | 
40 |     public function getContentName(array $captures): ?string
41 |     {
42 |         if ($this->contentName === null) {
43 |             return null;
44 |         }
45 | 
46 |         return Str::replaceScopeNameCapture($this->contentName, $captures);
47 |     }
48 | 
49 |     /**
50 |      * Compile the pattern into a list of matchable patterns.
51 |      *
52 |      * @return array
53 |      */
54 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
55 |     {
56 |         return [
57 |             [$this, $this->begin->get($allowA, $allowG)],
58 |         ];
59 |     }
60 | 
61 |     public function createWhilePattern(MatchedPattern $matched): WhilePattern
62 |     {
63 |         return new WhilePattern(
64 |             $this->id,
65 |             $matched,
66 |             $this->while,
67 |             $this->name,
68 |             $this->contentName,
69 |             $this->whileCaptures,
70 |             $this->captures,
71 |             $this->patterns,
72 |             $this->injection
73 |         );
74 |     }
75 | 
76 |     public function getId(): int
77 |     {
78 |         return $this->id;
79 |     }
80 | }
81 | 


--------------------------------------------------------------------------------
/src/Grammar/Capture.php:
--------------------------------------------------------------------------------
 1 | pattern->patterns) > 0;
21 |     }
22 | 
23 |     public function getScopeName(array $captures): ?string
24 |     {
25 |         if ($this->name === null) {
26 |             return null;
27 |         }
28 | 
29 |         return Str::replaceScopeNameCapture($this->name, $captures);
30 |     }
31 | 
32 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
33 |     {
34 |         return $this->pattern->compile($grammar, $grammars, $allowA, $allowG);
35 |     }
36 | 
37 |     public function getId(): int
38 |     {
39 |         return $this->id;
40 |     }
41 | }
42 | 


--------------------------------------------------------------------------------
/src/Grammar/CollectionPattern.php:
--------------------------------------------------------------------------------
 1 | 
28 |      */
29 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
30 |     {
31 |         $compiled = [];
32 | 
33 |         foreach ($this->patterns as $pattern) {
34 |             $compiled = array_merge($compiled, $pattern->compile($grammar, $grammars, $allowA, $allowG));
35 |         }
36 | 
37 |         return $compiled;
38 |     }
39 | 
40 |     public function getId(): int
41 |     {
42 |         return $this->id;
43 |     }
44 | }
45 | 


--------------------------------------------------------------------------------
/src/Grammar/EndPattern.php:
--------------------------------------------------------------------------------
 1 | name === null) {
27 |             return null;
28 |         }
29 | 
30 |         return Str::replaceScopeNameCapture($this->name, $captures);
31 |     }
32 | 
33 |     public function captures(): array
34 |     {
35 |         return count(array_filter($this->endCaptures)) > 0 ? $this->endCaptures : $this->captures;
36 |     }
37 | 
38 |     /**
39 |      * Compile the pattern into a list of matchable patterns.
40 |      *
41 |      * @return array
42 |      */
43 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
44 |     {
45 |         $compiled = [
46 |             [$this, $this->end->get($allowA, $allowG, $this->begin->matches)],
47 |         ];
48 | 
49 |         foreach ($this->patterns as $pattern) {
50 |             $compiled = array_merge($compiled, $pattern->compile($grammar, $grammars, $allowA, $allowG));
51 |         }
52 | 
53 |         return $compiled;
54 |     }
55 | 
56 |     public function getId(): int
57 |     {
58 |         return $this->id;
59 |     }
60 | }
61 | 


--------------------------------------------------------------------------------
/src/Grammar/GrammarRepository.php:
--------------------------------------------------------------------------------
 1 | grammars[$grammar->value] = $grammar->path();
20 |             $this->scopesToGrammar[$grammar->scopeName()] = $grammar->value;
21 | 
22 |             foreach ($grammar->aliases() as $alias) {
23 |                 $this->aliases[$alias] = $grammar->value;
24 |             }
25 |         }
26 |     }
27 | 
28 |     public function get(string $name): ParsedGrammar
29 |     {
30 |         if (! $this->has($name)) {
31 |             throw UnrecognisedGrammarException::make($name);
32 |         }
33 | 
34 |         $name = $this->aliases[$name] ?? $name;
35 |         $grammar = $this->grammars[$name];
36 | 
37 |         if ($grammar instanceof ParsedGrammar) {
38 |             return $grammar;
39 |         }
40 | 
41 |         $parser = new GrammarParser;
42 | 
43 |         return $this->grammars[$name] = $parser->parse(json_decode(file_get_contents($grammar), true));
44 |     }
45 | 
46 |     public function getFromScope(string $scope): ParsedGrammar
47 |     {
48 |         if (! isset($this->scopesToGrammar[$scope])) {
49 |             throw UnrecognisedGrammarException::make($scope);
50 |         }
51 | 
52 |         return $this->get($this->scopesToGrammar[$scope]);
53 |     }
54 | 
55 |     public function has(string $name): bool
56 |     {
57 |         return isset($this->grammars[$name]) || isset($this->aliases[$name]);
58 |     }
59 | 
60 |     public function alias(string $alias, string $target): void
61 |     {
62 |         $this->aliases[$alias] = $target;
63 |     }
64 | 
65 |     public function register(string $name, string|ParsedGrammar $pathOrGrammar): void
66 |     {
67 |         $this->grammars[$name] = $pathOrGrammar;
68 |     }
69 | 
70 |     public function resolve(string|Grammar|ParsedGrammar $grammar): ParsedGrammar
71 |     {
72 |         if ($grammar instanceof ParsedGrammar) {
73 |             return $grammar;
74 |         }
75 | 
76 |         return match (true) {
77 |             is_string($grammar) => $this->get($grammar),
78 |             $grammar instanceof Grammar => $grammar->toParsedGrammar($this),
79 |         };
80 |     }
81 | }
82 | 


--------------------------------------------------------------------------------
/src/Grammar/IncludePattern.php:
--------------------------------------------------------------------------------
 1 | 
27 |      */
28 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
29 |     {
30 |         try {
31 |             $resolved = match (true) {
32 |                 // "include": "$self"
33 |                 $this->reference === '$self' => $grammars->getFromScope($this->scopeName ?? $grammar->scopeName),
34 |                 // "include": "$base"
35 |                 $this->reference === '$base' => $grammar,
36 |                 // "include": "#name"
37 |                 $this->reference !== null && $this->scopeName === $grammar->scopeName => $grammar->resolve($this->reference),
38 |                 // "include": "scope#name"
39 |                 $this->reference !== null && $this->scopeName !== $grammar->scopeName => $grammars->getFromScope($this->scopeName)->resolve($this->reference),
40 |                 // "include": "scope"
41 |                 default => $grammars->getFromScope($this->scopeName),
42 |             };
43 |         } catch (UnrecognisedGrammarException) {
44 |             $resolved = null;
45 |         }
46 | 
47 |         if ($resolved === null) {
48 |             return [];
49 |         }
50 | 
51 |         return $resolved->compile($grammar, $grammars, $allowA, $allowG);
52 |     }
53 | 
54 |     public function getId(): int
55 |     {
56 |         return $this->id;
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Composite.php:
--------------------------------------------------------------------------------
 1 |   $expressions
11 |      */
12 |     public function __construct(
13 |         public array $expressions,
14 |     ) {}
15 | 
16 |     public function getPrefix(array $scopes): ?Prefix
17 |     {
18 |         if (! $this->matches($scopes)) {
19 |             return null;
20 |         }
21 | 
22 |         return $this->expressions[0]->getPrefix($scopes);
23 |     }
24 | 
25 |     public function matches(array $scopes): bool
26 |     {
27 |         $carry = false;
28 | 
29 |         foreach ($this->expressions as $expression) {
30 |             if (
31 |                 ($carry && $expression->operator === Operator::Or) ||
32 |                 (! $carry && $expression->operator === Operator::And) ||
33 |                 (! $carry && $expression->operator === Operator::Not)
34 |             ) {
35 |                 continue;
36 |             }
37 | 
38 |             $matches = $expression->matches($scopes);
39 | 
40 |             match ($expression->operator) {
41 |                 Operator::None => $carry = $matches,
42 |                 Operator::And => $carry = $carry && $matches,
43 |                 Operator::Or => $carry = $carry || $matches,
44 |                 Operator::Not => $carry = $carry && ! $matches,
45 |             };
46 |         }
47 | 
48 |         return $carry;
49 |     }
50 | }
51 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Expression.php:
--------------------------------------------------------------------------------
 1 | matches($scopes)) {
18 |             return null;
19 |         }
20 | 
21 |         return $this->child->getPrefix($scopes);
22 |     }
23 | 
24 |     public function matches(array $scopes): bool
25 |     {
26 |         $result = $this->child->matches($scopes);
27 | 
28 |         if ($this->negated) {
29 |             return ! $result;
30 |         }
31 | 
32 |         return $result;
33 |     }
34 | }
35 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Filter.php:
--------------------------------------------------------------------------------
 1 | matches($scopes)) {
17 |             return null;
18 |         }
19 | 
20 |         return $this->prefix;
21 |     }
22 | 
23 |     public function matches(array $scopes): bool
24 |     {
25 |         return $this->child->matches($scopes);
26 |     }
27 | }
28 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Group.php:
--------------------------------------------------------------------------------
 1 | matches($scopes)) {
16 |             return null;
17 |         }
18 | 
19 |         return $this->child->getPrefix($scopes);
20 |     }
21 | 
22 |     public function matches(array $scopes): bool
23 |     {
24 |         return $this->child->matches($scopes);
25 |     }
26 | }
27 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Injection.php:
--------------------------------------------------------------------------------
 1 | selector;
21 |     }
22 | 
23 |     public function getPrefix(array $scopes): ?Prefix
24 |     {
25 |         return $this->selector->getPrefix($scopes);
26 |     }
27 | 
28 |     public function matches(array $scopes): bool
29 |     {
30 |         return $this->selector->matches($scopes);
31 |     }
32 | 
33 |     public function getScopeName(array $captures): ?string
34 |     {
35 |         return $this->pattern->getScopeName($captures);
36 |     }
37 | 
38 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
39 |     {
40 |         return $this->pattern->compile($grammar, $grammars, $allowA, $allowG);
41 |     }
42 | 
43 |     public function getId(): int
44 |     {
45 |         return $this->id;
46 |     }
47 | }
48 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Operator.php:
--------------------------------------------------------------------------------
 1 | scopes[$index];
22 | 
23 |         foreach ($scopes as $scope) {
24 |             $scope = Scope::fromString($scope);
25 | 
26 |             if ($current->matches($scope)) {
27 |                 $current = $this->scopes[++$index] ?? null;
28 |             }
29 | 
30 |             if ($current === null) {
31 |                 return true;
32 |             }
33 |         }
34 | 
35 |         return false;
36 |     }
37 | }
38 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Prefix.php:
--------------------------------------------------------------------------------
 1 | parts as $i => $part) {
16 |             if ($part === '*') {
17 |                 continue;
18 |             }
19 | 
20 |             if ($part !== ($scope->parts[$i] ?? null)) {
21 |                 return false;
22 |             }
23 |         }
24 | 
25 |         return true;
26 |     }
27 | 
28 |     public function __toString(): string
29 |     {
30 |         return implode('.', $this->parts);
31 |     }
32 | 
33 |     public static function fromString(string $scope): self
34 |     {
35 |         return new self(explode('.', $scope));
36 |     }
37 | }
38 | 


--------------------------------------------------------------------------------
/src/Grammar/Injections/Selector.php:
--------------------------------------------------------------------------------
 1 |   $composites
11 |      */
12 |     public function __construct(
13 |         public array $composites,
14 |     ) {}
15 | 
16 |     public function getPrefix(array $scopes): ?Prefix
17 |     {
18 |         foreach ($this->composites as $composite) {
19 |             if ($composite->matches($scopes)) {
20 |                 return $composite->getPrefix($scopes);
21 |             }
22 |         }
23 | 
24 |         return null;
25 |     }
26 | 
27 |     public function matches(array $scopes): bool
28 |     {
29 |         foreach ($this->composites as $composite) {
30 |             if ($composite->matches($scopes)) {
31 |                 return true;
32 |             }
33 |         }
34 | 
35 |         return false;
36 |     }
37 | }
38 | 


--------------------------------------------------------------------------------
/src/Grammar/MatchPattern.php:
--------------------------------------------------------------------------------
 1 | name === null) {
26 |             return null;
27 |         }
28 | 
29 |         return Str::replaceScopeNameCapture($this->name, $captures);
30 |     }
31 | 
32 |     /**
33 |      * Compile the pattern into a list of matchable patterns.
34 |      *
35 |      * @return array
36 |      */
37 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
38 |     {
39 |         return [
40 |             [$this, $this->match->get($allowA, $allowG)],
41 |         ];
42 |     }
43 | 
44 |     public function getId(): int
45 |     {
46 |         return $this->id;
47 |     }
48 | }
49 | 


--------------------------------------------------------------------------------
/src/Grammar/MatchedInjection.php:
--------------------------------------------------------------------------------
 1 | matchedPattern->offset();
22 |     }
23 | }
24 | 


--------------------------------------------------------------------------------
/src/Grammar/MatchedPattern.php:
--------------------------------------------------------------------------------
 1 | matches[0][0];
20 |     }
21 | 
22 |     public function end(): int
23 |     {
24 |         return $this->matches[0][1] + strlen($this->matches[0][0]);
25 |     }
26 | 
27 |     /**
28 |      * Get the start position of the matched pattern.
29 |      */
30 |     public function offset(): int
31 |     {
32 |         return $this->matches[0][1];
33 |     }
34 | 
35 |     public function getCaptureGroup(int|string $index): ?array
36 |     {
37 |         return $this->matches[$index] ?? null;
38 |     }
39 | }
40 | 


--------------------------------------------------------------------------------
/src/Grammar/ParsedGrammar.php:
--------------------------------------------------------------------------------
 1 |   $repository
13 |      * @param  Injections\Injection[]  $injections
14 |      */
15 |     public function __construct(
16 |         public ?string $name,
17 |         public string $scopeName,
18 |         public array $patterns,
19 |         public array $repository,
20 |         public array $injections,
21 |     ) {}
22 | 
23 |     public function getScopeName(array $captures): ?string
24 |     {
25 |         return null;
26 |     }
27 | 
28 |     /**
29 |      * Compile the pattern into a list of matchable patterns.
30 |      *
31 |      * @return array
32 |      */
33 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
34 |     {
35 |         $compiled = [];
36 | 
37 |         foreach ($this->patterns as $pattern) {
38 |             $compiled = array_merge($compiled, $pattern->compile($grammar, $grammars, $allowA, $allowG));
39 |         }
40 | 
41 |         return $compiled;
42 |     }
43 | 
44 |     /** @return Injections\Injection[] */
45 |     public function getInjections(): array
46 |     {
47 |         return $this->injections;
48 |     }
49 | 
50 |     public function hasInjections(): bool
51 |     {
52 |         return count($this->injections) > 0;
53 |     }
54 | 
55 |     public function resolve(string $reference): ?PatternInterface
56 |     {
57 |         return $this->repository[$reference] ?? null;
58 |     }
59 | 
60 |     public static function fromArray(array $grammar): ParsedGrammar
61 |     {
62 |         $parser = new GrammarParser;
63 | 
64 |         return $parser->parse($grammar);
65 |     }
66 | 
67 |     public function getId(): int
68 |     {
69 |         return 0;
70 |     }
71 | }
72 | 


--------------------------------------------------------------------------------
/src/Grammar/WhilePattern.php:
--------------------------------------------------------------------------------
 1 | name === null) {
27 |             return null;
28 |         }
29 | 
30 |         return Str::replaceScopeNameCapture($this->name, $captures);
31 |     }
32 | 
33 |     public function captures(): array
34 |     {
35 |         return count(array_filter($this->whileCaptures)) > 0 ? $this->whileCaptures : $this->captures;
36 |     }
37 | 
38 |     /**
39 |      * Compile the pattern into a list of matchable patterns.
40 |      *
41 |      * @return array
42 |      */
43 |     public function compile(ParsedGrammar $grammar, GrammarRepositoryInterface $grammars, bool $allowA, bool $allowG): array
44 |     {
45 |         $compiled = [];
46 | 
47 |         foreach ($this->patterns as $pattern) {
48 |             $compiled = array_merge($compiled, $pattern->compile($grammar, $grammars, $allowA, $allowG));
49 |         }
50 | 
51 |         return $compiled;
52 |     }
53 | 
54 |     public function getId(): int
55 |     {
56 |         return $this->id;
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/src/Highlighting/Highlighter.php:
--------------------------------------------------------------------------------
 1 |   $themes
12 |      */
13 |     public function __construct(
14 |         public array $themes
15 |     ) {}
16 | 
17 |     public function highlight(array $tokens): array
18 |     {
19 |         $highlightedTokens = [];
20 | 
21 |         foreach ($tokens as $i => $line) {
22 |             foreach ($line as $token) {
23 |                 $settings = [];
24 | 
25 |                 foreach ($this->themes as $id => $theme) {
26 |                     if ($matched = $theme->match($token->scopes)) {
27 |                         $settings[$id] = $matched;
28 |                     }
29 |                 }
30 | 
31 |                 $highlightedTokens[$i][] = new HighlightedToken($token, $settings);
32 |             }
33 |         }
34 | 
35 |         return $highlightedTokens;
36 |     }
37 | }
38 | 


--------------------------------------------------------------------------------
/src/Phast/ClassList.php:
--------------------------------------------------------------------------------
 1 | classes, true);
16 |     }
17 | 
18 |     public function toggle(string $class, bool $state = true): self
19 |     {
20 |         if ($state && ! $this->contains($class)) {
21 |             $this->add($class);
22 |         } elseif (! $state && $this->contains($class)) {
23 |             $this->remove($class);
24 |         }
25 | 
26 |         return $this;
27 |     }
28 | 
29 |     public function add(string ...$class): self
30 |     {
31 |         $this->classes = array_unique(array_merge($this->classes, $class));
32 | 
33 |         return $this;
34 |     }
35 | 
36 |     public function remove(string ...$class): self
37 |     {
38 |         $this->classes = array_filter($this->classes, fn (string $c) => ! in_array($c, $class, true));
39 | 
40 |         return $this;
41 |     }
42 | 
43 |     public function all(): array
44 |     {
45 |         return $this->classes;
46 |     }
47 | 
48 |     public function isEmpty(): bool
49 |     {
50 |         return empty($this->classes);
51 |     }
52 | 
53 |     public function __toString(): string
54 |     {
55 |         return implode(' ', array_filter($this->classes, fn (string $class) => trim($class) !== ''));
56 |     }
57 | }
58 | 


--------------------------------------------------------------------------------
/src/Phast/Element.php:
--------------------------------------------------------------------------------
 1 |   $children
11 |      */
12 |     public function __construct(
13 |         public string $tagName,
14 |         public Properties $properties = new Properties,
15 |         public array $children = [],
16 |     ) {}
17 | 
18 |     public function __toString(): string
19 |     {
20 |         $properties = (string) $this->properties;
21 | 
22 |         $element = sprintf(
23 |             '<%s%s>',
24 |             $this->tagName,
25 |             $properties ? ' '.$properties : ''
26 |         );
27 | 
28 |         foreach ($this->children as $child) {
29 |             $element .= (string) $child;
30 |         }
31 | 
32 |         $element .= sprintf('', $this->tagName);
33 | 
34 |         return $element;
35 |     }
36 | }
37 | 


--------------------------------------------------------------------------------
/src/Phast/Literal.php:
--------------------------------------------------------------------------------
 1 | value;
16 |     }
17 | }
18 | 


--------------------------------------------------------------------------------
/src/Phast/Properties.php:
--------------------------------------------------------------------------------
 1 |   $properties
11 |      */
12 |     public function __construct(
13 |         public array $properties = [],
14 |     ) {}
15 | 
16 |     public function set(string $key, string|Stringable $value): self
17 |     {
18 |         $this->properties[$key] = $value;
19 | 
20 |         return $this;
21 |     }
22 | 
23 |     public function get(string $key): mixed
24 |     {
25 |         return $this->properties[$key] ?? null;
26 |     }
27 | 
28 |     public function has(string $key): bool
29 |     {
30 |         return array_key_exists($key, $this->properties);
31 |     }
32 | 
33 |     public function remove(string $key): self
34 |     {
35 |         unset($this->properties[$key]);
36 | 
37 |         return $this;
38 |     }
39 | 
40 |     public function __toString(): string
41 |     {
42 |         $properties = array_filter($this->properties, fn ($value) => $value instanceof ClassList ? (! $value->isEmpty()) : ((bool) $value));
43 | 
44 |         return implode(' ', array_map(
45 |             fn ($key, $value) => sprintf('%s="%s"', $key, $value),
46 |             array_keys($properties),
47 |             $properties,
48 |         ));
49 |     }
50 | }
51 | 


--------------------------------------------------------------------------------
/src/Phast/Root.php:
--------------------------------------------------------------------------------
 1 |   $children
11 |      */
12 |     public function __construct(
13 |         public array $children = [],
14 |     ) {}
15 | 
16 |     public function __toString(): string
17 |     {
18 |         return implode('', array_map(fn (Element|Text $child) => (string) $child, $this->children));
19 |     }
20 | }
21 | 


--------------------------------------------------------------------------------
/src/Phast/Text.php:
--------------------------------------------------------------------------------
1 |   $array
13 |      * @return T
14 |      */
15 |     public static function first(array $array): mixed
16 |     {
17 |         return reset($array);
18 |     }
19 | 
20 |     /**
21 |      * @template K
22 |      * @template V
23 |      *
24 |      * @param  array  $array
25 |      * @return K
26 |      */
27 |     public static function firstKey(array $array): mixed
28 |     {
29 |         return array_key_first($array);
30 |     }
31 | 
32 |     public static function map(array $array, Closure $callback): array
33 |     {
34 |         return array_map($callback, $array);
35 |     }
36 | 
37 |     public static function wrap(mixed $value): array
38 |     {
39 |         if (is_array($value)) {
40 |             return $value;
41 |         }
42 | 
43 |         return [$value];
44 |     }
45 | 
46 |     public static function filterMap(array $array, callable $callback): array
47 |     {
48 |         return array_filter(array_map($callback, $array));
49 |     }
50 | 
51 |     public static function any(array $array, callable $callback): bool
52 |     {
53 |         foreach ($array as $value) {
54 |             if ($callback($value)) {
55 |                 return true;
56 |             }
57 |         }
58 | 
59 |         return false;
60 |     }
61 | 
62 |     public static function partition(array $array, callable $callback): array
63 |     {
64 |         $matches = [];
65 |         $nonMatches = [];
66 | 
67 |         foreach ($array as $key => $value) {
68 |             if ($callback($value, $key)) {
69 |                 $matches[$key] = $value;
70 |             } else {
71 |                 $nonMatches[$key] = $value;
72 |             }
73 |         }
74 | 
75 |         return [$matches, $nonMatches];
76 |     }
77 | 
78 |     public static function flatten(array $array): array
79 |     {
80 |         return array_merge(...array_map(fn ($item) => is_array($item) ? self::flatten($item) : [$item], $array));
81 |     }
82 | }
83 | 


--------------------------------------------------------------------------------
/src/Support/Str.php:
--------------------------------------------------------------------------------
 1 |  `storage.type.const.php`
52 |      */
53 |     public static function replaceScopeNameCapture(string $scopeName, array $captures): string
54 |     {
55 |         return preg_replace_callback(self::CAPTURING_REGEX_SOURCE, function (array $matches) use ($captures) {
56 |             $capture = $captures[intval($matches[1])];
57 | 
58 |             if (! $capture) {
59 |                 return $matches[0];
60 |             }
61 | 
62 |             $result = $capture[0];
63 | 
64 |             if ($result === '') {
65 |                 return '';
66 |             }
67 | 
68 |             while ($result && $result[0] === '.') {
69 |                 $result = substr($result, 1);
70 |             }
71 | 
72 |             return match ($matches[3] ?? null) {
73 |                 'downcase' => strtolower($result),
74 |                 'upcase' => strtoupper($result),
75 |                 default => $result,
76 |             };
77 |         }, $scopeName);
78 |     }
79 | }
80 | 


--------------------------------------------------------------------------------
/src/Tests/Adapters/Laravel/TestCase.php:
--------------------------------------------------------------------------------
 1 | scopePath->push($scopeName));
26 |         }
27 | 
28 |         $scopeNames = explode(' ', $scopeName);
29 |         $result = $this;
30 | 
31 |         foreach ($scopeNames as $name) {
32 |             $result = new AttributedScopeStack($result, $result->scopePath->push($name));
33 |         }
34 | 
35 |         return $result;
36 |     }
37 | 
38 |     /**
39 |      * Get the scope names for this stack.
40 |      *
41 |      * @return list
42 |      */
43 |     public function getScopeNames(): array
44 |     {
45 |         return $this->scopePath->getSegments();
46 |     }
47 | 
48 |     /**
49 |      * Create the root scope stack.
50 |      */
51 |     public static function createRoot(string $rootScopeName): AttributedScopeStack
52 |     {
53 |         return new AttributedScopeStack(null, new ScopeStack(null, $rootScopeName));
54 |     }
55 | }
56 | 


--------------------------------------------------------------------------------
/src/TextMate/LineTokens.php:
--------------------------------------------------------------------------------
 1 |   $tokens
18 |      */
19 |     public function __construct(
20 |         public string $lineText,
21 |         public array $tokens = [],
22 |     ) {}
23 | 
24 |     /**
25 |      * Produce a set of tokens from the given state stack.
26 |      */
27 |     public function produce(StateStack $stack, int $endIndex): void
28 |     {
29 |         $this->produceFromScopes($stack->contentNameScopesList, $endIndex);
30 |     }
31 | 
32 |     /**
33 |      * Produce a set of tokens from the given scope list.
34 |      */
35 |     public function produceFromScopes(?AttributedScopeStack $scopesList, int $endIndex): void
36 |     {
37 |         if ($this->lastTokenEndIndex >= $endIndex) {
38 |             return;
39 |         }
40 | 
41 |         $scopes = $scopesList?->getScopeNames() ?? [];
42 | 
43 |         $this->tokens[] = new Token(
44 |             scopes: $scopes,
45 |             text: substr($this->lineText, $this->lastTokenEndIndex, $endIndex - $this->lastTokenEndIndex),
46 |             start: $this->lastTokenEndIndex,
47 |             end: $endIndex,
48 |         );
49 | 
50 |         $this->lastTokenEndIndex = $endIndex;
51 |     }
52 | 
53 |     /**
54 |      * Get all of the tokens in this line.
55 |      *
56 |      * @return array
57 |      */
58 |     public function getResult(StateStack $stack, int $lineLength): array
59 |     {
60 |         if (count($this->tokens) > 0 && $this->tokens[count($this->tokens) - 1]->start === $lineLength) {
61 |             array_pop($this->tokens);
62 |         }
63 | 
64 |         if (count($this->tokens) === 0) {
65 |             $this->lastTokenEndIndex = -1;
66 |             $this->produce($stack, $lineLength);
67 |             $this->tokens[count($this->tokens) - 1]->start = 0;
68 |         }
69 | 
70 |         return $this->tokens;
71 |     }
72 | }
73 | 


--------------------------------------------------------------------------------
/src/TextMate/LocalStackElement.php:
--------------------------------------------------------------------------------
 1 | 
29 |      */
30 |     public function getSegments(): array
31 |     {
32 |         $stack = $this;
33 |         $result = [];
34 | 
35 |         while ($stack !== null) {
36 |             $result[] = $stack->scopeName;
37 |             $stack = $stack->parent;
38 |         }
39 | 
40 |         return array_reverse($result);
41 |     }
42 | 
43 |     /**
44 |      * Get a string representation of the stack.
45 |      */
46 |     public function __toString(): string
47 |     {
48 |         return implode(' ', $this->getSegments());
49 |     }
50 | }
51 | 


--------------------------------------------------------------------------------
/src/TextMate/StateStack.php:
--------------------------------------------------------------------------------
  1 | depth = $parent ? $parent->depth + 1 : 0;
 30 |     }
 31 | 
 32 |     /**
 33 |      * Pop the current state stack.
 34 |      */
 35 |     public function pop(): ?StateStack
 36 |     {
 37 |         return $this->parent;
 38 |     }
 39 | 
 40 |     /**
 41 |      * Safely pop the current state stack.
 42 |      */
 43 |     public function safePop(): StateStack
 44 |     {
 45 |         if ($this->parent === null) {
 46 |             return $this;
 47 |         }
 48 | 
 49 |         return $this->parent;
 50 |     }
 51 | 
 52 |     /**
 53 |      * Push the given data into a new state stack.
 54 |      */
 55 |     public function push(PatternInterface $pattern, int $enterPos, int $anchorPos, bool $beginRuleCapturedEOL, ?string $endRule, ?AttributedScopeStack $nameScopesList, ?AttributedScopeStack $contentNameScopesList): StateStack
 56 |     {
 57 |         return new StateStack(
 58 |             parent: $this,
 59 |             pattern: $pattern,
 60 |             enterPos: $enterPos,
 61 |             anchorPos: $anchorPos,
 62 |             beginRuleCapturedEOL: $beginRuleCapturedEOL,
 63 |             endRule: $endRule,
 64 |             nameScopesList: $nameScopesList,
 65 |             contentNameScopesList: $contentNameScopesList,
 66 |         );
 67 |     }
 68 | 
 69 |     /**
 70 |      * Generate a near-identical state stack with the given content name scopes list.
 71 |      */
 72 |     public function withContentNameScopesList(AttributedScopeStack $contentNameScopesList): StateStack
 73 |     {
 74 |         $stack = clone $this;
 75 |         $stack->contentNameScopesList = $contentNameScopesList;
 76 | 
 77 |         return $stack;
 78 |     }
 79 | 
 80 |     /**
 81 |      * Generate a near-identical state stack with the given end rule.
 82 |      */
 83 |     public function withEndRule(EndPattern|WhilePattern $rule): StateStack
 84 |     {
 85 |         $stack = clone $this;
 86 |         $stack->pattern = $rule;
 87 | 
 88 |         return $stack;
 89 |     }
 90 | 
 91 |     /**
 92 |      * Check whether this state stack has the same rule as the given state stack.
 93 |      */
 94 |     public function hasSameRuleAs(StateStack $other): bool
 95 |     {
 96 |         $el = $this;
 97 | 
 98 |         while ($el !== null && $el->enterPos === $other->enterPos) {
 99 |             if ($el->pattern->getId() === $other->pattern->getId()) {
100 |                 return true;
101 |             }
102 | 
103 |             $el = $el->parent;
104 |         }
105 | 
106 |         return false;
107 |     }
108 | 
109 |     /**
110 |      * Reset the state stack.
111 |      */
112 |     public function reset(): void
113 |     {
114 |         $el = $this;
115 | 
116 |         while ($el !== null) {
117 |             $el->enterPos = -1;
118 |             $el->anchorPos = -1;
119 |             $el = $el->parent;
120 |         }
121 |     }
122 | }
123 | 


--------------------------------------------------------------------------------
/src/TextMate/WhileStackElement.php:
--------------------------------------------------------------------------------
 1 |   $colors
 9 |      * @param  TokenColor[]  $tokenColors
10 |      */
11 |     public function __construct(
12 |         public string $name,
13 |         public array $colors = [],
14 |         public array $tokenColors = [],
15 |     ) {}
16 | 
17 |     public function match(array $scopes): ?TokenSettings
18 |     {
19 |         $matches = [];
20 | 
21 |         foreach ($this->tokenColors as $tokenColor) {
22 |             if ($result = $tokenColor->match($scopes)) {
23 |                 $matches[] = new TokenColorMatchResult($tokenColor, $result);
24 |             }
25 |         }
26 | 
27 |         // No matches, so no need to highlight.
28 |         if ($matches === []) {
29 |             return null;
30 |         }
31 | 
32 |         // We've only got a single match so no need to do any specificity calculations.
33 |         if (count($matches) === 1) {
34 |             return $matches[0]->tokenColor->settings;
35 |         }
36 | 
37 |         // We need to sort the matches based on specificity.
38 |         // The precedence logic based on `vscode-textmate` is:
39 |         // 1. The depth of the match in the token's scope hierarchy -> deeper matches are more specific.
40 |         // 2. The dot count of the matching scope selector -> more segments makes it more specific.
41 |         // 3. If there's a tie, figure out how many ancestral matches there were and prefer the one with more ancestors.
42 |         usort($matches, function (TokenColorMatchResult $a, TokenColorMatchResult $b): int {
43 |             if ($a->scopeMatchResult->depth !== $b->scopeMatchResult->depth) {
44 |                 return $b->scopeMatchResult->depth - $a->scopeMatchResult->depth;
45 |             }
46 | 
47 |             if ($a->scopeMatchResult->length !== $b->scopeMatchResult->length) {
48 |                 return $b->scopeMatchResult->length - $a->scopeMatchResult->length;
49 |             }
50 | 
51 |             return $b->scopeMatchResult->ancestral - $a->scopeMatchResult->ancestral;
52 |         });
53 | 
54 |         return TokenSettings::flatten(array_map(fn (TokenColorMatchResult $match) => $match->tokenColor->settings, $matches));
55 |     }
56 | 
57 |     public function base(): TokenSettings
58 |     {
59 |         return new TokenSettings(
60 |             $this->colors['editor.background'] ?? null,
61 |             $this->colors['editor.foreground'] ?? null,
62 |             null,
63 |         );
64 |     }
65 | }
66 | 


--------------------------------------------------------------------------------
/src/Theme/ScopeMatchResult.php:
--------------------------------------------------------------------------------
 1 |  __DIR__."/../../resources/themes/{$this->value}.json",
74 |         };
75 |     }
76 | 
77 |     public function toParsedTheme(ThemeRepositoryInterface $repository): ParsedTheme
78 |     {
79 |         return $repository->get($this->value);
80 |     }
81 | 
82 |     public static function parse(array $theme): ParsedTheme
83 |     {
84 |         return (new ThemeParser)->parse($theme);
85 |     }
86 | }
87 | 


--------------------------------------------------------------------------------
/src/Theme/ThemeParser.php:
--------------------------------------------------------------------------------
 1 |  trim($part), explode(',', $part));
43 | 
44 |                 foreach ($parts as $part) {
45 |                     $scope[] = new Scope(array_map(fn (string $p) => trim($p), explode(' ', $part)));
46 |                 }
47 |             }
48 | 
49 |             return new TokenColor($scope, new TokenSettings(
50 |                 $tokenColor['settings']['background'] ?? null,
51 |                 $tokenColor['settings']['foreground'] ?? null,
52 |                 $tokenColor['settings']['fontStyle'] ?? null
53 |             ));
54 |         }, $theme['tokenColors']);
55 | 
56 |         return new ParsedTheme($name, $colors, $tokenColors);
57 |     }
58 | }
59 | 


--------------------------------------------------------------------------------
/src/Theme/ThemeRepository.php:
--------------------------------------------------------------------------------
 1 | themes[$theme->value] = $theme->path();
16 |         }
17 |     }
18 | 
19 |     public function get(string $name): ParsedTheme
20 |     {
21 |         if (! $this->has($name)) {
22 |             throw UnrecognisedThemeException::make($name);
23 |         }
24 | 
25 |         $theme = $this->themes[$name];
26 | 
27 |         if ($theme instanceof ParsedTheme) {
28 |             return $theme;
29 |         }
30 | 
31 |         $parser = new ThemeParser;
32 | 
33 |         return $this->themes[$name] = $parser->parse(json_decode(file_get_contents($theme), true));
34 |     }
35 | 
36 |     public function has(string $name): bool
37 |     {
38 |         return isset($this->themes[$name]);
39 |     }
40 | 
41 |     public function register(string $name, string|ParsedTheme $pathOrTheme): void
42 |     {
43 |         $this->themes[$name] = $pathOrTheme;
44 |     }
45 | 
46 |     public function resolve(string|Theme|ParsedTheme $theme): ParsedTheme
47 |     {
48 |         if ($theme instanceof ParsedTheme) {
49 |             return $theme;
50 |         }
51 | 
52 |         return match (true) {
53 |             is_string($theme) => $this->get($theme),
54 |             $theme instanceof Theme => $theme->toParsedTheme($this),
55 |         };
56 |     }
57 | }
58 | 


--------------------------------------------------------------------------------
/src/Theme/TokenColor.php:
--------------------------------------------------------------------------------
 1 | scope as $scope) {
18 |             if ($result = $scope->matches($scopes)) {
19 |                 return $result;
20 |             }
21 |         }
22 | 
23 |         return false;
24 |     }
25 | }
26 | 


--------------------------------------------------------------------------------
/src/Theme/TokenColorMatchResult.php:
--------------------------------------------------------------------------------
 1 |   $settings
 18 |      */
 19 |     public static function flatten(array $settings): TokenSettings
 20 |     {
 21 |         $flattened = [
 22 |             'background' => null,
 23 |             'foreground' => null,
 24 |             'fontStyle' => null,
 25 |         ];
 26 | 
 27 |         foreach ($settings as $setting) {
 28 |             if (! isset($flattened['background']) && isset($setting->background)) {
 29 |                 $flattened['background'] = $setting->background;
 30 |             }
 31 | 
 32 |             if (! isset($flattened['foreground']) && isset($setting->foreground)) {
 33 |                 $flattened['foreground'] = $setting->foreground;
 34 |             }
 35 | 
 36 |             if (! isset($flattened['fontStyle']) && isset($setting->fontStyle)) {
 37 |                 $flattened['fontStyle'] = $setting->fontStyle;
 38 |             }
 39 |         }
 40 | 
 41 |         return new TokenSettings(
 42 |             $flattened['background'],
 43 |             $flattened['foreground'],
 44 |             $flattened['fontStyle']
 45 |         );
 46 |     }
 47 | 
 48 |     public function toCssVarString(string $prefix): string
 49 |     {
 50 |         $styles = $this->toStyleArray();
 51 |         $vars = [];
 52 | 
 53 |         foreach ($styles as $property => $value) {
 54 |             $vars[] = "--phiki-{$prefix}-{$property}: {$value}";
 55 |         }
 56 | 
 57 |         return implode(';', $vars);
 58 |     }
 59 | 
 60 |     public function toStyleArray(): array
 61 |     {
 62 |         $styles = [];
 63 | 
 64 |         if (isset($this->background)) {
 65 |             $styles['background-color'] = $this->background;
 66 |         }
 67 | 
 68 |         if (isset($this->foreground)) {
 69 |             $styles['color'] = $this->foreground;
 70 |         }
 71 | 
 72 |         $fontStyles = explode(' ', $this->fontStyle ?? '');
 73 | 
 74 |         foreach ($fontStyles as $fontStyle) {
 75 |             if ($fontStyle === 'underline') {
 76 |                 $styles['text-decoration'] = 'underline';
 77 |             }
 78 | 
 79 |             if ($fontStyle === 'italic') {
 80 |                 $styles['font-style'] = 'italic';
 81 |             }
 82 | 
 83 |             if ($fontStyle === 'bold') {
 84 |                 $styles['font-weight'] = 'bold';
 85 |             }
 86 | 
 87 |             if ($fontStyle === 'strikethrough') {
 88 |                 $styles['text-decoration'] = 'line-through';
 89 |             }
 90 |         }
 91 | 
 92 |         return $styles;
 93 |     }
 94 | 
 95 |     public function toStyleString(): string
 96 |     {
 97 |         $styles = $this->toStyleArray();
 98 |         $styleString = '';
 99 | 
100 |         foreach ($styles as $property => $value) {
101 |             $styleString .= "{$property}: {$value};";
102 |         }
103 | 
104 |         return $styleString;
105 |     }
106 | }
107 | 


--------------------------------------------------------------------------------
/src/Token/HighlightedToken.php:
--------------------------------------------------------------------------------
 1 |   $settings
11 |      */
12 |     public function __construct(
13 |         public Token $token,
14 |         public array $settings,
15 |     ) {}
16 | }
17 | 


--------------------------------------------------------------------------------
/src/Token/Token.php:
--------------------------------------------------------------------------------
 1 | >  $tokens
 30 |      */
 31 |     public function tokens(array $tokens): array
 32 |     {
 33 |         return $tokens;
 34 |     }
 35 | 
 36 |     /**
 37 |      * Modify the highlighted tokens before they are converted into the HTML AST.
 38 |      *
 39 |      * @param  array>  $tokens
 40 |      */
 41 |     public function highlighted(array $tokens): array
 42 |     {
 43 |         return $tokens;
 44 |     }
 45 | 
 46 |     /**
 47 |      * Modify the root HTML element.
 48 |      */
 49 |     public function root(Root $root): Root
 50 |     {
 51 |         return $root;
 52 |     }
 53 | 
 54 |     /**
 55 |      * Modify the 
 tag.
 56 |      */
 57 |     public function pre(Element $pre): Element
 58 |     {
 59 |         return $pre;
 60 |     }
 61 | 
 62 |     /**
 63 |      * Modify the  tag.
 64 |      */
 65 |     public function code(Element $code): Element
 66 |     {
 67 |         return $code;
 68 |     }
 69 | 
 70 |     /**
 71 |      * Modify the  for each line.
 72 |      *
 73 |      * @param  array  $tokens
 74 |      */
 75 |     public function line(Element $span, array $tokens, int $index): Element
 76 |     {
 77 |         return $span;
 78 |     }
 79 | 
 80 |     /**
 81 |      * Modify the  for each token.
 82 |      */
 83 |     public function token(Element $span, HighlightedToken $token, int $index, int $line): Element
 84 |     {
 85 |         return $span;
 86 |     }
 87 | 
 88 |     /**
 89 |      * Modify the  for line number.
 90 |      */
 91 |     public function gutter(Element $span, int $lineNumber): Element
 92 |     {
 93 |         return $span;
 94 |     }
 95 | 
 96 |     /**
 97 |      * Modify the HTML output after the AST has been converted.
 98 |      */
 99 |     public function postprocess(string $html): string
100 |     {
101 |         return $html;
102 |     }
103 | 
104 |     /**
105 |      * Store the meta object.
106 |      */
107 |     public function withMeta(Meta $meta): void
108 |     {
109 |         $this->meta = $meta;
110 |     }
111 | }
112 | 


--------------------------------------------------------------------------------
/src/Transformers/AddClassesTransformer.php:
--------------------------------------------------------------------------------
 1 | ` for each token.
18 |      */
19 |     public function token(Element $span, HighlightedToken $token, int $index, int $line): Element
20 |     {
21 |         $classList = $span->properties->get('class') ?? new ClassList;
22 | 
23 |         foreach ($token->token->scopes as $scope) {
24 |             $classList->add('phiki-'.$scope);
25 |         }
26 | 
27 |         $span->properties->set('class', $classList);
28 | 
29 |         if (! $this->styles) {
30 |             $span->properties->remove('style');
31 |         }
32 | 
33 |         return $span;
34 |     }
35 | }
36 | 


--------------------------------------------------------------------------------
/src/Transformers/Concerns/RequiresGrammar.php:
--------------------------------------------------------------------------------
 1 | grammar = $grammar;
14 |     }
15 | }
16 | 


--------------------------------------------------------------------------------
/src/Transformers/Concerns/RequiresThemes.php:
--------------------------------------------------------------------------------
 1 | 
 9 |      */
10 |     protected array $themes;
11 | 
12 |     /**
13 |      * @param array $themes
14 |      */
15 |     public function withThemes(array $themes): void
16 |     {
17 |         $this->themes = $themes;
18 |     }
19 | }
20 | 


--------------------------------------------------------------------------------
/src/Transformers/Decorations/CodeDecoration.php:
--------------------------------------------------------------------------------
 1 | classes->add(...$classes);
21 | 
22 |         return $this;
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/src/Transformers/Decorations/DecorationTransformer.php:
--------------------------------------------------------------------------------
 1 |   $decorations
12 |      */
13 |     public function __construct(
14 |         public array &$decorations,
15 |     ) {}
16 | 
17 |     public function pre(Element $pre): Element
18 |     {
19 |         foreach ($this->decorations as $decoration) {
20 |             if (! $decoration instanceof PreDecoration) {
21 |                 continue;
22 |             }
23 | 
24 |             $pre->properties->get('class')->add(...$decoration->classes->all());
25 |         }
26 | 
27 |         return $pre;
28 |     }
29 | 
30 |     public function code(Element $code): Element
31 |     {
32 |         foreach ($this->decorations as $decoration) {
33 |             if (! $decoration instanceof CodeDecoration) {
34 |                 continue;
35 |             }
36 | 
37 |             $code->properties->get('class')->add(...$decoration->classes->all());
38 |         }
39 | 
40 |         return $code;
41 |     }
42 | 
43 |     public function line(Element $span, array $tokens, int $index): Element
44 |     {
45 |         foreach ($this->decorations as $decoration) {
46 |             if (! $decoration instanceof LineDecoration) {
47 |                 continue;
48 |             }
49 | 
50 |             if (! $decoration->appliesToLine($index)) {
51 |                 continue;
52 |             }
53 | 
54 |             $span->properties->get('class')->add(...$decoration->classes->all());
55 |         }
56 | 
57 |         return $span;
58 |     }
59 | 
60 |     public function gutter(Element $span, int $lineNumber): Element
61 |     {
62 |         foreach ($this->decorations as $decoration) {
63 |             if (! $decoration instanceof GutterDecoration) {
64 |                 continue;
65 |             }
66 | 
67 |             $span->properties->get('class')->add(...$decoration->classes->all());
68 |         }
69 | 
70 |         return $span;
71 |     }
72 | }
73 | 


--------------------------------------------------------------------------------
/src/Transformers/Decorations/GutterDecoration.php:
--------------------------------------------------------------------------------
 1 | classes->add(...$classes);
21 | 
22 |         return $this;
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/src/Transformers/Decorations/LineDecoration.php:
--------------------------------------------------------------------------------
 1 |   $line
11 |      */
12 |     public function __construct(
13 |         public int|array $line,
14 |         public ClassList $classes,
15 |     ) {}
16 | 
17 |     public static function forLine(int $line): self
18 |     {
19 |         return new self($line, new ClassList);
20 |     }
21 | 
22 |     public function class(string ...$classes): self
23 |     {
24 |         $this->classes->add(...$classes);
25 | 
26 |         return $this;
27 |     }
28 | 
29 |     public function appliesToLine(int $line): bool
30 |     {
31 |         return $this->line === $line || (is_array($this->line) && $line >= $this->line[0] && $line <= $this->line[1]);
32 |     }
33 | }
34 | 


--------------------------------------------------------------------------------
/src/Transformers/Decorations/PreDecoration.php:
--------------------------------------------------------------------------------
 1 | classes->add(...$classes);
21 | 
22 |         return $this;
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/src/Transformers/Meta.php:
--------------------------------------------------------------------------------
 1 |