├── .gitattributes
├── .github
├── FUNDING.yml
└── workflows
│ ├── CI.yml
│ ├── deploy.yml
│ ├── update-grammars.yml
│ └── update-themes.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── CHANGELOG.md
├── README.md
├── docs
├── languages.md
└── themes.md
├── jest.config.js
├── lerna.json
├── netlify.toml
├── package.json
├── packages
├── renderer-svg
│ ├── README.md
│ ├── package.json
│ ├── rollup.config.js
│ ├── src
│ │ ├── __tests__
│ │ │ └── styleAttributes.test.ts
│ │ ├── global.d.ts
│ │ ├── index.ts
│ │ └── measureMonospaceTypeface.ts
│ └── tsconfig.json
├── shiki
│ ├── README.md
│ ├── languages
│ │ ├── abap.tmLanguage.json
│ │ ├── actionscript-3.tmLanguage.json
│ │ ├── ada.tmLanguage.json
│ │ ├── apache.tmLanguage.json
│ │ ├── apex.tmLanguage.json
│ │ ├── apl.tmLanguage.json
│ │ ├── applescript.tmLanguage.json
│ │ ├── asm.tmLanguage.json
│ │ ├── awk.tmLanguage.json
│ │ ├── bat.tmLanguage.json
│ │ ├── c.tmLanguage.json
│ │ ├── clojure.tmLanguage.json
│ │ ├── cobol.tmLanguage.json
│ │ ├── coffee.tmLanguage.json
│ │ ├── cpp-macro.tmLanguage.json
│ │ ├── cpp.tmLanguage.json
│ │ ├── crystal.tmLanguage.json
│ │ ├── csharp.tmLanguage.json
│ │ ├── css.tmLanguage.json
│ │ ├── d.tmLanguage.json
│ │ ├── dart.tmLanguage.json
│ │ ├── diff.tmLanguage.json
│ │ ├── docker.tmLanguage.json
│ │ ├── dream-maker.tmLanguage.json
│ │ ├── elixir.tmLanguage.json
│ │ ├── elm.tmLanguage.json
│ │ ├── erb.tmLanguage.json
│ │ ├── erlang.tmLanguage.json
│ │ ├── fsharp.tmLanguage.json
│ │ ├── gherkin.tmLanguage.json
│ │ ├── git-commit.tmLanguage.json
│ │ ├── git-rebase.tmLanguage.json
│ │ ├── gnuplot.tmLanguage.json
│ │ ├── go.tmLanguage.json
│ │ ├── graphql.tmLanguage.json
│ │ ├── groovy.tmLanguage.json
│ │ ├── hack.tmLanguage.json
│ │ ├── haml.tmLanguage.json
│ │ ├── handlebars.tmLanguage.json
│ │ ├── haskell.tmLanguage.json
│ │ ├── hcl.tmLanguage.json
│ │ ├── hlsl.tmLanguage.json
│ │ ├── html.tmLanguage.json
│ │ ├── ini.tmLanguage.json
│ │ ├── java.tmLanguage.json
│ │ ├── javascript.tmLanguage.json
│ │ ├── jinja-html.tmLanguage.json
│ │ ├── jinja.tmLanguage.json
│ │ ├── json.tmLanguage.json
│ │ ├── jsonc.tmLanguage.json
│ │ ├── jsonnet.tmLanguage.json
│ │ ├── jssm.tmLanguage.json
│ │ ├── jsx.tmLanguage.json
│ │ ├── julia.tmLanguage.json
│ │ ├── jupyter.tmLanguage.json
│ │ ├── kotlin.tmLanguage.json
│ │ ├── latex.tmLanguage.json
│ │ ├── less.tmLanguage.json
│ │ ├── lisp.tmLanguage.json
│ │ ├── logo.tmLanguage.json
│ │ ├── lua.tmLanguage.json
│ │ ├── make.tmLanguage.json
│ │ ├── markdown.tmLanguage.json
│ │ ├── matlab.tmLanguage.json
│ │ ├── mdx.tmLanguage.json
│ │ ├── nginx.tmLanguage.json
│ │ ├── nim.tmLanguage.json
│ │ ├── nix.tmLanguage.json
│ │ ├── objective-c.tmLanguage.json
│ │ ├── objective-cpp.tmLanguage.json
│ │ ├── ocaml.tmLanguage.json
│ │ ├── pascal.tmLanguage.json
│ │ ├── perl.tmLanguage.json
│ │ ├── php-html.tmLanguage.json
│ │ ├── php.tmLanguage.json
│ │ ├── plsql.tmLanguage.json
│ │ ├── postcss.tmLanguage.json
│ │ ├── powershell.tmLanguage.json
│ │ ├── prisma.tmLanguage.json
│ │ ├── prolog.tmLanguage.json
│ │ ├── pug.tmLanguage.json
│ │ ├── puppet.tmLanguage.json
│ │ ├── purescript.tmLanguage.json
│ │ ├── python.tmLanguage.json
│ │ ├── r.tmLanguage.json
│ │ ├── raku.tmLanguage.json
│ │ ├── razor.tmLanguage.json
│ │ ├── riscv.tmLanguage.json
│ │ ├── ruby.tmLanguage.json
│ │ ├── rust.tmLanguage.json
│ │ ├── sas.tmLanguage.json
│ │ ├── sass.tmLanguage.json
│ │ ├── scala.tmLanguage.json
│ │ ├── scheme.tmLanguage.json
│ │ ├── scss.tmLanguage.json
│ │ ├── shaderlab.tmLanguage.json
│ │ ├── shellscript.tmLanguage.json
│ │ ├── smalltalk.tmLanguage.json
│ │ ├── solidity.tmLanguage.json
│ │ ├── sparql.tmLanguage.json
│ │ ├── sql.tmLanguage.json
│ │ ├── ssh-config.tmLanguage.json
│ │ ├── stylus.tmLanguage.json
│ │ ├── svelte.tmLanguage.json
│ │ ├── swift.tmLanguage.json
│ │ ├── system-verilog.tmLanguage.json
│ │ ├── tcl.tmLanguage.json
│ │ ├── tex.tmLanguage.json
│ │ ├── toml.tmLanguage.json
│ │ ├── tsx.tmLanguage.json
│ │ ├── turtle.tmLanguage.json
│ │ ├── twig.tmLanguage.json
│ │ ├── typescript.tmLanguage.json
│ │ ├── vb.tmLanguage.json
│ │ ├── verilog.tmLanguage.json
│ │ ├── vhdl.tmLanguage.json
│ │ ├── viml.tmLanguage.json
│ │ ├── vue-html.tmLanguage.json
│ │ ├── vue.tmLanguage.json
│ │ ├── wasm.tmLanguage.json
│ │ ├── wenyan.tmLanguage.json
│ │ ├── xml.tmLanguage.json
│ │ ├── xsl.tmLanguage.json
│ │ └── yaml.tmLanguage.json
│ ├── package.json
│ ├── rollup.config.js
│ ├── samples
│ │ ├── c.sample
│ │ ├── css.sample
│ │ ├── dm.sample
│ │ ├── fsl.sample
│ │ ├── go.sample
│ │ ├── html.sample
│ │ ├── java.sample
│ │ ├── javascript.sample
│ │ ├── jssm.sample
│ │ ├── prisma.sample
│ │ ├── python.sample
│ │ ├── ruby.sample
│ │ ├── sparql.sample
│ │ ├── tsx.sample
│ │ └── turtle.sample
│ ├── src
│ │ ├── __tests__
│ │ │ ├── 152.test.ts
│ │ │ ├── __snapshots__
│ │ │ │ ├── 152.test.ts.snap
│ │ │ │ └── simple.test.ts.snap
│ │ │ ├── background.test.ts
│ │ │ ├── comprehensive.test.ts
│ │ │ ├── custom-language
│ │ │ │ ├── __snapshots__
│ │ │ │ │ └── customLanguage.test.ts.snap
│ │ │ │ ├── customLanguage.test.ts
│ │ │ │ ├── rockstar-html.tmLanguage.json
│ │ │ │ ├── rockstar-override.tmLanguage.json
│ │ │ │ ├── rockstar.rock
│ │ │ │ └── rockstar.tmLanguage.json
│ │ │ ├── simple.test.ts
│ │ │ └── utils.test.ts
│ │ ├── global.d.ts
│ │ ├── highlighter.ts
│ │ ├── index.ts
│ │ ├── languages.ts
│ │ ├── loader.ts
│ │ ├── registry.ts
│ │ ├── renderer.ts
│ │ ├── resolver.ts
│ │ ├── stackElementMetadata.ts
│ │ ├── themedTokenizer.ts
│ │ ├── themes.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── themes
│ │ ├── dark-plus.json
│ │ ├── dracula-soft.json
│ │ ├── dracula.json
│ │ ├── github-dark.json
│ │ ├── github-light.json
│ │ ├── light-plus.json
│ │ ├── material-darker.json
│ │ ├── material-default.json
│ │ ├── material-lighter.json
│ │ ├── material-ocean.json
│ │ ├── material-palenight.json
│ │ ├── min-dark.json
│ │ ├── min-light.json
│ │ ├── monokai.json
│ │ ├── nord.json
│ │ ├── poimandres.json
│ │ ├── slack-dark.json
│ │ ├── slack-ochin.json
│ │ ├── solarized-dark.json
│ │ ├── solarized-light.json
│ │ ├── vitesse-dark.json
│ │ └── vitesse-light.json
│ └── tsconfig.json
├── site
│ ├── assets
│ │ ├── figma-editing.png
│ │ ├── leandro-fatih.png
│ │ ├── svg-figma-af.jpg
│ │ └── vscode-ts.png
│ ├── beer.wy
│ ├── chinese-svg.svg
│ ├── gen-custom-theme.js
│ ├── gen-index.js
│ ├── gen-mono.js
│ ├── gen-palenight.js
│ ├── gen-svg-sample.js
│ ├── gen-svg.js
│ ├── gen-wenyan.js
│ ├── index.html
│ ├── index.js
│ ├── index.md
│ ├── jsconfig.json
│ ├── mono.html
│ ├── mono.md
│ ├── monochrome-dark-subtle.json
│ ├── package.json
│ ├── palenight.html
│ ├── palenight.md
│ ├── rockstar.html
│ ├── rockstar.md
│ ├── rockstar.tmLanguage.json
│ ├── style.css
│ ├── svg.svg
│ └── 文言.html
├── tsconfig.json
└── vuepress-plugin
│ ├── README.md
│ ├── index.js
│ └── package.json
├── scripts
├── grammarSources.ts
├── grammars
│ ├── normalizeGrammarPaths.ts
│ ├── pullGrammarsFromGitHub.ts
│ └── updateGrammarSourceFiles.ts
├── pullGrammars.sh
├── pullThemes.sh
├── themeSources.ts
├── themes
│ ├── normalizeThemePaths.ts
│ ├── processVSCThemes.ts
│ ├── pullThemesFromGitHub.ts
│ ├── pullThemesFromMarketplace.ts
│ └── updateThemeSrc.ts
├── tsconfig.json
└── util
│ └── download.ts
├── tsconfig.json
└── yarn.lock
/.gitattributes:
--------------------------------------------------------------------------------
1 | packages/shiki/languages/*.json binary
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [octref]
2 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | branches:
8 | - main
9 |
10 | jobs:
11 | test:
12 | runs-on: ${{ matrix.os }}
13 |
14 | strategy:
15 | matrix:
16 | os: [ubuntu-latest, windows-2016]
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 | - uses: actions/setup-node@v2
21 | with:
22 | node-version: '14'
23 |
24 | - name: Get yarn cache directory path
25 | id: yarn-cache-dir-path
26 | run: echo "::set-output name=dir::$(yarn cache dir)"
27 |
28 | - uses: actions/cache@v2
29 | id: yarn-cache
30 | with:
31 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
32 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
33 | restore-keys: |
34 | ${{ runner.os }}-yarn-
35 |
36 | - run: yarn install
37 | - run: yarn build
38 | - run: yarn update
39 | - run: yarn workspace shiki-site gen
40 |
41 | - run: yarn test
42 | env:
43 | CI: true
44 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy npm modules
2 | on:
3 | push:
4 | branches: [main]
5 |
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v1
12 | - uses: actions/setup-node@v1
13 | with:
14 | node-version: '15.x'
15 | registry-url: 'https://registry.npmjs.org/'
16 |
17 | - run: yarn install
18 | - run: yarn build
19 | - run: yarn update
20 |
21 | - name: Deploy npm Packages
22 | run: npx pleb publish
23 | env:
24 | NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
25 |
--------------------------------------------------------------------------------
/.github/workflows/update-grammars.yml:
--------------------------------------------------------------------------------
1 | name: 'Update Grammars'
2 |
3 | on:
4 | schedule:
5 | - cron: '0 6 * * *'
6 | workflow_dispatch:
7 |
8 | jobs:
9 | update-grammars:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | - uses: actions/setup-node@v1
16 | with:
17 | node-version: '12'
18 |
19 | - name: Get yarn cache directory path
20 | id: yarn-cache-dir-path
21 | run: echo "::set-output name=dir::$(yarn cache dir)"
22 |
23 | - uses: actions/cache@v2
24 | id: yarn-cache
25 | with:
26 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
27 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
28 | restore-keys: |
29 | ${{ runner.os }}-yarn-
30 |
31 | - run: yarn install
32 |
33 | - run: yarn run update:grammars
34 |
35 | - name: Build
36 | run: yarn build
37 | - name: Test
38 | run: yarn test
39 | env:
40 | CI: true
41 |
42 | - name: Commit
43 | run: |
44 | if [[ `git status --porcelain` ]]; then
45 | git config user.name "Pine Wu"
46 | git config user.email octref@gmail.com
47 | git status
48 | git add -A
49 | git commit -m "chore: Update grammars"
50 | git push
51 | else
52 | echo "no changes"
53 | fi
54 |
--------------------------------------------------------------------------------
/.github/workflows/update-themes.yml:
--------------------------------------------------------------------------------
1 | name: 'Update Themes'
2 |
3 | on:
4 | schedule:
5 | - cron: '0 8 * * *'
6 | workflow_dispatch:
7 |
8 | jobs:
9 | update-themes:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | - uses: actions/setup-node@v1
16 | with:
17 | node-version: '12'
18 |
19 | - name: Get yarn cache directory path
20 | id: yarn-cache-dir-path
21 | run: echo "::set-output name=dir::$(yarn cache dir)"
22 |
23 | - uses: actions/cache@v2
24 | id: yarn-cache
25 | with:
26 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
27 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
28 | restore-keys: |
29 | ${{ runner.os }}-yarn-
30 |
31 | - run: yarn install
32 |
33 | - run: yarn run update:themes
34 |
35 | - name: Build
36 | run: yarn build
37 | - name: Test
38 | run: yarn test
39 | env:
40 | CI: true
41 |
42 | - name: Commit
43 | run: |
44 | if [[ `git status --porcelain` ]]; then
45 | git config user.name "Pine Wu"
46 | git config user.email octref@gmail.com
47 | git status
48 | git add -A
49 | git commit -m "chore: Update themes"
50 | git push
51 | else
52 | echo "no changes"
53 | fi
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | tsconfig.tsbuildinfo
4 | tmp
5 |
6 | .DS_Store
7 |
8 | yarn-error.log
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore as they are auto generated
2 |
3 | packages/shiki/src/languages.ts
4 | packages/shiki/src/themes.ts
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "semi": false,
4 | "singleQuote": true,
5 | "trailingComma": "none",
6 | "arrowParens": "avoid"
7 | }
8 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ### 0.2.7 | 2020-11-13
4 |
5 | - Fix color fallback issues. [#100](https://github.com/shikijs/shiki/issues/100).
6 | - 🙌 Add Applescript grammar. [#99](https://github.com/shikijs/shiki/issues/99). Thanks to contribution from [Arturo Galán](https://github.com/arturogalan).
7 |
8 | ### 0.2.6 | 2020-09-28
9 |
10 | - Upgrade to onigasm 2.2.5.
11 | - Add Erlang grammar.
12 | - 🙌 Add Elixir grammar. [#95](https://github.com/shikijs/shiki/issues/95). Thanks to contribution from [Sebastien Baudray](https://github.com/https://github.com/sbaudray).
13 | - 🙌 Fix wrong escape sequence in vuepress plugin. [#93](https://github.com/shikijs/shiki/issues/93). Thanks to contribution from [Yu Zhang](https://github.com/yzhang-gh).
14 |
15 | ### 0.2.5 | 2020-09-17
16 |
17 | - Reduce dependency size (shiki-themes is 47M). [#94](https://github.com/shikijs/shiki/issues/94).
18 |
19 | ### 0.2.4 | 2020-09-13
20 |
21 | - Fix `RangeError: Invalid array length` in `vuepress-plugin-shiki`.
22 | - 🙌 Wrap line in ` `. [#76](https://github.com/shikijs/shiki/issues/76). Thanks to contribution from [Christoph Werner](https://github.com/codepunkt).
23 |
24 | ### 0.2.3 | 2020-09-08
25 |
26 | - Add `文言` language. [#88](https://github.com/shikijs/shiki/issues/88).
27 | - Add `slack-theme-dark-mode` and `slack-theme-ochin` themes. Thanks to contribution from [Christoph Werner](https://github.com/codepunkt). [#78](https://github.com/shikijs/shiki/pull/78).
28 |
29 | ### 0.2.2 | 2020-08-26
30 |
31 | - Fix dark-plus syntax highlighting for uncolored white text.
32 |
33 | ### 0.2.1 | 2020-08-24
34 |
35 | - Allow custom languages for vuepress. [#80](https://github.com/shikijs/shiki/issues/80).
36 | - Fix `php` syntax highlighting. [#21](https://github.com/shikijs/shiki/issues/21).
37 | - Add `jinja-html` language, which embeds `jinja` language. [#24](https://github.com/shikijs/shiki/issues/24).
38 | - Remove `vue-html` language. Either use `vue` or `html` language.
39 |
40 | ### 0.2.0 | 2020-08-24
41 |
42 | - Normalize all theme names to kebab-case.
43 | - Add GitHub light/dark themes.
44 | - Remove less popular themes.
45 | - Add `hlsl`, `asm` (x86 Assembly), `m` (Matlab), `sas`, `d`, `dart`, `plsql`, `logo`, , `pas` (Object Pascal/Delphi), `cobol`, `kt` (Kotlin), `scala`, `abap`, `julia`, `scheme`, `prolog`, `ada`, `lisp`, `apex`, `fortran`, `haskell`, `hcl`, `hack`, `awk`, `as` (ActionScript), `tcl`, `ocaml`, `viml`, `puppet`, `jsonnet`, `smalltalk`, `cr` (Crystal), `wat` (WASM), `nix`, `elm`, `purescript` and `svelte` languages.
46 | - Add `pug` language and make `jade` an alias of it.
47 | - Use GitHub workflow to update grammars periodically. [#72](https://github.com/shikijs/shiki/issues/72).
48 | - Use GitHub workflow to update themes periodically. [#71](https://github.com/shikijs/shiki/issues/71).
49 | - Use theme foreground color when color of token is `undefined`. [#27](https://github.com/shikijs/shiki/issues/27).
50 | - SVG Renderer. [#2](https://github.com/shikijs/shiki/issues/2).
51 | - Fix HTML escaping. [#26](https://github.com/octref/shiki/issues/26) and [#28](https://github.com/octref/shiki/pull/28). Thanks to contribution from [@jackens](https://github.com/jackens).
52 | - 🙌 Add an option to skip generating the explanation text. [#52](https://github.com/shikijs/shiki/pull/52). Thanks to contribution from [Gerrit Birkeland](https://github.com/Gerrit0).
53 | - 🙌 Improve performance by avoiding some unnecessary string copies. [#51](https://github.com/shikijs/shiki/pull/51). Thanks to contribution from [Gerrit Birkeland](https://github.com/Gerrit0).
54 | - 🙌 Allow loading custom `tmLanguage`. [#10](https://github.com/octref/shiki/issues/10) and [#49](https://github.com/octref/shiki/pull/49). Thanks to contribution from [Orta Therox](https://github.com/orta) and [@pngwn](https://github.com/pngwn).
55 | - 🙌 Update Java grammar. [#36](https://github.com/octref/shiki/issues/36) and [#37](https://github.com/octref/shiki/issues/37). Thanks to contribution from [@0xflotus](https://github.com/0xflotus).
56 |
57 | ### 0.1.7 | 2020-04-28
58 |
59 | - Update to latest Dark+/Light+ theme from VS Code.
60 |
61 | ### 0.1.6 | 2019-09-19
62 |
63 | - Add `toml` language from https://github.com/bungcip/better-toml. [#20](https://github.com/octref/shiki/issues/20).
64 |
65 | ### 0.1.5 | 2019-09-09
66 |
67 | - Begin to keep a changelog. [#7](https://github.com/octref/shiki/issues/7).
68 | - Accept `plaintext`, `text` and `txt` as `lang`. Will return `code` as it is. [#16](https://github.com/octref/shiki/issues/16).
69 | - Add `jsonc` language. [#18](https://github.com/octref/shiki/issues/18).
70 | - Add `csharp` language. [#14](https://github.com/octref/shiki/issues/14).
71 | - Add `md` as an alias for `markdown`.
72 | - Add `zsh` as an alias for `bash`.
73 | - Add `yml` as an alias for `yaml`.
74 | - 🙌 Use json5 for parsing theme as JSONC. [#11](https://github.com/octref/shiki/issues/11). Thanks to contribution from [Wes Bos](https://github.com/wesbos).
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Shiki
3 |
4 |
5 | Shiki is a beautiful Syntax Highlighter. Demo .
6 |
7 |
8 | ## Usage
9 |
10 | ```sh
11 | npm i shiki
12 | # yarn add shiki
13 | ```
14 |
15 | ```js
16 | const shiki = require('shiki')
17 |
18 | shiki
19 | .getHighlighter({
20 | theme: 'nord'
21 | })
22 | .then(highlighter => {
23 | console.log(highlighter.codeToHtml(`console.log('shiki');`, 'js'))
24 | })
25 |
26 | //
27 | //
28 | //
29 | ```
30 |
31 | ```html
32 |
33 |
43 | ```
44 |
45 | - [Themes](./docs/themes.md)
46 | - [Languages](./docs/languages.md)
47 | - [SVG Renderer](./packages/renderer-svg/README.md)
48 | - [vuepress-plugin-shiki](./packages/vuepress-plugin/README.md)
49 |
50 | Clone [shikijs/shiki-starter](https://github.com/shikijs/shiki-starter) to play with Shiki, or try it out on [Repl.it](https://repl.it/@octref/shiki-starter).
51 |
52 | ## Seen
53 |
54 | - Shiki Docs: https://shiki.matsu.io
55 | - Interactive Demo on CodeSandbox (with Next.js): https://codesandbox.io/s/shiki-next-js-cir0y
56 | - [VS Code website](https://code.visualstudio.com), such as in the [Notebook API page](https://code.visualstudio.com/api/extension-guides/notebook).
57 | - [TypeScript website](https://www.typescriptlang.org), such as in the [Basic Types documentation page](https://www.typescriptlang.org/docs/handbook/basic-types.html#tuple).
58 | - [Markdown Preview Shiki Highlighting](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-Shiki), a VS Code plugin to use Shiki's highlighting in Markdown preview.
59 | - [Shiki LaTeX](https://www.npmjs.com/package/shiki-latex), a Shiki renderer for [LaTeX](https://www.latex-project.org). Compatible with [minted](https://github.com/gpoore/minted), replacing [Pygments](https://pygments.org).
60 | - [Fatih Kalifa's website](https://fatihkalifa.com/typescript-twoslash)
61 | - [Blockstack Documentation](https://docs.blockstack.org/)
62 | - [VPC Shiki](https://github.com/Vap0r1ze/vpc-shiki), Shiki codeblocks on Discord. Powered by [Powercord](http://powercord.dev/)
63 |
64 | ## Contributing
65 |
66 | - [Add a theme](./docs/themes.md#add)
67 | - [Add a language grammar](./docs/languages.md#adding-grammar)
68 |
69 | ## Credits
70 |
71 | - Shiki uses [Onigasm](https://github.com/NeekSandhu/onigasm) by [@NeekSandhu](https://github.com/NeekSandhu)
72 | - A lot of code is based on [vscode-textmate](https://github.com/Microsoft/vscode-textmate)
73 |
74 | ## Sponsorship
75 |
76 | If you find Shiki useful, please consider sponsoring my Open Source development. Thank you 🙏
77 |
78 | https://github.com/sponsors/octref
79 |
80 | ## License
81 |
82 | MIT © [Pine Wu](https://github.com/octref)
83 |
--------------------------------------------------------------------------------
/docs/languages.md:
--------------------------------------------------------------------------------
1 | # shiki-languages
2 |
3 | TextMate grammars for Shiki. Grammars are collected from two sources:
4 |
5 | - [VS Code](https://github.com/microsoft/vscode)
6 | - A [handpicked list](/scripts/grammarSources.ts) from GitHub
7 |
8 | A [build script](/scripts/pullGrammars.sh) runs every day to pull latest grammars from the upstream sources.
9 |
10 | ## Adding Grammar
11 |
12 | - Find grammar for a language by searching ` textmate` on GitHub or searching `` on VS Code Marketplace
13 | - Add your grammar to [/scripts/grammarSources.ts](/scripts/grammarSources.ts)
14 | - In [/packages/shiki/samples/](/packages/shiki/samples/), add a code sample file `.sample` for your language. A sample should include a variety of language syntaxes and succinctly capture the idiosyncrasy of a language. Format requirements:
15 | - Space for indentation
16 | - Less than 100 columns if possible
17 | - Link to source in the last line, for example `# From https://poignant.guide/book/chapter-5.html`
18 | - Run `yarn update:grammars`
19 | - Add your language to the language list, below
20 |
21 | ## All Languages
22 |
23 | ```ts
24 | export type Lang =
25 | | 'abap'
26 | | 'actionscript-3'
27 | | 'ada'
28 | | 'apache'
29 | | 'apex'
30 | | 'apl'
31 | | 'applescript'
32 | | 'asm'
33 | | 'awk'
34 | | 'bat' | 'batch'
35 | | 'c'
36 | | 'clojure' | 'clj'
37 | | 'cobol'
38 | | 'coffee'
39 | | 'cpp'
40 | | 'crystal'
41 | | 'csharp' | 'c#'
42 | | 'css'
43 | | 'd'
44 | | 'dart'
45 | | 'diff'
46 | | 'docker'
47 | | 'dream-maker'
48 | | 'elixir'
49 | | 'elm'
50 | | 'erb'
51 | | 'erlang'
52 | | 'fsharp' | 'f#'
53 | | 'gherkin'
54 | | 'git-commit'
55 | | 'git-rebase'
56 | | 'gnuplot'
57 | | 'go'
58 | | 'graphql'
59 | | 'groovy'
60 | | 'hack'
61 | | 'haml'
62 | | 'handlebars' | 'hbs'
63 | | 'haskell'
64 | | 'hcl'
65 | | 'hlsl'
66 | | 'html'
67 | | 'ini'
68 | | 'java'
69 | | 'javascript' | 'js'
70 | | 'jinja-html'
71 | | 'json'
72 | | 'jsonc'
73 | | 'jsonnet'
74 | | 'jssm' | 'fsl'
75 | | 'jsx'
76 | | 'julia'
77 | | 'jupyter'
78 | | 'kotlin'
79 | | 'latex'
80 | | 'less'
81 | | 'lisp'
82 | | 'logo'
83 | | 'lua'
84 | | 'make' | 'makefile'
85 | | 'markdown' | 'md'
86 | | 'matlab'
87 | | 'mdx'
88 | | 'nginx'
89 | | 'nim'
90 | | 'nix'
91 | | 'objective-c' | 'objc'
92 | | 'objective-cpp'
93 | | 'ocaml'
94 | | 'pascal'
95 | | 'perl'
96 | | 'php'
97 | | 'plsql'
98 | | 'postcss'
99 | | 'powershell' | 'ps' | 'ps1'
100 | | 'prisma'
101 | | 'prolog'
102 | | 'pug' | 'jade'
103 | | 'puppet'
104 | | 'purescript'
105 | | 'python' | 'py'
106 | | 'r'
107 | | 'raku' | 'perl6'
108 | | 'razor'
109 | | 'riscv'
110 | | 'ruby' | 'rb'
111 | | 'rust'
112 | | 'sas'
113 | | 'sass'
114 | | 'scala'
115 | | 'scheme'
116 | | 'scss'
117 | | 'shaderlab' | 'shader'
118 | | 'shellscript' | 'shell' | 'bash' | 'sh' | 'zsh'
119 | | 'smalltalk'
120 | | 'solidity'
121 | | 'sparql'
122 | | 'sql'
123 | | 'ssh-config'
124 | | 'stylus' | 'styl'
125 | | 'svelte'
126 | | 'swift'
127 | | 'system-verilog'
128 | | 'tcl'
129 | | 'tex'
130 | | 'toml'
131 | | 'tsx'
132 | | 'turtle'
133 | | 'twig'
134 | | 'typescript' | 'ts'
135 | | 'vb' | 'cmd'
136 | | 'verilog'
137 | | 'vhdl'
138 | | 'viml'
139 | | 'vue'
140 | | 'wasm'
141 | | 'wenyan' | '文言'
142 | | 'xml'
143 | | 'xsl'
144 | | 'yaml'
145 | ```
146 |
--------------------------------------------------------------------------------
/docs/themes.md:
--------------------------------------------------------------------------------
1 | # shiki-themes
2 |
3 | TextMate/vscode themes for Shiki. Themes are collected from three sources:
4 |
5 | - [VS Code](https://github.com/microsoft/vscode)
6 | - A [handpicked list](/scripts/themeSources.ts) from GitHub
7 | - A [handpicked list](/scripts/themeSources.ts) from VS Code marketplace
8 |
9 | A [build script](/scripts/pullThemes.sh) runs every day to pull latest themes from the upstream sources.
10 |
11 | ## Adding Theme
12 |
13 | - Find your theme's repository
14 | - If it has a compiled JSON theme, add its link to `githubThemeSources` in [/scripts/themeSources.ts](/scripts/themeSources.ts)
15 | - If it has a precompilation step, add its link to `marketplaceThemeSources` in [/scripts/themeSources.ts](/scripts/themeSources.ts)
16 | - Run `yarn update:themes`
17 |
18 | ## Loading Theme
19 |
20 | ```js
21 | const shiki = require('shiki')
22 |
23 | const t = shiki.loadTheme('./my-theme.json')
24 |
25 | shiki.getHighlighter({
26 | theme: t
27 | })
28 | ```
29 |
30 | ## All Themes
31 |
32 | ```ts
33 | export type Theme =
34 | | 'dark-plus'
35 | | 'dracula-soft'
36 | | 'dracula'
37 | | 'github-dark'
38 | | 'github-light'
39 | | 'light-plus'
40 | | 'material-darker'
41 | | 'material-default'
42 | | 'material-lighter'
43 | | 'material-ocean'
44 | | 'material-palenight'
45 | | 'min-dark'
46 | | 'min-light'
47 | | 'monokai'
48 | | 'nord'
49 | | 'poimandres'
50 | | 'slack-dark'
51 | | 'slack-ochin'
52 | | 'solarized-dark'
53 | | 'solarized-light'
54 | | 'vitesse-dark'
55 | | 'vitesse-light'
56 | ```
57 |
58 | You can preview some of these themes on https://vscodethemes.com/.
59 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | testMatch: ['/packages/**/__tests__/**/*test.ts'],
4 | testTimeout: 10000,
5 | testEnvironment: 'node',
6 | globals: {
7 | __BROWSER__: false
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": ["packages/*"],
3 | "version": "0.9.5",
4 | "npmClient": "yarn",
5 | "useWorkspaces": true
6 | }
7 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build.environment]
2 | NODE_VERSION = "14"
3 |
4 | [build]
5 | base = "."
6 | publish = "packages/site"
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "workspaces": [
4 | "packages/*"
5 | ],
6 | "scripts": {
7 | "build": "lerna run build --include-dependencies",
8 | "watch": "lerna run watch --parallel",
9 | "fmt": "prettier --write packages/**/*.ts",
10 | "test": "cross-env NODE_OPTIONS=--max-old-space-size=4096 jest --colors",
11 | "gen": "yarn workspace shiki-site gen",
12 | "release": "lerna publish",
13 | "update": "npm run update:themes && npm run update:grammars",
14 | "update:themes": "bash ./scripts/pullThemes.sh",
15 | "update:grammars": "bash ./scripts/pullGrammars.sh"
16 | },
17 | "gitHooks": {
18 | "pre-commit": "lint-staged"
19 | },
20 | "lint-staged": {
21 | "*.{js,json,yml}": [
22 | "prettier --write"
23 | ],
24 | "*.ts": [
25 | "prettier --write"
26 | ]
27 | },
28 | "devDependencies": {
29 | "@rollup/plugin-commonjs": "^20.0.0",
30 | "@rollup/plugin-node-resolve": "^13.0.4",
31 | "@rollup/plugin-replace": "^3.0.0",
32 | "@types/fs-extra": "^9.0.12",
33 | "@types/jest": "^26.0.24",
34 | "@types/js-yaml": "^4.0.2",
35 | "@types/json5": "^2.2.0",
36 | "@types/node": "^14.17.7",
37 | "@types/unzipper": "^0.10.4",
38 | "chalk": "^4.1.2",
39 | "cross-env": "^7.0.3",
40 | "esno": "^0.5.0",
41 | "fast-plist": "^0.1.2",
42 | "fs-extra": "^9.0.12",
43 | "jest": "^26.6.3",
44 | "json5": "^2.2.0",
45 | "lerna": "^3.22.1",
46 | "lint-staged": "^10.5.4",
47 | "lodash.kebabcase": "^4.1.1",
48 | "prettier": "^2.3.2",
49 | "rollup": "^2.55.1",
50 | "rollup-plugin-copy": "^3.4.0",
51 | "rollup-plugin-dts": "^3.0.2",
52 | "rollup-plugin-terser": "^7.0.2",
53 | "rollup-plugin-typescript2": "^0.29.0",
54 | "ts-jest": "^26.5.6",
55 | "tsup": "^4.12.5",
56 | "typescript": "^4.3.5",
57 | "unzipper": "^0.10.11",
58 | "yorkie": "^2.0.0"
59 | },
60 | "license": "MIT"
61 | }
62 |
--------------------------------------------------------------------------------
/packages/renderer-svg/README.md:
--------------------------------------------------------------------------------
1 | # shiki-renderer-svg
2 |
3 | A SVG renderer for Shiki.
4 |
5 | ## Usage
6 |
7 | ```js
8 | const fs = require('fs')
9 | const shiki = require('shiki')
10 | const { getSVGRenderer } = require('shiki-renderer-svg')
11 |
12 | ;(async () => {
13 | const highlighter = await shiki.getHighlighter({
14 | theme: 'nord'
15 | })
16 |
17 | const svgRenderer = await getSVGRenderer({
18 | bg: '#2E3440',
19 | fontFamily: 'IBM Plex Mono',
20 | fontSize: 14
21 | })
22 |
23 | const code = fs.readFileSync('gen-svg.js', 'utf-8')
24 |
25 | const tokens = highlighter.codeToThemedTokens(code, 'js')
26 | const out = svgRenderer.renderToSVG(tokens)
27 |
28 | fs.writeFileSync('svg.svg', out)
29 |
30 | console.log('done: svg.svg')
31 | })()
32 | ```
33 |
34 | ### CDN
35 |
36 | ```html
37 |
38 |
39 | ```
40 |
41 | ```html
42 |
61 |
--------------------------------------------------------------------------------
/packages/renderer-svg/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shiki-renderer-svg",
3 | "version": "0.9.5",
4 | "description": "SVG renderer for shiki",
5 | "author": "Pine Wu ",
6 | "homepage": "https://github.com/octref/shiki/tree/main/packages/renderer-svg",
7 | "license": "MIT",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/shikijs/shiki.git"
11 | },
12 | "main": "dist/index.js",
13 | "module": "dist/index.mjs",
14 | "browser": "dist/index.browser.mjs",
15 | "types": "dist/index.d.ts",
16 | "unpkg": "dist/index.iife.min.js",
17 | "jsdelivr": "dist/index.iife.min.js",
18 | "files": [
19 | "dist"
20 | ],
21 | "scripts": {
22 | "prepublishOnly": "npm run build",
23 | "build": "rollup -c",
24 | "watch": "rollup -c -w"
25 | },
26 | "peerDependencies": {
27 | "playwright": "^1.9.2",
28 | "shiki": "^0.9.3"
29 | },
30 | "devDependencies": {
31 | "@types/node": "^14.17.7",
32 | "playwright": "^1.13.1",
33 | "shiki": "^0.9.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/renderer-svg/rollup.config.js:
--------------------------------------------------------------------------------
1 | import { nodeResolve } from '@rollup/plugin-node-resolve'
2 | import commonjs from '@rollup/plugin-commonjs'
3 | import dts from 'rollup-plugin-dts'
4 | import typescript from 'rollup-plugin-typescript2'
5 | import replace from '@rollup/plugin-replace'
6 | import { terser } from 'rollup-plugin-terser'
7 |
8 | const external = ['shiki', 'playwright']
9 |
10 | export default [
11 | {
12 | input: 'src/index.ts',
13 | external,
14 | output: [
15 | {
16 | file: 'dist/index.js',
17 | format: 'cjs'
18 | },
19 | {
20 | file: 'dist/index.mjs',
21 | format: 'esm'
22 | }
23 | ],
24 | plugins: [
25 | replace({
26 | __BROWSER__: JSON.stringify(false)
27 | }),
28 | typescript(),
29 | nodeResolve(),
30 | commonjs()
31 | ]
32 | },
33 | {
34 | input: 'src/index.ts',
35 | external,
36 | output: [
37 | {
38 | file: 'dist/index.iife.js',
39 | format: 'iife',
40 | extend: true,
41 | name: 'shiki'
42 | },
43 | {
44 | file: 'dist/index.iife.min.js',
45 | format: 'iife',
46 | extend: true,
47 | name: 'shiki',
48 | plugins: [terser()]
49 | },
50 | {
51 | file: 'dist/index.browser.mjs',
52 | format: 'esm'
53 | }
54 | ],
55 | plugins: [
56 | replace({
57 | __BROWSER__: JSON.stringify(true)
58 | }),
59 | typescript(),
60 | nodeResolve(),
61 | commonjs()
62 | ]
63 | },
64 | {
65 | input: 'src/index.ts',
66 | output: [
67 | {
68 | file: 'dist/index.d.ts',
69 | format: 'es'
70 | }
71 | ],
72 | plugins: [dts()]
73 | }
74 | ]
75 |
--------------------------------------------------------------------------------
/packages/renderer-svg/src/__tests__/styleAttributes.test.ts:
--------------------------------------------------------------------------------
1 | import { getSVGRenderer } from '../index'
2 |
3 | test('SVG renderer should generate SVG with correct style attributes', async () => {
4 | const r = getSVGRenderer({
5 | fontFamily: 'IBM Plex Mono'
6 | })
7 |
8 | const out = (await r).renderToSVG([[{ content: 'foo', color: '#aabbccff' }]])
9 | // 0x40 = 64, 0xff = 256. 64/256 = 0.25
10 | expect(out).toContain('opacity="1"')
11 | })
12 |
--------------------------------------------------------------------------------
/packages/renderer-svg/src/global.d.ts:
--------------------------------------------------------------------------------
1 | declare var __BROWSER__: boolean
2 |
--------------------------------------------------------------------------------
/packages/renderer-svg/src/measureMonospaceTypeface.ts:
--------------------------------------------------------------------------------
1 | function measureFont([fontName, fontSize]: [string, number]) {
2 | /**
3 | * Measure `M` for width
4 | */
5 | var c = document.createElement('canvas')
6 | var ctx = c.getContext('2d')!
7 | ctx.font = `${fontSize}px "${fontName}"`
8 |
9 | const capMMeasurement = ctx.measureText('M')
10 |
11 | /**
12 | * Measure A-Z, a-z for height
13 | * A - 65
14 | * Z - 90
15 | * a - 97
16 | * z - 122
17 | */
18 | const characters = []
19 | for (let i = 65; i <= 90; i++) {
20 | characters.push(String.fromCharCode(i))
21 | }
22 | for (let i = 97; i <= 122; i++) {
23 | characters.push(String.fromCharCode(i))
24 | }
25 |
26 | let highC, lowC
27 | let highestAscent = 0
28 | let lowestDescent = 0
29 | characters.forEach(c => {
30 | const m = ctx.measureText(c)
31 | if (m.actualBoundingBoxAscent > highestAscent) {
32 | highestAscent = m.actualBoundingBoxAscent
33 | highC = c
34 | }
35 | if (m.actualBoundingBoxDescent > lowestDescent) {
36 | lowestDescent = m.actualBoundingBoxDescent
37 | lowC = c
38 | }
39 | })
40 |
41 | return {
42 | width: capMMeasurement.width,
43 | height: highestAscent + lowestDescent
44 | }
45 | }
46 |
47 | const getDocument = (fontName: string, url: string) => {
48 | return `
49 |
50 |
51 |
52 |
56 |
57 |
58 | Test
59 |
60 |
61 | `
62 | }
63 |
64 | export async function measureMonospaceTypeface(
65 | fontNameStr: string,
66 | fontSize: number,
67 | remoteFontCSSURL?: string
68 | ): Promise<{ width: number; height: number }> {
69 | if (__BROWSER__) {
70 | return measureFont([fontNameStr, fontSize])
71 | } else {
72 | const playwright = require('playwright') as typeof import('playwright')
73 | const browser = await playwright.chromium.launch({ headless: true })
74 |
75 | const page = await browser.newPage()
76 |
77 | if (remoteFontCSSURL) {
78 | await page.goto('data:text/html,' + getDocument(fontNameStr, remoteFontCSSURL), {
79 | waitUntil: 'networkidle'
80 | })
81 |
82 | const measurement = await page.evaluate(measureFont, [fontNameStr, fontSize])
83 | await browser.close()
84 | return measurement
85 | } else {
86 | const measurement = await page.evaluate(measureFont, [fontNameStr, fontSize])
87 |
88 | await browser.close()
89 |
90 | return measurement
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/packages/renderer-svg/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2017",
5 | "esModuleInterop": true,
6 | "moduleResolution": "node",
7 | "lib": ["esnext", "DOM"],
8 | "sourceMap": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/shiki/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Shiki
3 |
4 |
5 | Shiki is a beautiful Syntax Highlighter. Demo .
6 |
7 |
8 | ## Usage
9 |
10 | ```sh
11 | npm i shiki
12 | # yarn add shiki
13 | ```
14 |
15 | ```js
16 | const shiki = require('shiki')
17 |
18 | shiki
19 | .getHighlighter({
20 | theme: 'nord'
21 | })
22 | .then(highlighter => {
23 | console.log(highlighter.codeToHtml(`console.log('shiki');`, 'js'))
24 | })
25 |
26 | //
27 | //
28 | //
29 | ```
30 |
31 | ```html
32 |
33 |
43 | ```
44 |
45 | Clone [shikijs/shiki-starter](https://github.com/shikijs/shiki-starter) to play with Shiki, or try it out on [Repl.it](https://repl.it/@octref/shiki-starter).
46 |
47 | ## Seen
48 |
49 | - Shiki Docs: https://shiki.matsu.io
50 | - Interactive Demo on CodeSandbox (with Next.js): https://codesandbox.io/s/shiki-next-js-cir0y
51 | - [VS Code website](https://code.visualstudio.com), such as in the [Notebook API page](https://code.visualstudio.com/api/extension-guides/notebook).
52 | - [TypeScript website](https://www.typescriptlang.org), such as in the [Basic Types documentation page](https://www.typescriptlang.org/docs/handbook/basic-types.html#tuple).
53 | - [Markdown Preview Shiki Highlighting](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-Shiki), a VS Code plugin to use Shiki's highlighting in Markdown preview.
54 | - [Shiki LaTeX](https://www.npmjs.com/package/shiki-latex), a Shiki renderer for [LaTeX](https://www.latex-project.org). Compatible with [minted](https://github.com/gpoore/minted), replacing [Pygments](https://pygments.org).
55 | - [Fatih Kalifa's website](https://fatihkalifa.com/typescript-twoslash)
56 | - [Blockstack Documentation](https://docs.blockstack.org/)
57 |
58 | ## Contributing
59 |
60 | - [Add a theme](./docs/themes.md#add)
61 | - [Add a language grammar](./docs/languages.md#add)
62 |
63 | ## Credits
64 |
65 | - Shiki uses [Onigasm](https://github.com/NeekSandhu/onigasm) by [@NeekSandhu](https://github.com/NeekSandhu)
66 | - A lot of code is based on [vscode-textmate](https://github.com/Microsoft/vscode-textmate)
67 |
68 | ## Sponsorship
69 |
70 | If you find Shiki useful, please consider sponsoring my Open Source development. Thank you 🙏
71 |
72 | https://github.com/sponsors/octref
73 |
74 | ## License
75 |
76 | MIT © [Pine Wu](https://github.com/octref)
77 |
--------------------------------------------------------------------------------
/packages/shiki/languages/diff.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/textmate/diff.tmbundle/blob/master/Syntaxes/Diff.plist",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/textmate/diff.tmbundle/commit/0593bb775eab1824af97ef2172fd38822abd97d7",
8 | "name": "diff",
9 | "scopeName": "source.diff",
10 | "patterns": [
11 | {
12 | "captures": {
13 | "1": {
14 | "name": "punctuation.definition.separator.diff"
15 | }
16 | },
17 | "match": "^((\\*{15})|(={67})|(-{3}))$\\n?",
18 | "name": "meta.separator.diff"
19 | },
20 | {
21 | "match": "^\\d+(,\\d+)*(a|d|c)\\d+(,\\d+)*$\\n?",
22 | "name": "meta.diff.range.normal"
23 | },
24 | {
25 | "captures": {
26 | "1": {
27 | "name": "punctuation.definition.range.diff"
28 | },
29 | "2": {
30 | "name": "meta.toc-list.line-number.diff"
31 | },
32 | "3": {
33 | "name": "punctuation.definition.range.diff"
34 | }
35 | },
36 | "match": "^(@@)\\s*(.+?)\\s*(@@)($\\n?)?",
37 | "name": "meta.diff.range.unified"
38 | },
39 | {
40 | "captures": {
41 | "3": {
42 | "name": "punctuation.definition.range.diff"
43 | },
44 | "4": {
45 | "name": "punctuation.definition.range.diff"
46 | },
47 | "6": {
48 | "name": "punctuation.definition.range.diff"
49 | },
50 | "7": {
51 | "name": "punctuation.definition.range.diff"
52 | }
53 | },
54 | "match": "^(((\\-{3}) .+ (\\-{4}))|((\\*{3}) .+ (\\*{4})))$\\n?",
55 | "name": "meta.diff.range.context"
56 | },
57 | {
58 | "match": "^diff --git a/.*$\\n?",
59 | "name": "meta.diff.header.git"
60 | },
61 | {
62 | "match": "^diff (-|\\S+\\s+\\S+).*$\\n?",
63 | "name": "meta.diff.header.command"
64 | },
65 | {
66 | "captures": {
67 | "4": {
68 | "name": "punctuation.definition.from-file.diff"
69 | },
70 | "6": {
71 | "name": "punctuation.definition.from-file.diff"
72 | },
73 | "7": {
74 | "name": "punctuation.definition.from-file.diff"
75 | }
76 | },
77 | "match": "(^(((-{3}) .+)|((\\*{3}) .+))$\\n?|^(={4}) .+(?= - ))",
78 | "name": "meta.diff.header.from-file"
79 | },
80 | {
81 | "captures": {
82 | "2": {
83 | "name": "punctuation.definition.to-file.diff"
84 | },
85 | "3": {
86 | "name": "punctuation.definition.to-file.diff"
87 | },
88 | "4": {
89 | "name": "punctuation.definition.to-file.diff"
90 | }
91 | },
92 | "match": "(^(\\+{3}) .+$\\n?| (-) .* (={4})$\\n?)",
93 | "name": "meta.diff.header.to-file"
94 | },
95 | {
96 | "captures": {
97 | "3": {
98 | "name": "punctuation.definition.inserted.diff"
99 | },
100 | "6": {
101 | "name": "punctuation.definition.inserted.diff"
102 | }
103 | },
104 | "match": "^(((>)( .*)?)|((\\+).*))$\\n?",
105 | "name": "markup.inserted.diff"
106 | },
107 | {
108 | "captures": {
109 | "1": {
110 | "name": "punctuation.definition.changed.diff"
111 | }
112 | },
113 | "match": "^(!).*$\\n?",
114 | "name": "markup.changed.diff"
115 | },
116 | {
117 | "captures": {
118 | "3": {
119 | "name": "punctuation.definition.deleted.diff"
120 | },
121 | "6": {
122 | "name": "punctuation.definition.deleted.diff"
123 | }
124 | },
125 | "match": "^(((<)( .*)?)|((-).*))$\\n?",
126 | "name": "markup.deleted.diff"
127 | },
128 | {
129 | "begin": "^(#)",
130 | "captures": {
131 | "1": {
132 | "name": "punctuation.definition.comment.diff"
133 | }
134 | },
135 | "comment": "Git produces unified diffs with embedded comments\"",
136 | "end": "\\n",
137 | "name": "comment.line.number-sign.diff"
138 | },
139 | {
140 | "match": "^index [0-9a-f]{7,40}\\.\\.[0-9a-f]{7,40}.*$\\n?",
141 | "name": "meta.diff.index.git"
142 | },
143 | {
144 | "captures": {
145 | "1": {
146 | "name": "punctuation.separator.key-value.diff"
147 | },
148 | "2": {
149 | "name": "meta.toc-list.file-name.diff"
150 | }
151 | },
152 | "match": "^Index(:) (.+)$\\n?",
153 | "name": "meta.diff.index"
154 | },
155 | {
156 | "match": "^Only in .*: .*$\\n?",
157 | "name": "meta.diff.only-in"
158 | }
159 | ]
160 | }
161 |
--------------------------------------------------------------------------------
/packages/shiki/languages/docker.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/moby/moby/blob/master/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/moby/moby/commit/abd39744c6f3ed854500e423f5fabf952165161f",
8 | "name": "docker",
9 | "scopeName": "source.dockerfile",
10 | "patterns": [
11 | {
12 | "captures": {
13 | "1": {
14 | "name": "keyword.other.special-method.dockerfile"
15 | },
16 | "2": {
17 | "name": "keyword.other.special-method.dockerfile"
18 | }
19 | },
20 | "match": "^\\s*\\b(?i:(FROM))\\b.*?\\b(?i:(AS))\\b"
21 | },
22 | {
23 | "captures": {
24 | "1": {
25 | "name": "keyword.control.dockerfile"
26 | },
27 | "2": {
28 | "name": "keyword.other.special-method.dockerfile"
29 | }
30 | },
31 | "match": "^\\s*(?i:(ONBUILD)\\s+)?(?i:(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR))\\s"
32 | },
33 | {
34 | "captures": {
35 | "1": {
36 | "name": "keyword.operator.dockerfile"
37 | },
38 | "2": {
39 | "name": "keyword.other.special-method.dockerfile"
40 | }
41 | },
42 | "match": "^\\s*(?i:(ONBUILD)\\s+)?(?i:(CMD|ENTRYPOINT))\\s"
43 | },
44 | {
45 | "begin": "\"",
46 | "beginCaptures": {
47 | "1": {
48 | "name": "punctuation.definition.string.begin.dockerfile"
49 | }
50 | },
51 | "end": "\"",
52 | "endCaptures": {
53 | "1": {
54 | "name": "punctuation.definition.string.end.dockerfile"
55 | }
56 | },
57 | "name": "string.quoted.double.dockerfile",
58 | "patterns": [
59 | {
60 | "match": "\\\\.",
61 | "name": "constant.character.escaped.dockerfile"
62 | }
63 | ]
64 | },
65 | {
66 | "begin": "'",
67 | "beginCaptures": {
68 | "1": {
69 | "name": "punctuation.definition.string.begin.dockerfile"
70 | }
71 | },
72 | "end": "'",
73 | "endCaptures": {
74 | "1": {
75 | "name": "punctuation.definition.string.end.dockerfile"
76 | }
77 | },
78 | "name": "string.quoted.single.dockerfile",
79 | "patterns": [
80 | {
81 | "match": "\\\\.",
82 | "name": "constant.character.escaped.dockerfile"
83 | }
84 | ]
85 | },
86 | {
87 | "captures": {
88 | "1": {
89 | "name": "punctuation.whitespace.comment.leading.dockerfile"
90 | },
91 | "2": {
92 | "name": "comment.line.number-sign.dockerfile"
93 | },
94 | "3": {
95 | "name": "punctuation.definition.comment.dockerfile"
96 | }
97 | },
98 | "comment": "comment.line",
99 | "match": "^(\\s*)((#).*$\\n?)"
100 | }
101 | ]
102 | }
103 |
--------------------------------------------------------------------------------
/packages/shiki/languages/erb.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": ["erb", "rhtml", "html.erb"],
3 | "injections": {
4 | "text.html.erb - (meta.embedded.block.erb | meta.embedded.line.erb | comment)": {
5 | "patterns": [
6 | {
7 | "begin": "(^\\s*)(?=<%+#(?![^%]*%>))",
8 | "beginCaptures": {
9 | "0": {
10 | "name": "punctuation.whitespace.comment.leading.erb"
11 | }
12 | },
13 | "end": "(?!\\G)(\\s*$\\n)?",
14 | "endCaptures": {
15 | "0": {
16 | "name": "punctuation.whitespace.comment.trailing.erb"
17 | }
18 | },
19 | "patterns": [
20 | {
21 | "include": "#comment"
22 | }
23 | ]
24 | },
25 | {
26 | "begin": "(^\\s*)(?=<%(?![^%]*%>))",
27 | "beginCaptures": {
28 | "0": {
29 | "name": "punctuation.whitespace.embedded.leading.erb"
30 | }
31 | },
32 | "end": "(?!\\G)(\\s*$\\n)?",
33 | "endCaptures": {
34 | "0": {
35 | "name": "punctuation.whitespace.embedded.trailing.erb"
36 | }
37 | },
38 | "patterns": [
39 | {
40 | "include": "#tags"
41 | }
42 | ]
43 | },
44 | {
45 | "include": "#comment"
46 | },
47 | {
48 | "include": "#tags"
49 | }
50 | ]
51 | }
52 | },
53 | "keyEquivalent": "^~H",
54 | "name": "erb",
55 | "patterns": [
56 | {
57 | "include": "text.html.basic"
58 | }
59 | ],
60 | "repository": {
61 | "comment": {
62 | "patterns": [
63 | {
64 | "begin": "<%+#",
65 | "beginCaptures": {
66 | "0": {
67 | "name": "punctuation.definition.comment.begin.erb"
68 | }
69 | },
70 | "end": "%>",
71 | "endCaptures": {
72 | "0": {
73 | "name": "punctuation.definition.comment.end.erb"
74 | }
75 | },
76 | "name": "comment.block.erb"
77 | }
78 | ]
79 | },
80 | "tags": {
81 | "patterns": [
82 | {
83 | "begin": "<%+(?!>)[-=]?(?![^%]*%>)",
84 | "beginCaptures": {
85 | "0": {
86 | "name": "punctuation.section.embedded.begin.erb"
87 | }
88 | },
89 | "contentName": "source.ruby",
90 | "end": "(-?%)>",
91 | "endCaptures": {
92 | "0": {
93 | "name": "punctuation.section.embedded.end.erb"
94 | },
95 | "1": {
96 | "name": "source.ruby"
97 | }
98 | },
99 | "name": "meta.embedded.block.erb",
100 | "patterns": [
101 | {
102 | "captures": {
103 | "1": {
104 | "name": "punctuation.definition.comment.erb"
105 | }
106 | },
107 | "match": "(#).*?(?=-?%>)",
108 | "name": "comment.line.number-sign.erb"
109 | },
110 | {
111 | "include": "source.ruby"
112 | }
113 | ]
114 | },
115 | {
116 | "begin": "<%+(?!>)[-=]?",
117 | "beginCaptures": {
118 | "0": {
119 | "name": "punctuation.section.embedded.begin.erb"
120 | }
121 | },
122 | "contentName": "source.ruby",
123 | "end": "(-?%)>",
124 | "endCaptures": {
125 | "0": {
126 | "name": "punctuation.section.embedded.end.erb"
127 | },
128 | "1": {
129 | "name": "source.ruby"
130 | }
131 | },
132 | "name": "meta.embedded.line.erb",
133 | "patterns": [
134 | {
135 | "captures": {
136 | "1": {
137 | "name": "punctuation.definition.comment.erb"
138 | }
139 | },
140 | "match": "(#).*?(?=-?%>)",
141 | "name": "comment.line.number-sign.erb"
142 | },
143 | {
144 | "include": "source.ruby"
145 | }
146 | ]
147 | }
148 | ]
149 | }
150 | },
151 | "scopeName": "text.html.erb",
152 | "uuid": "13FF9439-15D0-4E74-9A8E-83ABF0BAA5E7"
153 | }
154 |
--------------------------------------------------------------------------------
/packages/shiki/languages/git-commit.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Commit%20Message.tmLanguage",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/textmate/git.tmbundle/commit/93897a78c6e52bef13dadc0d4091d203c5facb40",
8 | "name": "git-commit",
9 | "scopeName": "text.git-commit",
10 | "patterns": [
11 | {
12 | "begin": "\\A(?!# Please enter the commit message)",
13 | "end": "^(?=# Please enter the commit message)",
14 | "name": "meta.scope.message.git-commit",
15 | "patterns": [
16 | {
17 | "begin": "\\A(?=#)",
18 | "end": "^(?!#)",
19 | "patterns": [
20 | {
21 | "include": "#comment"
22 | }
23 | ]
24 | },
25 | {
26 | "begin": "^(?!# Please enter the commit message)",
27 | "end": "^(?=# Please enter the commit message)",
28 | "patterns": [
29 | {
30 | "begin": "\\G",
31 | "end": "^(?!\\G)",
32 | "name": "meta.scope.subject.git-commit",
33 | "patterns": [
34 | {
35 | "captures": {
36 | "1": {
37 | "name": "keyword.other.$2.git-commit"
38 | }
39 | },
40 | "match": "\\G((fixup|squash)!)\\s*"
41 | },
42 | {
43 | "match": ".{73,}$",
44 | "name": "invalid.illegal.line-too-long.git-commit"
45 | },
46 | {
47 | "match": ".{51,}$",
48 | "name": "invalid.deprecated.line-too-long.git-commit"
49 | }
50 | ]
51 | },
52 | {
53 | "begin": "^(?!# Please enter the commit message)",
54 | "end": "^(?=# Please enter the commit message)",
55 | "patterns": [
56 | {
57 | "include": "#comment"
58 | }
59 | ]
60 | }
61 | ]
62 | }
63 | ]
64 | },
65 | {
66 | "begin": "^(?=# Please enter the commit message)",
67 | "end": "\\z",
68 | "name": "meta.scope.metadata.git-commit",
69 | "patterns": [
70 | {
71 | "include": "#metadata"
72 | }
73 | ]
74 | }
75 | ],
76 | "repository": {
77 | "comment": {
78 | "begin": "^(#)",
79 | "captures": {
80 | "1": {
81 | "name": "punctuation.definition.comment.git-commit"
82 | }
83 | },
84 | "end": "\\n",
85 | "name": "comment.line.number-sign.git-commit"
86 | },
87 | "metadata": {
88 | "patterns": [
89 | {
90 | "begin": "(?=^# Changes to be committed:)",
91 | "end": "(?!\\G)((?=^# \\w)|(?!^#))",
92 | "patterns": [
93 | {
94 | "begin": "(^[ \\t]+)?(?=#)",
95 | "beginCaptures": {
96 | "1": {
97 | "name": "punctuation.whitespace.comment.leading.git-commit"
98 | }
99 | },
100 | "contentName": "comment.line.number-sign.git-commit",
101 | "end": "(?!\\G)^",
102 | "patterns": [
103 | {
104 | "match": "\\G#",
105 | "name": "punctuation.definition.comment.git-commit"
106 | },
107 | {
108 | "match": "((modified|renamed):.*)$\\n?",
109 | "name": "markup.changed.git-commit"
110 | },
111 | {
112 | "match": "(new file:.*)$\\n?",
113 | "name": "markup.inserted.git-commit"
114 | },
115 | {
116 | "match": "(deleted:.*)$\\n?",
117 | "name": "markup.deleted.git-commit"
118 | }
119 | ]
120 | }
121 | ]
122 | },
123 | {
124 | "include": "#comment"
125 | },
126 | {
127 | "begin": "(?=diff\\ \\-\\-git)",
128 | "comment": "diff presented at the end of the commit message when using commit -v.",
129 | "contentName": "source.diff",
130 | "end": "\\z",
131 | "name": "meta.embedded.diff.git-commit",
132 | "patterns": [
133 | {
134 | "include": "source.diff"
135 | }
136 | ]
137 | }
138 | ]
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/packages/shiki/languages/git-rebase.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Rebase%20Message.tmLanguage",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/textmate/git.tmbundle/commit/5870cf3f8abad3a6637bdf69250b5d2ded427dc4",
8 | "name": "git-rebase",
9 | "scopeName": "text.git-rebase",
10 | "patterns": [
11 | {
12 | "captures": {
13 | "1": {
14 | "name": "punctuation.definition.comment.git-rebase"
15 | }
16 | },
17 | "match": "^\\s*(#).*$\\n?",
18 | "name": "comment.line.number-sign.git-rebase"
19 | },
20 | {
21 | "captures": {
22 | "1": {
23 | "name": "support.function.git-rebase"
24 | },
25 | "2": {
26 | "name": "constant.sha.git-rebase"
27 | },
28 | "3": {
29 | "name": "meta.commit-message.git-rebase"
30 | }
31 | },
32 | "match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
33 | "name": "meta.commit-command.git-rebase"
34 | },
35 | {
36 | "captures": {
37 | "1": {
38 | "name": "support.function.git-rebase"
39 | },
40 | "2": {
41 | "patterns": [
42 | {
43 | "include": "source.shell"
44 | }
45 | ]
46 | }
47 | },
48 | "match": "^\\s*(exec|x)\\s+(.*)$",
49 | "name": "meta.commit-command.git-rebase"
50 | },
51 | {
52 | "captures": {
53 | "1": {
54 | "name": "support.function.git-rebase"
55 | }
56 | },
57 | "match": "^\\s*(break|b)\\s*$",
58 | "name": "meta.commit-command.git-rebase"
59 | }
60 | ]
61 | }
62 |
--------------------------------------------------------------------------------
/packages/shiki/languages/ini.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/textmate/ini.tmbundle/blob/master/Syntaxes/Ini.plist",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/textmate/ini.tmbundle/commit/2af0cbb0704940f967152616f2f1ff0aae6287a6",
8 | "name": "ini",
9 | "scopeName": "source.ini",
10 | "patterns": [
11 | {
12 | "begin": "(^[ \\t]+)?(?=#)",
13 | "beginCaptures": {
14 | "1": {
15 | "name": "punctuation.whitespace.comment.leading.ini"
16 | }
17 | },
18 | "end": "(?!\\G)",
19 | "patterns": [
20 | {
21 | "begin": "#",
22 | "beginCaptures": {
23 | "0": {
24 | "name": "punctuation.definition.comment.ini"
25 | }
26 | },
27 | "end": "\\n",
28 | "name": "comment.line.number-sign.ini"
29 | }
30 | ]
31 | },
32 | {
33 | "begin": "(^[ \\t]+)?(?=;)",
34 | "beginCaptures": {
35 | "1": {
36 | "name": "punctuation.whitespace.comment.leading.ini"
37 | }
38 | },
39 | "end": "(?!\\G)",
40 | "patterns": [
41 | {
42 | "begin": ";",
43 | "beginCaptures": {
44 | "0": {
45 | "name": "punctuation.definition.comment.ini"
46 | }
47 | },
48 | "end": "\\n",
49 | "name": "comment.line.semicolon.ini"
50 | }
51 | ]
52 | },
53 | {
54 | "captures": {
55 | "1": {
56 | "name": "keyword.other.definition.ini"
57 | },
58 | "2": {
59 | "name": "punctuation.separator.key-value.ini"
60 | }
61 | },
62 | "match": "\\b([a-zA-Z0-9_.-]+)\\b\\s*(=)"
63 | },
64 | {
65 | "captures": {
66 | "1": {
67 | "name": "punctuation.definition.entity.ini"
68 | },
69 | "3": {
70 | "name": "punctuation.definition.entity.ini"
71 | }
72 | },
73 | "match": "^(\\[)(.*?)(\\])",
74 | "name": "entity.name.section.group-title.ini"
75 | },
76 | {
77 | "begin": "'",
78 | "beginCaptures": {
79 | "0": {
80 | "name": "punctuation.definition.string.begin.ini"
81 | }
82 | },
83 | "end": "'",
84 | "endCaptures": {
85 | "0": {
86 | "name": "punctuation.definition.string.end.ini"
87 | }
88 | },
89 | "name": "string.quoted.single.ini",
90 | "patterns": [
91 | {
92 | "match": "\\\\.",
93 | "name": "constant.character.escape.ini"
94 | }
95 | ]
96 | },
97 | {
98 | "begin": "\"",
99 | "beginCaptures": {
100 | "0": {
101 | "name": "punctuation.definition.string.begin.ini"
102 | }
103 | },
104 | "end": "\"",
105 | "endCaptures": {
106 | "0": {
107 | "name": "punctuation.definition.string.end.ini"
108 | }
109 | },
110 | "name": "string.quoted.double.ini"
111 | }
112 | ]
113 | }
114 |
--------------------------------------------------------------------------------
/packages/shiki/languages/jinja-html.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jinja-html",
3 | "scopeName": "text.html.jinja",
4 | "comment": "Jinja HTML Templates",
5 | "firstLineMatch": "^{% extends [\"'][^\"']+[\"'] %}",
6 | "foldingStartMarker": "(<(?i:(head|table|tr|div|style|script|ul|ol|form|dl))\\b.*?>|{%\\s*(block|filter|for|if|macro|raw))",
7 | "foldingStopMarker": "((?i:(head|table|tr|div|style|script|ul|ol|form|dl))\\b.*?>|{%\\s*(endblock|endfilter|endfor|endif|endmacro|endraw)\\s*%})",
8 | "patterns": [
9 | {
10 | "include": "source.jinja"
11 | },
12 | {
13 | "include": "text.html.basic"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/packages/shiki/languages/jssm.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": ["jssm", "jssm_state"],
3 | "name": "jssm",
4 | "patterns": [
5 | {
6 | "begin": "/\\*",
7 | "captures": {
8 | "0": {
9 | "name": "punctuation.definition.comment.mn"
10 | }
11 | },
12 | "comment": "block comment",
13 | "end": "\\*/",
14 | "name": "comment.block.jssm"
15 | },
16 | {
17 | "begin": "//",
18 | "comment": "block comment",
19 | "end": "$",
20 | "name": "comment.line.jssm"
21 | },
22 | {
23 | "begin": "\\${",
24 | "captures": {
25 | "0": {
26 | "name": "entity.name.function"
27 | }
28 | },
29 | "comment": "js outcalls",
30 | "end": "}",
31 | "name": "keyword.other"
32 | },
33 | {
34 | "comment": "semver",
35 | "match": "([0-9]*)(\\.)([0-9]*)(\\.)([0-9]*)",
36 | "name": "constant.numeric"
37 | },
38 | {
39 | "comment": "jssm language tokens",
40 | "match": "graph_layout(\\s*)(:)",
41 | "name": "constant.language.jssmLanguage"
42 | },
43 | {
44 | "comment": "jssm language tokens",
45 | "match": "machine_name(\\s*)(:)",
46 | "name": "constant.language.jssmLanguage"
47 | },
48 | {
49 | "comment": "jssm language tokens",
50 | "match": "machine_version(\\s*)(:)",
51 | "name": "constant.language.jssmLanguage"
52 | },
53 | {
54 | "comment": "jssm language tokens",
55 | "match": "jssm_version(\\s*)(:)",
56 | "name": "constant.language.jssmLanguage"
57 | },
58 | {
59 | "comment": "transitions",
60 | "match": "<->",
61 | "name": "keyword.control.transition.jssmArrow.legal_legal"
62 | },
63 | {
64 | "comment": "transitions",
65 | "match": "<-",
66 | "name": "keyword.control.transition.jssmArrow.legal_none"
67 | },
68 | {
69 | "comment": "transitions",
70 | "match": "->",
71 | "name": "keyword.control.transition.jssmArrow.none_legal"
72 | },
73 | {
74 | "comment": "transitions",
75 | "match": "<=>",
76 | "name": "keyword.control.transition.jssmArrow.main_main"
77 | },
78 | {
79 | "comment": "transitions",
80 | "match": "=>",
81 | "name": "keyword.control.transition.jssmArrow.none_main"
82 | },
83 | {
84 | "comment": "transitions",
85 | "match": "<=",
86 | "name": "keyword.control.transition.jssmArrow.main_none"
87 | },
88 | {
89 | "comment": "transitions",
90 | "match": "<~>",
91 | "name": "keyword.control.transition.jssmArrow.forced_forced"
92 | },
93 | {
94 | "comment": "transitions",
95 | "match": "~>",
96 | "name": "keyword.control.transition.jssmArrow.none_forced"
97 | },
98 | {
99 | "comment": "transitions",
100 | "match": "<~",
101 | "name": "keyword.control.transition.jssmArrow.forced_none"
102 | },
103 | {
104 | "comment": "transitions",
105 | "match": "<-=>",
106 | "name": "keyword.control.transition.jssmArrow.legal_main"
107 | },
108 | {
109 | "comment": "transitions",
110 | "match": "<=->",
111 | "name": "keyword.control.transition.jssmArrow.main_legal"
112 | },
113 | {
114 | "comment": "transitions",
115 | "match": "<-~>",
116 | "name": "keyword.control.transition.jssmArrow.legal_forced"
117 | },
118 | {
119 | "comment": "transitions",
120 | "match": "<~->",
121 | "name": "keyword.control.transition.jssmArrow.forced_legal"
122 | },
123 | {
124 | "comment": "transitions",
125 | "match": "<=~>",
126 | "name": "keyword.control.transition.jssmArrow.main_forced"
127 | },
128 | {
129 | "comment": "transitions",
130 | "match": "<~=>",
131 | "name": "keyword.control.transition.jssmArrow.forced_main"
132 | },
133 | {
134 | "comment": "edge probability annotation",
135 | "match": "([0-9]+)%",
136 | "name": "constant.numeric.jssmProbability"
137 | },
138 | {
139 | "comment": "action annotation",
140 | "match": "\\'[^']*\\'",
141 | "name": "constant.character.jssmAction"
142 | },
143 | {
144 | "comment": "jssm label annotation",
145 | "match": "\\\"[^\"]*\\\"",
146 | "name": "entity.name.tag.jssmLabel.doublequoted"
147 | },
148 | {
149 | "comment": "jssm label annotation",
150 | "match": "([a-zA-Z0-9_.+&()#@!?,])",
151 | "name": "entity.name.tag.jssmLabel.atom"
152 | }
153 | ],
154 | "scopeName": "source.jssm",
155 | "uuid": "2bb22b55-e811-4383-9929-ae6d0ab92aca"
156 | }
157 |
--------------------------------------------------------------------------------
/packages/shiki/languages/jupyter.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "scopeName": "source.jupyter",
3 | "patterns": [
4 | {
5 | "include": "source.json"
6 | }
7 | ],
8 | "name": "jupyter"
9 | }
10 |
--------------------------------------------------------------------------------
/packages/shiki/languages/logo.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "comment": "Roughed out by Paul Bissex ",
3 | "fileTypes": [],
4 | "keyEquivalent": "^~L",
5 | "name": "logo",
6 | "patterns": [
7 | {
8 | "match": "^to [\\w.]+",
9 | "name": "entity.name.function.logo"
10 | },
11 | {
12 | "match": "continue|do\\.until|do\\.while|end|for(each)?|if(else|falsetrue|)|repeat|stop|until",
13 | "name": "keyword.control.logo"
14 | },
15 | {
16 | "match": "\\b(\\.defmacro|\\.eq|\\.macro|\\.maybeoutput|\\.setbf|\\.setfirst|\\.setitem|\\.setsegmentsize|allopen|allowgetset|and|apply|arc|arctan|arity|array|arrayp|arraytolist|ascii|ashift|back|background|backslashedp|beforep|bitand|bitnot|bitor|bitxor|buried|buriedp|bury|buryall|buryname|butfirst|butfirsts|butlast|bye|cascade|case|caseignoredp|catch|char|clean|clearscreen|cleartext|close|closeall|combine|cond|contents|copydef|cos|count|crossmap|cursor|define|definedp|dequeue|difference|dribble|edall|edit|editfile|edn|edns|edpl|edpls|edps|emptyp|eofp|epspict|equalp|erall|erase|erasefile|ern|erns|erpl|erpls|erps|erract|error|exp|fence|filep|fill|filter|find|first|firsts|forever|form|forward|fput|fullprintp|fullscreen|fulltext|gc|gensym|global|goto|gprop|greaterp|heading|help|hideturtle|home|ignore|int|invoke|iseq|item|keyp|label|last|left|lessp|list|listp|listtoarray|ln|load|loadnoisily|loadpict|local|localmake|log10|lowercase|lput|lshift|macroexpand|macrop|make|map|map.se|mdarray|mditem|mdsetitem|member|memberp|minus|modulo|name|namelist|namep|names|nodes|nodribble|norefresh|not|numberp|openappend|openread|openupdate|openwrite|or|output|palette|parse|pause|pen|pencolor|pendown|pendownp|penerase|penmode|penpaint|penreverse|pensize|penup|pick|plist|plistp|plists|pllist|po|poall|pon|pons|pop|popl|popls|pops|pos|pot|pots|power|pprop|prefix|primitivep|print|printdepthlimit|printwidthlimit|procedurep|procedures|product|push|queue|quoted|quotient|radarctan|radcos|radsin|random|rawascii|readchar|readchars|reader|readlist|readpos|readrawline|readword|redefp|reduce|refresh|remainder|remdup|remove|remprop|repcount|rerandom|reverse|right|round|rseq|run|runparse|runresult|save|savel|savepict|screenmode|scrunch|sentence|setbackground|setcursor|seteditor|setheading|sethelploc|setitem|setlibloc|setmargins|setpalette|setpen|setpencolor|setpensize|setpos|setprefix|setread|setreadpos|setscrunch|settemploc|settextcolor|setwrite|setwritepos|setx|setxy|sety|shell|show|shownp|showturtle|sin|splitscreen|sqrt|standout|startup|step|stepped|steppedp|substringp|sum|tag|test|text|textscreen|thing|throw|towards|trace|traced|tracedp|transfer|turtlemode|type|unbury|unburyall|unburyname|unburyonedit|unstep|untrace|uppercase|usealternatenam|wait|while|window|word|wordp|wrap|writepos|writer|xcor|ycor)\\b",
17 | "name": "keyword.other.logo"
18 | },
19 | {
20 | "captures": {
21 | "1": {
22 | "name": "punctuation.definition.variable.logo"
23 | }
24 | },
25 | "match": "(\\:)(?:\\|[^|]*\\||[-\\w.]*)+",
26 | "name": "variable.parameter.logo"
27 | },
28 | {
29 | "match": "\"(?:\\|[^|]*\\||[-\\w.]*)+",
30 | "name": "string.other.word.logo"
31 | },
32 | {
33 | "begin": "(^[ \\t]+)?(?=;)",
34 | "beginCaptures": {
35 | "1": {
36 | "name": "punctuation.whitespace.comment.leading.logo"
37 | }
38 | },
39 | "end": "(?!\\G)",
40 | "patterns": [
41 | {
42 | "begin": ";",
43 | "beginCaptures": {
44 | "0": {
45 | "name": "punctuation.definition.comment.logo"
46 | }
47 | },
48 | "end": "\\n",
49 | "name": "comment.line.semicolon.logo"
50 | }
51 | ]
52 | }
53 | ],
54 | "scopeName": "source.logo",
55 | "uuid": "7613EC24-B0F9-4D01-8706-1D54098BFFD8"
56 | }
57 |
--------------------------------------------------------------------------------
/packages/shiki/languages/mdx.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3 | "name": "mdx",
4 | "patterns": [
5 | {
6 | "include": "#jsx"
7 | },
8 | {
9 | "include": "#markdown"
10 | }
11 | ],
12 | "repository": {
13 | "jsx": {
14 | "patterns": [
15 | {
16 | "include": "#jsx-module"
17 | },
18 | {
19 | "include": "#jsx-tag"
20 | }
21 | ],
22 | "repository": {
23 | "jsx-module": {
24 | "patterns": [
25 | {
26 | "begin": "^(?=(import|export)\\b)",
27 | "while": "^(?!\\s*$)",
28 | "contentName": "source.js.jsx",
29 | "patterns": [
30 | {
31 | "include": "source.js.jsx"
32 | }
33 | ]
34 | }
35 | ]
36 | },
37 | "jsx-tag": {
38 | "patterns": [
39 | {
40 | "begin": "^(?=<([a-z]|[A-Z]))",
41 | "end": "(?<=>)",
42 | "contentName": "source.js.jsx",
43 | "patterns": [
44 | {
45 | "include": "source.js.jsx"
46 | }
47 | ]
48 | }
49 | ]
50 | }
51 | }
52 | },
53 | "markdown": {
54 | "contentName": "text.html.markdown",
55 | "patterns": [
56 | {
57 | "include": "text.html.markdown"
58 | }
59 | ]
60 | }
61 | },
62 | "scopeName": "text.html.markdown.jsx"
63 | }
64 |
--------------------------------------------------------------------------------
/packages/shiki/languages/pascal.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": ["pas", "p", "pp", "dfm", "fmx", "dpr", "dpk", "lfm", "lpr"],
3 | "keyEquivalent": "^~P",
4 | "name": "pascal",
5 | "patterns": [
6 | {
7 | "match": "\\b(?i:(absolute|abstract|all|and_then|array|as|asm|attribute|begin|bindable|case|class|const|contains|default|div|else|end|except|export|exports|external|far|file|finalization|finally|forward|generic|goto|if|implements|import|in|index|inherited|initialization|interrupt|is|label|library|mod|module|name|near|not|object|of|on|only|operator|or_else|otherwise|override|package|packed|pow|private|program|protected|public|published|interface|implementation|qualified|read|record|resident|requires|resourcestring|restricted|segment|set|shl|shr|specialize|stored|strict|then|threadvar|to|try|type|unit|uses|var|view|virtual|dynamic|overload|reintroduce|with|write|xor))\\b",
8 | "name": "keyword.pascal"
9 | },
10 | {
11 | "captures": {
12 | "1": {
13 | "name": "storage.type.prototype.pascal"
14 | },
15 | "2": {
16 | "name": "entity.name.function.prototype.pascal"
17 | }
18 | },
19 | "match": "\\b(?i:(function|procedure|constructor|destructor))\\b\\s+(\\w+(\\.\\w+)?)(\\(.*?\\))?;\\s*(?=(?i:attribute|forward|external))",
20 | "name": "meta.function.prototype.pascal"
21 | },
22 | {
23 | "captures": {
24 | "1": {
25 | "name": "storage.type.function.pascal"
26 | },
27 | "2": {
28 | "name": "entity.name.function.pascal"
29 | }
30 | },
31 | "match": "\\b(?i:(function|procedure|constructor|destructor|property|read|write))\\b\\s+(\\w+(\\.\\w+)?)",
32 | "name": "meta.function.pascal"
33 | },
34 | {
35 | "match": "\\b(?i:(self|result))\\b",
36 | "name": "token.variable"
37 | },
38 | {
39 | "match": "\\b(?i:(and|or))\\b",
40 | "name": "keyword.operator.pascal"
41 | },
42 | {
43 | "match": "\\b(?i:(break|continue|exit|abort|while|do|for|raise|repeat|until))\\b",
44 | "name": "keyword.control.pascal"
45 | },
46 | {
47 | "begin": "\\{\\$",
48 | "captures": {
49 | "0": {
50 | "name": "string.regexp"
51 | }
52 | },
53 | "end": "\\}",
54 | "name": "string.regexp"
55 | },
56 | {
57 | "match": "\\b(?i:(ansichar|ansistring|boolean|byte|cardinal|char|comp|currency|double|dword|extended|file|integer|int64|longint|longword|nativeint|nativeuint|olevariant|pansichar|pchar|pwidechar|pointer|real|shortint|shortstring|single|smallint|string|uint64|variant|widechar|widestring|word|wordbool))\\b",
58 | "name": "storage.support.type.pascal"
59 | },
60 | {
61 | "match": "\\b(\\d+)|(\\d*\\.\\d+([eE][\\-+]?\\d+)?)\\b",
62 | "name": "constant.numeric.pascal"
63 | },
64 | {
65 | "match": "\\$[0-9a-fA-F]{1,16}\\b",
66 | "name": "constant.numeric.hex.pascal"
67 | },
68 | {
69 | "match": "\\b(?i:(true|false|nil))\\b",
70 | "name": "constant.language.pascal"
71 | },
72 | {
73 | "match": "\\b(?i:(Assert))\\b",
74 | "name": "keyword.control"
75 | },
76 | {
77 | "begin": "(^[ \\t]+)?(?=//)",
78 | "beginCaptures": {
79 | "1": {
80 | "name": "punctuation.whitespace.comment.leading.pascal"
81 | }
82 | },
83 | "end": "(?!\\G)",
84 | "patterns": [
85 | {
86 | "begin": "//",
87 | "beginCaptures": {
88 | "0": {
89 | "name": "punctuation.definition.comment.pascal"
90 | }
91 | },
92 | "end": "\\n",
93 | "name": "comment.line.double-slash.pascal.two"
94 | }
95 | ]
96 | },
97 | {
98 | "begin": "\\(\\*",
99 | "captures": {
100 | "0": {
101 | "name": "punctuation.definition.comment.pascal"
102 | }
103 | },
104 | "end": "\\*\\)",
105 | "name": "comment.block.pascal.one"
106 | },
107 | {
108 | "begin": "\\{(?!\\$)",
109 | "captures": {
110 | "0": {
111 | "name": "punctuation.definition.comment.pascal"
112 | }
113 | },
114 | "end": "\\}",
115 | "name": "comment.block.pascal.two"
116 | },
117 | {
118 | "begin": "'",
119 | "beginCaptures": {
120 | "0": {
121 | "name": "punctuation.definition.string.begin.pascal"
122 | }
123 | },
124 | "end": "'",
125 | "endCaptures": {
126 | "0": {
127 | "name": "punctuation.definition.string.end.pascal"
128 | }
129 | },
130 | "name": "string.quoted.single.pascal",
131 | "patterns": [
132 | {
133 | "match": "''",
134 | "name": "constant.character.escape.apostrophe.pascal"
135 | }
136 | ]
137 | },
138 | {
139 | "match": "\\#\\d+",
140 | "name": "string.other.pascal"
141 | }
142 | ],
143 | "scopeName": "source.pascal",
144 | "uuid": "F42FA544-6B1C-11D9-9517-000D93589AF6"
145 | }
146 |
--------------------------------------------------------------------------------
/packages/shiki/languages/php-html.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/atom/language-php/blob/master/grammars/html.cson",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/atom/language-php/commit/2bf736a814e1a58aa63470c1a29590bd02e924e7",
8 | "name": "php-html",
9 | "scopeName": "text.html.php",
10 | "injections": {
11 | "text.html.php - (meta.embedded | meta.tag), L:((text.html.php meta.tag) - (meta.embedded.block.php | meta.embedded.line.php)), L:(source.js - (meta.embedded.block.php | meta.embedded.line.php)), L:(source.css - (meta.embedded.block.php | meta.embedded.line.php))": {
12 | "patterns": [
13 | {
14 | "include": "#php-tag"
15 | }
16 | ]
17 | }
18 | },
19 | "patterns": [
20 | {
21 | "begin": "\\A#!",
22 | "beginCaptures": {
23 | "0": {
24 | "name": "punctuation.definition.comment.php"
25 | }
26 | },
27 | "end": "$",
28 | "name": "comment.line.shebang.php"
29 | },
30 | {
31 | "include": "text.html.derivative"
32 | }
33 | ],
34 | "repository": {
35 | "php-tag": {
36 | "patterns": [
37 | {
38 | "begin": "<\\?(?i:php|=)?(?![^?]*\\?>)",
39 | "beginCaptures": {
40 | "0": {
41 | "name": "punctuation.section.embedded.begin.php"
42 | }
43 | },
44 | "end": "(\\?)>",
45 | "endCaptures": {
46 | "0": {
47 | "name": "punctuation.section.embedded.end.php"
48 | },
49 | "1": {
50 | "name": "source.php"
51 | }
52 | },
53 | "name": "meta.embedded.block.php",
54 | "contentName": "source.php",
55 | "patterns": [
56 | {
57 | "include": "source.php"
58 | }
59 | ]
60 | },
61 | {
62 | "begin": "<\\?(?i:php|=)?",
63 | "beginCaptures": {
64 | "0": {
65 | "name": "punctuation.section.embedded.begin.php"
66 | }
67 | },
68 | "end": "(\\?)>",
69 | "endCaptures": {
70 | "0": {
71 | "name": "punctuation.section.embedded.end.php"
72 | },
73 | "1": {
74 | "name": "source.php"
75 | }
76 | },
77 | "name": "meta.embedded.line.php",
78 | "contentName": "source.php",
79 | "patterns": [
80 | {
81 | "include": "source.php"
82 | }
83 | ]
84 | }
85 | ]
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/packages/shiki/languages/sparql.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sparql",
3 | "scopeName": "source.sparql",
4 | "fileTypes": ["rq", "sparql"],
5 | "patterns": [
6 | {
7 | "include": "source.turtle"
8 | },
9 | {
10 | "include": "#query-keyword-operators"
11 | },
12 | {
13 | "include": "#functions"
14 | },
15 | {
16 | "include": "#variables"
17 | },
18 | {
19 | "include": "#expression-operators"
20 | }
21 | ],
22 | "repository": {
23 | "query-keyword-operators": {
24 | "name": "keyword.control.sparql",
25 | "match": "\\b(?i:define|select|distinct|reduced|from|named|construct|ask|describe|where|graph|having|bind|as|filter|optional|union|order|by|group|limit|offset|values|insert data|delete data|with|delete|insert|clear|silent|default|all|create|drop|copy|move|add|to|using|service|not exists|exists|not in|in|minus|load)\\b"
26 | },
27 | "functions": {
28 | "name": "support.function.sparql",
29 | "match": "\\b(?i:concat|regex|asc|desc|bound|isiri|isuri|isblank|isliteral|isnumeric|str|lang|datatype|sameterm|langmatches|avg|count|group_concat|separator|max|min|sample|sum|iri|uri|bnode|strdt|uuid|struuid|strlang|strlen|substr|ucase|lcase|strstarts|strends|contains|strbefore|strafter|encode_for_uri|replace|abs|round|ceil|floor|rand|now|year|month|day|hours|minutes|seconds|timezone|tz|md5|sha1|sha256|sha384|sha512|coalesce|if)\\b"
30 | },
31 | "variables": {
32 | "name": "constant.variable.sparql.turtle",
33 | "match": "(?|<=|>=|\\*|/|\\+|-|\\||\\^|\\?|\\!)"
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/shiki/languages/ssh-config.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileTypes": ["ssh_config", ".ssh/config", "sshd_config"],
3 | "name": "ssh-config",
4 | "patterns": [
5 | {
6 | "match": "\\b(A(cceptEnv|dd(ressFamily|KeysToAgent)|llow(AgentForwarding|Groups|StreamLocalForwarding|TcpForwarding|Users)|uth(enticationMethods|orized((Keys(Command(User)?|File)|Principals(Command(User)?|File)))))|B(anner|atchMode|ind(Address|Interface))|C(anonical(Domains|ize(FallbackLocal|Hostname|MaxDots|PermittedCNAMEs))|ertificateFile|hallengeResponseAuthentication|heckHostIP|hrootDirectory|iphers?|learAllForwardings|ientAlive(CountMax|Interval)|ompression(Level)?|onnect(Timeout|ionAttempts)|ontrolMaster|ontrolPath|ontrolPersist)|D(eny(Groups|Users)|isableForwarding|ynamicForward)|E(nableSSHKeysign|scapeChar|xitOnForwardFailure|xposeAuthInfo)|F(ingerprintHash|orceCommand|orward(Agent|X11(Timeout|Trusted)?))|G(atewayPorts|SSAPI(Authentication|CleanupCredentials|ClientIdentity|DelegateCredentials|KeyExchange|RenewalForcesRekey|ServerIdentity|StrictAcceptorCheck|TrustDns)|atewayPorts|lobalKnownHostsFile)|H(ashKnownHosts|ost(based(AcceptedKeyTypes|Authentication|KeyTypes|UsesNameFromPacketOnly)|Certificate|Key(Agent|Algorithms|Alias)?|Name))|I(dentit(iesOnly|y(Agent|File))|gnore(Rhosts|Unknown|UserKnownHosts)|nclude|PQoS)|K(bdInteractive(Authentication|Devices)|erberos(Authentication|GetAFSToken|OrLocalPasswd|TicketCleanup)|exAlgorithms)|L(istenAddress|ocal(Command|Forward)|oginGraceTime|ogLevel)|M(ACs|atch|ax(AuthTries|Sessions|Startups))|N(oHostAuthenticationForLocalhost|umberOfPasswordPrompts)|P(KCS11Provider|asswordAuthentication|ermit(EmptyPasswords|LocalCommand|Open|RootLogin|TTY|Tunnel|User(Environment|RC))|idFile|ort|referredAuthentications|rint(LastLog|Motd)|rotocol|roxy(Command|Jump|UseFdpass)|ubkey(AcceptedKeyTypes|Authentication))|R(Domain|SAAuthentication|ekeyLimit|emote(Command|Forward)|equestTTY|evoked(HostKeys|Keys)|hostsRSAAuthentication)|S(endEnv|erverAlive(CountMax|Interval)|treamLocalBind(Mask|Unlink)|trict(HostKeyChecking|Modes)|ubsystem|yslogFacility)|T(CPKeepAlive|rustedUserCAKeys|unnel(Device)?)|U(pdateHostKeys|se(BlacklistedKeys|DNS|Keychain|PAM|PrivilegedPort|r(KnownHostsFile)?))|V(erifyHostKeyDNS|ersionAddendum|isualHostKey)|X(11(DisplayOffset|Forwarding|UseLocalhost)|AuthLocation))\\b",
7 | "name": "keyword.other.ssh-config"
8 | },
9 | {
10 | "begin": "(^[ \\t]+)?(?=#)",
11 | "beginCaptures": {
12 | "1": {
13 | "name": "punctuation.whitespace.comment.leading.ssh-config"
14 | }
15 | },
16 | "end": "(?!\\G)",
17 | "patterns": [
18 | {
19 | "begin": "#",
20 | "beginCaptures": {
21 | "0": {
22 | "name": "punctuation.definition.comment.ssh-config"
23 | }
24 | },
25 | "end": "\\n",
26 | "name": "comment.line.number-sign.ssh-config"
27 | }
28 | ]
29 | },
30 | {
31 | "begin": "(^[ \\t]+)?(?=//)",
32 | "beginCaptures": {
33 | "1": {
34 | "name": "punctuation.whitespace.comment.leading.ssh-config"
35 | }
36 | },
37 | "end": "(?!\\G)",
38 | "patterns": [
39 | {
40 | "begin": "//",
41 | "beginCaptures": {
42 | "0": {
43 | "name": "punctuation.definition.comment.ssh-config"
44 | }
45 | },
46 | "end": "\\n",
47 | "name": "comment.line.double-slash.ssh-config"
48 | }
49 | ]
50 | },
51 | {
52 | "captures": {
53 | "1": {
54 | "name": "storage.type.ssh-config"
55 | },
56 | "2": {
57 | "name": "entity.name.section.ssh-config"
58 | },
59 | "3": {
60 | "name": "meta.toc-list.ssh-config"
61 | }
62 | },
63 | "match": "(?:^| |\\t)(Host)\\s+((.*))$"
64 | },
65 | {
66 | "match": "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b",
67 | "name": "constant.numeric.ssh-config"
68 | },
69 | {
70 | "match": "\\b[0-9]+\\b",
71 | "name": "constant.numeric.ssh-config"
72 | },
73 | {
74 | "match": "\\b(yes|no)\\b",
75 | "name": "constant.language.ssh-config"
76 | },
77 | {
78 | "match": "\\b[A-Z_]+\\b",
79 | "name": "constant.language.ssh-config"
80 | }
81 | ],
82 | "scopeName": "source.ssh-config",
83 | "uuid": "B273855C-59D3-4DF3-9B7C-E68E0057D315"
84 | }
85 |
--------------------------------------------------------------------------------
/packages/shiki/languages/wenyan.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3 | "scopeName": "source.wenyan",
4 | "name": "wenyan",
5 | "patterns": [
6 | {
7 | "include": "#keywords"
8 | },
9 | {
10 | "include": "#constants"
11 | },
12 | {
13 | "include": "#operators"
14 | },
15 | {
16 | "include": "#symbols"
17 | },
18 | {
19 | "include": "#expression"
20 | },
21 | {
22 | "include": "#comment-blocks"
23 | },
24 | {
25 | "include": "#comment-lines"
26 | }
27 | ],
28 | "repository": {
29 | "expression": {
30 | "patterns": [
31 | {
32 | "include": "#variables"
33 | }
34 | ]
35 | },
36 | "keywords": {
37 | "patterns": [
38 | {
39 | "name": "storage.type",
40 | "match": "數|列|言|術|爻|物|元"
41 | },
42 | {
43 | "name": "keyword.control",
44 | "match": "乃行是術曰|若其不然者|乃歸空無|欲行是術|乃止是遍|若其然者|其物如是|乃得矣|之術也|必先得|是術曰|恆為是|之物也|乃得|是謂|云云|中之|為是|乃止|若非|或若|之長|其餘"
45 | },
46 | {
47 | "name": "keyword.control",
48 | "match": "或云|蓋謂"
49 | },
50 | {
51 | "name": "keyword.operator",
52 | "match": "中有陽乎|中無陰乎|所餘幾何|不等於|不大於|不小於|等於|大於|小於|加|減|乘|除|變|以|於"
53 | },
54 | {
55 | "name": "keyword.other",
56 | "match": "不知何禍歟|不復存矣|姑妄行此|如事不諧|名之曰|吾嘗觀|之禍歟|乃作罷|吾有|今有|物之|書之|以施|昔之|是矣|之書|方悟|之義|嗚呼|之禍|有|施|曰|噫|取|今|夫|中|豈"
57 | },
58 | {
59 | "name": "keyword.control",
60 | "match": "也|凡|遍|若|者|之|充|銜"
61 | }
62 | ]
63 | },
64 | "comment-lines": {
65 | "name": "comment.line",
66 | "begin": "注曰|疏曰|批曰",
67 | "end": "$",
68 | "patterns": [
69 | {
70 | "name": "constant.character",
71 | "match": "\\\\."
72 | }
73 | ]
74 | },
75 | "comment-blocks": {
76 | "name": "comment.block",
77 | "begin": "(注曰|疏曰|批曰)。?(「「|『)",
78 | "end": "(」」|』)",
79 | "patterns": [
80 | {
81 | "name": "constant.character",
82 | "match": "\\\\."
83 | }
84 | ]
85 | },
86 | "constants": {
87 | "patterns": [
88 | {
89 | "name": "constant.numeric",
90 | "match": "負|·|又|零|〇|一|二|三|四|五|六|七|八|九|十|百|千|萬|億|兆|京|垓|秭|穰|溝|澗|正|載|極|分|釐|毫|絲|忽|微|纖|沙|塵|埃|渺|漠"
91 | },
92 | {
93 | "name": "constant.language",
94 | "match": "其|陰|陽"
95 | },
96 | {
97 | "name": "string.quoted",
98 | "begin": "「「|『",
99 | "end": "」」|』",
100 | "patterns": [
101 | {
102 | "name": "constant.character",
103 | "match": "\\\\."
104 | }
105 | ]
106 | }
107 | ]
108 | },
109 | "symbols": {
110 | "patterns": [
111 | {
112 | "name": "punctuation.separator",
113 | "match": "。|、"
114 | }
115 | ]
116 | },
117 | "variables": {
118 | "name": "variable.other",
119 | "begin": "「",
120 | "end": "」",
121 | "patterns": [
122 | {
123 | "name": "constant.character",
124 | "match": "\\\\."
125 | }
126 | ]
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/packages/shiki/languages/xsl.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "information_for_contributors": [
3 | "This file has been converted from https://github.com/atom/language-xml/blob/master/grammars/xsl.cson",
4 | "If you want to provide a fix or improvement, please create a pull request against the original repository.",
5 | "Once accepted there, we are happy to receive an update request."
6 | ],
7 | "version": "https://github.com/atom/language-xml/commit/507de2ee7daca60cf02e9e21fbeb92bbae73e280",
8 | "name": "xsl",
9 | "scopeName": "text.xml.xsl",
10 | "patterns": [
11 | {
12 | "begin": "(<)(xsl)((:))(template)",
13 | "captures": {
14 | "1": {
15 | "name": "punctuation.definition.tag.xml"
16 | },
17 | "2": {
18 | "name": "entity.name.tag.namespace.xml"
19 | },
20 | "3": {
21 | "name": "entity.name.tag.xml"
22 | },
23 | "4": {
24 | "name": "punctuation.separator.namespace.xml"
25 | },
26 | "5": {
27 | "name": "entity.name.tag.localname.xml"
28 | }
29 | },
30 | "end": "(>)",
31 | "name": "meta.tag.xml.template",
32 | "patterns": [
33 | {
34 | "captures": {
35 | "1": {
36 | "name": "entity.other.attribute-name.namespace.xml"
37 | },
38 | "2": {
39 | "name": "entity.other.attribute-name.xml"
40 | },
41 | "3": {
42 | "name": "punctuation.separator.namespace.xml"
43 | },
44 | "4": {
45 | "name": "entity.other.attribute-name.localname.xml"
46 | }
47 | },
48 | "match": " (?:([-_a-zA-Z0-9]+)((:)))?([a-zA-Z-]+)"
49 | },
50 | {
51 | "include": "#doublequotedString"
52 | },
53 | {
54 | "include": "#singlequotedString"
55 | }
56 | ]
57 | },
58 | {
59 | "include": "text.xml"
60 | }
61 | ],
62 | "repository": {
63 | "doublequotedString": {
64 | "begin": "\"",
65 | "beginCaptures": {
66 | "0": {
67 | "name": "punctuation.definition.string.begin.xml"
68 | }
69 | },
70 | "end": "\"",
71 | "endCaptures": {
72 | "0": {
73 | "name": "punctuation.definition.string.end.xml"
74 | }
75 | },
76 | "name": "string.quoted.double.xml"
77 | },
78 | "singlequotedString": {
79 | "begin": "'",
80 | "beginCaptures": {
81 | "0": {
82 | "name": "punctuation.definition.string.begin.xml"
83 | }
84 | },
85 | "end": "'",
86 | "endCaptures": {
87 | "0": {
88 | "name": "punctuation.definition.string.end.xml"
89 | }
90 | },
91 | "name": "string.quoted.single.xml"
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/packages/shiki/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shiki",
3 | "version": "0.9.6",
4 | "description": "shiki",
5 | "author": "Pine Wu ",
6 | "homepage": "https://github.com/octref/shiki/tree/main/packages/shiki",
7 | "license": "MIT",
8 | "main": "dist/index.js",
9 | "module": "dist/index.esm.js",
10 | "types": "dist/index.d.ts",
11 | "unpkg": "dist/index.unpkg.iife.js",
12 | "jsdelivr": "dist/index.jsdelivr.iife.js",
13 | "keywords": [
14 | "shiki",
15 | "syntax-highlighter",
16 | "highlighter"
17 | ],
18 | "files": [
19 | "dist",
20 | "languages",
21 | "themes",
22 | "samples"
23 | ],
24 | "scripts": {
25 | "prepublishOnly": "npm run build",
26 | "build": "rollup -c",
27 | "watch": "rollup -c -w"
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "git+https://github.com/octref/shiki.git"
32 | },
33 | "dependencies": {
34 | "json5": "^2.2.0",
35 | "onigasm": "^2.2.5",
36 | "vscode-textmate": "5.2.0"
37 | },
38 | "browser": {
39 | "fs": false,
40 | "path": false
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/shiki/rollup.config.js:
--------------------------------------------------------------------------------
1 | import { nodeResolve } from '@rollup/plugin-node-resolve'
2 | import commonjs from '@rollup/plugin-commonjs'
3 | import dts from 'rollup-plugin-dts'
4 | import typescript from 'rollup-plugin-typescript2'
5 | import copy from 'rollup-plugin-copy'
6 | import replace from '@rollup/plugin-replace'
7 | import { terser } from 'rollup-plugin-terser'
8 | import { version } from './package.json'
9 |
10 | const external = ['onigasm', 'vscode-textmate']
11 |
12 | export default [
13 | {
14 | input: 'src/index.ts',
15 | external,
16 | output: [
17 | {
18 | file: 'dist/index.js',
19 | format: 'cjs'
20 | },
21 | {
22 | file: 'dist/index.esm.js',
23 | format: 'esm'
24 | }
25 | ],
26 | plugins: [
27 | replace({
28 | __CDN_ROOT__: '',
29 | __BROWSER__: JSON.stringify(false)
30 | }),
31 | typescript(),
32 | nodeResolve(),
33 | commonjs()
34 | ]
35 | },
36 | {
37 | input: 'src/index.ts',
38 | output: [
39 | {
40 | file: 'dist/index.browser.mjs',
41 | format: 'esm',
42 | plugins: [
43 | replace({
44 | __CDN_ROOT__: ''
45 | })
46 | ]
47 | },
48 | {
49 | file: 'dist/index.iife.js',
50 | format: 'iife',
51 | name: 'shiki',
52 | extend: true,
53 | plugins: [
54 | replace({
55 | __CDN_ROOT__: ''
56 | })
57 | ]
58 | },
59 | {
60 | file: 'dist/index.unpkg.iife.js',
61 | format: 'iife',
62 | name: 'shiki',
63 | extend: true,
64 | plugins: [
65 | replace({
66 | __CDN_ROOT__: `https://unpkg.com/shiki@${version}/`
67 | })
68 | ]
69 | },
70 | {
71 | file: 'dist/index.jsdelivr.iife.js',
72 | format: 'iife',
73 | name: 'shiki',
74 | extend: true,
75 | plugins: [
76 | replace({
77 | __CDN_ROOT__: `https://cdn.jsdelivr.net/npm/shiki@${version}/`
78 | })
79 | ]
80 | }
81 | ],
82 | plugins: [
83 | replace({
84 | __BROWSER__: JSON.stringify(true)
85 | }),
86 | typescript(),
87 | nodeResolve(),
88 | commonjs(),
89 | terser()
90 | ]
91 | },
92 | {
93 | input: 'src/index.ts',
94 | output: [
95 | {
96 | file: 'dist/index.d.ts',
97 | format: 'es'
98 | }
99 | ],
100 | plugins: [
101 | dts(),
102 | copy({
103 | targets: [{ src: '../../node_modules/onigasm/lib/onigasm.wasm', dest: 'dist' }]
104 | })
105 | ],
106 | onwarn: (msg, warn) => {
107 | if (!/Circular/.test(msg)) {
108 | warn(msg)
109 | }
110 | }
111 | }
112 | ]
113 |
--------------------------------------------------------------------------------
/packages/shiki/samples/c.sample:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define ARR_LEN 7
4 |
5 | void qsort(int v[], int left, int right);
6 | void printArr(int v[], int len);
7 |
8 | int main()
9 | {
10 | int i;
11 | int v[ARR_LEN] = { 4, 3, 1, 7, 9, 6, 2 };
12 | printArr(v, ARR_LEN);
13 | qsort(v, 0, ARR_LEN-1);
14 | printArr(v, ARR_LEN);
15 | return 0;
16 | }
17 |
18 | void qsort(int v[], int left, int right)
19 | {
20 | int i, last;
21 | void swap(int v[], int i, int j);
22 |
23 | if (left >= right)
24 | return;
25 | swap(v, left, (left + right) / 2);
26 | last = left;
27 | for (i = left+1; i <= right; i++)
28 | if (v[i] < v[left])
29 | swap(v, ++last, i);
30 | swap(v, left, last);
31 | qsort(v, left, last-1);
32 | qsort(v, last+1, right);
33 | }
34 |
35 | void swap(int v[], int i, int j)
36 | {
37 | int temp;
38 |
39 | temp = v[i];
40 | v[i] = v[j];
41 | v[j] = temp;
42 | }
43 |
44 | void printArr(int v[], int len)
45 | {
46 | int i;
47 | for (i = 0; i < len; i++)
48 | printf("%d ", v[i]);
49 | printf("\n");
50 | }
51 |
52 | // From https://github.com/Heatwave/The-C-Programming-Language-2nd-Edition/blob/master/chapter-4-functions-and-program-structure/8.qsort.c
--------------------------------------------------------------------------------
/packages/shiki/samples/css.sample:
--------------------------------------------------------------------------------
1 | .Aligner {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 |
7 | .Aligner-item {
8 | max-width: 50%;
9 | }
10 |
11 | .Aligner-item--top {
12 | align-self: flex-start;
13 | }
14 |
15 | .Aligner-item--bottom {
16 | align-self: flex-end;
17 | }
18 |
19 | /* From https://philipwalton.github.io/solved-by-flexbox/demos/vertical-centering/ */
--------------------------------------------------------------------------------
/packages/shiki/samples/dm.sample:
--------------------------------------------------------------------------------
1 | //Allows you to set a theme for a set of areas without tying them to looping sounds explicitly
2 | /datum/component/area_sound_manager
3 | //area -> looping sound type
4 | var/list/area_to_looping_type = list()
5 | //Current sound loop
6 | var/datum/looping_sound/our_loop
7 | //A list of "acceptable" z levels to be on. If you leave this, we're gonna delete ourselves
8 | var/list/accepted_zs
9 | //The timer id of our current start delay, if it exists
10 | var/timerid
11 |
12 | /datum/component/area_sound_manager/Initialize(area_loop_pairs, change_on, remove_on, acceptable_zs)
13 | if(!ismovable(parent))
14 | return
15 | area_to_looping_type = area_loop_pairs
16 | accepted_zs = acceptable_zs
17 | change_the_track()
18 |
19 | RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/react_to_move)
20 | RegisterSignal(parent, COMSIG_MOVABLE_Z_CHANGED, .proc/react_to_z_move)
21 | RegisterSignal(parent, change_on, .proc/handle_change)
22 | RegisterSignal(parent, remove_on, .proc/handle_removal)
23 |
24 | /datum/component/area_sound_manager/Destroy(force, silent)
25 | QDEL_NULL(our_loop)
26 | . = ..()
27 |
28 | /datum/component/area_sound_manager/proc/react_to_move(datum/source, atom/oldloc, dir, forced)
29 | SIGNAL_HANDLER
30 | var/list/loop_lookup = area_to_looping_type
31 | if(loop_lookup[get_area(oldloc)] == loop_lookup[get_area(parent)])
32 | return
33 | change_the_track(TRUE)
34 |
35 | /datum/component/area_sound_manager/proc/react_to_z_move(datum/source, old_z, new_z)
36 | SIGNAL_HANDLER
37 | if(!length(accepted_zs) || (new_z in accepted_zs))
38 | return
39 | qdel(src)
40 |
41 | /datum/component/area_sound_manager/proc/handle_removal(datum/source)
42 | SIGNAL_HANDLER
43 | qdel(src)
44 |
45 | /datum/component/area_sound_manager/proc/handle_change(datum/source)
46 | SIGNAL_HANDLER
47 | change_the_track()
48 |
49 | /datum/component/area_sound_manager/proc/change_the_track(skip_start = FALSE)
50 | var/time_remaining = 0
51 |
52 | if(our_loop)
53 | var/our_id = our_loop.timerid || timerid
54 | if(our_id)
55 | time_remaining = timeleft(our_id, SSsound_loops) || 0
56 | //Time left will sometimes return negative values, just ignore them and start a new sound loop now
57 | time_remaining = max(time_remaining, 0)
58 | QDEL_NULL(our_loop)
59 |
60 | var/area/our_area = get_area(parent)
61 | var/new_loop_type = area_to_looping_type[our_area]
62 | if(!new_loop_type)
63 | return
64 |
65 | our_loop = new new_loop_type(parent, FALSE, TRUE, skip_start)
66 |
67 | //If we're still playing, wait a bit before changing the sound so we don't double up
68 | if(time_remaining)
69 | timerid = addtimer(CALLBACK(src, .proc/start_looping_sound), time_remaining, TIMER_UNIQUE | TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_NO_HASH_WAIT | TIMER_DELETE_ME, SSsound_loops)
70 | return
71 | timerid = null
72 | our_loop.start()
73 |
74 | /datum/component/area_sound_manager/proc/start_looping_sound()
75 | timerid = null
76 | if(our_loop)
77 | our_loop.start()
78 |
--------------------------------------------------------------------------------
/packages/shiki/samples/fsl.sample:
--------------------------------------------------------------------------------
1 |
2 | machine_name : "TCP/IP";
3 | machine_reference : "http://www.texample.net/tikz/examples/tcp-state-machine/";
4 | machine_version : 1.0.0;
5 |
6 | machine_author : "John Haugeland ";
7 | machine_license : MIT;
8 |
9 | jssm_version : >= 5.0.0;
10 |
11 |
12 |
13 | Closed 'Passive open' -> Listen;
14 | Closed 'Active Open / SYN' -> SynSent;
15 |
16 | Listen 'Close' -> Closed;
17 | Listen 'Send / SYN' -> SynSent;
18 | Listen 'SYN / SYN+ACK' -> SynRcvd;
19 |
20 | SynSent 'Close' -> Closed;
21 | SynSent 'SYN / SYN+ACK' -> SynRcvd;
22 | SynSent 'SYN+ACK / ACK' -> Established;
23 |
24 | SynRcvd 'Timeout / RST' -> Closed;
25 | SynRcvd 'Close / FIN' -> FinWait1;
26 | SynRcvd 'ACK' -> Established;
27 |
28 | Established 'Close / FIN' -> FinWait1;
29 | Established 'FIN / ACK' -> CloseWait;
30 |
31 | FinWait1 'FIN / ACK' -> Closing; // the source diagram has this action wrong
32 | FinWait1 'FIN+ACK / ACK' -> TimeWait;
33 | FinWait1 'ACK / Nothing' -> FinWait2; // see http://www.cs.odu.edu/~cs779/spring17/lectures/architecture_files/image009.jpg
34 |
35 | FinWait2 'FIN / ACK' -> TimeWait;
36 |
37 | Closing 'ACK' -> TimeWait;
38 |
39 | TimeWait 'Up to 2*MSL' -> Closed;
40 |
41 | CloseWait 'Close / FIN' -> LastAck;
42 |
43 | LastAck 'ACK' -> Closed;
44 |
45 |
46 |
47 | # From https://github.com/StoneCypher/jssm/blob/main/src/machines/linguist/tcp%20ip.fsl
--------------------------------------------------------------------------------
/packages/shiki/samples/go.sample:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | )
8 |
9 | func handler(w http.ResponseWriter, r *http.Request) {
10 | fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
11 | }
12 |
13 | func main() {
14 | http.HandleFunc("/", handler)
15 | log.Fatal(http.ListenAndServe(":8080", nil))
16 | }
17 |
18 | // From https://golang.org/doc/articles/wiki/#tmp_3
--------------------------------------------------------------------------------
/packages/shiki/samples/html.sample:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
…
23 |
…
24 |
…
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/packages/shiki/samples/java.sample:
--------------------------------------------------------------------------------
1 | public class HelloWorld {
2 |
3 | public static void main(String[] args) {
4 | // Prints "Hello, World" to the terminal window.
5 | System.out.println("Hello, World");
6 | }
7 |
8 | }
9 |
10 | // From https://introcs.cs.princeton.edu/java/11hello/HelloWorld.java.html
--------------------------------------------------------------------------------
/packages/shiki/samples/javascript.sample:
--------------------------------------------------------------------------------
1 | // posts will be populated at build time by getStaticProps()
2 | function Blog({ posts }) {
3 | return (
4 |
5 | {posts.map((post) => (
6 | {post.title}
7 | ))}
8 |
9 | )
10 | }
11 |
12 | // This function gets called at build time on server-side.
13 | export async function getStaticProps() {
14 | const res = await fetch('https://.../posts')
15 | const posts = await res.json()
16 |
17 | return {
18 | props: {
19 | posts
20 | }
21 | }
22 | }
23 |
24 | export default Blog
25 |
26 | // From https://nextjs.org/docs/basic-features/data-fetching
27 |
--------------------------------------------------------------------------------
/packages/shiki/samples/jssm.sample:
--------------------------------------------------------------------------------
1 |
2 | machine_name : "BGP";
3 | machine_reference : "http://www.inetdaemon.com/tutorials/internet/ip/routing/bgp/operation/finite_state_model.shtml";
4 | machine_version : 1.0.0;
5 |
6 | machine_author : "John Haugeland ";
7 | machine_license : MIT;
8 |
9 | jssm_version : >= 5.0.0;
10 |
11 |
12 |
13 | Idle -> [Idle Connect];
14 | Connect -> [Idle Connect OpenSent Active];
15 | Active -> [Idle Connect OpenSent Active];
16 | OpenSent -> [Idle Active OpenConfirm];
17 | OpenConfirm -> [Idle OpenSent OpenConfirm Established];
18 | Established -> [Idle Established];
19 |
20 |
21 |
22 | # from https://github.com/StoneCypher/jssm/blob/main/src/machines/linguist/bgp.fsl
--------------------------------------------------------------------------------
/packages/shiki/samples/prisma.sample:
--------------------------------------------------------------------------------
1 | datasource db {
2 | provider = "postgresql"
3 | url = env("DATABASE_URL")
4 | }
5 |
6 | generator client {
7 | provider = "prisma-client-js"
8 | }
9 |
10 | /// Post including an author and content.
11 | model Post {
12 | id Int @default(autoincrement()) @id
13 | content String?
14 | published Boolean @default(false)
15 | author User? @relation(fields: [authorId], references: [id])
16 | authorId Int?
17 | }
18 |
19 | // Documentation for this model.
20 | model User {
21 | id Int @default(autoincrement()) @id
22 | email String @unique
23 | name String?
24 | posts Post[]
25 | specialName UserName
26 | test Test
27 | }
28 |
29 | /// This is an enum specifying the UserName.
30 | enum UserName {
31 | Fred
32 | Eric
33 | }
34 |
35 | // This is a test enum.
36 | enum Test {
37 | TestUno
38 | TestDue
39 | }
40 |
41 | // taken from https://github.com/prisma/language-tools/blob/master/packages/vscode/testFixture/hover.prisma
42 |
--------------------------------------------------------------------------------
/packages/shiki/samples/python.sample:
--------------------------------------------------------------------------------
1 | def fib(n): # write Fibonacci series up to n
2 | """Print a Fibonacci series up to n."""
3 | a, b = 0, 1
4 | while a < n:
5 | print(a, end=' ')
6 | a, b = b, a+b
7 | print()
8 |
9 | # Now call the function we just defined:
10 | fib(2000)
11 |
12 | # From https://docs.python.org/3/tutorial/controlflow.html#defining-functions
--------------------------------------------------------------------------------
/packages/shiki/samples/ruby.sample:
--------------------------------------------------------------------------------
1 | class LotteryTicket
2 |
3 | NUMERIC_RANGE = 1..25
4 |
5 | attr_reader :picks, :purchased
6 |
7 | def initialize( *picks )
8 | if picks.length != 3
9 | raise ArgumentError, "three numbers must be picked"
10 | elsif picks.uniq.length != 3
11 | raise ArgumentError, "the three picks must be different numbers"
12 | elsif picks.detect { |p| not NUMERIC_RANGE === p }
13 | raise ArgumentError, "the three picks must be numbers between 1 and 25"
14 | end
15 | @picks = picks
16 | @purchased = Time.now
17 | end
18 |
19 | end
20 |
21 | # From https://poignant.guide/book/chapter-5.html
--------------------------------------------------------------------------------
/packages/shiki/samples/sparql.sample:
--------------------------------------------------------------------------------
1 | PREFIX foaf:
2 | SELECT ?name (COUNT(?friend) AS ?count)
3 | WHERE {
4 | ?person foaf:name ?name .
5 | ?person foaf:knows ?friend .
6 | } GROUP BY ?person ?name
7 |
8 | # From https://www.w3.org/TR/sparql11-overview/#sparql11-query
--------------------------------------------------------------------------------
/packages/shiki/samples/tsx.sample:
--------------------------------------------------------------------------------
1 | // posts will be populated at build time by getStaticProps()
2 | function Blog({ posts }) {
3 | return (
4 |
5 | {posts.map((post) => (
6 | {post.title}
7 | ))}
8 |
9 | )
10 | }
11 |
12 | // This function gets called at build time on server-side.
13 | export async function getStaticProps() {
14 | const res = await fetch('https://.../posts')
15 | const posts = await res.json()
16 |
17 | return {
18 | props: {
19 | posts
20 | }
21 | }
22 | }
23 |
24 | export default Blog
25 |
26 | // From https://nextjs.org/docs/basic-features/data-fetching
27 |
--------------------------------------------------------------------------------
/packages/shiki/samples/turtle.sample:
--------------------------------------------------------------------------------
1 | @prefix foaf: .
2 | @prefix rdfs: .
3 |
4 | a foaf:Person .
5 | foaf:name "Alice" .
6 | foaf:mbox .
7 | foaf:knows .
8 | foaf:knows .
9 | foaf:name "Bob" .
10 | foaf:knows .
11 | foaf:knows .
12 | foaf:name "Charlie" .
13 | foaf:knows .
14 | foaf:name "Snoopy"@en .
15 |
16 | # From https://www.w3.org/TR/sparql11-overview/#Example
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/152.test.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/shikijs/shiki/issues/152
2 | import { getHighlighter } from '../index'
3 |
4 | test('Correctly highlights LaTeX', async () => {
5 | const highlighter = await getHighlighter({
6 | theme: 'nord',
7 | langs: ['tex', 'latex']
8 | })
9 |
10 | const out = highlighter.codeToThemedTokens(`%\\usepackage{pkg}`, 'latex', 'nord', {
11 | includeExplanation: true
12 | })
13 | expect(out).toMatchSnapshot()
14 | })
15 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/__snapshots__/152.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Correctly highlights LaTeX 1`] = `
4 | Array [
5 | Array [
6 | Object {
7 | "color": "#616E88",
8 | "content": "%\\\\usepackage{pkg}",
9 | "explanation": Array [
10 | Object {
11 | "content": "%",
12 | "scopes": Array [
13 | Object {
14 | "scopeName": "text.tex.latex",
15 | "themeMatches": Array [],
16 | },
17 | Object {
18 | "scopeName": "comment.line.percentage.tex",
19 | "themeMatches": Array [
20 | Object {
21 | "name": "Comment",
22 | "scope": "comment",
23 | "settings": Object {
24 | "foreground": "#616E88",
25 | },
26 | },
27 | ],
28 | },
29 | Object {
30 | "scopeName": "punctuation.definition.comment.tex",
31 | "themeMatches": Array [
32 | Object {
33 | "name": "Punctuation",
34 | "scope": "punctuation",
35 | "settings": Object {
36 | "foreground": "#ECEFF4",
37 | },
38 | },
39 | Object {
40 | "name": "Punctuation Definition Comment",
41 | "scope": Array [
42 | "punctuation.definition.comment",
43 | "punctuation.end.definition.comment",
44 | "punctuation.start.definition.comment",
45 | ],
46 | "settings": Object {
47 | "foreground": "#616E88",
48 | },
49 | },
50 | ],
51 | },
52 | ],
53 | },
54 | Object {
55 | "content": "\\\\usepackage{pkg}",
56 | "scopes": Array [
57 | Object {
58 | "scopeName": "text.tex.latex",
59 | "themeMatches": Array [],
60 | },
61 | Object {
62 | "scopeName": "comment.line.percentage.tex",
63 | "themeMatches": Array [
64 | Object {
65 | "name": "Comment",
66 | "scope": "comment",
67 | "settings": Object {
68 | "foreground": "#616E88",
69 | },
70 | },
71 | ],
72 | },
73 | ],
74 | },
75 | ],
76 | "fontStyle": 0,
77 | },
78 | ],
79 | ]
80 | `;
81 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/__snapshots__/simple.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Nord highlighter highlights simple JavaScript 1`] = `"console . log ( ' shiki ' ) ;
"`;
4 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/background.test.ts:
--------------------------------------------------------------------------------
1 | import { getHighlighter } from '../index'
2 |
3 | test(`Token with no color shouldn't generate color: undefined`, async () => {
4 | const highlighter = await getHighlighter({
5 | theme: 'monokai'
6 | })
7 | const out = highlighter.codeToHtml(`whatever`, 'txt')
8 | expect(out).not.toContain('undefined')
9 | })
10 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/comprehensive.test.ts:
--------------------------------------------------------------------------------
1 | import { themes } from '../themes'
2 | import { getHighlighter } from '../index'
3 | import { languages } from '../languages'
4 |
5 | describe('validates all themes run some JS', () => {
6 | themes.forEach(theme => {
7 | it(theme, async () => {
8 | const highlighter = await getHighlighter({ theme })
9 | highlighter.codeToHtml(`console.log('shiki');`, 'js')
10 | })
11 | })
12 | })
13 |
14 | describe('validates all languages can show a hello-world', () => {
15 | languages.forEach(language => {
16 | it(language.id, async () => {
17 | const highlighter = await getHighlighter({ theme: 'nord' })
18 | highlighter.codeToHtml(`console.log('shiki');`, language.id)
19 | })
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/custom-language/__snapshots__/customLanguage.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Custom language registration can override builtin language: rockstar 1`] = `"Shiki is "a beautiful Syntax Highlighter"
"`;
4 |
5 | exports[`Highlights custom language - Rockstar 1`] = `"Shiki is "a beautiful Syntax Highlighter"
"`;
6 |
7 | exports[`Multiple custom language registrations should use last one 1`] = `"Shiki is "a beautiful Syntax Highlighter"
"`;
8 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/custom-language/customLanguage.test.ts:
--------------------------------------------------------------------------------
1 | import { readFileSync } from 'fs'
2 | import { getHighlighter } from '../../index'
3 | import { resolve } from 'path'
4 |
5 | function currentDirPath(p) {
6 | return resolve(__dirname, p)
7 | }
8 |
9 | test('Highlights custom language - Rockstar', async () => {
10 | const highlighter = await getHighlighter({
11 | theme: 'nord',
12 | langs: [
13 | {
14 | id: 'rockstar',
15 | scopeName: 'source.rockstar',
16 | path: currentDirPath('./rockstar.tmLanguage.json'),
17 | aliases: []
18 | }
19 | ]
20 | })
21 |
22 | const code = readFileSync(currentDirPath('rockstar.rock'), 'utf-8')
23 | const out = highlighter.codeToHtml(code, 'rockstar')
24 | expect(out).toMatchSnapshot()
25 | })
26 |
27 | test('Multiple custom language registrations should use last one', async () => {
28 | const highlighter = await getHighlighter({
29 | theme: 'nord',
30 | langs: [
31 | {
32 | id: 'rockstar',
33 | scopeName: 'source.rockstar',
34 | path: currentDirPath('./rockstar.tmLanguage.json'),
35 | aliases: []
36 | },
37 | {
38 | id: 'rockstar',
39 | scopeName: 'source.rockstar',
40 | path: currentDirPath('./rockstar-override.tmLanguage.json'),
41 | aliases: []
42 | }
43 | ]
44 | })
45 |
46 | const code = readFileSync(currentDirPath('rockstar.rock'), 'utf-8')
47 | const out = highlighter.codeToHtml(code, 'rockstar')
48 | expect(out).toMatchSnapshot()
49 | })
50 |
51 | test('Custom language registration can override builtin language', async () => {
52 | const highlighter = await getHighlighter({
53 | theme: 'nord',
54 | langs: [
55 | {
56 | id: 'html',
57 | scopeName: 'text.html.basic',
58 | path: currentDirPath('./rockstar-html.tmLanguage.json'),
59 | aliases: []
60 | }
61 | ]
62 | })
63 |
64 | const code = readFileSync(currentDirPath('rockstar.rock'), 'utf-8')
65 | const out = highlighter.codeToHtml(code, 'html')
66 | expect(out).toMatchSnapshot('rockstar')
67 | })
68 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/custom-language/rockstar-html.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "_source":"https://github.com/ra100/vscode-rockstar-language",
3 | "_license": "https://github.com/ra100/vscode-rockstar-language/blob/master/LICENSE",
4 | "scopeName": "text.html.basic",
5 | "name": "Rockstar HTML",
6 | "fileTypes": [
7 | "rock",
8 | "rockstar"
9 | ],
10 | "patterns": [{
11 | "include": "#proper-variable"
12 | }, {
13 | "include": "#loop"
14 | }, {
15 | "include": "#conditional"
16 | }, {
17 | "include": "#method"
18 | }, {
19 | "include": "#comment"
20 | }, {
21 | "include": "#string"
22 | }, {
23 | "include": "#io"
24 | }, {
25 | "include": "#pronoun"
26 | }, {
27 | "include": "#number"
28 | }, {
29 | "include": "#boolean"
30 | }, {
31 | "include": "#common"
32 | }, {
33 | "include": "#equal"
34 | }, {
35 | "include": "#comparator"
36 | }, {
37 | "include": "#arithmetic"
38 | }, {
39 | "include": "#string-assignment"
40 | }, {
41 | "include": "#null"
42 | }],
43 | "repository": {
44 | "comment": {
45 | "patterns": [{
46 | "begin": "\\(",
47 | "beginCaptures": {
48 | "0": {
49 | "name": "comment.block.rockstar"
50 | }
51 | },
52 | "end": "\\)",
53 | "endCaptures": {
54 | "0": {
55 | "name": "comment.block.rockstar"
56 | }
57 | },
58 | "name": "comment.block.rockstar"
59 | }]
60 | },
61 | "boolean": {
62 | "patterns": [{
63 | "match": "(\\b(is|was|were) )?\\b(true|false|right|yes|ok|wrong|no($| +)|lies)\\b",
64 | "name": "keyword.operator.rockstar",
65 | "captures": {
66 | "2": {
67 | "name": "constant.language.rockstar"
68 | },
69 | "3": {
70 | "name": "constant.language.rockstar"
71 | }
72 | }
73 | }]
74 | },
75 | "null": {
76 | "patterns": [{
77 | "match": "(\\b(is|was|were) )?\\b(nothing|nowhere|nobody|null)\\b",
78 | "captures": {
79 | "2": {
80 | "name": "keyword.operator.rockstar"
81 | },
82 | "3": {
83 | "name": "constant.language.rockstar"
84 | }
85 | }
86 | }]
87 | },
88 | "pronoun": {
89 | "patterns": [{
90 | "match": "\\b(it|he|she|him|her|they|them|ze|hir|zie|zir|xe|xem|ve|ver)\\b",
91 | "name": "storage.type.pronoun.rockstar"
92 | }]
93 | },
94 | "number": {
95 | "patterns": [{
96 | "match": "\\b(is|was|were) (?!and|as|nothing|nowhere|nobody|null|true|false|right|yes|ok|wrong|no|lies)(([a-z]+($|\\s))+)",
97 | "captures": {
98 | "1": {
99 | "name": "keyword.operator.rockstar"
100 | },
101 | "2": {
102 | "name": "constant.numeric.rockstar"
103 | }
104 | }
105 | }]
106 | },
107 | "string": {
108 | "patterns": [{
109 | "begin": "\"",
110 | "beginCaptures": {
111 | "0": {
112 | "name": "constant.numeric.rockstar"
113 | }
114 | },
115 | "end": "\"",
116 | "endCaptures": {
117 | "0": {
118 | "name": "constant.numeric.rockstar"
119 | }
120 | },
121 | "name": "constant.numeric.rockstar"
122 | },
123 | {
124 | "match": "'\\w*'",
125 | "name": "constant.numeric.rockstar"
126 | },
127 | {
128 | "match": ",",
129 | "scope": "constant.numeric.rockstar"
130 | }
131 | ]
132 | },
133 | "equal": {
134 | "patterns": [{
135 | "match": "\\b('s|is( not($| +))?|ain't|was|were)\\b",
136 | "name": "keyword.operator.rockstar"
137 | }]
138 | },
139 | "comparator": {
140 | "patterns": [{
141 | "match": "(higher|greater|bigger|stronger|lower|less|smaller|weaker) than|as (high|great|big|strong|low|little|small|weak) as",
142 | "name": "keyword.operator.rockstar"
143 | }]
144 | },
145 | "loop": {
146 | "patterns": [{
147 | "match": "(^| )(While|Until|Continue|Break it down|break|Take it to the top)($| )",
148 | "name": "keyword.control.rockstar"
149 | }]
150 | },
151 | "conditional": {
152 | "patterns": [{
153 | "match": "(^| )(If|if|Else|else)",
154 | "name": "keyword.control.conditional.rockstar"
155 | }]
156 | },
157 | "method": {
158 | "patterns": [{
159 | "match": "\\b(taking|takes|and|Give back)\\b",
160 | "name": "keyword.other.rockstar"
161 | }]
162 | },
163 | "io": {
164 | "patterns": [{
165 | "match": "(^| )(Say|Shout|Whisper|Scream|Listen( to)?)",
166 | "name": "support.function.builtin.rockstar"
167 | }]
168 | },
169 | "assignment": {
170 | "patterns": [{
171 | "match": "((^Put\\b)|\\b(into)\\b)",
172 | "name": "keyword.operator.rockstar"
173 | }]
174 | },
175 | "arithmetic": {
176 | "patterns": [{
177 | "match": "(Knock | down|Build | up|plus|without|minus|with|times|of|over|by)",
178 | "name": "keyword.operator.arithmetic.rockstar"
179 | }]
180 | },
181 | "common": {
182 | "patterns": [{
183 | "match": "(? {
4 | const highlighter = await getHighlighter({
5 | theme: 'nord'
6 | })
7 | const out = highlighter.codeToHtml(`console.log('shiki');`, 'js')
8 | expect(out).toMatchSnapshot()
9 | })
10 |
--------------------------------------------------------------------------------
/packages/shiki/src/__tests__/utils.test.ts:
--------------------------------------------------------------------------------
1 | import { trimEndSlash, join, dirname } from '../utils'
2 |
3 | test('trimEndSlash', async () => {
4 | expect(trimEndSlash('/abc')).toBe('/abc')
5 | expect(trimEndSlash('/abc/')).toBe('/abc')
6 | expect(trimEndSlash('/abc//')).toBe('/abc/')
7 |
8 | expect(trimEndSlash('\\abc\\')).toBe('\\abc')
9 | expect(trimEndSlash('\\abc\\\\')).toBe('\\abc\\')
10 | })
11 |
12 | test('join', async () => {
13 | expect(join('abc', 'a', 'b')).toBe('abc/a/b')
14 | expect(join()).toBe('')
15 | expect(join('a/', 'b/')).toBe('a/b')
16 | expect(join('a', './b')).toBe('a/b')
17 | })
18 |
19 | test('dirname', async () => {
20 | expect(dirname('a/b/c')).toBe('b')
21 | expect(dirname('a/b/c/')).toBe('c')
22 | expect(dirname('a')).toBe(undefined)
23 | expect(dirname('')).toBe(undefined)
24 | })
25 |
--------------------------------------------------------------------------------
/packages/shiki/src/global.d.ts:
--------------------------------------------------------------------------------
1 | declare var __BROWSER__: boolean
2 |
--------------------------------------------------------------------------------
/packages/shiki/src/highlighter.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | Highlighter,
3 | HighlighterOptions,
4 | ILanguageRegistration,
5 | IShikiTheme,
6 | IThemeRegistration,
7 | StringLiteralUnion
8 | } from './types'
9 | import { Resolver } from './resolver'
10 | import { tokenizeWithTheme } from './themedTokenizer'
11 | import { renderToHtml } from './renderer'
12 |
13 | import { getOnigasm } from './loader'
14 | import { Lang, languages as BUNDLED_LANGUAGES } from './languages'
15 | import { Registry } from './registry'
16 | import { Theme } from './themes'
17 |
18 | function resolveLang(lang: ILanguageRegistration | Lang) {
19 | return typeof lang === 'string'
20 | ? BUNDLED_LANGUAGES.find(l => l.id === lang || l.aliases?.includes(lang))
21 | : lang
22 | }
23 |
24 | function resolveOptions(options: HighlighterOptions) {
25 | let _languages: ILanguageRegistration[] = BUNDLED_LANGUAGES
26 | let _themes: IThemeRegistration[] = options.themes || []
27 |
28 | if (options.langs?.length) {
29 | _languages = options.langs.map(resolveLang)
30 | }
31 | if (options.theme) {
32 | _themes.unshift(options.theme)
33 | }
34 | if (!_themes.length) {
35 | _themes = ['nord']
36 | }
37 |
38 | return { _languages, _themes }
39 | }
40 |
41 | export async function getHighlighter(options: HighlighterOptions): Promise {
42 | const { _languages, _themes } = resolveOptions(options)
43 | const _resolver = new Resolver(getOnigasm(), 'onigasm')
44 | const _registry = new Registry(_resolver)
45 |
46 | if (options.paths?.themes) {
47 | _registry.themesPath = options.paths.themes
48 | }
49 |
50 | if (options.paths?.languages) {
51 | _resolver.languagesPath = options.paths.languages
52 | }
53 |
54 | const themes = await _registry.loadThemes(_themes)
55 | const _defaultTheme = themes[0]
56 | let _currentTheme: IShikiTheme | undefined
57 | await _registry.loadLanguages(_languages)
58 |
59 | function getTheme(theme?: IThemeRegistration) {
60 | const _theme = theme ? _registry.getTheme(theme) : _defaultTheme
61 | if (!_theme) {
62 | throw Error(`No theme registration for ${theme}`)
63 | }
64 | if (!_currentTheme || _currentTheme.name !== _theme.name) {
65 | _registry.setTheme(_theme)
66 | _currentTheme = _theme
67 | }
68 | const _colorMap = _registry.getColorMap()
69 | return { _theme, _colorMap }
70 | }
71 |
72 | function getGrammer(lang: string) {
73 | const _grammer = _registry.getGrammer(lang)
74 | if (!_grammer) {
75 | throw Error(`No language registration for ${lang}`)
76 | }
77 | return { _grammer }
78 | }
79 |
80 | function codeToThemedTokens(
81 | code: string,
82 | lang = 'text',
83 | theme?: StringLiteralUnion,
84 | options = { includeExplanation: true }
85 | ) {
86 | if (isPlaintext(lang)) {
87 | return [[{ content: code }]]
88 | }
89 | const { _grammer } = getGrammer(lang)
90 | const { _theme, _colorMap } = getTheme(theme)
91 | return tokenizeWithTheme(_theme, _colorMap, code, _grammer, options)
92 | }
93 |
94 | function codeToHtml(code: string, lang = 'text', theme?: StringLiteralUnion) {
95 | const tokens = codeToThemedTokens(code, lang, theme, {
96 | includeExplanation: false
97 | })
98 | const { _theme } = getTheme(theme)
99 | return renderToHtml(tokens, {
100 | fg: _theme.fg,
101 | bg: _theme.bg
102 | })
103 | }
104 |
105 | async function loadTheme(theme: IShikiTheme | Theme) {
106 | await _registry.loadTheme(theme)
107 | }
108 |
109 | async function loadLanguage(lang: ILanguageRegistration | Lang) {
110 | const _lang = resolveLang(lang)
111 | _resolver.addLanguage(_lang)
112 | await _registry.loadLanguage(_lang)
113 | }
114 |
115 | function getLoadedThemes() {
116 | return _registry.getLoadedThemes()
117 | }
118 |
119 | function getLoadedLanguages() {
120 | return _registry.getLoadedLanguages()
121 | }
122 |
123 | function getBackgroundColor(theme?: StringLiteralUnion) {
124 | const { _theme } = getTheme(theme)
125 | return _theme.bg
126 | }
127 |
128 | function getForegroundColor(theme?: StringLiteralUnion) {
129 | const { _theme } = getTheme(theme)
130 | return _theme.fg
131 | }
132 |
133 | return {
134 | codeToThemedTokens,
135 | codeToHtml,
136 | getTheme: (theme: IThemeRegistration) => {
137 | return getTheme(theme)._theme
138 | },
139 | loadTheme,
140 | loadLanguage,
141 | getBackgroundColor,
142 | getForegroundColor,
143 | getLoadedThemes,
144 | getLoadedLanguages
145 | }
146 | }
147 |
148 | function isPlaintext(lang: string | null | undefined) {
149 | return !lang || ['plaintext', 'txt', 'text'].includes(lang)
150 | }
151 |
--------------------------------------------------------------------------------
/packages/shiki/src/index.ts:
--------------------------------------------------------------------------------
1 | export { themes as BUNDLED_THEMES, Theme } from './themes'
2 | export { languages as BUNDLED_LANGUAGES, Lang } from './languages'
3 |
4 | export { FontStyle } from './stackElementMetadata'
5 |
6 | export { getHighlighter } from './highlighter'
7 | export { renderToHtml, HtmlRendererOptions } from './renderer'
8 | export { IThemedToken } from './themedTokenizer'
9 | export { setCDN, setOnigasmWASM, fetchTheme as loadTheme } from './loader'
10 | export {
11 | ILanguageRegistration,
12 | IShikiTheme,
13 | IThemeRegistration,
14 | Highlighter,
15 | HighlighterOptions
16 | } from './types'
17 |
--------------------------------------------------------------------------------
/packages/shiki/src/registry.ts:
--------------------------------------------------------------------------------
1 | import { IGrammar, Registry as TextMateRegistry } from 'vscode-textmate'
2 | import { IShikiTheme, IThemeRegistration, ILanguageRegistration } from './types'
3 | import { fetchTheme, toShikiTheme } from './loader'
4 | import { Theme } from './themes'
5 | import { Resolver } from './resolver'
6 | import { Lang } from './languages'
7 |
8 | export class Registry extends TextMateRegistry {
9 | public themesPath: string = 'themes/'
10 |
11 | private _resolvedThemes: Record = {}
12 | private _resolvedGrammars: Record = {}
13 |
14 | constructor(private _resolver: Resolver) {
15 | super(_resolver)
16 | }
17 |
18 | public getTheme(theme: Theme | IShikiTheme | string) {
19 | if (typeof theme === 'string') {
20 | return this._resolvedThemes[theme]
21 | } else {
22 | return theme
23 | }
24 | }
25 |
26 | public async loadTheme(theme: Theme | IShikiTheme | string) {
27 | if (typeof theme === 'string') {
28 | if (!this._resolvedThemes[theme]) {
29 | this._resolvedThemes[theme] = await fetchTheme(`${this.themesPath}${theme}.json`)
30 | }
31 | return this._resolvedThemes[theme]
32 | } else {
33 | theme = toShikiTheme(theme)
34 | if (theme.name) {
35 | this._resolvedThemes[theme.name] = theme
36 | }
37 | return theme
38 | }
39 | }
40 |
41 | public async loadThemes(themes: IThemeRegistration[]) {
42 | return await Promise.all(themes.map(theme => this.loadTheme(theme)))
43 | }
44 |
45 | public getLoadedThemes() {
46 | return Object.keys(this._resolvedThemes) as Theme[]
47 | }
48 |
49 | public getGrammer(name: string) {
50 | return this._resolvedGrammars[name]
51 | }
52 |
53 | public async loadLanguage(lang: ILanguageRegistration) {
54 | const g = await this.loadGrammar(lang.scopeName)
55 | this._resolvedGrammars[lang.id] = g
56 | if (lang.aliases) {
57 | lang.aliases.forEach(la => {
58 | this._resolvedGrammars[la] = g
59 | })
60 | }
61 | }
62 |
63 | public async loadLanguages(langs: ILanguageRegistration[]) {
64 | for (const lang of langs) {
65 | this._resolver.addLanguage(lang)
66 | }
67 | for (const lang of langs) {
68 | await this.loadLanguage(lang)
69 | }
70 | }
71 |
72 | public getLoadedLanguages() {
73 | return Object.keys(this._resolvedGrammars) as Lang[]
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/packages/shiki/src/renderer.ts:
--------------------------------------------------------------------------------
1 | import { FontStyle } from './stackElementMetadata'
2 | import { IThemedToken } from './themedTokenizer'
3 |
4 | export interface HtmlRendererOptions {
5 | langId?: string
6 | fg?: string
7 | bg?: string
8 | }
9 |
10 | const FONT_STYLE_TO_CSS = {
11 | [FontStyle.Italic]: 'font-style: italic',
12 | [FontStyle.Bold]: 'font-weight: bold',
13 | [FontStyle.Underline]: 'text-decoration: underline'
14 | }
15 |
16 | export function renderToHtml(lines: IThemedToken[][], options: HtmlRendererOptions = {}) {
17 | const bg = options.bg || '#fff'
18 |
19 | let html = ''
20 |
21 | html += ``
22 | if (options.langId) {
23 | html += `${options.langId}
`
24 | }
25 | html += ``
26 |
27 | lines.forEach((l: IThemedToken[]) => {
28 | html += ``
29 |
30 | l.forEach(token => {
31 | const cssDeclarations = [`color: ${token.color || options.fg}`]
32 | if (token.fontStyle > FontStyle.None) {
33 | cssDeclarations.push(FONT_STYLE_TO_CSS[token.fontStyle])
34 | }
35 | html += `${escapeHtml(token.content)} `
36 | })
37 | html += ` \n`
38 | })
39 | html = html.replace(/\n*$/, '') // Get rid of final new lines
40 | html += `
`
41 |
42 | return html
43 | }
44 |
45 | const htmlEscapes = {
46 | '&': '&',
47 | '<': '<',
48 | '>': '>',
49 | '"': '"',
50 | "'": '''
51 | }
52 |
53 | function escapeHtml(html: string) {
54 | return html.replace(/[&<>"']/g, chr => htmlEscapes[chr])
55 | }
56 |
--------------------------------------------------------------------------------
/packages/shiki/src/resolver.ts:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------------
2 | * Copyright (C) Microsoft Corporation. All rights reserved.
3 | *--------------------------------------------------------*/
4 | 'use strict'
5 |
6 | import { IRawGrammar, IOnigLib, RegistryOptions } from 'vscode-textmate'
7 | import { languages } from './languages'
8 |
9 | import { fetchGrammar } from './loader'
10 | import { ILanguageRegistration } from './types'
11 |
12 | export class Resolver implements RegistryOptions {
13 | public languagesPath: string = 'languages/'
14 |
15 | private readonly languageMap: { [langIdOrAlias: string]: ILanguageRegistration } = {}
16 | private readonly scopeToLangMap: { [scope: string]: ILanguageRegistration } = {}
17 |
18 | private readonly _onigLibPromise: Promise
19 | private readonly _onigLibName: string
20 |
21 | constructor(onigLibPromise: Promise, onigLibName: string) {
22 | this._onigLibPromise = onigLibPromise
23 | this._onigLibName = onigLibName
24 | }
25 |
26 | public get onigLib(): Promise {
27 | return this._onigLibPromise
28 | }
29 |
30 | public getOnigLibName(): string {
31 | return this._onigLibName
32 | }
33 |
34 | public getLangRegistration(langIdOrAlias: string): ILanguageRegistration {
35 | return this.languageMap[langIdOrAlias]
36 | }
37 |
38 | public async loadGrammar(scopeName: string): Promise {
39 | const lang = this.scopeToLangMap[scopeName]
40 |
41 | if (!lang) {
42 | return null
43 | }
44 |
45 | if (lang.grammar) {
46 | return lang.grammar
47 | }
48 |
49 | const g = await fetchGrammar(
50 | languages.includes(lang) ? `${this.languagesPath}${lang.path}` : lang.path
51 | )
52 | lang.grammar = g
53 | return g
54 | }
55 |
56 | public addLanguage(l: ILanguageRegistration) {
57 | this.languageMap[l.id] = l
58 | if (l.aliases) {
59 | l.aliases.forEach(a => {
60 | this.languageMap[a] = l
61 | })
62 | }
63 | this.scopeToLangMap[l.scopeName] = l
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/packages/shiki/src/stackElementMetadata.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Helpers to manage the "collapsed" metadata of an entire StackElement stack.
3 | * The following assumptions have been made:
4 | * - languageId < 256 => needs 8 bits
5 | * - unique color count < 512 => needs 9 bits
6 | *
7 | * The binary format is:
8 | * - -------------------------------------------
9 | * 3322 2222 2222 1111 1111 1100 0000 0000
10 | * 1098 7654 3210 9876 5432 1098 7654 3210
11 | * - -------------------------------------------
12 | * xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
13 | * bbbb bbbb bfff ffff ffFF FTTT LLLL LLLL
14 | * - -------------------------------------------
15 | * - L = LanguageId (8 bits)
16 | * - T = StandardTokenType (3 bits)
17 | * - F = FontStyle (3 bits)
18 | * - f = foreground color (9 bits)
19 | * - b = background color (9 bits)
20 | */
21 | export const enum MetadataConsts {
22 | LANGUAGEID_MASK = 0b00000000000000000000000011111111,
23 | TOKEN_TYPE_MASK = 0b00000000000000000000011100000000,
24 | FONT_STYLE_MASK = 0b00000000000000000011100000000000,
25 | FOREGROUND_MASK = 0b00000000011111111100000000000000,
26 | BACKGROUND_MASK = 0b11111111100000000000000000000000,
27 |
28 | LANGUAGEID_OFFSET = 0,
29 | TOKEN_TYPE_OFFSET = 8,
30 | FONT_STYLE_OFFSET = 11,
31 | FOREGROUND_OFFSET = 14,
32 | BACKGROUND_OFFSET = 23
33 | }
34 |
35 | export const enum TemporaryStandardTokenType {
36 | Other = 0,
37 | Comment = 1,
38 | String = 2,
39 | RegEx = 4,
40 | MetaEmbedded = 8
41 | }
42 |
43 | export const enum FontStyle {
44 | NotSet = -1,
45 | None = 0,
46 | Italic = 1,
47 | Bold = 2,
48 | Underline = 4
49 | }
50 |
51 | export const enum StandardTokenType {
52 | Other = 0,
53 | Comment = 1,
54 | String = 2,
55 | RegEx = 4
56 | }
57 |
58 | export class StackElementMetadata {
59 | public static toBinaryStr(metadata: number): string {
60 | let r = metadata.toString(2)
61 | while (r.length < 32) {
62 | r = '0' + r
63 | }
64 | return r
65 | }
66 |
67 | public static printMetadata(metadata: number): void {
68 | let languageId = StackElementMetadata.getLanguageId(metadata)
69 | let tokenType = StackElementMetadata.getTokenType(metadata)
70 | let fontStyle = StackElementMetadata.getFontStyle(metadata)
71 | let foreground = StackElementMetadata.getForeground(metadata)
72 | let background = StackElementMetadata.getBackground(metadata)
73 |
74 | console.log({
75 | languageId: languageId,
76 | tokenType: tokenType,
77 | fontStyle: fontStyle,
78 | foreground: foreground,
79 | background: background
80 | })
81 | }
82 |
83 | public static getLanguageId(metadata: number): number {
84 | return (metadata & MetadataConsts.LANGUAGEID_MASK) >>> MetadataConsts.LANGUAGEID_OFFSET
85 | }
86 |
87 | public static getTokenType(metadata: number): number {
88 | return (metadata & MetadataConsts.TOKEN_TYPE_MASK) >>> MetadataConsts.TOKEN_TYPE_OFFSET
89 | }
90 |
91 | public static getFontStyle(metadata: number): number {
92 | return (metadata & MetadataConsts.FONT_STYLE_MASK) >>> MetadataConsts.FONT_STYLE_OFFSET
93 | }
94 |
95 | public static getForeground(metadata: number): number {
96 | return (metadata & MetadataConsts.FOREGROUND_MASK) >>> MetadataConsts.FOREGROUND_OFFSET
97 | }
98 |
99 | public static getBackground(metadata: number): number {
100 | return (metadata & MetadataConsts.BACKGROUND_MASK) >>> MetadataConsts.BACKGROUND_OFFSET
101 | }
102 |
103 | public static set(
104 | metadata: number,
105 | languageId: number,
106 | tokenType: TemporaryStandardTokenType,
107 | fontStyle: FontStyle,
108 | foreground: number,
109 | background: number
110 | ): number {
111 | let _languageId = StackElementMetadata.getLanguageId(metadata)
112 | let _tokenType = StackElementMetadata.getTokenType(metadata)
113 | let _fontStyle = StackElementMetadata.getFontStyle(metadata)
114 | let _foreground = StackElementMetadata.getForeground(metadata)
115 | let _background = StackElementMetadata.getBackground(metadata)
116 |
117 | if (languageId !== 0) {
118 | _languageId = languageId
119 | }
120 | if (tokenType !== TemporaryStandardTokenType.Other) {
121 | _tokenType =
122 | tokenType === TemporaryStandardTokenType.MetaEmbedded ? StandardTokenType.Other : tokenType
123 | }
124 | if (fontStyle !== FontStyle.NotSet) {
125 | _fontStyle = fontStyle
126 | }
127 | if (foreground !== 0) {
128 | _foreground = foreground
129 | }
130 | if (background !== 0) {
131 | _background = background
132 | }
133 |
134 | return (
135 | ((_languageId << MetadataConsts.LANGUAGEID_OFFSET) |
136 | (_tokenType << MetadataConsts.TOKEN_TYPE_OFFSET) |
137 | (_fontStyle << MetadataConsts.FONT_STYLE_OFFSET) |
138 | (_foreground << MetadataConsts.FOREGROUND_OFFSET) |
139 | (_background << MetadataConsts.BACKGROUND_OFFSET)) >>>
140 | 0
141 | )
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/packages/shiki/src/themes.ts:
--------------------------------------------------------------------------------
1 | export type Theme =
2 | | 'dark-plus'
3 | | 'dracula-soft'
4 | | 'dracula'
5 | | 'github-dark'
6 | | 'github-light'
7 | | 'light-plus'
8 | | 'material-darker'
9 | | 'material-default'
10 | | 'material-lighter'
11 | | 'material-ocean'
12 | | 'material-palenight'
13 | | 'min-dark'
14 | | 'min-light'
15 | | 'monokai'
16 | | 'nord'
17 | | 'poimandres'
18 | | 'slack-dark'
19 | | 'slack-ochin'
20 | | 'solarized-dark'
21 | | 'solarized-light'
22 | | 'vitesse-dark'
23 | | 'vitesse-light'
24 |
25 | export const themes: Theme[] = [
26 | 'dark-plus',
27 | 'dracula-soft',
28 | 'dracula',
29 | 'github-dark',
30 | 'github-light',
31 | 'light-plus',
32 | 'material-darker',
33 | 'material-default',
34 | 'material-lighter',
35 | 'material-ocean',
36 | 'material-palenight',
37 | 'min-dark',
38 | 'min-light',
39 | 'monokai',
40 | 'nord',
41 | 'poimandres',
42 | 'slack-dark',
43 | 'slack-ochin',
44 | 'solarized-dark',
45 | 'solarized-light',
46 | 'vitesse-dark',
47 | 'vitesse-light'
48 | ]
49 |
--------------------------------------------------------------------------------
/packages/shiki/src/types.ts:
--------------------------------------------------------------------------------
1 | import { IRawGrammar, IRawTheme, IRawThemeSetting } from 'vscode-textmate'
2 | import { Lang } from './languages'
3 | import { IThemedToken } from './themedTokenizer'
4 | import { Theme } from './themes'
5 |
6 | export interface HighlighterOptions {
7 | /**
8 | * The theme to load upfront.
9 | */
10 | theme?: IThemeRegistration
11 |
12 | /**
13 | * A list of themes to load upfront.
14 | *
15 | * Default to: `['dark-plus', 'light-plus']`
16 | */
17 | themes?: IThemeRegistration[]
18 |
19 | /**
20 | * A list of languages to load upfront.
21 | *
22 | * Default to `['html', 'css', 'javascript']`
23 | */
24 | langs?: (Lang | ILanguageRegistration)[]
25 |
26 | /**
27 | * Paths for loading themes and langs. Relative to the package's root.
28 | */
29 | paths?: IHighlighterPaths
30 | }
31 |
32 | export interface Highlighter {
33 | /**
34 | * Convert code to HTML tokens.
35 | * `lang` and `theme` must have been loaded.
36 | */
37 | codeToHtml(
38 | code: string,
39 | lang?: StringLiteralUnion,
40 | theme?: StringLiteralUnion
41 | ): string
42 |
43 | /**
44 | * Convert code to themed tokens for custom processing.
45 | * `lang` and `theme` must have been loaded.
46 | * You may customize the bundled HTML / SVG renderer or write your own
47 | * renderer for another render target.
48 | */
49 | codeToThemedTokens(
50 | code: string,
51 | lang?: StringLiteralUnion,
52 | theme?: StringLiteralUnion,
53 | options?: ThemedTokenizerOptions
54 | ): IThemedToken[][]
55 |
56 | /**
57 | * Get the loaded theme
58 | */
59 | getTheme(theme?: IThemeRegistration): IShikiTheme
60 |
61 | /**
62 | * Load a theme
63 | */
64 | loadTheme(theme: IThemeRegistration): Promise
65 |
66 | /**
67 | * Load a language
68 | */
69 | loadLanguage(lang: ILanguageRegistration | Lang): Promise
70 |
71 | /**
72 | * Get all loaded themes
73 | */
74 | getLoadedThemes(): Theme[]
75 |
76 | /**
77 | * Get all loaded languages
78 | */
79 | getLoadedLanguages(): Lang[]
80 |
81 | /**
82 | * Get the foreground color for theme. Can be used for CSS `color`.
83 | */
84 | getForegroundColor(theme?: StringLiteralUnion): string
85 |
86 | /**
87 | * Get the background color for theme. Can be used for CSS `background-color`.
88 | */
89 | getBackgroundColor(theme?: StringLiteralUnion): string
90 |
91 | // codeToRawHtml?(code: string): string
92 | // getRawCSS?(): string
93 |
94 | // codeToImage?(): string
95 | }
96 |
97 | export interface IHighlighterPaths {
98 | /**
99 | * @default 'themes/'
100 | */
101 | themes?: string
102 |
103 | /**
104 | * @default 'languages/'
105 | */
106 | languages?: string
107 | }
108 |
109 | export type ILanguageRegistration = {
110 | id: string
111 | scopeName: string
112 | aliases?: string[]
113 | samplePath?: string
114 | /**
115 | * A list of languages the current language embeds.
116 | * If manually specifying languages to load, make sure to load the embedded
117 | * languages for each parent language.
118 | */
119 | embeddedLangs?: Lang[]
120 | } & (
121 | | {
122 | path: string
123 | grammar?: IRawGrammar
124 | }
125 | | {
126 | path?: string
127 | grammar: IRawGrammar
128 | }
129 | )
130 |
131 | export type IThemeRegistration = IShikiTheme | StringLiteralUnion
132 |
133 | export interface IShikiTheme extends IRawTheme {
134 | /**
135 | * @description theme name
136 | */
137 | name: string
138 |
139 | /**
140 | * @description light/dark theme
141 | */
142 | type: 'light' | 'dark'
143 |
144 | /**
145 | * @description tokenColors of the theme file
146 | */
147 | settings: IRawThemeSetting[]
148 |
149 | /**
150 | * @description text default foreground color
151 | */
152 | fg: string
153 |
154 | /**
155 | * @description text default background color
156 | */
157 | bg: string
158 |
159 | /**
160 | * @description relative path of included theme
161 | */
162 | include?: string
163 |
164 | /**
165 | *
166 | * @description color map of the theme file
167 | */
168 | colors?: Record
169 | }
170 |
171 | /**
172 | * type StringLiteralUnion<'foo'> = 'foo' | string
173 | * This has auto completion whereas `'foo' | string` doesn't
174 | * Adapted from https://github.com/microsoft/TypeScript/issues/29729
175 | */
176 | export type StringLiteralUnion = T | (U & {})
177 |
178 | export interface ThemedTokenizerOptions {
179 | /**
180 | * Whether to include explanation of each token's matching scopes and
181 | * why it's given its color. Default to false to reduce output verbosity.
182 | */
183 | includeExplanation?: boolean
184 | }
185 |
--------------------------------------------------------------------------------
/packages/shiki/src/utils.ts:
--------------------------------------------------------------------------------
1 | export function trimEndSlash(str: string) {
2 | if (str.endsWith('/') || str.endsWith('\\')) return str.slice(0, -1)
3 | return str
4 | }
5 |
6 | export function trimStartDot(str: string) {
7 | if (str.startsWith('./')) return str.slice(2)
8 | return str
9 | }
10 |
11 | export function dirname(str: string) {
12 | const parts = str.split(/[\/\\]/g)
13 | return parts[parts.length - 2]
14 | }
15 |
16 | export function join(...parts: string[]) {
17 | return parts.map(trimEndSlash).map(trimStartDot).join('/')
18 | }
19 |
--------------------------------------------------------------------------------
/packages/shiki/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2017",
5 | "esModuleInterop": true,
6 | "moduleResolution": "node",
7 | "lib": ["esnext", "DOM", "WebWorker"],
8 | "sourceMap": true
9 | },
10 | "exclude": ["samples"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/site/assets/figma-editing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yyx990803/shiki/d39789ccd42b7d3dffb2b1d1bb53aa751757a806/packages/site/assets/figma-editing.png
--------------------------------------------------------------------------------
/packages/site/assets/leandro-fatih.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yyx990803/shiki/d39789ccd42b7d3dffb2b1d1bb53aa751757a806/packages/site/assets/leandro-fatih.png
--------------------------------------------------------------------------------
/packages/site/assets/svg-figma-af.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yyx990803/shiki/d39789ccd42b7d3dffb2b1d1bb53aa751757a806/packages/site/assets/svg-figma-af.jpg
--------------------------------------------------------------------------------
/packages/site/assets/vscode-ts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yyx990803/shiki/d39789ccd42b7d3dffb2b1d1bb53aa751757a806/packages/site/assets/vscode-ts.png
--------------------------------------------------------------------------------
/packages/site/beer.wy:
--------------------------------------------------------------------------------
1 | 吾有一言。曰「「春日宴。」」。書之。
2 | 有數九。名之曰「酒數」。
3 |
4 | 恆為是。若「酒數」等於零者乃止也。
5 |
6 | 吾有三言。曰「「與君」」。曰「酒數」。
7 | 曰「「杯酒。可以窮歡宴。綠酒一杯歌一遍。」」。書之。
8 |
9 | 減「酒數」以一。昔之「酒數」者。今其是矣云云。
10 |
11 | 吾有一言。曰「「綠酒千杯腸已爛。」」。書之。
--------------------------------------------------------------------------------
/packages/site/chinese-svg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | 吾有 一 言 。 曰 「「春日宴。」」 。 書之 。
4 |
5 |
6 | 有數 九 。 名之曰 「酒數」 。
7 |
8 |
9 |
10 | 恆為是 。 若 「酒數」 等於 零 者乃止也 。
11 |
12 |
13 |
14 | 吾有 三 言 。 曰 「「與君」」 。 曰 「酒數」 。
15 |
16 |
17 | 曰 「「杯酒。可以窮歡宴。綠酒一杯歌一遍。」」 。 書之 。
18 |
19 |
20 |
21 | 減 「酒數」 以 一 。 昔之 「酒數」 者 。 今其是矣云云 。
22 |
23 |
24 |
25 | 吾有 一 言 。 曰 「「綠酒千杯腸已爛。」」 。 書之 。
26 |
27 |
28 |
--------------------------------------------------------------------------------
/packages/site/gen-custom-theme.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const markdown = require('markdown-it')
3 | const shiki = require('shiki')
4 | const path = require('path')
5 |
6 | shiki
7 | .getHighlighter({
8 | theme: 'nord',
9 | langs: [
10 | {
11 | id: 'rockstar',
12 | scopeName: 'source.rockstar',
13 | path: path.resolve('./rockstar.tmLanguage.json'),
14 | aliases: []
15 | }
16 | ]
17 | })
18 | .then(highlighter => {
19 | const md = markdown({
20 | highlight: (code, lang) => {
21 | return highlighter.codeToHtml(code, lang)
22 | }
23 | })
24 |
25 | const result = md.render(fs.readFileSync('rockstar.md', 'utf-8'))
26 | fs.writeFileSync('rockstar.html', result)
27 |
28 | console.log('done: rockstar.html')
29 | })
30 |
--------------------------------------------------------------------------------
/packages/site/gen-index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const markdown = require('markdown-it')
3 | const shiki = require('shiki')
4 |
5 | shiki
6 | .getHighlighter({
7 | theme: 'nord'
8 | })
9 | .then(highlighter => {
10 | const md = markdown({
11 | html: true,
12 | highlight: (code, lang) => {
13 | return highlighter.codeToHtml(code, lang)
14 | }
15 | })
16 |
17 | const html = md.render(fs.readFileSync('index.md', 'utf-8'))
18 | const out = `
19 | Shiki
20 |
21 | ${html}
22 |
23 | `
24 | fs.writeFileSync('index.html', out)
25 |
26 | console.log('done: index.html')
27 | })
28 |
--------------------------------------------------------------------------------
/packages/site/gen-mono.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const markdown = require('markdown-it')
3 | const shiki = require('shiki')
4 |
5 | shiki
6 | .getHighlighter({
7 | theme: JSON.parse(fs.readFileSync('./monochrome-dark-subtle.json', 'utf-8'))
8 | })
9 | .then(highlighter => {
10 | const md = markdown({
11 | highlight: (code, lang) => {
12 | return highlighter.codeToHtml(code, lang)
13 | }
14 | })
15 |
16 | const result = md.render(fs.readFileSync('mono.md', 'utf-8'))
17 | fs.writeFileSync('mono.html', result)
18 |
19 | console.log('done: mono.html')
20 | })
21 |
--------------------------------------------------------------------------------
/packages/site/gen-palenight.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const markdown = require('markdown-it')
3 | const shiki = require('shiki')
4 |
5 | shiki
6 | .getHighlighter({
7 | theme: 'material-palenight'
8 | })
9 | .then(highlighter => {
10 | const md = markdown({
11 | highlight: (code, lang) => {
12 | return highlighter.codeToHtml(code, lang)
13 | }
14 | })
15 |
16 | const result = md.render(fs.readFileSync('palenight.md', 'utf-8'))
17 | fs.writeFileSync('palenight.html', result)
18 |
19 | console.log('done: palenight.html')
20 | })
21 |
--------------------------------------------------------------------------------
/packages/site/gen-svg-sample.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const shiki = require('shiki')
3 | const { getSVGRenderer } = require('shiki-renderer-svg')
4 |
5 | ;(async () => {
6 | const highlighter = await shiki.getHighlighter({
7 | theme: 'nord'
8 | })
9 |
10 | const svgRenderer = await getSVGRenderer({
11 | bg: '#2E3440',
12 | fontFamily: {
13 | name: 'Inconsolata',
14 | cssURL: 'https://fonts.googleapis.com/css2?family=Inconsolata&display=swap'
15 | },
16 | fontSize: 14
17 | })
18 |
19 | const code = fs.readFileSync('gen-svg.js', 'utf-8')
20 |
21 | const tokens = highlighter.codeToThemedTokens(code, 'js')
22 | const out = svgRenderer.renderToSVG(tokens)
23 |
24 | fs.writeFileSync('svg.svg', out)
25 |
26 | console.log('done: svg.svg')
27 | })()
28 |
--------------------------------------------------------------------------------
/packages/site/gen-svg.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const shiki = require('shiki')
3 | const { getSVGRenderer } = require('shiki-renderer-svg')
4 |
5 | ;(async () => {
6 | const highlighter = await shiki.getHighlighter({
7 | theme: 'nord'
8 | })
9 |
10 | const svgRenderer = await getSVGRenderer({
11 | bg: '#2E3440',
12 | fontFamily: {
13 | name: 'IBM Plex Mono',
14 | cssURL:
15 | 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap'
16 | },
17 | fontSize: 14
18 | })
19 |
20 | const code = fs.readFileSync('gen-svg-sample.js', 'utf-8')
21 |
22 | const tokens = highlighter.codeToThemedTokens(code, 'js')
23 | const out = svgRenderer.renderToSVG(tokens)
24 |
25 | fs.writeFileSync('svg.svg', out)
26 |
27 | console.log('done: svg.svg')
28 | })()
29 |
--------------------------------------------------------------------------------
/packages/site/gen-wenyan.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const shiki = require('shiki')
3 |
4 | ;(async () => {
5 | const highlighter = await shiki.getHighlighter({
6 | theme: 'nord'
7 | })
8 |
9 | const code = fs.readFileSync('beer.wy', 'utf-8')
10 |
11 | const html = highlighter.codeToHtml(code, '文言')
12 |
13 | fs.writeFileSync('文言.html', html)
14 |
15 | console.log('done: 文言')
16 | })()
17 |
--------------------------------------------------------------------------------
/packages/site/index.js:
--------------------------------------------------------------------------------
1 | async function go() {
2 | const urlAndIds = [
3 | ['/palenight', 'palenight'],
4 | ['/mono', 'mono'],
5 | ['/rockstar', 'rockstar'],
6 | ['/文言', '文言'],
7 | ['/svg.svg', 'svg']
8 | ]
9 |
10 | for (let [url, id] of urlAndIds) {
11 | await getHtmlAndReplace(url, id)
12 | }
13 | }
14 |
15 | async function getHtmlAndReplace(url, elementId) {
16 | const targetHtml = await (await fetch(url)).text()
17 | document.getElementById(elementId).innerHTML = targetHtml
18 | }
19 |
20 | go()
21 |
--------------------------------------------------------------------------------
/packages/site/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "checkJs": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/site/mono.html:
--------------------------------------------------------------------------------
1 | const shiki = require ( ' shiki ' )
2 |
3 | shiki . getHighlighter ({
4 | theme: JSON. parse ( fs . readFileSync ( ' ./monochrome-dark-subtle.json ' , ' utf-8 ' ))
5 | })
6 |
7 |
--------------------------------------------------------------------------------
/packages/site/mono.md:
--------------------------------------------------------------------------------
1 | ```js
2 | const shiki = require('shiki')
3 |
4 | shiki.getHighlighter({
5 | theme: JSON.parse(fs.readFileSync('./monochrome-dark-subtle.json', 'utf-8'))
6 | })
7 | ```
8 |
--------------------------------------------------------------------------------
/packages/site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shiki-site",
3 | "version": "0.9.5",
4 | "private": true,
5 | "devDependencies": {
6 | "@types/node": "^10.17.60",
7 | "markdown-it": "^8.4.2",
8 | "playwright": "^1.13.1",
9 | "shiki": "^0.9.5",
10 | "shiki-renderer-svg": "^0.9.5"
11 | },
12 | "scripts": {
13 | "gen": "node gen-index.js && node gen-palenight.js && node gen-mono.js && node gen-custom-theme.js && node gen-svg.js && node gen-wenyan.js"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/site/palenight.md:
--------------------------------------------------------------------------------
1 | ```tsx
2 | import * as React from 'react';
3 | import './App.css';
4 | import Hello from './components/Hello';
5 |
6 | const logo = require('./logo.svg');
7 |
8 | function App() {
9 | return (
10 |
11 |
12 |
13 |
Welcome to React
14 |
15 |
16 | To get started, edit src/App.tsx
and save to reload.
17 |
18 |
19 |
20 | );
21 | }
22 |
23 | export default App;
24 | ```
--------------------------------------------------------------------------------
/packages/site/rockstar.html:
--------------------------------------------------------------------------------
1 | Midnight takes your heart and your soul
2 | While your heart is as high as your soul
3 | Put your heart without your soul into your heart
4 |
5 | Give back your heart
6 |
7 |
8 | Desire is a lovestruck ladykiller
9 | My world is nothing
10 | Fire is ice
11 | Hate is water
12 | Until my world is Desire,
13 | Build my world up
14 | If Midnight taking my world , Fire is nothing and Midnight taking my world , Hate is nothing
15 | Shout "FizzBuzz!"
16 | Take it to the top
17 |
18 | If Midnight taking my world , Fire is nothing
19 | Shout "Fizz!"
20 | Take it to the top
21 |
22 | If Midnight taking my world , Hate is nothing
23 | Say "Buzz!"
24 | Take it to the top
25 |
26 | Whisper my world
27 |
28 |
--------------------------------------------------------------------------------
/packages/site/rockstar.md:
--------------------------------------------------------------------------------
1 | ```rockstar
2 | Midnight takes your heart and your soul
3 | While your heart is as high as your soul
4 | Put your heart without your soul into your heart
5 |
6 | Give back your heart
7 |
8 |
9 | Desire is a lovestruck ladykiller
10 | My world is nothing
11 | Fire is ice
12 | Hate is water
13 | Until my world is Desire,
14 | Build my world up
15 | If Midnight taking my world, Fire is nothing and Midnight taking my world, Hate is nothing
16 | Shout "FizzBuzz!"
17 | Take it to the top
18 |
19 | If Midnight taking my world, Fire is nothing
20 | Shout "Fizz!"
21 | Take it to the top
22 |
23 | If Midnight taking my world, Hate is nothing
24 | Say "Buzz!"
25 | Take it to the top
26 |
27 | Whisper my world
28 | ```
29 |
--------------------------------------------------------------------------------
/packages/site/rockstar.tmLanguage.json:
--------------------------------------------------------------------------------
1 | {
2 | "_source":"https://github.com/ra100/vscode-rockstar-language",
3 | "_license": "https://github.com/ra100/vscode-rockstar-language/blob/master/LICENSE",
4 | "scopeName": "source.rockstar",
5 | "name": "Rockstar",
6 | "fileTypes": [
7 | "rock",
8 | "rockstar"
9 | ],
10 | "patterns": [{
11 | "include": "#proper-variable"
12 | }, {
13 | "include": "#loop"
14 | }, {
15 | "include": "#conditional"
16 | }, {
17 | "include": "#method"
18 | }, {
19 | "include": "#comment"
20 | }, {
21 | "include": "#string"
22 | }, {
23 | "include": "#io"
24 | }, {
25 | "include": "#pronoun"
26 | }, {
27 | "include": "#number"
28 | }, {
29 | "include": "#boolean"
30 | }, {
31 | "include": "#common"
32 | }, {
33 | "include": "#equal"
34 | }, {
35 | "include": "#comparator"
36 | }, {
37 | "include": "#arithmetic"
38 | }, {
39 | "include": "#string-assignment"
40 | }, {
41 | "include": "#null"
42 | }],
43 | "repository": {
44 | "comment": {
45 | "patterns": [{
46 | "begin": "\\(",
47 | "beginCaptures": {
48 | "0": {
49 | "name": "comment.block.rockstar"
50 | }
51 | },
52 | "end": "\\)",
53 | "endCaptures": {
54 | "0": {
55 | "name": "comment.block.rockstar"
56 | }
57 | },
58 | "name": "comment.block.rockstar"
59 | }]
60 | },
61 | "boolean": {
62 | "patterns": [{
63 | "match": "(\\b(is|was|were) )?\\b(true|false|right|yes|ok|wrong|no($| +)|lies)\\b",
64 | "name": "keyword.operator.rockstar",
65 | "captures": {
66 | "2": {
67 | "name": "constant.language.rockstar"
68 | },
69 | "3": {
70 | "name": "constant.language.rockstar"
71 | }
72 | }
73 | }]
74 | },
75 | "null": {
76 | "patterns": [{
77 | "match": "(\\b(is|was|were) )?\\b(nothing|nowhere|nobody|null)\\b",
78 | "captures": {
79 | "2": {
80 | "name": "keyword.operator.rockstar"
81 | },
82 | "3": {
83 | "name": "constant.language.rockstar"
84 | }
85 | }
86 | }]
87 | },
88 | "pronoun": {
89 | "patterns": [{
90 | "match": "\\b(it|he|she|him|her|they|them|ze|hir|zie|zir|xe|xem|ve|ver)\\b",
91 | "name": "storage.type.pronoun.rockstar"
92 | }]
93 | },
94 | "number": {
95 | "patterns": [{
96 | "match": "\\b(is|was|were) (?!and|as|nothing|nowhere|nobody|null|true|false|right|yes|ok|wrong|no|lies)(([a-z]+($|\\s))+)",
97 | "captures": {
98 | "1": {
99 | "name": "keyword.operator.rockstar"
100 | },
101 | "2": {
102 | "name": "constant.numeric.rockstar"
103 | }
104 | }
105 | }]
106 | },
107 | "string": {
108 | "patterns": [{
109 | "begin": "\"",
110 | "beginCaptures": {
111 | "0": {
112 | "name": "string.double.rockstar"
113 | }
114 | },
115 | "end": "\"",
116 | "endCaptures": {
117 | "0": {
118 | "name": "string.double.rockstar"
119 | }
120 | },
121 | "name": "string.double.rockstar"
122 | },
123 | {
124 | "match": "'\\w*'",
125 | "name": "string.double.rockstar"
126 | },
127 | {
128 | "match": ",",
129 | "scope": "string.double.rockstar"
130 | }
131 | ]
132 | },
133 | "equal": {
134 | "patterns": [{
135 | "match": "\\b('s|is( not($| +))?|ain't|was|were)\\b",
136 | "name": "keyword.operator.rockstar"
137 | }]
138 | },
139 | "comparator": {
140 | "patterns": [{
141 | "match": "(higher|greater|bigger|stronger|lower|less|smaller|weaker) than|as (high|great|big|strong|low|little|small|weak) as",
142 | "name": "keyword.operator.rockstar"
143 | }]
144 | },
145 | "loop": {
146 | "patterns": [{
147 | "match": "(^| )(While|Until|Continue|Break it down|break|Take it to the top)($| )",
148 | "name": "keyword.control.rockstar"
149 | }]
150 | },
151 | "conditional": {
152 | "patterns": [{
153 | "match": "(^| )(If|if|Else|else)",
154 | "name": "keyword.control.conditional.rockstar"
155 | }]
156 | },
157 | "method": {
158 | "patterns": [{
159 | "match": "\\b(taking|takes|and|Give back)\\b",
160 | "name": "keyword.other.rockstar"
161 | }]
162 | },
163 | "io": {
164 | "patterns": [{
165 | "match": "(^| )(Say|Shout|Whisper|Scream|Listen( to)?)",
166 | "name": "support.function.builtin.rockstar"
167 | }]
168 | },
169 | "assignment": {
170 | "patterns": [{
171 | "match": "((^Put\\b)|\\b(into)\\b)",
172 | "name": "keyword.operator.rockstar"
173 | }]
174 | },
175 | "arithmetic": {
176 | "patterns": [{
177 | "match": "(Knock | down|Build | up|plus|without|minus|with|times|of|over|by)",
178 | "name": "keyword.operator.arithmetic.rockstar"
179 | }]
180 | },
181 | "common": {
182 | "patterns": [{
183 | "match": "(?吾有 一 言 。 曰 「「春日宴。」」 。 書之 。
2 | 有數 九 。 名之曰 「酒數」 。
3 |
4 | 恆為是 。 若 「酒數」 等於 零 者乃止也 。
5 |
6 | 吾有 三 言 。 曰 「「與君」」 。 曰 「酒數」 。
7 | 曰 「「杯酒。可以窮歡宴。綠酒一杯歌一遍。」」 。 書之 。
8 |
9 | 減 「酒數」 以 一 。 昔之 「酒數」 者 。 今其是矣云云 。
10 |
11 | 吾有 一 言 。 曰 「「綠酒千杯腸已爛。」」 。 書之 。
--------------------------------------------------------------------------------
/packages/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "files": [],
4 | "references": [{ "path": "./shiki" }, { "path": "./renderer-svg" }]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/vuepress-plugin/README.md:
--------------------------------------------------------------------------------
1 | # vuepress-plugin-shiki
2 |
3 | ```bash
4 | yarn global add vuepress@next
5 | yarn add -D vuepress-plugin-shiki
6 | ```
7 |
8 | `.vuepress/config.js`
9 |
10 | ```js
11 | module.exports = {
12 | plugins: {
13 | shiki: { theme: 'nord' } // theme: TTheme
14 | }
15 | }
16 | ```
17 |
18 | [`TTheme` values](../themes/README.md#literal-values)
19 |
20 | ```ts
21 | export type TVSCode =
22 | | 'abyss'
23 | | 'dark_vs'
24 | | 'light_vs'
25 | | 'hc_black'
26 | | 'dark_plus'
27 | | 'light_plus'
28 | | 'kimbie_dark'
29 | | 'monokai'
30 | | 'monokai_dimmed'
31 | | 'quietlight'
32 | | 'red'
33 | | 'solarized_dark'
34 | | 'solarized_light'
35 |
36 | export type TMaterial =
37 | | 'Darker-High-Contrast'
38 | | 'Darker'
39 | | 'Default-High-Contrast'
40 | | 'Default'
41 | | 'Lighter-High-Contrast'
42 | | 'Lighter'
43 | | 'Ocean-High-Contrast'
44 | | 'Ocean'
45 | | 'Palenight-High-Contrast'
46 | | 'Palenight'
47 |
48 | export type TNice =
49 | | 'nord'
50 | | 'min-light'
51 | | 'min-dark'
52 | | 'white'
53 | | 'white-night'
54 |
55 | export type TTheme = TVSCode | TMaterial | TNice
56 | ```
--------------------------------------------------------------------------------
/packages/vuepress-plugin/index.js:
--------------------------------------------------------------------------------
1 | const shiki = require('shiki')
2 |
3 | let h
4 |
5 | module.exports = (options, ctx) => {
6 | return {
7 | async ready() {
8 | h = await shiki.getHighlighter({
9 | theme: options.theme ? options.theme : 'nord',
10 | langs: options.langs ? options.langs : []
11 | })
12 | },
13 |
14 | chainMarkdown(config) {
15 | config.options.highlight((code, lang) => {
16 | if (!lang) {
17 | return `${escapeHtml(code)}
`
18 | }
19 | return h.codeToHtml(code, lang)
20 | })
21 | }
22 | }
23 | }
24 |
25 | const htmlEscapes = {
26 | '&': '&',
27 | '<': '<',
28 | '>': '>',
29 | '"': '"',
30 | "'": '''
31 | }
32 |
33 | function escapeHtml(html) {
34 | return html.replace(/[&<>"']/g, chr => htmlEscapes[chr])
35 | }
36 |
--------------------------------------------------------------------------------
/packages/vuepress-plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vuepress-plugin-shiki",
3 | "private": true,
4 | "version": "0.9.5",
5 | "description": "Vuepress plugin for Shiki",
6 | "keywords": [
7 | "shiki",
8 | "vuepress",
9 | "vuepress-plugin",
10 | "syntax-highlighter",
11 | "highlighter"
12 | ],
13 | "author": "Pine Wu ",
14 | "homepage": "https://github.com/octref/shiki/tree/master/packages/vuepress-plugin",
15 | "license": "MIT",
16 | "main": "index.js",
17 | "repository": {
18 | "type": "git",
19 | "url": "git+https://github.com/octref/shiki.git"
20 | },
21 | "dependencies": {
22 | "shiki": "^0.9.5"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/scripts/grammars/normalizeGrammarPaths.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import { vscodeGrammarsToRemove, vscodeGrammarsToRename } from '../grammarSources'
4 | import chalk from 'chalk'
5 | import json5 from 'json5'
6 |
7 | const GRAMMAR_FOLDER_PATH = path.join(__dirname, '../..', 'tmp/grammars')
8 |
9 | /**
10 | * Remove unneeded grammars
11 | */
12 | let files = fs.readdirSync(GRAMMAR_FOLDER_PATH)
13 | for (let f of files) {
14 | const fName = f.replace(/\.tmLanguage.json$/i, '')
15 |
16 | if (vscodeGrammarsToRemove.includes(fName)) {
17 | const fPath = path.resolve(GRAMMAR_FOLDER_PATH, f)
18 | fs.unlinkSync(fPath)
19 | console.log(`${chalk.red('removed')} ${chalk.blue(fPath)}`)
20 | }
21 | }
22 |
23 | /**
24 | * Rename some grammars
25 | */
26 | files = fs.readdirSync(GRAMMAR_FOLDER_PATH)
27 | for (let f of files) {
28 | const fPath = path.resolve(GRAMMAR_FOLDER_PATH, f)
29 | const fName = f.replace(/\.tmLanguage.json$/i, '')
30 | if (vscodeGrammarsToRename[fName]) {
31 | const fNewPath = path.resolve(
32 | GRAMMAR_FOLDER_PATH,
33 | vscodeGrammarsToRename[fName] + '.tmLanguage.json'
34 | )
35 | fs.renameSync(fPath, fNewPath)
36 | console.log(
37 | `${chalk.red('renamed')} ${chalk.blue(f)} to ${chalk.blue(
38 | vscodeGrammarsToRename[fName] + '.tmLanguage.json'
39 | )}`
40 | )
41 | }
42 | }
43 |
44 | /**
45 | * - Make sure each grammar's file name matches its `name` key
46 | */
47 | files = fs.readdirSync(GRAMMAR_FOLDER_PATH)
48 | for (let f of files) {
49 | normalizeGrammarFile(f)
50 | }
51 |
52 | export function normalizeGrammarFile(f: string) {
53 | const fPath = path.resolve(GRAMMAR_FOLDER_PATH, f)
54 | const fNameWithoutSuffix = f.replace(/\.tmLanguage.json$/i, '')
55 | const fName = fNameWithoutSuffix.toLowerCase()
56 |
57 | if (fs.existsSync(fPath)) {
58 | const parsedContent = json5.parse(fs.readFileSync(fPath, 'utf-8'))
59 |
60 | if (parsedContent.name !== fName) {
61 | parsedContent.name = fName
62 | fs.writeFileSync(fPath, JSON.stringify(parsedContent, null, 2))
63 | console.log(`${chalk.red('normalized')} ${f}'s \`name\` to ${chalk.yellow(fName)}`)
64 | }
65 | if (fNameWithoutSuffix !== fNameWithoutSuffix.toLowerCase()) {
66 | const fNewPath = path.resolve(
67 | GRAMMAR_FOLDER_PATH,
68 | fNameWithoutSuffix.toLowerCase() + '.tmLanguage.json'
69 | )
70 | fs.renameSync(fPath, fNewPath)
71 | console.log(`${chalk.red('renamed')} ${chalk.blue(f)} to ${chalk.blue(f.toLowerCase())}`)
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/scripts/grammars/pullGrammarsFromGitHub.ts:
--------------------------------------------------------------------------------
1 | import { parse as plistParse } from 'fast-plist'
2 | import fs from 'fs'
3 | import yaml from 'js-yaml'
4 | import kebabCase from 'lodash.kebabcase'
5 | import path from 'path'
6 | import { githubGrammarSources } from '../grammarSources'
7 | import { convertGHURLToDownloadURL, get } from '../util/download'
8 | import json5 from 'json5'
9 | import chalk from 'chalk'
10 |
11 | const GRAMMAR_FOLDER_PATH = path.join(__dirname, '../..', 'tmp/grammars')
12 |
13 | async function go() {
14 | for (let urlOrNameWithUrl of githubGrammarSources) {
15 | await downloadGrammarFromGH(urlOrNameWithUrl)
16 | }
17 | }
18 |
19 | go()
20 |
21 | async function downloadGrammarFromGH(urlOrNameWithUrl: string | [string, string]) {
22 | const ghUrl = typeof urlOrNameWithUrl === 'string' ? urlOrNameWithUrl : urlOrNameWithUrl[1]
23 | const targetUrl = convertGHURLToDownloadURL(ghUrl)
24 |
25 | let content
26 | try {
27 | content = await get(targetUrl)
28 | } catch (e) {
29 | throw Error(`Failed to download grammar from ${ghUrl}: ${e}`)
30 | }
31 |
32 | let contentObj
33 | if (ghUrl.endsWith('.json')) {
34 | contentObj = json5.parse(content)
35 | } else if (ghUrl.endsWith('.plist')) {
36 | contentObj = plistParse(content)
37 | } else if (ghUrl.endsWith('.yml') || ghUrl.endsWith('.yaml')) {
38 | contentObj = yaml.load(content)
39 | } else {
40 | if (content[0] === '{') {
41 | contentObj = json5.parse(content)
42 | } else if (content[0] === '<') {
43 | contentObj = plistParse(content)
44 | } else {
45 | contentObj = yaml.load(content)
46 | }
47 | }
48 |
49 | /**
50 | * Make sure downloaded grammar has correct `name`
51 | */
52 | const specifiedLangId = typeof urlOrNameWithUrl === 'string' ? undefined : urlOrNameWithUrl[0]
53 | if (specifiedLangId) {
54 | contentObj['name'] = specifiedLangId
55 | }
56 |
57 | const newFileName = specifiedLangId
58 | ? specifiedLangId + '.tmLanguage.json'
59 | : kebabCase(contentObj['name'].toLowerCase()) + '.tmLanguage.json'
60 |
61 | /**
62 | * Write file
63 | */
64 | fs.writeFileSync(
65 | path.resolve(GRAMMAR_FOLDER_PATH, newFileName),
66 | JSON.stringify(contentObj, null, 2)
67 | )
68 | console.log(`Downloaded grammar: ${chalk.blue(newFileName)}`)
69 | }
70 |
--------------------------------------------------------------------------------
/scripts/grammars/updateGrammarSourceFiles.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import json5 from 'json5'
4 | import { embeddedLanguagesToExclude, languageAliases } from '../grammarSources'
5 |
6 | const langDir = path.resolve(__dirname, '../../packages/shiki/languages')
7 | const sampleDir = path.resolve(__dirname, '../../packages/shiki/samples')
8 | const langPath = path.resolve(__dirname, '../../packages/shiki/src/languages.ts')
9 | const readmePath = path.resolve(__dirname, '../../docs/languages.md')
10 |
11 | // Regex to quickly see if a grammar uses `include` keys to embed other languages
12 | const INCLUDE_REGEX = /"include": "([^#$].+)"/g
13 |
14 | const files = fs.readdirSync(langDir)
15 | const langIds = files.map(f => f.replace('.tmLanguage.json', ''))
16 | const scopeToIdMap = {}
17 | langIds
18 | .filter(id => !embeddedLanguagesToExclude.includes(id))
19 | .forEach(id => {
20 | const grammarPath = path.resolve(langDir, `${id}.tmLanguage.json`)
21 | const grammarSrc = fs.readFileSync(grammarPath, 'utf-8')
22 | const grammar = json5.parse(grammarSrc)
23 |
24 | scopeToIdMap[grammar.scopeName] = id
25 | })
26 |
27 | const langRegistrationContent = langIds
28 | .filter(id => !embeddedLanguagesToExclude.includes(id))
29 | .map(id => {
30 | const grammarPath = path.resolve(langDir, `${id}.tmLanguage.json`)
31 | const grammarSrc = fs.readFileSync(grammarPath, 'utf-8')
32 | const grammar = json5.parse(grammarSrc)
33 |
34 | let regContent = ` {
35 | id: '${id}',
36 | scopeName: '${grammar.scopeName}',
37 | path: '${id}.tmLanguage.json'`
38 |
39 | if (fs.existsSync(path.resolve(sampleDir, `${id}.sample`))) {
40 | regContent += `,
41 | samplePath: '${id}.sample'`
42 | }
43 |
44 | if (languageAliases[id]) {
45 | const aliasStr = languageAliases[id].map(a => `'` + a + `'`).join(', ')
46 | regContent += `,
47 | aliases: [${aliasStr}]`
48 | }
49 |
50 | const embeddedLangs = new Set()
51 | ;[...grammarSrc.matchAll(INCLUDE_REGEX)].forEach(([full, captured]) => {
52 | const scope = captured.split('#')[0]
53 | if (!grammar.scopeName || (grammar.scopeName && scope !== grammar.scopeName)) {
54 | if (scopeToIdMap[scope]) {
55 | embeddedLangs.add(scopeToIdMap[scope])
56 | }
57 | }
58 | })
59 | if (embeddedLangs.size > 0) {
60 | regContent += `,
61 | embeddedLangs: [${[...embeddedLangs].map(id => `'` + id + `'`).join(', ')}]`
62 | }
63 |
64 | regContent += `
65 | }`
66 |
67 | return regContent
68 | })
69 | .join(',\n')
70 |
71 | const langContent = `import { ILanguageRegistration } from './types'
72 |
73 | export type Lang =
74 | ${langIds
75 | .filter(id => !embeddedLanguagesToExclude.includes(id))
76 | .map(id => {
77 | if (!languageAliases[id]) {
78 | return ` | '${id}'`
79 | }
80 |
81 | const baseContent = ` | '${id}'`
82 | const aliasesContent = languageAliases[id].map(l => `'` + l + `'`).join(' | ')
83 | return `${baseContent} | ${aliasesContent}`
84 | })
85 | .join('\n')}
86 |
87 | export const languages: ILanguageRegistration[] = [
88 | ${langRegistrationContent}
89 | ]
90 | `
91 |
92 | fs.writeFileSync(langPath, langContent)
93 |
94 | const readmeReplaceContent = `export type Lang =
95 | ${langIds
96 | .filter(id => !embeddedLanguagesToExclude.includes(id))
97 | .map(id => {
98 | if (!languageAliases[id]) {
99 | return ` | '${id}'`
100 | }
101 |
102 | const baseContent = ` | '${id}'`
103 | const aliasesContent = languageAliases[id].map(l => `'` + l + `'`).join(' | ')
104 | return `${baseContent} | ${aliasesContent}`
105 | })
106 | .join('\n')}
107 | `
108 |
109 | const readmeSrc = fs.readFileSync(readmePath, 'utf-8')
110 | const newReadmeSrc = readmeSrc.replace(/## All Languages\n\n```ts([^`]+)```/, (_match, langs) => {
111 | return '## All Languages\n\n```ts\n' + readmeReplaceContent + '```'
112 | })
113 |
114 | fs.writeFileSync(readmePath, newReadmeSrc)
115 |
--------------------------------------------------------------------------------
/scripts/pullGrammars.sh:
--------------------------------------------------------------------------------
1 | # clean up
2 | rm -rf tmp/grammars
3 | mkdir -p tmp/grammars
4 |
5 | echo "> Getting VS Code grammars"
6 | if [ ! -d tmp/vscode ]; then
7 | git clone https://github.com/microsoft/vscode.git tmp/vscode --depth=1
8 | else
9 | (cd tmp/vscode && git checkout . && git pull)
10 | fi
11 | # Two html file will cause `cp` to fail
12 | mv tmp/vscode/extensions/php/syntaxes/html.tmLanguage.json tmp/vscode/extensions/php/syntaxes/php-html.tmLanguage.json
13 | cp tmp/vscode/extensions/**/syntaxes/*.json tmp/grammars
14 | echo "> Done getting VS Code grammars"
15 |
16 | echo "> Getting grammars from GitHub"
17 | npx esno scripts/grammars/pullGrammarsFromGitHub.ts
18 | echo "> Done getting grammars from GitHub"
19 |
20 | echo "> Normalizing grammars"
21 | npx esno scripts/grammars/normalizeGrammarPaths.ts
22 | echo "> Done normalizing grammars"
23 |
24 | echo "> Copying grammars"
25 | cp tmp/grammars/*.json packages/shiki/languages
26 | echo "> Done copying grammars"
27 |
28 | echo "> Updating source files"
29 | npx esno scripts/grammars/updateGrammarSourceFiles.ts
30 | echo "> Done updating source files"
31 |
32 | echo "> Formatting grammar files"
33 | npx prettier --write packages/shiki/languages/*
34 | echo "> Done formatting grammar files"
35 |
36 | echo "> All done"
37 |
--------------------------------------------------------------------------------
/scripts/pullThemes.sh:
--------------------------------------------------------------------------------
1 | # clean up
2 | rm -rf tmp/themes
3 | mkdir -p tmp/themes
4 |
5 | echo "> Getting VS Code themes"
6 | if [ ! -d tmp/vscode ]; then
7 | git clone https://github.com/microsoft/vscode.git tmp/vscode --depth=1
8 | else
9 | (cd tmp/vscode && git checkout . && git pull)
10 | fi
11 | cp tmp/vscode/extensions/theme-*/themes/*.json tmp/themes
12 | npx esno scripts/themes/processVSCThemes.ts
13 | echo "> Done getting VS Code themes"
14 |
15 | echo "> Getting themes from GitHub"
16 | npx esno scripts/themes/pullThemesFromGitHub.ts
17 | echo "> Done getting themes from GitHub"
18 |
19 | echo "> Getting themes from VS Code marketplace"
20 | npx esno scripts/themes/pullThemesFromMarketplace.ts
21 | echo "> Done getting themes from VS Code marketplace"
22 |
23 | echo "> Normalizing themes"
24 | npx esno scripts/themes/normalizeThemePaths.ts
25 | echo "> Done normalizing themes"
26 |
27 | echo "> Copying themes"
28 | cp tmp/themes/*.json packages/shiki/themes
29 | echo "> Done copying themes"
30 |
31 | echo "> Updating source files"
32 | npx esno scripts/themes/updateThemeSrc.ts
33 | echo "> Done updating source files"
34 |
35 | echo "> Formatting theme files"
36 | npx prettier --write packages/shiki/themes/*
37 | echo "> Done formatting theme files"
38 |
39 | echo "> All done"
40 |
--------------------------------------------------------------------------------
/scripts/themeSources.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * All themes in vscode are copied over, with some transformations
3 | */
4 |
5 | /**
6 | * Remove these themes bundled in vscode
7 | */
8 | export const vscodeThemesToRemove = [
9 | // Included in dark_plus
10 | 'dark_vs',
11 | // Included in light_plus
12 | 'light_vs',
13 | 'Red-color-theme',
14 | 'dimmed-monokai-color-theme',
15 | 'kimbie-dark-color-theme',
16 | 'quietlight-color-theme',
17 | 'abyss-color-theme',
18 | 'hc_black',
19 | 'tomorrow-night-blue-color-theme'
20 | ]
21 |
22 | /**
23 | * Rename these themes bundled in vscode
24 | */
25 | export const vscodeThemesToRename = {
26 | dark_plus: 'dark-plus',
27 | light_plus: 'light-plus',
28 | 'monokai-color-theme': 'monokai',
29 | 'solarized-dark-color-theme': 'solarized-dark',
30 | 'solarized-light-color-theme': 'solarized-light'
31 | }
32 |
33 | /**
34 | * All theme sources on github.com.
35 | *
36 | * To add one:
37 | * - Add the URL to the end
38 | * - Run `yarn update:themes`, examine the changes
39 | *
40 | * The theme id is normalized from the `name` key of the theme json file.
41 | * When the theme provides an undesirable name (or no `name` key), for example `Slack Theme Dark Mode` at
42 | * https://github.com/slack-theme/visual-studio-code/blob/f4c3c57d35b89874de3c96df551d6809a30a82d7/themes/dark-mode.json#L2
43 | * provide an array like `['slack-dark', '']` to name the theme `slack-dark`
44 | */
45 | export const githubThemeSources: (string | [string, string])[] = [
46 | [
47 | 'nord',
48 | 'https://github.com/arcticicestudio/nord-visual-studio-code/blob/develop/themes/nord-color-theme.json'
49 | ],
50 | 'https://github.com/misolori/min-theme/blob/master/themes/min-light.json',
51 | 'https://github.com/misolori/min-theme/blob/master/themes/min-dark.json',
52 | [
53 | 'slack-ochin',
54 | 'https://github.com/slack-theme/visual-studio-code/blob/master/themes/ochin.json'
55 | ],
56 | [
57 | 'slack-dark',
58 | 'https://github.com/slack-theme/visual-studio-code/blob/master/themes/dark-mode.json'
59 | ],
60 | [
61 | 'poimandres',
62 | 'https://github.com/drcmda/poimandres-theme/blob/main/themes/poimandres-color-theme.json'
63 | ]
64 | ]
65 |
66 | /**
67 | * Themes from VS Code marketplace
68 | * Some themes have compilation step and do not include the built theme on GitHub,
69 | * so pull from VS Code marketplace instead.
70 | *
71 | * Key is publisher + extId
72 | * Value is a list. Each item represents a file to extract from the downloaded VSIX.
73 | * If given a single path `extension/foo/bar.json`, extract `bar.json` to `tmp/themes/bar.json`
74 | * If given ['baz.json', `extension/foo/bar.json`], extract `bar.json` to `tmp/themes/baz.json`
75 | */
76 | export const marketplaceThemeSources: { [extPublisherAndId: string]: (string | string[])[] } = {
77 | 'equinusocio.vsc-material-theme': [
78 | ['material-darker.json', 'extension/build/themes/Material-Theme-Darker.json'],
79 | ['material-default.json', 'extension/build/themes/Material-Theme-Default.json'],
80 | ['material-lighter.json', 'extension/build/themes/Material-Theme-Lighter.json'],
81 | ['material-ocean.json', 'extension/build/themes/Material-Theme-Ocean.json'],
82 | ['material-palenight.json', 'extension/build/themes/Material-Theme-Palenight.json']
83 | ],
84 | 'dracula-theme.theme-dracula': [
85 | ['dracula.json', 'extension/theme/dracula.json'],
86 | ['dracula-soft.json', 'extension/theme/dracula-soft.json']
87 | ],
88 | 'GitHub.github-vscode-theme': [
89 | ['github-dark.json', 'extension/themes/dark.json'],
90 | ['github-light.json', 'extension/themes/light.json']
91 | ],
92 | 'antfu.theme-vitesse': [
93 | ['vitesse-dark.json', 'themes/vitesse-dark.json'],
94 | ['vitesse-light.json', 'themes/vitesse-light.json']
95 | ]
96 | }
97 |
--------------------------------------------------------------------------------
/scripts/themes/normalizeThemePaths.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import json5 from 'json5'
4 | import { vscodeThemesToRename, vscodeThemesToRemove } from '../themeSources'
5 | import chalk from 'chalk'
6 |
7 | const THEME_FOLDER_PATH = path.join(__dirname, '../..', 'tmp/themes')
8 |
9 | /**
10 | * Remove unneeded themes
11 | */
12 | let files = fs.readdirSync(THEME_FOLDER_PATH)
13 | for (let f of files) {
14 | const fName = f.replace(/\.json$/i, '')
15 |
16 | if (vscodeThemesToRemove.includes(fName)) {
17 | const fPath = path.resolve(THEME_FOLDER_PATH, f)
18 | fs.unlinkSync(fPath)
19 | console.log(`${chalk.red('removed')} ${chalk.blue(fPath)}`)
20 | }
21 | }
22 |
23 | /**
24 | * Rename some themes
25 | */
26 | files = fs.readdirSync(THEME_FOLDER_PATH)
27 | for (let f of files) {
28 | const fPath = path.resolve(THEME_FOLDER_PATH, f)
29 | const fName = f.replace(/\.json$/i, '')
30 | if (vscodeThemesToRename[fName]) {
31 | const fNewPath = path.resolve(THEME_FOLDER_PATH, vscodeThemesToRename[fName] + '.json')
32 | fs.renameSync(fPath, fNewPath)
33 | console.log(
34 | `${chalk.red('renamed')} ${chalk.blue(f)} to ${chalk.blue(
35 | vscodeThemesToRename[fName] + '.json'
36 | )}`
37 | )
38 | }
39 | }
40 |
41 | /**
42 | * - Make sure each theme's file name matches its `name` key
43 | */
44 | files = fs.readdirSync(THEME_FOLDER_PATH)
45 | for (let f of files) {
46 | normalizeThemeFile(f)
47 | }
48 |
49 | /**
50 | * - Make sure each theme's file name matches its `name` key
51 | */
52 | export function normalizeThemeFile(f: string) {
53 | const fPath = path.resolve(THEME_FOLDER_PATH, f)
54 | const fNameWithoutSuffix = f.replace(/\.json$/i, '')
55 | const fName = fNameWithoutSuffix.toLowerCase()
56 |
57 | if (fs.existsSync(fPath)) {
58 | const parsedContent = json5.parse(fs.readFileSync(fPath, 'utf-8'))
59 |
60 | if (!parsedContent.name || parsedContent.name !== fName) {
61 | parsedContent.name = fName
62 | fs.writeFileSync(fPath, JSON.stringify(parsedContent, null, 2))
63 | console.log(`${chalk.red('normalized')} ${f}'s \`name\` to ${chalk.yellow(fName)}`)
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/scripts/themes/processVSCThemes.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import json5 from 'json5'
4 |
5 | const THEME_FOLDER_PATH = path.join(__dirname, '../..', 'tmp/themes')
6 |
7 | function readJson5(f) {
8 | const p = path.resolve(THEME_FOLDER_PATH, f)
9 | if (!fs.existsSync(p)) {
10 | return undefined
11 | }
12 |
13 | return json5.parse(fs.readFileSync(p, 'utf-8'))
14 | }
15 |
16 | /**
17 | * Handle dark/light plus
18 | *
19 | * - Merge dark_vs into dark_plus
20 | * - Merge light_vs into light_plus
21 | * - Unshift `editor.foreground` and `editor.background` to beginning of `tokenColors`.
22 | * - Remove dark_vs and light_vs
23 | */
24 | const darkVSContent = readJson5('dark_vs.json')
25 | const darkPlusContent = readJson5('dark_plus.json')
26 |
27 | if (darkVSContent && darkPlusContent) {
28 | delete darkPlusContent['include']
29 | const darkDefaultFgBgTokenColor = {
30 | settings: {
31 | foreground: darkVSContent['colors']['editor.foreground']
32 | }
33 | }
34 | darkPlusContent.name = 'dark-plus'
35 | darkPlusContent.colors = { ...darkVSContent.colors }
36 | darkPlusContent.tokenColors = [
37 | darkDefaultFgBgTokenColor,
38 | ...darkVSContent.tokenColors,
39 | ...darkPlusContent.tokenColors
40 | ]
41 | darkPlusContent.semanticTokenColors = {
42 | ...darkVSContent.semanticTokenColors,
43 | ...darkPlusContent.semanticTokenColors
44 | }
45 |
46 | fs.writeFileSync(
47 | path.resolve(THEME_FOLDER_PATH, 'dark_plus.json'),
48 | JSON.stringify(darkPlusContent, null, 2)
49 | )
50 | }
51 |
52 | const lightVSContent = readJson5('light_vs.json')
53 | const lightPlusContent = readJson5('light_plus.json')
54 |
55 | if (lightVSContent && lightPlusContent) {
56 | delete lightPlusContent['include']
57 | const lightDefaultFgBgTokenColor = {
58 | settings: {
59 | foreground: lightVSContent['colors']['editor.foreground']
60 | }
61 | }
62 | lightPlusContent.name = 'light-plus'
63 | lightPlusContent.colors = { ...lightVSContent.colors }
64 | lightPlusContent.tokenColors = [
65 | lightDefaultFgBgTokenColor,
66 | ...lightVSContent.tokenColors,
67 | ...lightPlusContent.tokenColors
68 | ]
69 | lightPlusContent.semanticTokenColors = {
70 | ...lightVSContent.semanticTokenColors,
71 | ...lightPlusContent.semanticTokenColors
72 | }
73 |
74 | fs.writeFileSync(
75 | path.resolve(THEME_FOLDER_PATH, 'light_plus.json'),
76 | JSON.stringify(lightPlusContent, null, 2)
77 | )
78 | }
79 |
--------------------------------------------------------------------------------
/scripts/themes/pullThemesFromGitHub.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import json5 from 'json5'
3 | import kebabCase from 'lodash.kebabcase'
4 | import path from 'path'
5 | import { githubThemeSources } from '../themeSources'
6 | import { convertGHURLToDownloadURL, get } from '../util/download'
7 | import chalk from 'chalk'
8 |
9 | const THEME_FOLDER_PATH = path.join(__dirname, '../..', 'tmp/themes')
10 |
11 | async function go() {
12 | for (let urlOrNameWithUrl of githubThemeSources) {
13 | await downloadThemeFromGH(urlOrNameWithUrl)
14 | }
15 | }
16 |
17 | go()
18 |
19 | async function downloadThemeFromGH(urlOrNameWithUrl: string | [string, string]) {
20 | const ghUrl = typeof urlOrNameWithUrl === 'string' ? urlOrNameWithUrl : urlOrNameWithUrl[1]
21 | const targetUrl = convertGHURLToDownloadURL(ghUrl)
22 |
23 | let content
24 | try {
25 | content = await get(targetUrl)
26 | } catch (e) {
27 | throw Error(`Failed to download grammar from ${ghUrl}: ${e}`)
28 | }
29 |
30 | const contentObj = json5.parse(content)
31 |
32 | /**
33 | * Make sure downloaded theme has correct `name`
34 | */
35 | const specifiedLangId = typeof urlOrNameWithUrl === 'string' ? undefined : urlOrNameWithUrl[0]
36 | if (specifiedLangId) {
37 | contentObj['name'] = specifiedLangId
38 | }
39 |
40 | const newFileName = specifiedLangId
41 | ? specifiedLangId + '.json'
42 | : kebabCase(contentObj['name'].toLowerCase()) + '.json'
43 |
44 | /**
45 | * Write file
46 | */
47 | fs.writeFileSync(
48 | path.resolve(THEME_FOLDER_PATH, newFileName),
49 | JSON.stringify(contentObj, null, 2)
50 | )
51 | console.log(`Downloaded theme: ${chalk.blue(newFileName)}`)
52 | }
53 |
--------------------------------------------------------------------------------
/scripts/themes/pullThemesFromMarketplace.ts:
--------------------------------------------------------------------------------
1 | import { get } from '../util/download'
2 | import fs from 'fs'
3 | import unzipper from 'unzipper'
4 | import { marketplaceThemeSources } from '../themeSources'
5 | import chalk from 'chalk'
6 |
7 | go()
8 |
9 | async function go() {
10 | for (let [extFullId, fPaths] of Object.entries(marketplaceThemeSources)) {
11 | const [_publisher, extId] = extFullId.split('.')
12 | let content
13 | try {
14 | content = await get(getMarketplaceLink(extFullId), 'binary')
15 | } catch (e) {
16 | console.log(e)
17 | throw Error(`Failed`)
18 | }
19 |
20 | const zipPath = `tmp/${extId}.zip`
21 | fs.writeFileSync(zipPath, content)
22 |
23 | const zip = fs.createReadStream(zipPath).pipe(unzipper.Parse({ forceStream: true }))
24 |
25 | for await (const entry of zip) {
26 | const match = fPaths.filter(pathOrNameWithPath => {
27 | if (typeof pathOrNameWithPath === 'string') {
28 | return entry.path === pathOrNameWithPath
29 | } else {
30 | return entry.path === pathOrNameWithPath[1]
31 | }
32 | })
33 |
34 | if (match.length > 0) {
35 | const fName = typeof match[0] === 'string' ? entry.path.split('/').pop() : match[0][0]
36 |
37 | entry.pipe(fs.createWriteStream(`tmp/themes/${fName}`))
38 | console.log(
39 | `${chalk.red('extracted')} ${chalk.blue(fName)} from ${chalk.yellow(extFullId)}`
40 | )
41 | } else {
42 | entry.autodrain()
43 | }
44 | }
45 | }
46 | }
47 |
48 | function getMarketplaceLink(publisherDotExtId: string) {
49 | const [publisher, extId] = publisherDotExtId.split('.')
50 |
51 | return (
52 | `https://${publisher}.gallery.vsassets.io` +
53 | `/_apis/public/gallery/publisher/${publisher}` +
54 | `/extension/${extId}/latest` +
55 | `/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage`
56 | )
57 | }
58 |
--------------------------------------------------------------------------------
/scripts/themes/updateThemeSrc.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 |
4 | const themeDir = path.resolve(__dirname, '../../packages/shiki/themes')
5 | const themePath = path.resolve(__dirname, '../../packages/shiki/src/themes.ts')
6 | const readmePath = path.resolve(__dirname, '../../docs/themes.md')
7 |
8 | const files = fs.readdirSync(themeDir)
9 | const themeIds = files.map(f => f.replace('.json', ''))
10 |
11 | const themeContent = `export type Theme =
12 | ${themeIds.map(id => ` | '${id}'`).join('\n')}
13 |
14 | export const themes: Theme[] = [
15 | ${themeIds.map(id => ` '${id}'`).join(',\n')}
16 | ]
17 | `
18 |
19 | fs.writeFileSync(themePath, themeContent)
20 |
21 | const readmeReplaceContent = `export type Theme =
22 | ${themeIds.map(id => ` | '${id}'`).join('\n')}
23 | `
24 |
25 | const readmeSrc = fs.readFileSync(readmePath, 'utf-8')
26 | const newReadmeSrc = readmeSrc.replace(/## All Themes\n\n```ts([^`]+)```/, (_match, langs) => {
27 | return '## All Themes\n\n```ts\n' + readmeReplaceContent + '```'
28 | })
29 |
30 | fs.writeFileSync(readmePath, newReadmeSrc)
31 |
--------------------------------------------------------------------------------
/scripts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2017",
5 | "esModuleInterop": true,
6 | "moduleResolution": "node",
7 | "lib": ["esnext"],
8 | "sourceMap": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/scripts/util/download.ts:
--------------------------------------------------------------------------------
1 | import url from 'url'
2 | import https from 'https'
3 |
4 | export async function get(url: string, encoding: BufferEncoding = 'utf-8'): Promise {
5 | return new Promise((r, reject) => {
6 | https
7 | .get(url, res => {
8 | const { statusCode } = res
9 | if (statusCode !== 200) {
10 | reject('request failed')
11 | }
12 |
13 | res.setEncoding(encoding)
14 | if (encoding === 'utf-8') {
15 | let rawData = ''
16 | res.on('data', chunk => (rawData += chunk))
17 | res.on('end', () => {
18 | try {
19 | r(rawData)
20 | } catch (e) {
21 | console.log(e)
22 | reject('get failed')
23 | }
24 | })
25 | } else if (encoding === 'binary') {
26 | let data = []
27 | res.on('data', chunk => data.push(Buffer.from(chunk, 'binary')))
28 | res.on('end', function () {
29 | r(Buffer.concat(data))
30 | })
31 | res.on('error', function (err) {
32 | console.log(err)
33 | reject('get failed')
34 | })
35 | }
36 | })
37 | .on('error', e => {
38 | reject('get failed')
39 | })
40 | })
41 | }
42 |
43 | export function convertGHURLToDownloadURL(ghURL: string) {
44 | const oldPath = url.parse(ghURL).path
45 | return 'https://raw.githubusercontent.com' + oldPath.replace('/blob/', '/')
46 | }
47 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es5",
5 | "declaration": true,
6 | "esModuleInterop": true,
7 | "moduleResolution": "node",
8 | "lib": ["es2015", "es2016.array.include", "DOM", "WebWorker"],
9 | "sourceMap": true
10 | },
11 | "references": [{ "path": "packages/shiki" }, { "path": "packages/renderer-svg" }]
12 | }
13 |
--------------------------------------------------------------------------------