├── .prettierignore ├── .prettierrc.js ├── logo.png ├── logo.psd ├── screenshot.png ├── .gitignore ├── .vscodeignore ├── .editorconfig ├── tsconfig.json ├── .eslintrc.js ├── .vscode └── launch.json ├── code-examples ├── .sh ├── .py ├── .go ├── .c ├── .java ├── .ts ├── jquery.github.js ├── .css ├── .html └── .js ├── LICENSE ├── src ├── models.ts ├── util.ts ├── build.ts ├── colors.ts ├── workbench.ts └── tokens.ts ├── CHANGELOG.md ├── README.md └── package.json /.prettierignore: -------------------------------------------------------------------------------- 1 | themes/ 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | singleQuote: true, 4 | } 5 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamsome/vscode-theme-gruvbox-minor/HEAD/logo.png -------------------------------------------------------------------------------- /logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamsome/vscode-theme-gruvbox-minor/HEAD/logo.psd -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adamsome/vscode-theme-gruvbox-minor/HEAD/screenshot.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | themes/ 3 | 4 | node_modules/ 5 | *.log 6 | 7 | *.code-workspace 8 | *.vsix 9 | 10 | *.local.* 11 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | 5 | build/ 6 | src/ 7 | node_modules/ 8 | *.log 9 | *.code-workspace 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "es5", 6 | "sourceMap": true, 7 | "outDir": "./build", 8 | "strictNullChecks": true, 9 | "noImplicitAny": true, 10 | "noUnusedParameters": true, 11 | "noUnusedLocals": true, 12 | "types": ["node"] 13 | }, 14 | "exclude": ["node_modules"], 15 | "include": ["./src/**/*"] 16 | } 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | extends: [ 4 | 'plugin:@typescript-eslint/recommended', 5 | 'prettier/@typescript-eslint', 6 | 'plugin:prettier/recommended', 7 | ], 8 | rules: { 9 | '@typescript-eslint/member-delimiter-style': 'off', 10 | '@typescript-eslint/no-unused-vars': [ 11 | 'error', 12 | { argsIgnorePattern: '^_', ignoreRestSiblings: true }, 13 | ], 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "type": "node", 7 | "request": "launch", 8 | "name": "Make Themes", 9 | "program": "${workspaceFolder}/build/index.js", 10 | "sourceMaps": true, 11 | "outFiles": ["${workspaceFolder}/build/**/*.js"] 12 | }, 13 | { 14 | "type": "node", 15 | "request": "launch", 16 | "name": "Build & Make Themes", 17 | "runtimeExecutable": "npm", 18 | "runtimeArgs": ["run-script", "start"], 19 | "port": 9229 20 | }, 21 | { 22 | "name": "Launch Extension", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "internalConsoleOptions": "openOnFirstSessionStart", 26 | "stopOnEntry": false, 27 | "runtimeExecutable": "${execPath}", 28 | "args": ["--extensionDevelopmentPath=${workspaceRoot}"] 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /code-examples/.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $ROOT_DIR 4 | DOT_FILES="lastpass weechat ssh Xauthority" 5 | for dotfile in $DOT_FILES; do conform_link "$DATA_DIR/$dotfile" ".$dotfile"; done 6 | 7 | case "$PLATFORM" in 8 | linux) 9 | #conform_link "$CONF_DIR/shell/zshenv" ".zshenv" 10 | crontab -l > $ROOT_DIR/tmp/crontab-conflict-arch 11 | cd $ROOT_DIR/$CONF_DIR/cron 12 | if [[ "$(diff ~/tmp/crontab-conflict-arch crontab-current-arch)" == "" 13 | ]]; 14 | then # no difference with current backup 15 | logger "$LOG_PREFIX: crontab live settings match stored "\ 16 | "settings; no restore required" 17 | rm ~/tmp/crontab-conflict-arch 18 | else # current crontab settings in file do not match live settings 19 | crontab $ROOT_DIR/$CONF_DIR/cron/crontab-current-arch 20 | logger "$LOG_PREFIX: crontab stored settings conflict with "\ 21 | "live settings; stored settings restored. "\ 22 | "Previous settings recorded in ~/tmp/crontab-conflict-arch." 23 | fi 24 | ;; 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Adam Banda 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 | -------------------------------------------------------------------------------- /code-examples/.py: -------------------------------------------------------------------------------- 1 | '''Binary Tree node class and traversal functions 2 | 3 | A node object holds a value, and optional left and/or right child 4 | ''' 5 | 6 | class node: 7 | '''Binary Tree Node''' 8 | def __init__(self, value, left=None, right=None): 9 | self.value = value 10 | self.left = left 11 | self.right = right 12 | 13 | def __str__(self, unicode=True, spacing=' '): 14 | '''Returns subtree starting from this node 15 | 16 | Use the unicode flag to use unicode numbers (unicode characters are still used for the branches) 17 | ''' 18 | ret = '' 19 | if self.right: # right branch 20 | ret += self.right.__str__(spacing = spacing[:-2] + ('│ ' if spacing[-2:] == '└─' else ' ') + '┌─', unicode=unicode) 21 | ret += spacing + (chr(self.value + (10121 if self.value < 11 else 9440)) if unicode else str(self.value)) + '\n' 22 | if self.left: # left branch 23 | ret += self.left.__str__(spacing = spacing[:-2] + ('│ ' if spacing[-2:] == '┌─' else ' ') + '└─',unicode=unicode) 24 | 25 | return ret 26 | 27 | def __repr__(self): 28 | return "\n%s" % str(self.__str__())[:-1] 29 | 30 | def print_tree(self, unicode=True): 31 | '''Print subtree starting from this node''' 32 | print(str(self.__str__(unicode=unicode))[:-1]) -------------------------------------------------------------------------------- /src/models.ts: -------------------------------------------------------------------------------- 1 | export enum Type { 2 | Dark = 'dark', 3 | Light = 'light', 4 | } 5 | export enum Subtype { 6 | Hard = 'hard', 7 | Medium = 'medium', 8 | Soft = 'soft', 9 | } 10 | export enum Color { 11 | BG = 'bg', 12 | FG = 'fg', 13 | Gray = 'gray', 14 | Red = 'red', 15 | Green = 'green', 16 | Yellow = 'yellow', 17 | Blue = 'blue', 18 | Purple = 'purple', 19 | Aqua = 'aqua', 20 | Orange = 'orange', 21 | // TODO: Sticky Scroll (currently no border available, temp use custom bg) 22 | BG2 = 'bg2', 23 | } 24 | 25 | export interface WorkbenchColors { 26 | [selector: string]: string 27 | } 28 | 29 | export type FontStyle = 'bold' | 'italic' | 'underline' 30 | 31 | export interface TokenSettings { 32 | foreground?: string 33 | fontStyle?: FontStyle 34 | } 35 | 36 | export interface TokenColor { 37 | name?: string 38 | scope?: string | string[] 39 | settings: TokenSettings 40 | } 41 | 42 | export interface Theme { 43 | name: string 44 | type: Type 45 | colors: WorkbenchColors 46 | tokenColors: TokenColor[] 47 | semanticHighlighting: boolean 48 | } 49 | 50 | export enum UITheme { 51 | Dark = 'vs-dark', 52 | Light = 'vs', 53 | } 54 | 55 | export interface ThemeDef { 56 | label: string 57 | uiTheme: UITheme 58 | path: string 59 | make?: boolean 60 | subtype?: Subtype 61 | } 62 | 63 | export interface PackageDef { 64 | contributes?: { 65 | themes?: ThemeDef[] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | import * as path from 'path' 3 | 4 | const JSON_EXT = '.json' 5 | 6 | export function writeJson(filePath: string, value: object): void 7 | export function writeJson( 8 | filePath: string, 9 | fileName: string, 10 | value: object 11 | ): void 12 | export function writeJson( 13 | filePath: string, 14 | valueOrFileName: object | string, 15 | value?: object 16 | ): void { 17 | let _path = 18 | value != null ? path.join(filePath, valueOrFileName as string) : filePath 19 | if (_path.lastIndexOf(JSON_EXT) !== _path.length - JSON_EXT.length) { 20 | _path += JSON_EXT 21 | } 22 | const _value = value ? value : valueOrFileName 23 | fs.writeFileSync(_path, JSON.stringify(_value, null, 2), 'utf8') 24 | } 25 | 26 | export const readJson = (filePath: string): object => 27 | JSON.parse(fs.readFileSync(path.resolve(filePath), 'utf8')) 28 | 29 | export const padZeroes = (size: number, value: number | string): string => { 30 | let _value = value.toString() 31 | while (_value.length < size) { 32 | _value = '0' + _value 33 | } 34 | return _value 35 | } 36 | export const opacity = (percent: number, color: string): string => { 37 | // Convert percent to range from 0 - 255 38 | let percent256 = Math.round((percent * 256) / 100) 39 | percent256 = percent256 < 0 ? 0 : percent256 > 255 ? 255 : percent256 40 | // Convert to hex string 41 | const opacityHex = percent256.toString(16) 42 | // Append, padding left w/ zeroes 43 | return color + padZeroes(2, opacityHex) 44 | } 45 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 2.2.2 4 | 5 | - change editor hover to opaque background ([#4](https://github.com/adamsome/vscode-theme-gruvbox-minor/issues/4)) 6 | 7 | ## 2.2.1 8 | 9 | - fix issue where theme files not published 10 | 11 | ## 2.2.0 12 | 13 | - enable semantic highlighting support 14 | 15 | ## 2.1.0 16 | 17 | - increase border contrast 18 | - add breadcrumb colors 19 | - add menubar colors 20 | - add settings colors 21 | 22 | ## 2.0.0 23 | 24 | - major theme color changes 25 | - add theme generator program to automatically build all themes at once 26 | 27 | ## 1.3.2 28 | 29 | - added borders for activity bar & sidebar 30 | - inactive tab background color 31 | 32 | ## 1.3.1 33 | 34 | - used light foreground for activityBarBadge on light versions 35 | 36 | ## 1.3.0 37 | 38 | - now including 6 variants: Dark & Light with Medium, Hard & Soft contrast 39 | 40 | ## 1.2.0 41 | 42 | - added golang syntax 43 | 44 | ## 1.1.2 45 | 46 | - changed foreground color to use #ebdbb2 instead of fbf1c7 according to the original gruvbox 47 | 48 | ## 1.1.1 49 | 50 | - added minor lisp syntax ([@3ximus](https://github.com/3ximus)) 51 | - added git colors ([@3ximus](https://github.com/3ximus)) 52 | - made scrollbar slider background brighter for accessibility 53 | 54 | ## 1.1.0 55 | 56 | - more workbench colors, improvements & additional languages (c, java, python, shell) ([@3ximus](https://github.com/3ximus)) 57 | 58 | ## 1.0.0 59 | 60 | - added workbench & terminal colors ([@3ximus](https://github.com/3ximus)) 61 | 62 | ## 0.0.6 63 | 64 | - added line highlight color (#32302f) 65 | - changed caret line color to #fbf1c7 66 | -------------------------------------------------------------------------------- /src/build.ts: -------------------------------------------------------------------------------- 1 | import { makeColors } from './colors' 2 | import { Color, PackageDef, Subtype, Theme, Type, UITheme } from './models' 3 | import TokensConfig from './tokens' 4 | import { readJson, writeJson } from './util' 5 | import WorkbenchConfig from './workbench' 6 | 7 | console.log('Reading theme definitions from package.json') 8 | 9 | const pkg: PackageDef = readJson('./package.json') 10 | if (pkg && pkg.contributes && pkg.contributes.themes) { 11 | const themesToMake = pkg.contributes.themes.filter((t) => t.make === true) 12 | if (!themesToMake.length) { 13 | console.warn('No themes defined to make in package.json.') 14 | } 15 | themesToMake.map((t) => { 16 | console.log(`Writing ${t.label} to '${t.path}'`) 17 | const type = t.uiTheme === UITheme.Light ? Type.Light : Type.Dark 18 | const colorBuilder = makeColors(type, t.subtype || Subtype.Medium) 19 | const colors = WorkbenchConfig(colorBuilder) 20 | const tokenColors = TokensConfig(colorBuilder) 21 | const theme: Theme = { 22 | name: t.label, 23 | type, 24 | semanticHighlighting: true, 25 | colors, 26 | tokenColors, 27 | } 28 | 29 | // Exceptions to the Light is the inverse of Dark rule 30 | if (type === Type.Light) { 31 | // Invert the activity badge text (FG1 to BG1) 32 | theme.colors['activityBarBadge.foreground'] = colorBuilder(Color.BG, 1) 33 | // Remove inactive tab background opacity 34 | theme.colors['tab.inactiveBackground'] = colorBuilder(Color.BG, 1) 35 | } 36 | 37 | writeJson(t.path, theme) 38 | }) 39 | } else { 40 | console.error('Could not find themes in package.json to make.') 41 | } 42 | -------------------------------------------------------------------------------- /code-examples/.go: -------------------------------------------------------------------------------- 1 | package badger 2 | 3 | import ( 4 | "bytes" 5 | "container/heap" 6 | "fmt" 7 | "math" 8 | "strconv" 9 | "sync" 10 | "sync/atomic" 11 | "time" 12 | 13 | "github.com/dgraph-io/badger/y" 14 | farm "github.com/dgryski/go-farm" 15 | "github.com/pkg/errors" 16 | ) 17 | 18 | type uint64Heap []uint64 19 | 20 | func (u uint64Heap) Len() int { return len(u) } 21 | func (u uint64Heap) Less(i int, j int) bool { return u[i] < u[j] } 22 | func (u uint64Heap) Swap(i int, j int) { u[i], u[j] = u[j], u[i] } 23 | func (u *uint64Heap) Push(x interface{}) { *u = append(*u, x.(uint64)) } 24 | func (u *uint64Heap) Pop() interface{} { 25 | old := *u 26 | n := len(old) 27 | x := old[n-1] 28 | *u = old[0 : n-1] 29 | return x 30 | } 31 | 32 | type oracle struct { 33 | curRead uint64 // Managed by the mutex. 34 | refCount int64 35 | isManaged bool // Does not change value, so no locking required. 36 | 37 | sync.Mutex 38 | nextCommit uint64 39 | 40 | // These two structures are used to figure out when a commit is done. The minimum done commit is 41 | // used to update curRead. 42 | commitMark uint64Heap 43 | pendingCommits map[uint64]struct{} 44 | 45 | // commits stores a key fingerprint and latest commit counter for it. 46 | // refCount is used to clear out commits map to avoid a memory blowup. 47 | commits map[uint64]uint64 48 | } 49 | 50 | func (o *oracle) addRef() { 51 | atomic.AddInt64(&o.refCount, 1) 52 | } 53 | 54 | func (o *oracle) decrRef() { 55 | if count := atomic.AddInt64(&o.refCount, -1); count == 0 { 56 | // Clear out pendingCommits maps to release memory. 57 | o.Lock() 58 | y.AssertTrue(len(o.commitMark) == 0) 59 | y.AssertTrue(len(o.pendingCommits) == 0) 60 | if len(o.commits) >= 1000 { // If the map is still small, let it slide. 61 | o.commits = make(map[uint64]uint64) 62 | } 63 | o.Unlock() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /code-examples/.c: -------------------------------------------------------------------------------- 1 | /* Common */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* System */ 10 | #include 11 | #include 12 | 13 | /* Net */ 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | /* Default port if none is specified */ 22 | #define DEFAULT_PORT_ECP 58057 23 | #define DEFAULT_PORT_TES 59000 24 | 25 | 26 | /* 27 | * This program creates a udp server on a given port an waits for incoming requests 28 | * It offers a shell so you can kill the created server 29 | */ 30 | int main(int argc, char** argv) 31 | { 32 | int port, socket_fd, server_pid; 33 | char cmd[10]; 34 | char **parsed_cmd; 35 | 36 | if(argc == 1) 37 | port = DEFAULT_PORT_ECP; 38 | else if(argc == 3 && ((strcmp(argv[1],"-p")) == 0)) 39 | port = atoi(argv[2]); 40 | else{ 41 | printf("ERROR: Wrong input format.\ninput: ./ECP [-p ECPport]\n"); 42 | exit(1); 43 | } 44 | /* Create a UDP server on port */ 45 | server_pid = start_udp_server(port, &socket_fd); 46 | printf("Server PID: %d\n", server_pid); 47 | 48 | printf("Type \"exit\" to terminate server\n"); 49 | while(1){ 50 | printf("> "); 51 | if ((fgets(cmd, 50, stdin)) == NULL){ 52 | perror("[ERROR] no command\n"); 53 | continue; 54 | } 55 | 56 | parsed_cmd = parseString(cmd, "\n"); 57 | 58 | if (strcmp(parsed_cmd[0], "exit") == 0){ 59 | /* To kill the server child process */ 60 | printf("Closing Server...\n"); 61 | close(socket_fd); 62 | if (kill(server_pid, SIGTERM) == -1){ 63 | perror("[ERROR] Killing Server Process"); 64 | free(parsed_cmd); 65 | /* Close server socket */ 66 | exit(-1); 67 | } 68 | /* Exit */ 69 | free(parsed_cmd); 70 | return 0; 71 | } 72 | else 73 | printf("Wrong command \"%s\".\n", parsed_cmd[0]); 74 | 75 | /* Free memory */ 76 | free(parsed_cmd); 77 | } 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gruvbox Minor 2 | 3 | A functional Visual Studio Code theme based off of the original 4 | [gruvbox](https://github.com/morhetz/gruvbox) theme and the 5 | Visual Studio Code 6 | [Gruvbox Theme](https://github.com/jdinhify/vscode-theme-gruvbox). 7 | Contains a dark and light mode as well as three sub-modes each, 8 | hard, medium, and soft. 9 | 10 | ## Screenshot 11 | 12 | ![screenshot](screenshot.png) 13 | 14 | ## Extensions 15 | 16 | ### Font 17 | 18 | The font used in the above preview is [Lilex](https://github.com/mishamyrt/Lilex). 19 | 20 | ### Bracket Highlight 21 | 22 | In Visual Studio Code user settings, add the following to enable editor bracket highlighting: 23 | 24 | ```json 25 | "editor.bracketPairColorization.enabled": true, 26 | ``` 27 | 28 | ### Indent-rainbow 29 | 30 | If you use [indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow), add the following to your settings for matching colors: 31 | 32 | ```json 33 | "indentRainbow.colors": [ 34 | "rgba(250, 189, 47, 0.05)", 35 | "rgba(142, 192, 124, 0.05)", 36 | "rgba(131, 165, 152, 0.05)", 37 | "rgba(211, 134, 155, 0.05)", 38 | "rgba(254, 128, 25, 0.05)" 39 | ], 40 | "indentRainbow.errorColor": "rgba(251, 73, 52, 0.2)", 41 | ``` 42 | 43 | ## PRs are welcomed 44 | 45 | ### Tips 46 | 47 | - In the `json` file, `scope` can be an `array` or a `string` 48 | of CSS classes 49 | - VSCode's `Developer: Inspect TM Scopes` command is useful 50 | to find out the scope 51 | 52 | ### Customization 53 | 54 | Customizations and tweaks can be made to all six themes at once by: 55 | 56 | 1. Saving the customizations in [tokens](src/theme/tokens) for syntax change, 57 | and/or [workbench](src/theme/workbench) for editor chrome changes, 58 | 2. Running `npm start`, which builds the TypeScript files and launches a 59 | program that regenerates the six theme files. 60 | 61 | #### Publishing 62 | 63 | ```bash 64 | npm start 65 | # Replace w/ vscode marketplace publisher ID (e.g. `adamsome-gruvbox`) 66 | vsce login 67 | vsce package 68 | # Replace <...> w/ the semanitic version segment to increment 69 | vsce publish <'patch' | 'minor' | 'major'> 70 | ``` 71 | 72 | ## Thank Yous 73 | 74 | Special thanks to the creator of [gruvbox](https://github.com/morhetz/gruvbox) 75 | 76 | Thanks to: 77 | 78 | - [jdinhify](https://github.com/jdinhify) 79 | - [eximus](https://github.com/3ximus) 80 | 81 | who worked on the original VSCode Gruvbox theme that this is based on: 82 | 83 | [Gruvbox Theme](https://github.com/jdinhify/vscode-theme-gruvbox) 84 | -------------------------------------------------------------------------------- /code-examples/.java: -------------------------------------------------------------------------------- 1 | package globals; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | 7 | import org.apache.commons.codec.binary.Base64; 8 | 9 | import java.security.KeyStore; 10 | import java.security.PrivateKey; 11 | import java.security.PublicKey; 12 | import java.security.Signature; 13 | import java.security.SignatureException; 14 | import java.security.cert.Certificate; 15 | import java.security.cert.CertificateEncodingException; 16 | import java.security.cert.CertificateFactory; 17 | import java.security.cert.X509Certificate; 18 | 19 | 20 | import java.lang.Thread; 21 | 22 | public class Resources { 23 | 24 | // ------- PORTS ------------ 25 | public static final int REGISTRY_PORT = 1099; 26 | 27 | // ------- OTHER ------------ 28 | public static final String CA_DIGEST = "SHA-256"; 29 | 30 | // ------- CERTIFICATES ------------ 31 | 32 | public static Certificate readCertificateFile(String certificateFilePath) throws Exception { 33 | FileInputStream fis; 34 | 35 | try { fis = new FileInputStream(certificateFilePath); } 36 | catch (FileNotFoundException e) { 37 | System.err.println(ERROR_MSG("Certificate File not found: " + certificateFilePath)); 38 | return null; 39 | } 40 | BufferedInputStream bis = new BufferedInputStream(fis); 41 | CertificateFactory cf = CertificateFactory.getInstance("X.509"); 42 | 43 | if (bis.available() > 0) { return cf.generateCertificate(bis); } 44 | bis.close(); 45 | fis.close(); 46 | return null; 47 | } 48 | 49 | public static boolean verifySignedCertificate(Certificate certificate, PublicKey caPublicKey) { 50 | try { certificate.verify(caPublicKey); } 51 | catch (Exception e) { 52 | return false; 53 | } 54 | return true; 55 | } 56 | 57 | public static String convertToPemCertificate(X509Certificate certificate) { 58 | Base64 encoder = new Base64(64, "\n".getBytes()); 59 | String cert_begin = "-----BEGIN CERTIFICATE-----\n"; 60 | String end_cert = "-----END CERTIFICATE-----\n"; 61 | 62 | byte[] derCert = null; 63 | try { 64 | derCert = certificate.getEncoded(); 65 | } catch (CertificateEncodingException e) { 66 | System.err.println(WARNING_MSG("Error in certificate conversion :" + e.getMessage())); 67 | return null; 68 | } 69 | String pemCertPre = new String(encoder.encode(derCert)); 70 | String pemCert = cert_begin + pemCertPre + end_cert; 71 | return pemCert; 72 | } 73 | 74 | // ----------------------------------- 75 | 76 | 77 | // ------- SIGNATURES ------------ 78 | 79 | public static byte[] makeDigitalSignature(byte[] bytes, PrivateKey privateKey) throws Exception { 80 | Signature sig = Signature.getInstance("SHA1WithRSA"); 81 | sig.initSign(privateKey); 82 | sig.update(bytes); 83 | byte[] signature = sig.sign(); 84 | return signature; 85 | } 86 | 87 | public static boolean verifyDigitalSignature(byte[] cipherDigest, byte[] bytes, PublicKey publicKey) throws Exception { 88 | Signature sig = Signature.getInstance("SHA1WithRSA"); 89 | sig.initVerify(publicKey); 90 | sig.update(bytes); 91 | try { 92 | return sig.verify(cipherDigest); 93 | } catch (SignatureException se) { 94 | System.err.println(WARNING_MSG("Invalid Signature :" + se.getMessage())); 95 | return false; 96 | } 97 | } 98 | 99 | public class TestClass() { 100 | Signature sig 101 | 102 | contructor() { 103 | this.sig = Signature.getInstance("SHA1WithRSA") 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-theme-gruvbox-minor", 3 | "version": "2.7.2", 4 | "displayName": "Gruvbox Minor", 5 | "homepage": "https://github.com/adamsome/vscode-theme-gruvbox-minor", 6 | "description": "Gruvbox Minor", 7 | "publisher": "adamsome", 8 | "author": "adamsome (https://github.com/adamsome)", 9 | "license": "MIT", 10 | "scripts": { 11 | "build": "npm run build:compile && npm run build:themes", 12 | "build:compile": "tsc -p .", 13 | "build:themes": "mkdir -p ./themes && node build/build.js", 14 | "start": "npm run build", 15 | "lint": "tsc --noEmit && eslint './src/**/*.{js,ts,tsx}' --quiet --fix", 16 | "vscode:prepublish": "npm run build" 17 | }, 18 | "maintainers": [ 19 | "adamsome (https://github.com/adamsome)" 20 | ], 21 | "contributors": [ 22 | "adamsome (https://github.com/adamsome)", 23 | "jdinhify (https://github.com/jdinhify)", 24 | "eximus (https://github.com/3ximus)" 25 | ], 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/adamsome/vscode-theme-gruvbox-minor.git" 29 | }, 30 | "engines": { 31 | "vscode": "^1.19.0" 32 | }, 33 | "categories": [ 34 | "Themes" 35 | ], 36 | "keywords": [ 37 | "gruvbox-minor", 38 | "gruvbox", 39 | "theme", 40 | "color-theme" 41 | ], 42 | "icon": "logo.png", 43 | "galleryBanner": { 44 | "color": "#32302f", 45 | "theme": "dark" 46 | }, 47 | "contributes": { 48 | "themes": [ 49 | { 50 | "label": "Gruvbox Minor Dark Medium", 51 | "uiTheme": "vs-dark", 52 | "path": "./themes/gruvbox-minor-dark-medium.json", 53 | "subtype": "medium", 54 | "make": true 55 | }, 56 | { 57 | "label": "Gruvbox Minor Dark Hard", 58 | "uiTheme": "vs-dark", 59 | "path": "./themes/gruvbox-minor-dark-hard.json", 60 | "subtype": "hard", 61 | "make": true 62 | }, 63 | { 64 | "label": "Gruvbox Minor Dark Soft", 65 | "uiTheme": "vs-dark", 66 | "path": "./themes/gruvbox-minor-dark-soft.json", 67 | "subtype": "soft", 68 | "make": true 69 | }, 70 | { 71 | "label": "Gruvbox Minor Light Medium", 72 | "uiTheme": "vs", 73 | "path": "./themes/gruvbox-minor-light-medium.json", 74 | "subtype": "medium", 75 | "make": true 76 | }, 77 | { 78 | "label": "Gruvbox Minor Light Hard", 79 | "uiTheme": "vs", 80 | "path": "./themes/gruvbox-minor-light-hard.json", 81 | "subtype": "hard", 82 | "make": true 83 | }, 84 | { 85 | "label": "Gruvbox Minor Light Soft", 86 | "uiTheme": "vs", 87 | "path": "./themes/gruvbox-minor-light-soft.json", 88 | "subtype": "soft", 89 | "make": true 90 | } 91 | ] 92 | }, 93 | "husky": { 94 | "hooks": { 95 | "pre-commit": "tsc --noEmit && lint-staged" 96 | } 97 | }, 98 | "lint-staged": { 99 | "*.{js,ts,tsx}": [ 100 | "eslint --fix", 101 | "git add" 102 | ] 103 | }, 104 | "devDependencies": { 105 | "@types/node": "^14.18.33", 106 | "@typescript-eslint/eslint-plugin": "^5.42.0", 107 | "@typescript-eslint/parser": "^5.42.0", 108 | "eslint": "^8.26.0", 109 | "eslint-config-prettier": "^8.5.0", 110 | "eslint-plugin-prettier": "^4.2.1", 111 | "husky": "^8.0.1", 112 | "lint-staged": "^13.0.3", 113 | "prettier": "^2.7.1", 114 | "typescript": "^4.8.4" 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /code-examples/.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient, HttpHeaders } from '@angular/common/http' 2 | import { Injectable } from '@angular/core' 3 | import { environment as ENV } from 'environments' 4 | import { Observable } from 'rxjs/Observable' 5 | import { catchError, map } from 'rxjs/operators' 6 | import { errorPayload } from '../../error/model/error' 7 | import { KVPList } from '../../shared' 8 | import { toExternalDataframeType } from '../dataframe/type-converter' 9 | import { Error, handleError, log } from '../error-handler' 10 | import { 11 | AddReportRequest, 12 | AddReportResponse, 13 | COMPUTE_CONFIG_DEFAULT, 14 | COMPUTE_SUCCESS_STATUS, 15 | ComputeConfig, 16 | ComputeRequest, 17 | ComputeRequestParameter, 18 | ComputeResponseBase, 19 | ComputeResult, 20 | } from './model' 21 | 22 | const BASE_COMPUTE_URL = ENV.computeServiceUrls.base 23 | const COMPUTE_SYNC_URL = BASE_COMPUTE_URL + ENV.computeServiceUrls.compute.sync 24 | 25 | const BASE_SERVICE_URL = ENV.servicesUrls.base 26 | const ADD_REPORT_URL = BASE_SERVICE_URL + ENV.servicesUrls.report.addReport 27 | 28 | const COMPUTE_SERVICE_FAILED = 'Compute Service Failed' 29 | 30 | @Injectable() 31 | export class ComputeService { 32 | constructor(private http: HttpClient) {} 33 | 34 | addReport(config: ComputeConfig): Observable { 35 | const errorRes: ComputeResult = { outputIDs: [] } 36 | const url = `${ADD_REPORT_URL}/${config.scriptID}` 37 | const body = ComputeService.toAddReportRequest(config) 38 | const opts = { 39 | headers: new HttpHeaders({ 40 | 'Content-Type': 'application/json', 41 | Accept: 'application/json', 42 | }), 43 | } 44 | log.post(url, body) 45 | return this.http.post(url, body, opts).pipe( 46 | map((res) => ComputeService.handleComputeResponse(res.jobInfo)), 47 | catchError(handleError('Add Report', errorRes)) 48 | ) 49 | } 50 | 51 | compute(config: ComputeConfig): Observable { 52 | const errorRes: ComputeResult = { outputIDs: [] } 53 | const body = ComputeService.toComputeRequest(config) 54 | const opts = { 55 | headers: new HttpHeaders({ 56 | 'Content-Type': 'application/json', 57 | Accept: 'application/json', 58 | }), 59 | } 60 | console.log('Api.Compute', JSON.stringify(body, null, 2)) 61 | return this.http 62 | .post(COMPUTE_SYNC_URL, body, opts) 63 | .pipe( 64 | map(ComputeService.handleComputeResponse), 65 | catchError(handleError('Compute', errorRes)) 66 | ) 67 | } 68 | 69 | static handleComputeResponse(res: ComputeResponseBase): ComputeResult { 70 | const error = ComputeService.getComputeResponseError(res) 71 | if (error) { 72 | return { outputIDs: [], error } 73 | } 74 | return { outputIDs: res.dataframes } 75 | } 76 | 77 | static getComputeResponseError(res: ComputeResponseBase): Error | null { 78 | // a compute call is considered a success if: 79 | // - the status is 'Success' 80 | // - there is no value for stderr 81 | // - stdout is an empty string OR 82 | // stdout does not contain 'Error' or 'Exception 83 | // - the compute call generated at least 1 dataframe 84 | if ( 85 | res.status === COMPUTE_SUCCESS_STATUS && 86 | !res.stderr && 87 | res.stdout !== undefined && 88 | (res.stdout.length === 0 || 89 | (res.stdout.length > 0 && 90 | !res.stdout.toLowerCase().includes('error') && 91 | !res.stdout.toLowerCase().includes('exception'))) 92 | ) { 93 | if (res.dataframes && res.dataframes.length === 0) { 94 | return errorPayload('Script had zero output dataframes.') 95 | } else { 96 | return null 97 | } 98 | } 99 | if (res.stderr !== undefined && res.stderr.length > 0) { 100 | return errorPayload(COMPUTE_SERVICE_FAILED, [res.stderr]) 101 | } else if ( 102 | res.stdout !== undefined && 103 | (res.stdout.toLowerCase().includes('error') || 104 | res.stdout.toLowerCase().includes('exception')) 105 | ) { 106 | return errorPayload(COMPUTE_SERVICE_FAILED, [res.stdout]) 107 | } else { 108 | return errorPayload(COMPUTE_SERVICE_FAILED, [res.status]) 109 | } 110 | } 111 | 112 | static toComputeRequest(config: ComputeConfig): ComputeRequest { 113 | const cfg = { ...COMPUTE_CONFIG_DEFAULT, ...config } 114 | return { 115 | user: cfg.username, 116 | scriptId: cfg.scriptID, 117 | parameters: ComputeService.toComputeRequestParams(cfg.options), 118 | dataframes: cfg.inputIDs, 119 | dataframeType: toExternalDataframeType(cfg.outputType!), 120 | computeContainer: cfg.computeContainer!, 121 | environment: cfg.environment!, 122 | } 123 | } 124 | 125 | static toComputeRequestParams( 126 | options: KVPList = [] 127 | ): ComputeRequestParameter[] { 128 | return options.map((o) => { 129 | return { 130 | key: o.name, 131 | value: [o.value], 132 | type: 'string', 133 | } as ComputeRequestParameter 134 | }) 135 | } 136 | 137 | static toAddReportRequest(config: ComputeConfig): AddReportRequest { 138 | return { 139 | parameters: ComputeService.toComputeRequestParams(config.options), 140 | dataframeIds: config.inputIDs, 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/colors.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/camelcase */ 2 | import { Color, Subtype, Type } from './models' 3 | 4 | // prettier-ignore 5 | export const NAMED = { 6 | dark0_hard : '#1d2021', // 234, 29-32-33 7 | dark0 : '#282828', // 235, 40-40-40 8 | dark0_soft : '#32302f', // 236, 50-48-47 9 | dark1 : '#3c3836', // 237, 60-56-54 10 | dark2 : '#504945', // 239, 80-73-69 11 | dark3 : '#665c54', // 241, 102-92-84 12 | dark4 : '#7c6f64', // 243, 124-111-100 13 | dark4_256 : '#7c6f64', // 243, 124-111-100 14 | gray_245 : '#928374', // 245, 146-131-116 15 | gray_244 : '#928374', // 244, 146-131-116 16 | light0_hard : '#f9f5d7', // 230, 249-245-215 17 | light0 : '#fbf1c7', // 229, 253-244-193 18 | light0_soft : '#f2e5bc', // 228, 242-229-188 19 | light1 : '#ebdbb2', // 223, 235-219-178 20 | light2 : '#d5c4a1', // 250, 213-196-161 21 | light3 : '#bdae93', // 248, 189-174-147 22 | light4 : '#a89984', // 246, 168-153-132 23 | light4_256 : '#a89984', // 246, 168-153-132 24 | bright_red : '#fb4934', // 167, 251-73-52 25 | bright_green : '#b8bb26', // 142, 184-187-38 26 | bright_yellow : '#fabd2f', // 214, 250-189-47 27 | bright_blue : '#83a598', // 109, 131-165-152 28 | bright_purple : '#d3869b', // 175, 211-134-155 29 | bright_aqua : '#8ec07c', // 108, 142-192-124 30 | bright_orange : '#fe8019', // 208, 254-128-25 31 | neutral_red : '#cc241d', // 124, 204-36-29 32 | neutral_green : '#98971a', // 106, 152-151-26 33 | neutral_yellow : '#d79921', // 172, 215-153-33 34 | neutral_blue : '#458588', // 66, 69-133-136 35 | neutral_purple : '#b16286', // 132, 177-98-134 36 | neutral_aqua : '#689d6a', // 72, 104-157-106 37 | neutral_orange : '#d65d0e', // 166, 214-93-14 38 | faded_red : '#9d0006', // 88, 157-0-6 39 | faded_green : '#79740e', // 100, 121-116-14 40 | faded_yellow : '#b57614', // 136, 181-118-20 41 | faded_blue : '#076678', // 24, 7-102-120 42 | faded_purple : '#8f3f71', // 96, 143-63-113 43 | faded_aqua : '#427b58', // 66, 66-123-88 44 | faded_orange : '#af3a03', // 130, 175-58-3 45 | } 46 | 47 | const getBG0 = (type: Type, subtype: Subtype): string => { 48 | switch (type) { 49 | case Type.Light: { 50 | switch (subtype) { 51 | case Subtype.Hard: 52 | return NAMED.light0_hard 53 | case Subtype.Soft: 54 | return NAMED.light0_soft 55 | case Subtype.Medium: 56 | default: 57 | return NAMED.light0 58 | } 59 | } 60 | case Type.Dark: 61 | default: { 62 | switch (subtype) { 63 | case Subtype.Hard: 64 | return NAMED.dark0_hard 65 | case Subtype.Soft: 66 | return NAMED.dark0_soft 67 | case Subtype.Medium: 68 | default: 69 | return NAMED.dark0 70 | } 71 | } 72 | } 73 | } 74 | const getDark = (subtype: Subtype): Record => ({ 75 | bg: [ 76 | getBG0(Type.Dark, subtype), 77 | NAMED.dark1, 78 | NAMED.dark2, 79 | NAMED.dark3, 80 | NAMED.dark4, 81 | ], 82 | fg: [NAMED.light0, NAMED.light1, NAMED.light2, NAMED.light3, NAMED.light4], 83 | gray: [NAMED.gray_244], 84 | red: [NAMED.neutral_red, NAMED.bright_red], 85 | green: [NAMED.neutral_green, NAMED.bright_green], 86 | yellow: [NAMED.neutral_yellow, NAMED.bright_yellow], 87 | blue: [NAMED.neutral_blue, NAMED.bright_blue], 88 | purple: [NAMED.neutral_purple, NAMED.bright_purple], 89 | aqua: [NAMED.neutral_aqua, NAMED.bright_aqua], 90 | orange: [NAMED.neutral_orange, NAMED.bright_orange], 91 | bg2: 92 | subtype === Subtype.Soft 93 | ? [NAMED.dark1, NAMED.dark2] 94 | : [NAMED.dark0_soft, NAMED.dark1], 95 | }) 96 | 97 | const getLight = (subtype: Subtype): Record => ({ 98 | bg: [ 99 | getBG0(Type.Light, subtype), 100 | NAMED.light1, 101 | NAMED.light2, 102 | NAMED.light3, 103 | NAMED.light4, 104 | ], 105 | fg: [NAMED.dark0, NAMED.dark1, NAMED.dark2, NAMED.dark3, NAMED.dark4], 106 | gray: [NAMED.gray_244], 107 | red: [NAMED.neutral_red, NAMED.faded_red], 108 | green: [NAMED.neutral_green, NAMED.faded_green], 109 | yellow: [NAMED.neutral_yellow, NAMED.faded_yellow], 110 | blue: [NAMED.neutral_blue, NAMED.faded_blue], 111 | purple: [NAMED.neutral_purple, NAMED.faded_purple], 112 | aqua: [NAMED.neutral_aqua, NAMED.faded_aqua], 113 | orange: [NAMED.neutral_orange, NAMED.faded_orange], 114 | bg2: 115 | subtype === Subtype.Soft 116 | ? [NAMED.light1, NAMED.light2] 117 | : [NAMED.light0_soft, NAMED.light1], 118 | }) 119 | 120 | export const MAP: Record>> = { 121 | dark: { 122 | hard: getDark(Subtype.Hard), 123 | medium: getDark(Subtype.Medium), 124 | soft: getDark(Subtype.Soft), 125 | }, 126 | light: { 127 | hard: getLight(Subtype.Hard), 128 | medium: getLight(Subtype.Medium), 129 | soft: getLight(Subtype.Soft), 130 | }, 131 | } 132 | export const makeColors = (type: Type, subtype: Subtype) => ( 133 | color: Color, 134 | lightness?: number 135 | ): string => { 136 | const c = MAP[type][subtype][color] 137 | return lightness === undefined || lightness < 0 138 | ? c[0] 139 | : lightness >= c.length 140 | ? c[c.length - 1] 141 | : c[lightness] 142 | } 143 | -------------------------------------------------------------------------------- /code-examples/jquery.github.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-this-alias */ 2 | /* eslint-disable no-var */ 3 | /* eslint-disable @typescript-eslint/camelcase */ 4 | /* eslint-disable @typescript-eslint/explicit-function-return-type */ 5 | // -- Github Repository -------------------------------------------------------- 6 | 7 | function GithubRepo(repo) { 8 | this.description = repo.description 9 | this.forks = repo.forks_count 10 | this.name = repo.name 11 | this.open_issues = repo.open_issues 12 | this.pushed_at = repo.pushed_at 13 | this.url = repo.html_url 14 | this.stargazers = repo.stargazers_count 15 | } 16 | 17 | // Parses HTML template 18 | GithubRepo.prototype.toHTML = function () { 19 | this.pushed_at = this._parsePushedDate(this.pushed_at) 20 | 21 | return $( 22 | "
" + 23 | "
" + 24 | '

' + 25 | "" + 28 | this.name + 29 | '' + 30 | '

' + 31 | "' + 48 | '
' + 49 | "
" + 50 | '

' + 51 | this.description + 52 | " — Read More

" + 55 | '
' + 56 | "
" + 57 | "

Latest commit to master on " + 58 | this.pushed_at + 59 | '

' + 60 | "" + 63 | '
' + 64 | '
' 65 | ) 66 | } 67 | 68 | // Parses pushed_at with date format 69 | GithubRepo.prototype._parsePushedDate = (pushed_at) => { 70 | var date = new Date(pushed_at) 71 | 72 | return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() 73 | } 74 | 75 | // -- Github Plugin ------------------------------------------------------------ 76 | 77 | function Github(element, options) { 78 | var defaults = { 79 | iconStars: true, 80 | iconForks: true, 81 | iconIssues: false, 82 | } 83 | 84 | this.element = element 85 | this.$container = $(element) 86 | this.repo = this.$container.attr('data-repo') 87 | 88 | this.options = $.extend({}, defaults, options) 89 | 90 | this._defaults = defaults 91 | 92 | this.init() 93 | 94 | const x = /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i 95 | const y = /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/ 96 | 97 | console.log('xy', x, y) 98 | } 99 | 100 | // Initializer 101 | Github.prototype.init = function () { 102 | var cached = this.getCache() 103 | 104 | if (cached !== null) { 105 | this.applyTemplate(JSON.parse(cached)) 106 | return 107 | } 108 | 109 | this.requestData(this.repo) 110 | } 111 | 112 | // Display or hide icons 113 | Github.prototype.displayIcons = function () { 114 | var options = this.options, 115 | $iconStars = $('.repo-stars'), 116 | $iconForks = $('.repo-forks'), 117 | $iconIssues = $('.repo-issues') 118 | 119 | $iconStars.css('display', options.iconStars ? 'inline-block' : 'none') 120 | $iconForks.css('display', options.iconForks ? 'inline-block' : 'none') 121 | $iconIssues.css('display', options.iconIssues ? 'inline-block' : 'none') 122 | } 123 | 124 | // Request repositories from Github 125 | Github.prototype.requestData = function (repo) { 126 | var that = this 127 | 128 | $.ajax({ 129 | url: 'https://api.github.com/repos/' + repo, 130 | dataType: 'jsonp', 131 | success: function (results) { 132 | var result_data = results.data, 133 | isFailling = results.meta.status >= 400 && result_data.message 134 | 135 | if (isFailling) { 136 | that.handleErrorRequest(result_data) 137 | return 138 | } 139 | 140 | that.handleSuccessfulRequest(result_data) 141 | }, 142 | }) 143 | } 144 | 145 | // Handle Errors requests 146 | Github.prototype.handleErrorRequest = function (result_data) { 147 | console.warn(result_data.message) 148 | return 149 | } 150 | 151 | // Handle Successful request 152 | Github.prototype.handleSuccessfulRequest = function (result_data) { 153 | this.applyTemplate(result_data) 154 | this.setCache(result_data) 155 | } 156 | 157 | // Stores repostories in sessionStorage if available 158 | Github.prototype.setCache = function (result_data) { 159 | // Cache data 160 | if (window.sessionStorage) { 161 | window.sessionStorage.setItem( 162 | 'gh-repos:' + this.repo, 163 | JSON.stringify(result_data) 164 | ) 165 | } 166 | } 167 | 168 | // Grab cached results 169 | Github.prototype.getCache = function () { 170 | if (window.sessionStorage) { 171 | return window.sessionStorage.getItem('gh-repos:' + this.repo) 172 | } else { 173 | return false 174 | } 175 | } 176 | 177 | // Apply results to HTML template 178 | Github.prototype.applyTemplate = function (repo) { 179 | var githubRepo = new GithubRepo(repo), 180 | $widget = githubRepo.toHTML() 181 | 182 | $widget.appendTo(this.$container) 183 | 184 | this.displayIcons() 185 | } 186 | 187 | // -- Attach plugin to jQuery's prototype -------------------------------------- 188 | ;(function ($, _window, _undefined) { 189 | $.fn.github = function (options) { 190 | return this.each(function () { 191 | if (!$(this).data('plugin_github')) { 192 | $(this).data('plugin_github', new Github(this, options)) 193 | } 194 | }) 195 | } 196 | })(window.jQuery || window.Zepto, window) 197 | -------------------------------------------------------------------------------- /code-examples/.css: -------------------------------------------------------------------------------- 1 | @import url(http://fonts.googleapis.com/css?family=Questrial); 2 | @import url(http://fonts.googleapis.com/css?family=Arvo); 3 | @font-face { 4 | src: url(http://lea.verou.me/logo.otf); 5 | font-family: 'LeaVerou'; 6 | } 7 | /* 8 | Shared styles 9 | */ 10 | 11 | section h1, 12 | #features li strong, 13 | header h2, 14 | footer p { 15 | font: 100% Rockwell, Arvo, serif; 16 | } 17 | /* 18 | Styles 19 | */ 20 | 21 | * { 22 | margin: 0; 23 | padding: 0; 24 | font-weight: normal; 25 | } 26 | body { 27 | font: 100%/1.5 Questrial, sans-serif; 28 | tab-size: 4; 29 | hyphens: auto; 30 | } 31 | a { 32 | color: inherit; 33 | } 34 | section h1 { 35 | font-size: 250%; 36 | } 37 | section section h1 { 38 | font-size: 150%; 39 | } 40 | section h1 code { 41 | font-style: normal; 42 | } 43 | section h1 > a { 44 | text-decoration: none; 45 | } 46 | section h1 > a:before { 47 | content: '§'; 48 | position: absolute; 49 | padding: 0 .2em; 50 | margin-left: -1em; 51 | border-radius: .2em; 52 | color: silver; 53 | text-shadow: 0 1px white; 54 | } 55 | section h1 > a:hover:before { 56 | color: black; 57 | background: #f1ad26; 58 | } 59 | p { 60 | margin: 1em 0; 61 | } 62 | section h1, 63 | h2 { 64 | margin: 1em 0 .3em; 65 | } 66 | dt { 67 | margin: 1em 0 0 0; 68 | font-size: 130%; 69 | } 70 | dt:after { 71 | content: ':'; 72 | } 73 | dd { 74 | margin-left: 2em; 75 | } 76 | strong { 77 | font-weight: bold; 78 | } 79 | code, 80 | pre { 81 | font-family: Consolas, Monaco, 'Andale Mono', 'Lucida Console', monospace; 82 | hyphens: none; 83 | } 84 | pre { 85 | max-height: 30em; 86 | overflow: auto; 87 | } 88 | pre > code.highlight { 89 | outline: .4em solid red; 90 | outline-offset: .4em; 91 | } 92 | header, 93 | body > section { 94 | display: block; 95 | max-width: 900px; 96 | margin: auto; 97 | } 98 | header, 99 | footer { 100 | position: relative; 101 | padding: 30px -webkit-calc(50% - 450px); 102 | /* Workaround for bug */ 103 | 104 | padding: 30px calc(50% - 450px); 105 | color: white; 106 | text-shadow: 0 -1px 2px black; 107 | background: url(img/spectrum.png) fixed; 108 | } 109 | header:before, 110 | footer:before { 111 | content: ''; 112 | position: absolute; 113 | bottom: 0; 114 | left: 0; 115 | right: 0; 116 | height: 20px; 117 | background-size: 20px 40px; 118 | background-repeat: repeat-x; 119 | } 120 | header {} header .intro, 121 | html.simple header { 122 | overflow: hidden; 123 | } 124 | header h1 { 125 | float: left; 126 | margin-right: 30px; 127 | color: #7fab14; 128 | text-align: center; 129 | font-size: 140%; 130 | text-transform: uppercase; 131 | letter-spacing: .25em; 132 | } 133 | header h2 { 134 | margin-top: .5em; 135 | color: #f1ad26; 136 | } 137 | header h1 a { 138 | text-decoration: none; 139 | } 140 | header img { 141 | display: block; 142 | width: 150px; 143 | height: 128px; 144 | margin-bottom: .3em; 145 | border: 0; 146 | } 147 | header h2 { 148 | font-size: 300%; 149 | } 150 | header .intro p { 151 | margin: 0; 152 | font: 150%/1.4 Questrial, sans-serif; 153 | font-size: 150%; 154 | } 155 | #features { 156 | width: 66em; 157 | margin-top: 2em; 158 | font-size: 80%; 159 | } 160 | #features li { 161 | margin: 0 0 2em 0; 162 | list-style: none; 163 | display: inline-block; 164 | width: 27em; 165 | vertical-align: top; 166 | } 167 | #features li:nth-child(odd) { 168 | margin-right: 5em; 169 | } 170 | #features li:before { 171 | content: '✓'; 172 | float: left; 173 | margin-left: -.8em; 174 | color: #7fab14; 175 | font-size: 400%; 176 | line-height: 1; 177 | } 178 | #features li strong { 179 | display: block; 180 | margin-bottom: .1em; 181 | font-size: 200%; 182 | } 183 | header .download-button { 184 | float: right; 185 | margin: 0 0 .5em .5em; 186 | } 187 | #theme { 188 | position: relative; 189 | z-index: 1; 190 | float: right; 191 | margin-right: -1em; 192 | text-align: center; 193 | text-transform: uppercase; 194 | letter-spacing: .2em; 195 | } 196 | #theme > p { 197 | position: absolute; 198 | left: 100%; 199 | transform: translateX(50%) rotate(90deg); 200 | transform-origin: top left; 201 | font-size: 130%; 202 | } 203 | #theme > label { 204 | position: relative; 205 | display: block; 206 | width: 7em; 207 | line-height: 1em; 208 | padding: 3em 0; 209 | border-radius: 50%; 210 | background: hsla(0, 0%, 100%, .5); 211 | cursor: pointer; 212 | font-size: 110%; 213 | } 214 | #theme > label:before { 215 | content: ''; 216 | position: absolute; 217 | top: 0; 218 | right: 0; 219 | bottom: 0; 220 | left: 0; 221 | z-index: -1; 222 | border-radius: inherit; 223 | background: url(img/spectrum.png) fixed; 224 | } 225 | #theme > label:nth-of-type(n+2) { 226 | margin-top: -2.5em; 227 | } 228 | #theme > input:not(:checked) + label:hover { 229 | background: hsla(77, 80%, 60%, .5); 230 | } 231 | #theme > input { 232 | position: absolute; 233 | clip: rect(0, 0, 0, 0); 234 | } 235 | #theme > input:checked + label { 236 | background: #7fab14; 237 | } 238 | footer { 239 | margin-top: 2em; 240 | background-position: bottom; 241 | color: white; 242 | text-shadow: 0 -1px 2px black; 243 | } 244 | footer:before { 245 | bottom: auto; 246 | top: 0; 247 | background-position: bottom; 248 | } 249 | footer p { 250 | font-size: 150%; 251 | } 252 | footer ul { 253 | column-count: 3; 254 | } 255 | .download-button { 256 | display: block; 257 | padding: .2em .8em .1em; 258 | border: 1px solid rgba(0, 0, 0, 0.5); 259 | border-radius: 10px; 260 | background: #39a1cf; 261 | color: white; 262 | text-shadow: 0 -1px 2px black; 263 | text-align: center; 264 | font-size: 250%; 265 | line-height: 1.5; 266 | text-transform: uppercase; 267 | text-decoration: none; 268 | hyphens: manual; 269 | } 270 | .download-button:hover { 271 | background-color: #7fab14; 272 | } 273 | .download-button:active { 274 | box-shadow: inset 0 2px 8px rgba(0, 0, 0, .8); 275 | } 276 | #toc { 277 | position: fixed; 278 | left: 1%; 279 | max-width: calc(48% - 450px); 280 | font-size: 80%; 281 | opacity: .3; 282 | } 283 | @media (max-width: 1200px) { 284 | #toc { 285 | display: none; 286 | } 287 | } 288 | #toc:hover { 289 | opacity: 1; 290 | } 291 | #toc h1 { 292 | font-size: 180%; 293 | } 294 | #toc li { 295 | list-style: none; 296 | } 297 | #logo:before { 298 | content: '☠'; 299 | float: right; 300 | font: 100px/1.6 LeaVerou; 301 | } 302 | .used-by-logos { 303 | overflow: hidden; 304 | } 305 | .used-by-logos > a { 306 | float: left; 307 | width: 33.33%; 308 | height: 100px; 309 | text-align: center; 310 | background: #F5F2F0; 311 | box-sizing: border-box; 312 | border: 5px solid white; 313 | position: relative; 314 | } 315 | .used-by-logos > .uswds { 316 | background: url('img/screen-us-web-design-standards.png') no-repeat 0 0; 317 | background-size: cover; 318 | text-indent: -999em; 319 | } 320 | .used-by-logos > a > img { 321 | max-height: 100%; 322 | max-width: 100%; 323 | position: absolute; 324 | top: 50%; 325 | left: 50%; 326 | transform: translate(-50%, -50%); 327 | } 328 | label a.owner { 329 | margin: 0 .5em; 330 | } 331 | label a.owner:not(:hover) { 332 | text-decoration: none; 333 | color: #aaa; 334 | } 335 | #languages-list ul { 336 | column-count: 3; 337 | } 338 | #languages-list li { 339 | padding: .2em; 340 | } 341 | #languages-list li[data-id="javascript"] { 342 | border-bottom: 1px solid #aaa; 343 | padding-bottom: 1em; 344 | margin-bottom: 1em; 345 | margin-right: 1em; 346 | } -------------------------------------------------------------------------------- /src/workbench.ts: -------------------------------------------------------------------------------- 1 | import { Color, WorkbenchColors } from './models' 2 | import { opacity } from './util' 3 | 4 | export default ( 5 | c: (color: Color, lightness?: number) => string 6 | ): WorkbenchColors => { 7 | // Background 8 | const bg = c(Color.BG) 9 | const bgSoft = c(Color.BG, 1) 10 | const bgSofter = c(Color.BG, 2) 11 | const bgDrop = opacity(25, c(Color.Aqua, 1)) 12 | const transparent = opacity(0, c(Color.BG)) 13 | // Foreground 14 | const fg = c(Color.Gray) 15 | const fgHard = c(Color.FG, 3) 16 | const fgHint = c(Color.BG, 2) 17 | const fgSubtle = c(Color.BG, 3) 18 | // Border 19 | const border = c(Color.BG, 1) 20 | const borderSubtle = opacity(30, fgHint) 21 | const borderHint = opacity(20, fgHint) 22 | // General UI 23 | const primary = c(Color.Yellow, 1) 24 | const highlight = c(Color.Yellow) 25 | const highlightHard = c(Color.Yellow, 1) 26 | const selection = c(Color.Aqua) 27 | const findMatch = c(Color.Purple, 1) 28 | const highlightWordSoft = c(Color.Blue) 29 | const highlightWord = c(Color.Blue, 1) 30 | const cursor = primary 31 | const links = c(Color.Blue, 1) 32 | const linksSoft = c(Color.Blue) 33 | // Notifications 34 | const info = c(Color.Yellow, 1) 35 | const infoSoft = c(Color.Yellow) 36 | const error = c(Color.Red, 1) 37 | const errorSoft = c(Color.Red) 38 | const warn = c(Color.Orange, 1) 39 | const warnSoft = c(Color.Orange) 40 | // Changes 41 | const changed = c(Color.Yellow, 1) 42 | const added = c(Color.Green, 1) 43 | const addedSoft = c(Color.Green) 44 | const deleted = c(Color.Red, 1) 45 | const deletedSoft = c(Color.Red) 46 | const modified = c(Color.Blue) 47 | const conflicted = c(Color.Purple) 48 | // Merge 49 | const mergeCurrent = c(Color.Blue) 50 | const mergeIncoming = c(Color.Aqua) 51 | const mergeCommon = c(Color.Gray) 52 | 53 | return { 54 | // Base Colors 55 | focusBorder: border, 56 | foreground: fg, 57 | 'widget.shadow': opacity(18.75, bg), 58 | 'selection.background': opacity(25, selection), 59 | errorForeground: error, 60 | 'sash.hoverBorder': primary, 61 | // Buttons 62 | 'button.background': opacity(80, primary), 63 | 'button.foreground': bg, 64 | 'button.hoverBackground': opacity(50, primary), 65 | // Dropdowns 66 | 'dropdown.background': bg, 67 | 'dropdown.border': border, 68 | 'dropdown.foreground': fg, 69 | // Inputs 70 | 'input.background': opacity(1.953125, fg), 71 | 'input.border': border, 72 | 'input.foreground': fg, 73 | 'input.placeholderForeground': opacity(37.5, fg), 74 | 'inputValidation.errorForeground': error, 75 | 'inputValidation.errorBorder': error, 76 | 'inputValidation.errorBackground': opacity(50, errorSoft), 77 | 'inputValidation.infoForeground': info, 78 | 'inputValidation.infoBorder': info, 79 | 'inputValidation.infoBackground': opacity(50, infoSoft), 80 | 'inputValidation.warningForeground': warn, 81 | 'inputValidation.warningBorder': warn, 82 | 'inputValidation.warningBackground': opacity(50, warnSoft), 83 | // Scrollbars 84 | 'scrollbar.shadow': bg, 85 | 'scrollbarSlider.activeBackground': highlight, 86 | 'scrollbarSlider.hoverBackground': fgSubtle, 87 | 'scrollbarSlider.background': opacity(59.765625, bgSofter), 88 | // Sticky Scroll 89 | 'editorStickyScroll.background': c(Color.BG2), 90 | 'editorStickyScrollHover.background': c(Color.BG2, 1), 91 | // Badges 92 | 'badge.background': primary, 93 | 'badge.foreground': bg, 94 | // Progress Bars 95 | 'progressBar.background': highlight, 96 | // Lists 97 | 'list.activeSelectionBackground': bgSoft, 98 | 'list.activeSelectionForeground': fgHard, 99 | 'list.inactiveSelectionBackground': opacity(50, bgSoft), 100 | 'list.inactiveSelectionForeground': fgHard, 101 | 'list.hoverBackground': opacity(25, bgSoft), 102 | 'list.hoverForeground': fg, 103 | 'list.focusBackground': bgSoft, 104 | 'list.focusForeground': fg, 105 | 'list.dropBackground': bgDrop, 106 | 'list.focusHighlightForeground': highlightWord, 107 | 'list.highlightForeground': highlightWordSoft, 108 | // Side Bar 109 | 'sideBar.background': bg, 110 | 'sideBar.foreground': fg, 111 | 'sideBar.border': borderSubtle, 112 | 'sideBarTitle.foreground': fg, 113 | 'sideBarSectionHeader.background': transparent, 114 | 'sideBarSectionHeader.foreground': fg, 115 | // Activity Bar 116 | 'activityBar.background': bg, 117 | 'activityBar.dropBackground': bgDrop, 118 | 'activityBar.foreground': fg, 119 | 'activityBar.border': transparent, 120 | 'activityBarBadge.background': primary, 121 | 'activityBarBadge.foreground': bg, 122 | // Editor Groups 123 | 'editorGroup.emptyBackground': bg, 124 | 'editorGroupHeader.noTabsBackground': bg, 125 | 'editorGroupHeader.tabsBackground': bg, 126 | 'editorGroup.border': borderSubtle, 127 | 'editorGroup.dropBackground': bgDrop, 128 | 'editorGroup.noTabsBackground': bgSoft, 129 | 'editorGroup.tabsbackground': bgSoft, 130 | 'editorGroup.tabsBorder': borderSubtle, 131 | // Tabs 132 | 'tab.border': bg, 133 | 'tab.activeBorder': bg, 134 | 'tab.activeForeground': fgHard, 135 | 'tab.inactiveForeground': fg, 136 | 'tab.inactiveBackground': opacity(50, bgSoft), 137 | 'tab.unfocusedActiveForeground': fg, 138 | 'tab.unfocusedActiveBorder': transparent, 139 | 'tab.unfocusedInactiveForeground': fgSubtle, 140 | // Editors 141 | 'editor.background': bg, 142 | 'editor.foreground': fg, 143 | 'editorLineNumber.foreground': fgHint, 144 | 'editorLineNumber.activeForeground': cursor, 145 | 'editorCursor.foreground': cursor, 146 | 'editorCursor.background': bg, 147 | 'editor.selectionBackground': opacity(25, selection), 148 | 'editor.selectionHighlightBackground': opacity(15, fg), 149 | 'editor.wordHighlightBackground': opacity(20, highlightWord), 150 | 'editor.wordHighlightStrongBackground': opacity(50, highlightWord), 151 | 'editor.hoverHighlightBackground': opacity(31.25, selection), 152 | 'editor.findMatchBackground': opacity(50, findMatch), 153 | 'editor.findMatchHighlightBackground': opacity(30, findMatch), 154 | 'editor.findRangeHighlightBackground': opacity(15, findMatch), 155 | 'editor.lineHighlightBackground': opacity(37.5, bgSoft), 156 | 'editor.lineHighlightBorder': transparent, 157 | 'editorWhitespace.foreground': opacity(15, fgSubtle), 158 | 'editorIndentGuide.background': borderHint, 159 | 'editorRuler.foreground': borderHint, 160 | 'editorCodeLens.foreground': opacity(56.25, fgSubtle), 161 | 'editorBracketMatch.border': transparent, 162 | 'editorBracketMatch.background': opacity(50, fg), 163 | 'editorHoverWidget.background': bgSoft, 164 | 'editorHoverWidget.border': border, 165 | 'editorOverviewRuler.border': transparent, 166 | 'editorOverviewRuler.findMatchForeground': opacity(30, findMatch), 167 | 'editorOverviewRuler.rangeHighlightForeground': opacity(15, findMatch), 168 | 'editorOverviewRuler.selectionHighlightForeground': fgHint, 169 | 'editorOverviewRuler.wordHighlightForeground': opacity(40, highlightWord), 170 | 'editorOverviewRuler.wordHighlightStrongForeground': opacity( 171 | 60, 172 | highlightWord 173 | ), 174 | 'editorOverviewRuler.modifiedForeground': changed, 175 | 'editorOverviewRuler.addedForeground': changed, 176 | 'editorOverviewRuler.deletedForeground': changed, 177 | 'editorOverviewRuler.errorForeground': error, 178 | 'editorOverviewRuler.warningForeground': warnSoft, 179 | 'editorOverviewRuler.infoForeground': selection, 180 | 'editorGutter.background': transparent, 181 | 'editorGutter.modifiedBackground': changed, 182 | 'editorGutter.addedBackground': added, 183 | 'editorGutter.deletedBackground': deleted, 184 | 'editorError.foreground': errorSoft, 185 | 'editorWarning.foreground': warnSoft, 186 | 'editorInfo.foreground': infoSoft, 187 | 'editorLink.activeForeground': fg, 188 | // Editor Bracket Highlight 189 | 'editorBracketHighlight.foreground1': c(Color.FG, 3), 190 | 'editorBracketHighlight.foreground2': c(Color.Aqua), 191 | 'editorBracketHighlight.foreground3': c(Color.Blue), 192 | 'editorBracketHighlight.foreground4': c(Color.Purple), 193 | 'editorBracketHighlight.foreground5': c(Color.Orange), 194 | 'editorBracketHighlight.foreground6': c(Color.Yellow), 195 | 'editorBracketHighlight.unexpectedBracket.foreground': c(Color.Red), 196 | // Diff Editors 197 | 'diffEditor.insertedTextBackground': opacity(18.75, added), 198 | 'diffEditorGutter.insertedLineBackground': opacity(7.5, added), 199 | 'diffEditor.removedTextBackground': opacity(18.75, deleted), 200 | 'diffEditorGutter.removedLineBackground': opacity(7.5, deleted), 201 | // Widgets 202 | 'editorWidget.background': bg, 203 | 'editorWidget.border': border, 204 | 'editorSuggestWidget.background': bg, 205 | 'editorSuggestWidget.foreground': fg, 206 | 'editorSuggestWidget.focusHighlightForeground': highlightWord, 207 | 'editorSuggestWidget.highlightForeground': highlightWordSoft, 208 | 'editorSuggestWidget.selectedBackground': bgSoft, 209 | 'editorSuggestWidget.border': border, 210 | // Peek Views 211 | 'peekView.border': border, 212 | 'peekViewEditor.background': opacity(31.25, bgSoft), 213 | 'peekViewEditorGutter.background': opacity(31.25, bgSoft), 214 | 'peekViewResult.background': opacity(31.25, bgSoft), 215 | 'peekViewResult.fileForeground': fg, 216 | 'peekViewResult.matchHighlightBackground': opacity(18.75, highlightHard), 217 | 'peekViewResult.selectionBackground': opacity(18.75, highlightHard), 218 | 'peekViewResult.selectionForeground': opacity(18.75, highlightHard), 219 | 'peekViewTitle.background': opacity(31.25, bgSoft), 220 | 'peekViewTitleDescription.foreground': fgSubtle, 221 | 'peekViewTitleLabel.foreground': fg, 222 | // Merges 223 | 'merge.currentHeaderBackground': opacity(25, mergeCurrent), 224 | 'merge.currentContentBackground': opacity(12.5, mergeCurrent), 225 | 'merge.incomingHeaderBackground': opacity(25, mergeIncoming), 226 | 'merge.incomingContentBackground': opacity(12.5, mergeIncoming), 227 | 'merge.border': transparent, 228 | 'editorOverviewRuler.currentContentForeground': mergeCurrent, 229 | 'editorOverviewRuler.incomingContentForeground': mergeIncoming, 230 | 'editorOverviewRuler.commonContentForeground': mergeCommon, 231 | // Panels 232 | 'panel.border': borderSubtle, 233 | 'panelTitle.activeForeground': fg, 234 | // Status Bar 235 | 'statusBar.background': bg, 236 | 'statusBar.foreground': fg, 237 | 'statusBar.debuggingBackground': primary, 238 | 'statusBar.debuggingForeground': bg, 239 | 'statusBar.debuggingBorder': borderSubtle, 240 | 'statusBar.noFolderBackground': bg, 241 | 'statusBar.noFolderBorder': transparent, 242 | 'statusBar.prominentBackground': highlight, 243 | 'statusBar.prominentHoverBackground': opacity(43.75, highlight), 244 | // Terminal 245 | 'terminal.ansiBlack': c(Color.BG, 1), 246 | 'terminal.ansiBrightBlack': c(Color.Gray), 247 | 'terminal.ansiRed': c(Color.Red), 248 | 'terminal.ansiBrightRed': c(Color.Red, 1), 249 | 'terminal.ansiGreen': c(Color.Green), 250 | 'terminal.ansiBrightGreen': c(Color.Green, 1), 251 | 'terminal.ansiYellow': c(Color.Yellow), 252 | 'terminal.ansiBrightYellow': c(Color.Yellow, 1), 253 | 'terminal.ansiBlue': c(Color.Blue), 254 | 'terminal.ansiBrightBlue': c(Color.Blue, 1), 255 | 'terminal.ansiMagenta': c(Color.Purple), 256 | 'terminal.ansiBrightMagenta': c(Color.Purple, 1), 257 | 'terminal.ansiCyan': c(Color.Aqua), 258 | 'terminal.ansiBrightCyan': c(Color.Aqua, 1), 259 | 'terminal.ansiWhite': c(Color.FG, 4), 260 | 'terminal.ansiBrightWhite': c(Color.FG, 1), 261 | 'terminal.foreground': fg, 262 | 'terminal.background': bg, 263 | // Title Bar (macOS) 264 | 'titleBar.activeBackground': bg, 265 | 'titleBar.activeForeground': fg, 266 | 'titleBar.inactiveBackground': bg, 267 | // Git Decorations 268 | 'gitDecoration.modifiedResourceForeground': modified, 269 | 'gitDecoration.deletedResourceForeground': deletedSoft, 270 | 'gitDecoration.untrackedResourceForeground': addedSoft, 271 | 'gitDecoration.ignoredResourceForeground': fgHint, 272 | 'gitDecoration.conflictingResourceForeground': conflicted, 273 | // Notifications 274 | 'notification.background': bg, 275 | 'notification.foreground': fg, 276 | 'notification.buttonBackground': opacity(80, primary), 277 | 'notification.buttonHoverBackground': opacity(50, primary), 278 | 'notification.buttonForeground': bg, 279 | 'notification.infoBackground': info, 280 | 'notification.infoForeground': bg, 281 | 'notification.warningBackground': warn, 282 | 'notification.warningForeground': bg, 283 | 'notification.errorBackground': error, 284 | 'notification.errorForeground': bg, 285 | // Extension Buttonss 286 | 'extensionButton.prominentForeground': bg, 287 | 'extensionButton.prominentBackground': opacity(100, primary), 288 | 'extensionButton.prominentHoverBackground': opacity(75, primary), 289 | // Breadcrumbs 290 | 'breadcrumb.foreground': fg, 291 | 'breadcrumb.focusForeground': fgHard, 292 | 'breadcrumb.activeSelectionForegraph': opacity(50, bgSoft), 293 | 'breadcrumbPicker.background': bg, 294 | // Settings 295 | 'settings.headerForeground': fgHard, 296 | 'settings.modifiedItemForeground': primary, 297 | 'settings.inactiveSelectedItemBorder': bgSoft, 298 | // Menu 299 | 'menu.background': bg, 300 | 'menu.foreground': fg, 301 | 'menu.selectionBackground': primary, 302 | 'menu.selectionForeground': bg, 303 | 'menu.selectionBorder': primary, 304 | 'menubar.selectionBackground': primary, 305 | 'menubar.selectionForeground': bg, 306 | 'menubar.selectionBorder': primary, 307 | // Misc 308 | 'textLink.foreground': links, 309 | 'textLink.activeForeground': linksSoft, 310 | 'debugToolBar.background': bg, 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /code-examples/.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | Prism 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | 24 |
    25 |
  • 26 | Dead simple 27 | Include prism.css and prism.js, use proper HTML5 code tags (code.language-xxxx), done! 28 |
  • 29 |
  • 30 | Intuitive 31 | Language classes are inherited so you can only define the language once for multiple code snippets. 32 |
  • 33 |
  • 34 | Light as a feather 35 | The core is 2KB minified & gzipped. Languages add 0.3-0.5KB each, themes are around 1KB. 36 |
  • 37 |
  • 38 | Blazing fast 39 | Supports parallelism with Web Workers, if available. 40 |
  • 41 |
  • 42 | Extensible 43 | Define new languages or extend existing ones. 44 | Add new features thanks to Prism’s plugin architecture. 45 |
  • 46 |
  • 47 | Easy styling 48 | All styling is done through CSS, with sensible class names like .comment, .string, .property etc 49 |
  • 50 |
51 | 52 |
53 | 54 |
55 |

Used By

56 | 57 |

Prism is used on several websites, small and large. Some of them are:

58 | 59 |
60 | Smashing Magazine 61 | U.S. Web Design Standards 62 | A List Apart 63 | 64 | Mozilla Developer Network (MDN) 65 | CSS-Tricks 66 | SitePoint 67 | Drupal 68 |
69 | 70 |

It’s also used on the personal blog of Brendan Eich, creator of JavaScript itself!

71 |
72 | 73 |
74 |

Examples

75 | 76 |

The Prism source, highlighted with Prism (don’t you just love how meta this is?):

77 |

 78 | 
 79 |     

This page’s CSS code, highlighted with Prism:

80 |

 81 | 
 82 |     

This page’s HTML, highlighted with Prism:

83 |

 84 | 
 85 |     

This page’s logo (SVG), highlighted with Prism:

86 |

 87 | 
 88 |     

If you’re still not sold, you can view more examples or try it out for yourself.

89 |
90 | 91 |
92 |

Full list of features

93 |
    94 |
  • Only 2KB minified & gzipped (core). Each language definition adds roughly 300-500 bytes.
  • 95 |
  • Encourages good author practices. Other highlighters encourage or even force you to use elements that are semantically wrong, 96 | like <pre> (on its own) or <script>. 97 | Prism forces you to use the correct element for marking up code: <code>. 98 | On its own for inline code, or inside a <pre> for blocks of code. 99 | In addition, the language is defined through the way recommended in the HTML5 draft: through a language-xxxx class.
  • 100 |
  • The language definition is inherited. This means that if multiple code snippets have the same language, you can just define it once, in one of their common ancestors.
  • 101 |
  • Supports parallelism with Web Workers, if available. Disabled by default (why?).
  • 102 |
  • Very easy to extend without modifying the code, due to Prism’s plugin architecture. Multiple hooks are scattered throughout the source.
  • 103 |
  • Very easy to define new languages. Only thing you need is a good understanding of regular expressions
  • 104 |
  • All styling is done through CSS, with sensible class names rather than ugly namespaced abbreviated nonsense.
  • 105 |
  • Wide browser support: IE9+, Firefox, Chrome, Safari, Opera, most Mobile browsers
  • 106 |
  • Highlights embedded languages (e.g. CSS inside HTML, JavaScript inside HTML)
  • 107 |
  • Highlights inline code as well, not just code blocks
  • 108 |
  • Highlights nested languages (CSS in HTML, JavaScript in HTML)
  • 109 |
  • It doesn’t force you to use any Prism-specific markup, not even a Prism-specific class name, only standard markup you should be using anyway. So, you can just try it for a while, remove it if you don’t like it and leave no traces behind.
  • 110 |
  • Highlight specific lines and/or line ranges (requires plugin)
  • 111 |
  • Show invisible characters like tabs, line breaks etc (requires plugin)
  • 112 |
  • Autolink URLs and emails, use Markdown links in comments (requires plugin)
  • 113 |
114 |
115 | 116 |
117 |

Limitations

118 |
    119 |
  • Any pre-existing HTML in the code will be stripped off. There are ways around it though.
  • 120 |
  • Regex-based so it *will* fail on certain edge cases.
  • 121 |
  • No IE 6-8 support. If someone can read code, they are probably in the 85% of the population with a modern browser.
  • 122 |
123 |
124 | 125 |
126 |

Basic usage

127 | 128 |

You will need to include the prism.css and prism.js files you downloaded in your page. Example: 129 |

<!DOCTYPE html>
130 | <html>
131 | <head>
132 |     ...
133 |     <link href="themes/prism.css" rel="stylesheet" />
134 | </head>
135 | <body>
136 |     ...
137 |     <script src="prism.js"></script>
138 | </body>
139 | </html>
140 | 141 |

Prism does its best to encourage good authoring practices. Therefore, it only works with <code> elements, since marking up code without a <code> element is semantically invalid. 142 | According to the HTML5 spec, the recommended way to define a code language is a language-xxxx class, which is what Prism uses. 143 | To make things easier however, Prism assumes that this language definition is inherited. Therefore, if multiple <code> elements have the same language, you can add the language-xxxx class on one of their common ancestors. 144 | This way, you can also define a document-wide default language, by adding a language-xxxx class on the <body> or <html> element. 145 | 146 |

If you want to opt-out of highlighting for a <code> element that is a descendant of an element with a declared code language, you can add the class language-none to it (or any non-existing language, really).

147 | 148 |

The recommended way to mark up a code block 149 | (both for semantics and for Prism) is a <pre> element with a <code> element inside, like so:

150 |
<pre><code class="language-css">p { color: red }</code></pre>
151 |

If you use that pattern, the <pre> will automatically get the language-xxxx class (if it doesn’t already have it) and will be styled as a code block.

152 | 153 |

If you want to prevent any elements from being automatically highlighted, you can use the attribute data-manual on the <script> element you used for prism and use the API. 154 | Example:

155 |
<script src="prism.js" data-manual></script>
156 | 157 |

If you want to use Prism on the server or through the command line, Prism can be used with Node.js as well. 158 | This might be useful if you're trying to generate static HTML pages with highlighted code for environments that don't support browser-side JS, like AMP pages.

159 | 160 |

You can install Prism for Node.js by running:

161 |
$ npm install prismjs
162 | 163 |

Example:

164 |
var Prism = require('prismjs');
165 | 
166 | // The code snippet you want to highlight, as a string
167 | var code = "var data = 1;";
168 | 
169 | // Returns a highlighted HTML string
170 | var html = Prism.highlight(code, Prism.languages.javascript);
171 |
172 | 173 |
174 |

Supported languages

175 |

This is the list of all languages currently supported by Prism, with their corresponding alias, to use in place of xxxx in the language-xxxx class:

176 |
177 | 178 |
179 |

Plugins

180 |

Plugins are additional scripts (and CSS code) that extend Prism’s functionality. Many of the following plugins are official, but are released as plugins to keep the Prism Core small for those who don’t need the extra functionality.

181 |
    182 | 183 |

    No assembly required to use them. Just select them in the download page.

    184 |

    It’s very easy to write your own Prism plugins. Did you write a plugin for Prism that you want added to this list? Send a pull request!

    185 |
    186 | 187 |
    188 |

    Third-party language definitions

    189 | 190 | 193 |
    194 | 195 |
    196 |

    Third-party tutorials

    197 | 198 |

    Several tutorials have been written by members of the community to help you integrate Prism into multiple different website types and configurations:

    199 | 200 | 213 | 214 |

    Please note that the tutorials listed here are not verified to contain correct information. Read at your risk and always check the official documentation here if something doesn’t work :)

    215 | 216 |

    Have you written a tutorial about Prism that’s not already included here? Send a pull request!

    217 |
    218 | 219 |
    220 |

    Credits

    221 | 228 |
    229 | 230 |
    231 | 232 | 233 | 234 | 235 | 236 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /code-examples/.js: -------------------------------------------------------------------------------- 1 | /* ********************************************** 2 | Begin prism-core.js 3 | ********************************************** */ 4 | 5 | var _self = (typeof window !== 'undefined') 6 | ? window // if in browser 7 | : ( 8 | (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) 9 | ? self // if in worker 10 | : {} // if in node js 11 | ); 12 | 13 | /** 14 | * Prism: Lightweight, robust, elegant syntax highlighting 15 | * MIT license http://www.opensource.org/licenses/mit-license.php/ 16 | * @author Lea Verou http://lea.verou.me 17 | */ 18 | 19 | var Prism = (function(){ 20 | 21 | // Private helper vars 22 | var lang = /\blang(?:uage)?-(\w+)\b/i; 23 | var uniqueId = 0; 24 | 25 | var _ = _self.Prism = { 26 | manual: _self.Prism && _self.Prism.manual, 27 | util: { 28 | encode: function (tokens) { 29 | if (tokens instanceof Token) { 30 | return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); 31 | } else if (_.util.type(tokens) === 'Array') { 32 | return tokens.map(_.util.encode); 33 | } else { 34 | return tokens.replace(/&/g, '&').replace(/ text.length) { 298 | // Something went terribly wrong, ABORT, ABORT! 299 | return; 300 | } 301 | 302 | if (str instanceof Token) { 303 | continue; 304 | } 305 | 306 | pattern.lastIndex = 0; 307 | 308 | var match = pattern.exec(str), 309 | delNum = 1; 310 | 311 | // Greedy patterns can override/remove up to two previously matched tokens 312 | if (!match && greedy && i != strarr.length - 1) { 313 | pattern.lastIndex = pos; 314 | match = pattern.exec(text); 315 | if (!match) { 316 | break; 317 | } 318 | 319 | var from = match.index + (lookbehind ? match[1].length : 0), 320 | to = match.index + match[0].length, 321 | k = i, 322 | p = pos; 323 | 324 | for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) { 325 | p += strarr[k].length; 326 | // Move the index i to the element in strarr that is closest to from 327 | if (from >= p) { 328 | ++i; 329 | pos = p; 330 | } 331 | } 332 | 333 | /* 334 | * If strarr[i] is a Token, then the match starts inside another Token, which is invalid 335 | * If strarr[k - 1] is greedy we are in conflict with another greedy pattern 336 | */ 337 | if (strarr[i] instanceof Token || strarr[k - 1].greedy) { 338 | continue; 339 | } 340 | 341 | // Number of tokens to delete and replace with the new match 342 | delNum = k - i; 343 | str = text.slice(pos, p); 344 | match.index -= pos; 345 | } 346 | 347 | if (!match) { 348 | if (oneshot) { 349 | break; 350 | } 351 | 352 | continue; 353 | } 354 | 355 | if(lookbehind) { 356 | lookbehindLength = match[1].length; 357 | } 358 | 359 | var from = match.index + lookbehindLength, 360 | match = match[0].slice(lookbehindLength), 361 | to = from + match.length, 362 | before = str.slice(0, from), 363 | after = str.slice(to); 364 | 365 | var args = [i, delNum]; 366 | 367 | if (before) { 368 | ++i; 369 | pos += before.length; 370 | args.push(before); 371 | } 372 | 373 | var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); 374 | 375 | args.push(wrapped); 376 | 377 | if (after) { 378 | args.push(after); 379 | } 380 | 381 | Array.prototype.splice.apply(strarr, args); 382 | 383 | if (delNum != 1) 384 | _.matchGrammar(text, strarr, grammar, i, pos, true, token); 385 | 386 | if (oneshot) 387 | break; 388 | } 389 | } 390 | } 391 | }, 392 | 393 | tokenize: function(text, grammar, language) { 394 | var strarr = [text]; 395 | 396 | var rest = grammar.rest; 397 | 398 | if (rest) { 399 | for (var token in rest) { 400 | grammar[token] = rest[token]; 401 | } 402 | 403 | delete grammar.rest; 404 | } 405 | 406 | _.matchGrammar(text, strarr, grammar, 0, 0, false); 407 | 408 | return strarr; 409 | }, 410 | 411 | hooks: { 412 | all: {}, 413 | 414 | add: function (name, callback) { 415 | var hooks = _.hooks.all; 416 | 417 | hooks[name] = hooks[name] || []; 418 | 419 | hooks[name].push(callback); 420 | }, 421 | 422 | run: function (name, env) { 423 | var callbacks = _.hooks.all[name]; 424 | 425 | if (!callbacks || !callbacks.length) { 426 | return; 427 | } 428 | 429 | for (var i=0, callback; callback = callbacks[i++];) { 430 | callback(env); 431 | } 432 | } 433 | } 434 | }; 435 | 436 | var Token = _.Token = function(type, content, alias, matchedStr, greedy) { 437 | this.type = type; 438 | this.content = content; 439 | this.alias = alias; 440 | // Copy of the full string this token was created from 441 | this.length = (matchedStr || "").length|0; 442 | this.greedy = !!greedy; 443 | }; 444 | 445 | Token.stringify = function(o, language, parent) { 446 | if (typeof o == 'string') { 447 | return o; 448 | } 449 | 450 | if (_.util.type(o) === 'Array') { 451 | return o.map(function(element) { 452 | return Token.stringify(element, language, o); 453 | }).join(''); 454 | } 455 | 456 | var env = { 457 | type: o.type, 458 | content: Token.stringify(o.content, language, parent), 459 | tag: 'span', 460 | classes: ['token', o.type], 461 | attributes: {}, 462 | language: language, 463 | parent: parent 464 | }; 465 | 466 | if (env.type == 'comment') { 467 | env.attributes['spellcheck'] = 'true'; 468 | } 469 | 470 | if (o.alias) { 471 | var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; 472 | Array.prototype.push.apply(env.classes, aliases); 473 | } 474 | 475 | _.hooks.run('wrap', env); 476 | 477 | var attributes = Object.keys(env.attributes).map(function(name) { 478 | return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; 479 | }).join(' '); 480 | 481 | return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; 482 | 483 | }; 484 | 485 | if (!_self.document) { 486 | if (!_self.addEventListener) { 487 | // in Node.js 488 | return _self.Prism; 489 | } 490 | // In worker 491 | _self.addEventListener('message', function(evt) { 492 | var message = JSON.parse(evt.data), 493 | lang = message.language, 494 | code = message.code, 495 | immediateClose = message.immediateClose; 496 | 497 | _self.postMessage(_.highlight(code, _.languages[lang], lang)); 498 | if (immediateClose) { 499 | _self.close(); 500 | } 501 | }, false); 502 | 503 | return _self.Prism; 504 | } 505 | 506 | //Get current script and highlight 507 | var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop(); 508 | 509 | if (script) { 510 | _.filename = script.src; 511 | 512 | if (!_.manual && !script.hasAttribute('data-manual')) { 513 | if(document.readyState !== "loading") { 514 | if (window.requestAnimationFrame) { 515 | window.requestAnimationFrame(_.highlightAll); 516 | } else { 517 | window.setTimeout(_.highlightAll, 16); 518 | } 519 | } 520 | else { 521 | document.addEventListener('DOMContentLoaded', _.highlightAll); 522 | } 523 | } 524 | } 525 | 526 | return _self.Prism; 527 | 528 | })(); 529 | 530 | if (typeof module !== 'undefined' && module.exports) { 531 | module.exports = Prism; 532 | } 533 | 534 | // hack for components to work correctly in node.js 535 | if (typeof global !== 'undefined') { 536 | global.Prism = Prism; 537 | } 538 | 539 | 540 | /* ********************************************** 541 | Begin prism-markup.js 542 | ********************************************** */ 543 | 544 | Prism.languages.markup = { 545 | 'comment': //, 546 | 'prolog': /<\?[\s\S]+?\?>/, 547 | 'doctype': //i, 548 | 'cdata': //i, 549 | 'tag': { 550 | pattern: /<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\s\S])*\1|[^\s'">=]+))?)*\s*\/?>/i, 551 | inside: { 552 | 'tag': { 553 | pattern: /^<\/?[^\s>\/]+/i, 554 | inside: { 555 | 'punctuation': /^<\/?/, 556 | 'namespace': /^[^\s>\/:]+:/ 557 | } 558 | }, 559 | 'attr-value': { 560 | pattern: /=(?:('|")[\s\S]*?(\1)|[^\s>]+)/i, 561 | inside: { 562 | 'punctuation': /[=>"']/ 563 | } 564 | }, 565 | 'punctuation': /\/?>/, 566 | 'attr-name': { 567 | pattern: /[^\s>\/]+/, 568 | inside: { 569 | 'namespace': /^[^\s>\/:]+:/ 570 | } 571 | } 572 | 573 | } 574 | }, 575 | 'entity': /&#?[\da-z]{1,8};/i 576 | }; 577 | 578 | Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = 579 | Prism.languages.markup['entity']; 580 | 581 | // Plugin to make entity title show the real entity, idea by Roman Komarov 582 | Prism.hooks.add('wrap', function(env) { 583 | 584 | if (env.type === 'entity') { 585 | env.attributes['title'] = env.content.replace(/&/, '&'); 586 | } 587 | }); 588 | 589 | Prism.languages.xml = Prism.languages.markup; 590 | Prism.languages.html = Prism.languages.markup; 591 | Prism.languages.mathml = Prism.languages.markup; 592 | Prism.languages.svg = Prism.languages.markup; 593 | 594 | 595 | /* ********************************************** 596 | Begin prism-css.js 597 | ********************************************** */ 598 | 599 | Prism.languages.css = { 600 | 'comment': /\/\*[\s\S]*?\*\//, 601 | 'atrule': { 602 | pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, 603 | inside: { 604 | 'rule': /@[\w-]+/ 605 | // See rest below 606 | } 607 | }, 608 | 'url': /url\((?:(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, 609 | 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/, 610 | 'string': { 611 | pattern: /("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 612 | greedy: true 613 | }, 614 | 'property': /(\b|\B)[\w-]+(?=\s*:)/i, 615 | 'important': /\B!important\b/i, 616 | 'function': /[-a-z0-9]+(?=\()/i, 617 | 'punctuation': /[(){};:]/ 618 | }; 619 | 620 | Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css); 621 | 622 | if (Prism.languages.markup) { 623 | Prism.languages.insertBefore('markup', 'tag', { 624 | 'style': { 625 | pattern: /()[\s\S]*?(?=<\/style>)/i, 626 | lookbehind: true, 627 | inside: Prism.languages.css, 628 | alias: 'language-css' 629 | } 630 | }); 631 | 632 | Prism.languages.insertBefore('inside', 'attr-value', { 633 | 'style-attr': { 634 | pattern: /\s*style=("|').*?\1/i, 635 | inside: { 636 | 'attr-name': { 637 | pattern: /^\s*style/i, 638 | inside: Prism.languages.markup.tag.inside 639 | }, 640 | 'punctuation': /^\s*=\s*['"]|['"]\s*$/, 641 | 'attr-value': { 642 | pattern: /.+/i, 643 | inside: Prism.languages.css 644 | } 645 | }, 646 | alias: 'language-css' 647 | } 648 | }, Prism.languages.markup.tag); 649 | } 650 | 651 | /* ********************************************** 652 | Begin prism-clike.js 653 | ********************************************** */ 654 | 655 | Prism.languages.clike = { 656 | 'comment': [ 657 | { 658 | pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, 659 | lookbehind: true 660 | }, 661 | { 662 | pattern: /(^|[^\\:])\/\/.*/, 663 | lookbehind: true 664 | } 665 | ], 666 | 'string': { 667 | pattern: /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 668 | greedy: true 669 | }, 670 | 'class-name': { 671 | pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, 672 | lookbehind: true, 673 | inside: { 674 | punctuation: /(\.|\\)/ 675 | } 676 | }, 677 | 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, 678 | 'boolean': /\b(true|false)\b/, 679 | 'function': /[a-z0-9_]+(?=\()/i, 680 | 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, 681 | 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, 682 | 'punctuation': /[{}[\];(),.:]/ 683 | }; 684 | 685 | 686 | /* ********************************************** 687 | Begin prism-javascript.js 688 | ********************************************** */ 689 | 690 | Prism.languages.javascript = Prism.languages.extend('clike', { 691 | 'keyword': /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, 692 | 'number': /\b-?(0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, 693 | // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) 694 | 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i, 695 | 'operator': /-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/ 696 | }); 697 | 698 | Prism.languages.insertBefore('javascript', 'keyword', { 699 | 'regex': { 700 | pattern: /(^|[^/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, 701 | lookbehind: true, 702 | greedy: true 703 | } 704 | }); 705 | 706 | Prism.languages.insertBefore('javascript', 'string', { 707 | 'template-string': { 708 | pattern: /`(?:\\\\|\\?[^\\])*?`/, 709 | greedy: true, 710 | inside: { 711 | 'interpolation': { 712 | pattern: /\$\{[^}]+\}/, 713 | inside: { 714 | 'interpolation-punctuation': { 715 | pattern: /^\$\{|\}$/, 716 | alias: 'punctuation' 717 | }, 718 | rest: Prism.languages.javascript 719 | } 720 | }, 721 | 'string': /[\s\S]+/ 722 | } 723 | } 724 | }); 725 | 726 | if (Prism.languages.markup) { 727 | Prism.languages.insertBefore('markup', 'tag', { 728 | 'script': { 729 | pattern: /()[\s\S]*?(?=<\/script>)/i, 730 | lookbehind: true, 731 | inside: Prism.languages.javascript, 732 | alias: 'language-javascript' 733 | } 734 | }); 735 | } 736 | 737 | Prism.languages.js = Prism.languages.javascript; 738 | 739 | 740 | /* ********************************************** 741 | Begin prism-file-highlight.js 742 | ********************************************** */ 743 | 744 | (function () { 745 | if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) { 746 | return; 747 | } 748 | 749 | self.Prism.fileHighlight = function() { 750 | 751 | var Extensions = { 752 | 'js': 'javascript', 753 | 'py': 'python', 754 | 'rb': 'ruby', 755 | 'ps1': 'powershell', 756 | 'psm1': 'powershell', 757 | 'sh': 'bash', 758 | 'bat': 'batch', 759 | 'h': 'c', 760 | 'tex': 'latex' 761 | }; 762 | 763 | Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) { 764 | var src = pre.getAttribute('data-src'); 765 | 766 | var language, parent = pre; 767 | var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; 768 | while (parent && !lang.test(parent.className)) { 769 | parent = parent.parentNode; 770 | } 771 | 772 | if (parent) { 773 | language = (pre.className.match(lang) || [, ''])[1]; 774 | } 775 | 776 | if (!language) { 777 | var extension = (src.match(/\.(\w+)$/) || [, ''])[1]; 778 | language = Extensions[extension] || extension; 779 | } 780 | 781 | var code = document.createElement('code'); 782 | code.className = 'language-' + language; 783 | 784 | pre.textContent = ''; 785 | 786 | code.textContent = 'Loading…'; 787 | 788 | pre.appendChild(code); 789 | 790 | var xhr = new XMLHttpRequest(); 791 | 792 | xhr.open('GET', src, true); 793 | 794 | xhr.onreadystatechange = function () { 795 | if (xhr.readyState == 4) { 796 | 797 | if (xhr.status < 400 && xhr.responseText) { 798 | code.textContent = xhr.responseText; 799 | 800 | Prism.highlightElement(code); 801 | } 802 | else if (xhr.status >= 400) { 803 | code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText; 804 | } 805 | else { 806 | code.textContent = '✖ Error: File does not exist or is empty'; 807 | } 808 | } 809 | }; 810 | 811 | xhr.send(null); 812 | }); 813 | 814 | }; 815 | 816 | document.addEventListener('DOMContentLoaded', self.Prism.fileHighlight); 817 | 818 | })(); -------------------------------------------------------------------------------- /src/tokens.ts: -------------------------------------------------------------------------------- 1 | import { Color, TokenColor } from './models' 2 | 3 | export default ( 4 | c: (color: Color, lightness?: number) => string 5 | ): TokenColor[] => { 6 | const fg = c(Color.FG, 1) 7 | const fgSubtle = c(Color.FG, 3) 8 | const headers = c(Color.Yellow, 1) 9 | const punctuation = fgSubtle 10 | // Comments 11 | const comments = c(Color.BG, 4) 12 | const commentTags = c(Color.Yellow, 1) 13 | const commentParams = fgSubtle 14 | // Numbers 15 | const numbers = c(Color.Purple, 1) 16 | // Strings 17 | const strings = c(Color.Green, 1) 18 | const stringInterpolation = c(Color.Orange, 1) 19 | const stringEscape = c(Color.Orange, 1) 20 | // Regex 21 | const regex = c(Color.Green, 1) 22 | const regexCharacterClass = c(Color.Purple, 1) 23 | const regexGroup = fgSubtle 24 | const regexQuantifier = regexCharacterClass 25 | // Keywords 26 | const keywords = c(Color.Red, 1) 27 | const operators = fgSubtle 28 | const operatorsSpecial = keywords 29 | const storage = keywords 30 | const controls = keywords 31 | const imports = keywords 32 | // Functions 33 | const functions = c(Color.Blue, 1) 34 | // Types 35 | const thisKeyword = c(Color.Yellow, 1) 36 | const interfaces = c(Color.Yellow, 1) 37 | const classes = c(Color.Aqua, 1) 38 | const decorators = c(Color.Aqua, 1) 39 | // Variables 40 | const variables = fg 41 | // HTML 42 | const tags = c(Color.Aqua, 1) 43 | const tagsClose = c(Color.Aqua) 44 | const attributes = c(Color.Blue, 1) 45 | const attributeIDs = c(Color.Orange, 1) 46 | // Serializable 47 | const keys1 = c(Color.Yellow, 1) 48 | const keys2 = c(Color.Aqua, 1) 49 | const keys3 = c(Color.Blue, 1) 50 | const keys4 = c(Color.Orange, 1) 51 | // Markup 52 | const bold = c(Color.Orange, 1) 53 | const links = c(Color.Blue, 1) 54 | const code = c(Color.Aqua, 1) 55 | // Misc 56 | const added = c(Color.Green) 57 | const deleted = c(Color.Red) 58 | const modified = c(Color.Blue) 59 | return [ 60 | // General 61 | 62 | { 63 | name: 'Text', 64 | scope: ['source', 'text.html'], 65 | settings: { 66 | foreground: fg, 67 | }, 68 | }, 69 | { 70 | scope: 'emphasis', 71 | settings: { 72 | fontStyle: 'italic', 73 | }, 74 | }, 75 | { 76 | scope: 'strong', 77 | settings: { 78 | fontStyle: 'bold', 79 | }, 80 | }, 81 | { 82 | scope: 'header', 83 | settings: { 84 | foreground: headers, 85 | }, 86 | }, 87 | { 88 | name: 'URL', 89 | scope: ['*url*', '*link*', '*uri*'], 90 | settings: { 91 | fontStyle: 'underline', 92 | }, 93 | }, 94 | { 95 | scope: 'invalid', 96 | settings: { 97 | foreground: deleted, 98 | }, 99 | }, 100 | 101 | // Punctuation 102 | 103 | { 104 | name: 'Punctuation', 105 | scope: [ 106 | 'punctuation', 107 | // TypeScript/JavaScript string interpolation reset 108 | 'meta.embedded', 109 | // TypeScript/JavaScript unmarked punctuation reset 110 | 'source.js', 111 | 'source.ts', 112 | // JSX/TSX 113 | 'punctuation.section.embedded.begin.tsx', 114 | 'punctuation.section.embedded.end.tsx', 115 | 'punctuation.section.embedded.begin.jsx', 116 | 'punctuation.section.embedded.end.jsx', 117 | ], 118 | settings: { 119 | foreground: punctuation, 120 | }, 121 | }, 122 | 123 | // Comments 124 | 125 | { 126 | scope: [ 127 | 'comment', 128 | 'punctuation.definition.comment', 129 | 'unused.comment', 130 | 'wildcard.comment', 131 | ], 132 | settings: { 133 | foreground: comments, 134 | fontStyle: 'italic', 135 | }, 136 | }, 137 | { 138 | scope: [ 139 | 'comment keyword.codetag.notation', 140 | 'comment.block.documentation keyword', 141 | 'comment.block.documentation storage.type.class', 142 | 'comment.block.documentation storage.type.class punctuation', 143 | ], 144 | settings: { 145 | foreground: commentTags, 146 | fontStyle: 'italic', 147 | }, 148 | }, 149 | { 150 | scope: [ 151 | 'comment.block.documentation variable', 152 | 'comment.block.documentation variable.other', 153 | ], 154 | settings: { 155 | foreground: commentParams, 156 | fontStyle: 'italic', 157 | }, 158 | }, 159 | 160 | // Constants 161 | 162 | { 163 | name: 'Constants', 164 | scope: [ 165 | 'constant', 166 | 'constant.numeric', 167 | 'constant.language', 168 | 'support.constant', 169 | 'meta.preprocessor.numeric', 170 | 'keyword.other.unit', 171 | ], 172 | settings: { 173 | foreground: numbers, 174 | }, 175 | }, 176 | 177 | // Strings 178 | 179 | { 180 | scope: ['string', 'meta.preprocessor.string'], 181 | settings: { 182 | foreground: strings, 183 | }, 184 | }, 185 | { 186 | name: 'String escape sequences', 187 | scope: ['constant.character', 'constant.regexp'], 188 | settings: { 189 | foreground: stringEscape, 190 | }, 191 | }, 192 | { 193 | name: 'String interpolation', 194 | scope: [ 195 | 'punctuation.section.embedded', 196 | 'meta.string-contents.quoted.double punctuation.definition.variable', 197 | 'punctuation.definition.template-expression.begin', 198 | 'punctuation.definition.template-expression.end', 199 | 'punctuation.definition.interpolation.begin.bracket', 200 | 'punctuation.definition.interpolation.end.bracket', 201 | 'punctuation.definition.variable.makefile', 202 | 'string.interpolated punctuation.definition.string.begin', 203 | 'string.interpolated punctuation.definition.string.end', 204 | ], 205 | settings: { 206 | foreground: stringInterpolation, 207 | }, 208 | }, 209 | 210 | // RegEx 211 | 212 | { 213 | name: 'Regex text', 214 | scope: 'string.regexp', 215 | settings: { 216 | foreground: regex, 217 | }, 218 | }, 219 | { 220 | name: 'RegEx groups', 221 | scope: [ 222 | 'punctuation.definition.group.regexp', 223 | 'punctuation.definition.group.assertion.regexp', 224 | 'support.other.parenthesis.regexp', 225 | ], 226 | settings: { 227 | foreground: regexGroup, 228 | }, 229 | }, 230 | { 231 | name: 'RegEx character classes or sets', 232 | scope: [ 233 | 'punctuation.definition.character-class.regexp', 234 | 'punctuation.character.set.begin.regexp', 235 | 'punctuation.character.set.end.regexp', 236 | 'constant.character.character-class.regexp', 237 | 'constant.other.character-class.set.regexp', 238 | 'constant.other.character-class.regexp', 239 | 'constant.character.set.regexp', 240 | ], 241 | settings: { 242 | foreground: regexCharacterClass, 243 | }, 244 | }, 245 | { 246 | name: 'RegEx Quantifiers', 247 | scope: 'keyword.operator.quantifier.regexp', 248 | settings: { 249 | foreground: regexQuantifier, 250 | }, 251 | }, 252 | { 253 | name: 'RegEx suffix control character', 254 | scope: 'string.regexp keyword.other', 255 | settings: { 256 | foreground: punctuation, 257 | }, 258 | }, 259 | 260 | // Storage 261 | 262 | { 263 | scope: [ 264 | 'storage', 265 | // ObjC 266 | 'meta.implementation storage.type.objc', 267 | 'meta.interface-or-protocol storage.type.objc', 268 | // Groovy 269 | 'source.groovy storage.type.def', 270 | ], 271 | settings: { 272 | foreground: storage, 273 | }, 274 | }, 275 | 276 | // Types 277 | 278 | { 279 | name: 'Types declaration and references', 280 | scope: [ 281 | 'entity.name.type.class', 282 | 'support.class', 283 | // Swift 284 | 'keyword.primitive-datatypes.swift', 285 | 'storage.type.attribute.swift', 286 | // ObjC 287 | 'storage.type.objc', 288 | 'meta.protocol-list.objc', 289 | 'meta.return-type.objc', 290 | // Go 291 | 'source.go storage.type', 292 | 'keyword.struct.go', 293 | 'keyword.interface.go', 294 | // C 295 | 'storage.type.c', 296 | // C# 297 | 'keyword.type.cs', 298 | 'storage.type.cs', 299 | 'storage.type.generic.cs', 300 | 'storage.type.modifier.cs', 301 | 'storage.type.variable.cs', 302 | // Groovy 303 | 'storage.type.groovy', 304 | 'source.groovy storage.type', 305 | // PHP 306 | 'storage.type.php', 307 | // Haskell 308 | 'storage.type.haskell', 309 | // OCaml 310 | 'storage.type.ocaml', 311 | // Java 312 | 'source.java storage.type', 313 | // Rust 314 | 'storage.type.core.rust', 315 | 'storage.class.std.rust', 316 | // Powershell 317 | 'source.powershell entity.other.attribute-name', 318 | // TypeScript 319 | 'meta.type.cast.expr', 320 | 'meta.type.new.expr', 321 | 'support.constant.math', 322 | 'support.constant.dom', 323 | 'support.constant.json', 324 | 'entity.other.inherited-class', 325 | ], 326 | settings: { 327 | foreground: classes, 328 | }, 329 | }, 330 | { 331 | name: 'Interfaces', 332 | scope: [ 333 | 'entity.name.type.interface', 334 | 'support.interface', 335 | 'support.type', 336 | 'meta.return-type', 337 | 'meta.return.type', 338 | 'meta.type.name', 339 | 'meta.cast', 340 | 'meta.type.annotation', 341 | // Swift 342 | 'keyword.primitive-datatypes.swift', 343 | 'storage.type.attribute.swift', 344 | // ObjC 345 | 'storage.type.objc', 346 | 'meta.protocol-list.objc', 347 | 'meta.return-type.objc', 348 | // Go 349 | 'source.go storage.type', 350 | 'keyword.struct.go', 351 | 'keyword.interface.go', 352 | // C 353 | 'storage.type.c', 354 | // C# 355 | 'keyword.type.cs', 356 | 'storage.type.cs', 357 | 'storage.type.generic.cs', 358 | 'storage.type.modifier.cs', 359 | 'storage.type.variable.cs', 360 | // Groovy 361 | 'storage.type.groovy', 362 | 'source.groovy storage.type', 363 | // PHP 364 | 'storage.type.php', 365 | // Haskell 366 | 'storage.type.haskell', 367 | // OCaml 368 | 'storage.type.ocaml', 369 | // Java 370 | 'source.java storage.type', 371 | // Rust 372 | 'storage.type.core.rust', 373 | 'storage.class.std.rust', 374 | // Powershell 375 | 'source.powershell entity.other.attribute-name', 376 | // TypeScript 377 | 'meta.type.cast.expr', 378 | 'meta.type.new.expr', 379 | 'support.constant.math', 380 | 'support.constant.dom', 381 | 'support.constant.json', 382 | 'entity.other.inherited-class', 383 | ], 384 | settings: { 385 | foreground: interfaces, 386 | }, 387 | }, 388 | { 389 | name: 'This keyword', 390 | scope: [ 391 | 'variable.language.this', 392 | 'variable.language.super', 393 | 'variable.this', 394 | 'variable.language.special.self', 395 | 'variable.parameter.function.language.special.self', 396 | 'keyword.other.this', 397 | // Swift 398 | 'keyword.expressions-and-types.swift', 399 | ], 400 | settings: { 401 | foreground: thisKeyword, 402 | }, 403 | }, 404 | 405 | // Keywords 406 | 407 | { 408 | scope: ['keyword', 'punctuation.definition.keyword'], 409 | settings: { 410 | foreground: keywords, 411 | }, 412 | }, 413 | { 414 | scope: 'keyword.operator', 415 | settings: { 416 | foreground: operators, 417 | }, 418 | }, 419 | { 420 | name: 'Keywords, special/emphasized', 421 | scope: ['keyword.operator.ternary'], 422 | settings: { 423 | foreground: operatorsSpecial, 424 | }, 425 | }, 426 | { 427 | name: 'Keyword-like Operators', 428 | scope: [ 429 | 'variable.language', 430 | 'keyword.control.new', 431 | 'keyword.operator.new', 432 | 'keyword.operator.expression', 433 | 'keyword.operator.cast', 434 | 'keyword.operator.sizeof', 435 | 'keyword.operator.logical.python', 436 | 'meta.preprocessor', 437 | 'meta.diff.header', 438 | 'meta.selector', 439 | ], 440 | settings: { 441 | foreground: keywords, 442 | }, 443 | }, 444 | { 445 | name: 'Control flow Keywords', 446 | scope: [ 447 | 'keyword.control', 448 | 'keyword.control punctuation.definition.keyword', 449 | ], 450 | settings: { 451 | foreground: controls, 452 | }, 453 | }, 454 | 455 | // Imports 456 | 457 | { 458 | name: 'Import Keywords', 459 | scope: [ 460 | 'keyword.import', 461 | 'keyword.package', 462 | 'keyword.control.directive', 463 | 'keyword.control.export', 464 | 'keyword.control.import', 465 | 'keyword.other.import', 466 | 'keyword.other.package', 467 | 'meta.import keyword.control', 468 | 'support.type.object.module', 469 | ], 470 | settings: { 471 | foreground: imports, 472 | }, 473 | }, 474 | { 475 | name: 'Import Identifiers', 476 | scope: [ 477 | // Java 478 | 'storage.modifier.import.java', 479 | 'storage.modifier.package.java', 480 | 'variable.language.wildcard.java', 481 | ], 482 | settings: { 483 | foreground: classes, 484 | }, 485 | }, 486 | 487 | // Functions 488 | 489 | { 490 | name: 'Function', 491 | scope: [ 492 | 'entity.name.function', 493 | 'entity.name.method', 494 | 'entity.name.static.function-call', 495 | 'support.function', 496 | 'support.constant.handlebars', 497 | 'variable.function', 498 | 'keyword.operator.function.infix', 499 | 'meta.function-call.generic', 500 | 'meta.function-call.object', 501 | 'meta.function-call.static', 502 | // Python 503 | 'meta.function.python', 504 | // PHP 505 | 'meta.function-call.php', 506 | // Java 507 | 'meta.method-call.java meta.method', 508 | // Groovy 509 | 'meta.method.groovy', 510 | // Lua 511 | 'support.function.any-method.lua', 512 | // Go 513 | 'entity.name.function.go', 514 | ], 515 | settings: { 516 | foreground: functions, 517 | }, 518 | }, 519 | { 520 | name: 'Function parameters', 521 | scope: [ 522 | 'entity.name.variable.parameter', 523 | 'variable.parameter', 524 | // PHP 525 | 'meta.function.arguments variable.other.php', 526 | // GraphQL 527 | 'meta.selectionset.graphql meta.arguments.graphql variable.arguments.graphql', 528 | // Sass 529 | 'meta.at-rule.function variable', 530 | 'meta.at-rule.mixin variable', 531 | ], 532 | settings: { 533 | foreground: variables, 534 | }, 535 | }, 536 | { 537 | name: 'Decorators', 538 | scope: [ 539 | 'meta.decorator entity.name.function', 540 | 'storage.type.annotation', 541 | 'meta.decorator punctuation.decorator', 542 | 'meta.decorator variable.other.readwrite', 543 | 'meta.decorator variable.other.property', 544 | 'meta.decorator variable.other.object', 545 | ], 546 | settings: { 547 | foreground: decorators, 548 | }, 549 | }, 550 | 551 | // Variables 552 | 553 | { 554 | name: 'Variables', 555 | scope: [ 556 | 'meta.parameter.type.variable', 557 | 'support.variable', 558 | 'variable.name', 559 | 'variable.other', 560 | 'variable', 561 | 'string.constant.other.placeholder', 562 | // TypeScript 563 | 'meta.object-literal.key', 564 | 'meta.decorator.ts meta.object.member', 565 | // Perl 566 | 'constant.other.key.perl', 567 | ], 568 | settings: { 569 | foreground: variables, 570 | }, 571 | }, 572 | { 573 | name: 'Variable Aliasing, Original', 574 | scope: [ 575 | // Destructuring 576 | 'meta.object-binding-pattern-variable variable.object.property', 577 | // Module aliasing, original name 578 | 'meta.import variable.other.readwrite', 579 | 'meta.export variable.other.readwrite', 580 | ], 581 | settings: { 582 | foreground: fgSubtle, 583 | }, 584 | }, 585 | { 586 | name: 'Variable Aliasing, Alias', 587 | scope: [ 588 | // Module aliasing, alias name 589 | 'meta.import variable.other.readwrite.alias', 590 | 'meta.export variable.other.readwrite.alias', 591 | // CoffeeScript 592 | 'meta.variable.assignment.destructured.object.coffee variable variable', 593 | ], 594 | settings: { 595 | foreground: fg, 596 | }, 597 | }, 598 | { 599 | name: 'Variable Aliasing, Reset inside export default', 600 | scope: ['meta.export.default variable.other.readwrite'], 601 | settings: { 602 | foreground: fg, 603 | }, 604 | }, 605 | 606 | // Serialized (JSON, YAML, etc.) 607 | 608 | { 609 | name: 'Serialized keys', 610 | scope: [ 611 | // Makefile 612 | 'entity.name.function.target.makefile', 613 | // TOML 614 | 'entity.name.section.toml', 615 | 'variable.other.key.toml', 616 | // YAML 617 | 'entity.name.tag.yaml', 618 | ], 619 | settings: { 620 | foreground: keys1, 621 | }, 622 | }, 623 | { 624 | name: 'Serialized dates', 625 | scope: ['constant.other.date', 'constant.other.timestamp'], 626 | settings: { 627 | foreground: numbers, 628 | }, 629 | }, 630 | { 631 | name: 'YAML Aliases', 632 | scope: ['variable.other.alias.yaml'], 633 | settings: { 634 | foreground: functions, 635 | }, 636 | }, 637 | { 638 | name: 'JSON Level 0', 639 | scope: [ 640 | 'source.json meta.structure.dictionary.json support.type.property-name.json', 641 | ], 642 | settings: { 643 | foreground: keys1, 644 | }, 645 | }, 646 | { 647 | name: 'JSON Level 1', 648 | scope: [ 649 | 'source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json', 650 | ], 651 | settings: { 652 | foreground: keys2, 653 | }, 654 | }, 655 | { 656 | name: 'JSON Level 2', 657 | scope: [ 658 | 'source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json', 659 | ], 660 | settings: { 661 | foreground: keys3, 662 | }, 663 | }, 664 | { 665 | name: 'JSON Level 3', 666 | scope: [ 667 | 'source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json', 668 | ], 669 | settings: { 670 | foreground: keys4, 671 | }, 672 | }, 673 | 674 | // HTML / XML / CSS 675 | 676 | { 677 | name: 'HTML Tag', 678 | scope: 'entity.name.tag', 679 | settings: { 680 | foreground: tags, 681 | fontStyle: 'bold', 682 | }, 683 | }, 684 | { 685 | name: 'HTML Tag Close', 686 | scope: 'tag.close entity.name.tag', 687 | settings: { 688 | foreground: tagsClose, 689 | }, 690 | }, 691 | { 692 | name: 'HTML Attribute', 693 | scope: [ 694 | 'entity.other.attribute-name', 695 | 'meta.tag.inline.any.html', 696 | 'meta.tag.sgml', 697 | ], 698 | settings: { 699 | foreground: attributes, 700 | }, 701 | }, 702 | { 703 | name: 'HTML Attribute ID', 704 | scope: ['entity.other.attribute-name.id'], 705 | settings: { 706 | foreground: attributeIDs, 707 | }, 708 | }, 709 | { 710 | name: 'HTML Codes Punctuation', 711 | scope: 'punctuation.definition.entity.html', 712 | settings: { 713 | foreground: stringEscape, 714 | }, 715 | }, 716 | { 717 | name: 'CSS Pseudo Classes/Elements', 718 | scope: [ 719 | 'entity.other.attribute-name.pseudo-class', 720 | 'entity.other.attribute-name.pseudo-element', 721 | ], 722 | settings: { 723 | foreground: fgSubtle, 724 | }, 725 | }, 726 | { 727 | name: 'CSS Attribute Parent Selectors', 728 | scope: ['entity.other.attribute-name.parent-selector'], 729 | settings: { 730 | foreground: keywords, 731 | }, 732 | }, 733 | 734 | // Python 735 | 736 | { 737 | name: 'Python Function Arguments', 738 | scope: 'meta.function-call.arguments', 739 | settings: { 740 | foreground: fg, 741 | }, 742 | }, 743 | 744 | // GraphQL 745 | 746 | { 747 | name: 'GraphQL types', 748 | scope: ['meta.selectionset.graphql variable'], 749 | settings: { 750 | foreground: strings, 751 | }, 752 | }, 753 | { 754 | name: 'GraphQL arguments', 755 | scope: ['meta.selectionset.graphql meta.arguments variable'], 756 | settings: { 757 | foreground: fg, 758 | }, 759 | }, 760 | { 761 | name: 'GraphQL fragment', 762 | scope: ['source.shell support.function.builtin'], 763 | settings: { 764 | foreground: classes, 765 | }, 766 | }, 767 | 768 | // Shell 769 | 770 | { 771 | name: 'Shell Script Built-in Functions', 772 | scope: ['source.shell support.function.builtin'], 773 | settings: { 774 | foreground: functions, 775 | }, 776 | }, 777 | { 778 | name: 'Shell Script Variables', 779 | scope: [ 780 | 'punctuation.definition.variable.shell', 781 | 'source.shell variable.other', 782 | ], 783 | settings: { 784 | foreground: classes, 785 | }, 786 | }, 787 | { 788 | name: 'Shell Script Interpolated Content', 789 | scope: [ 790 | 'string.interpolated.backtick.shell', 791 | 'string.interpolated.dollar.shell', 792 | ], 793 | settings: { 794 | foreground: code, 795 | }, 796 | }, 797 | { 798 | name: 'Shell Foreground Reset', 799 | scope: [ 800 | 'meta.scope.for-loop.shell punctuation.definition.string.begin', 801 | 'meta.scope.for-loop.shell punctuation.definition.string.end', 802 | 'meta.scope.for-loop.shell string', 803 | ], 804 | settings: { 805 | foreground: fg, 806 | }, 807 | }, 808 | 809 | // MAKEFILE 810 | 811 | { 812 | name: 'Makefile Prerequisites', 813 | scope: 'meta.scope.prerequisites', 814 | settings: { 815 | foreground: classes, 816 | }, 817 | }, 818 | { 819 | name: 'Makefile Function Targets', 820 | scope: 'entity.name.function.target', 821 | settings: { 822 | foreground: strings, 823 | fontStyle: 'bold', 824 | }, 825 | }, 826 | 827 | // Lisp 828 | 829 | { 830 | name: 'Lisp optional function parameters', 831 | scope: 'meta.function-parameters.lisp', 832 | settings: { 833 | foreground: functions, 834 | }, 835 | }, 836 | 837 | // Markup 838 | 839 | { 840 | scope: 'markup.underline', 841 | settings: { 842 | fontStyle: 'underline', 843 | }, 844 | }, 845 | { 846 | scope: 'markup.bold', 847 | settings: { 848 | fontStyle: 'bold', 849 | foreground: bold, 850 | }, 851 | }, 852 | { 853 | scope: 'markup.italic', 854 | settings: { 855 | fontStyle: 'italic', 856 | }, 857 | }, 858 | { 859 | name: 'Markup headings/sections', 860 | scope: ['markup.heading', 'entity.name.section'], 861 | settings: { 862 | fontStyle: 'bold', 863 | foreground: headers, 864 | }, 865 | }, 866 | { 867 | name: 'Markup link text', 868 | scope: [ 869 | 'meta.link.reference.def.restructuredtext', 870 | 'punctuation.definition.directive.restructuredtext', 871 | 'string.other.link.description', 872 | 'string.other.link.title', 873 | ], 874 | settings: { 875 | foreground: links, 876 | fontStyle: 'underline', 877 | }, 878 | }, 879 | { 880 | name: 'Markup links', 881 | scope: ['markup.underline.link', 'markup.underline.link.image'], 882 | settings: { 883 | foreground: fgSubtle, 884 | }, 885 | }, 886 | { 887 | name: 'Markup inline code', 888 | scope: ['markup.inline.raw', 'markup.raw.restructuredtext'], 889 | settings: { 890 | foreground: code, 891 | }, 892 | }, 893 | { 894 | name: 'Markup code blocks', 895 | scope: [ 896 | 'fenced_code.block.language', 897 | 'markup.raw.inner.restructuredtext', 898 | 'markup.fenced_code.block.markdown punctuation.definition.markdown', 899 | ], 900 | settings: { 901 | foreground: code, 902 | }, 903 | }, 904 | { 905 | name: 'Markup blockquotes', 906 | scope: ['entity.name.directive.restructuredtext', 'markup.quote'], 907 | settings: { 908 | foreground: strings, 909 | }, 910 | }, 911 | { 912 | name: 'Markup bullets & lists', 913 | scope: [ 914 | 'beginning.punctuation.definition.list.markdown', 915 | 'beginning.punctuation.definition.quote.markdown', 916 | 'punctuation.definition.link.restructuredtext', 917 | 'markup.punctuation.quote.beginning', 918 | 'markup.punctuation.list.beginning', 919 | ], 920 | settings: { 921 | foreground: numbers, 922 | }, 923 | }, 924 | { 925 | name: 'Markup horizontal rule', 926 | scope: ['meta.separator.markdown'], 927 | settings: { 928 | foreground: fgSubtle, 929 | }, 930 | }, 931 | { 932 | name: 'Markup constants', 933 | scope: ['punctuation.definition.constant.restructuredtext'], 934 | settings: { 935 | foreground: numbers, 936 | }, 937 | }, 938 | { 939 | scope: 'markup.inserted', 940 | settings: { 941 | foreground: added, 942 | }, 943 | }, 944 | { 945 | scope: 'markup.deleted', 946 | settings: { 947 | foreground: deleted, 948 | }, 949 | }, 950 | { 951 | scope: 'markup.changed', 952 | settings: { 953 | foreground: modified, 954 | }, 955 | }, 956 | 957 | // Go 958 | 959 | { 960 | name: 'Go Import Names', 961 | scope: ['source.go entity.name.import'], 962 | settings: { 963 | foreground: strings, 964 | }, 965 | }, 966 | { 967 | name: 'Go Entity Names Override', 968 | scope: ['source.go entity.name.type'], 969 | settings: { 970 | foreground: fg, 971 | }, 972 | }, 973 | 974 | // Cucumber 975 | 976 | { 977 | name: 'Cucumber Table Keywords', 978 | scope: ['keyword.control.cucumber.table'], 979 | settings: { 980 | foreground: functions, 981 | }, 982 | }, 983 | 984 | // PHP 985 | 986 | { 987 | name: 'PHP Metatags', 988 | scope: 'metatag.php', 989 | settings: { 990 | foreground: tags, 991 | }, 992 | }, 993 | 994 | // Git 995 | 996 | { 997 | name: 'Git Rebase Function Header', 998 | scope: 'support.function.git-rebase', 999 | settings: { 1000 | foreground: code, 1001 | }, 1002 | }, 1003 | { 1004 | name: 'Git Rebase SHA Header', 1005 | scope: 'constant.sha.git-rebase', 1006 | settings: { 1007 | foreground: strings, 1008 | }, 1009 | }, 1010 | ] 1011 | } 1012 | --------------------------------------------------------------------------------