├── .eslintignore ├── .eslintrc.cjs ├── .github ├── actions │ └── build │ │ └── action.yml ├── highlighter_512.jpg └── workflows │ ├── pipeline.yml │ └── release.yml ├── .gitignore ├── .husky └── pre-commit ├── .prettierignore ├── .prettierrc ├── .vscode ├── launch.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── api-extractor.json ├── docs ├── highlighter.createhighlighter.md ├── highlighter.md ├── highlighter.mdvexhighlighter.md ├── highlighter.parsemetadata.md ├── highlighter.tmetadata.md └── index.md ├── etc └── highlighter.api.md ├── lint-staged.config.cjs ├── package.json ├── rollup.config.js ├── scripts ├── build-docs.sh ├── build-pkg.js ├── build-pkg.sh ├── build-types.js ├── build-types.sh ├── esm.sh ├── rollup │ ├── cjs.js │ ├── config.js │ └── getBundleBanner.mjs └── utils │ └── exec.js ├── setupTests.js ├── ship.config.cjs ├── src ├── highlighter │ ├── default-render-options.ts │ ├── hast-utils.ts │ ├── highlighter.ts │ ├── index.ts │ ├── render-to-hast.ts │ ├── tsconfig.json │ ├── types.ts │ └── utils.ts ├── index.ts ├── parse-metadata │ ├── index.ts │ ├── lexer.ts │ ├── parse-metadata.ts │ ├── tsconfig.json │ └── types.ts ├── tsconfig.base.json └── tsconfig.json ├── tests ├── __snapshots__ │ ├── highlighter-fixtures.test.ts.snap │ ├── metadata-lexer.test.ts.snap │ └── render-to-hast.test.ts.snap ├── fixtures │ ├── fixture.c │ ├── fixture.cpp │ ├── fixture.css │ ├── fixture.html │ ├── fixture.js │ ├── fixture.rb │ ├── fixture.sh │ ├── fixture.ts │ └── fixture.txt ├── highlighter-fixtures.test.ts ├── highlighter.test.ts ├── metadata-lexer.test.ts ├── parse-metadata.test.ts ├── render-to-hast.test.ts ├── tsconfig.json └── utils │ └── run-fixture.ts ├── tsconfig.tsbuildinfo ├── vitest.config.js └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | build 5 | dist 6 | lib 7 | temp 8 | 9 | tests/fixtures 10 | 11 | .env 12 | .env.* 13 | !.env.example 14 | 15 | # Ignore files for PNPM, NPM and YARN 16 | pnpm-lock.yaml 17 | package-lock.json 18 | yarn.lock 19 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "eslint:recommended", 5 | "plugin:@typescript-eslint/recommended", 6 | "plugin:import/recommended", 7 | "plugin:import/typescript", 8 | "prettier", 9 | ], 10 | plugins: ["@typescript-eslint"], 11 | ignorePatterns: ["*.cjs"], 12 | rules: { 13 | "import/order": [ 14 | "error", 15 | { 16 | alphabetize: { 17 | order: "asc", 18 | caseInsensitive: true, 19 | }, 20 | "newlines-between": "always", 21 | groups: ["builtin", "external", "parent", "sibling", "index"], 22 | pathGroupsExcludedImportTypes: ["builtin"], 23 | }, 24 | ], 25 | }, 26 | settings: { 27 | "import/parsers": { 28 | "@typescript-eslint/parser": [".ts"], 29 | }, 30 | "import/resolver": { 31 | typescript: { 32 | alwaysTryTypes: true, 33 | projects: ["./"], 34 | }, 35 | }, 36 | }, 37 | parserOptions: { 38 | sourceType: "module", 39 | ecmaVersion: 2020, 40 | }, 41 | env: { 42 | browser: true, 43 | es2017: true, 44 | node: true, 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /.github/actions/build/action.yml: -------------------------------------------------------------------------------- 1 | name: Build application 2 | 3 | runs: 4 | using: "composite" 5 | steps: 6 | - name: Setup Node 7 | uses: actions/setup-node@v3 8 | with: 9 | node-version: "16" 10 | 11 | - name: Install specific Yarn version 12 | shell: bash 13 | run: | 14 | curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.22.19 15 | echo 'export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"' >> $GITHUB_PATH 16 | 17 | - name: Get yarn cache directory path 18 | id: yarn-cache-dir-path 19 | shell: bash 20 | run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT 21 | 22 | - name: Cache node_modules 23 | uses: actions/cache@v3 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 | - name: Install Packages 32 | shell: bash 33 | run: yarn install --frozen-lockfile 34 | 35 | - name: Build application 36 | shell: bash 37 | run: yarn build 38 | 39 | - name: Test application 40 | shell: bash 41 | run: yarn test 42 | 43 | - name: Lint application 44 | shell: bash 45 | run: yarn lint 46 | 47 | - name: Type check application 48 | shell: bash 49 | run: yarn run check 50 | -------------------------------------------------------------------------------- /.github/highlighter_512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnhooks/highlighter/4e9c0bafb9927fcd15ce8e9a33e9b65daea8e4c0/.github/highlighter_512.jpg -------------------------------------------------------------------------------- /.github/workflows/pipeline.yml: -------------------------------------------------------------------------------- 1 | name: Run build pipeline 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: [opened, synchronize, reopened] 7 | branches: 8 | - "**/*" 9 | 10 | env: 11 | # Used by scripts/build-types.sh 12 | CI: true 13 | 14 | jobs: 15 | pipeline: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | 21 | - name: Build application 22 | uses: ./.github/actions/build 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release if needed 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | 9 | env: 10 | # Used by scripts/build-types.sh 11 | CI: true 12 | 13 | jobs: 14 | release: 15 | runs-on: ubuntu-latest 16 | environment: production 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | 21 | - name: Build application 22 | uses: ./.github/actions/build 23 | 24 | - name: Release if needed 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 28 | shell: bash 29 | run: | 30 | git config --global user.email "bitmachina@outlook.com" 31 | git config --global user.name "John Hooks" 32 | yarn run shipjs trigger 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | build 5 | dist 6 | lib 7 | temp 8 | 9 | .env 10 | .env.* 11 | !.env.example 12 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | build 5 | dist 6 | lib 7 | temp 8 | 9 | tests/fixtures 10 | 11 | **/*.md 12 | 13 | .env 14 | .env.* 15 | !.env.example 16 | 17 | # Ignore files for PNPM, NPM and YARN 18 | pnpm-lock.yaml 19 | package-lock.json 20 | yarn.lock 21 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "singleQuote": false, 4 | "semi": true, 5 | "trailingComma": "es5", 6 | "printWidth": 100, 7 | "proseWrap": "never", 8 | "pluginSearchDirs": ["."], 9 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "skipFiles": ["/**"], 12 | "program": "${workspaceFolder}/scratch.js" 13 | }, 14 | { 15 | "type": "node", 16 | "request": "launch", 17 | "name": "Debug Current Test File", 18 | "autoAttachChildProcesses": true, 19 | "skipFiles": ["/**", "**/node_modules/**"], 20 | "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs", 21 | "args": ["run", "${relativeFile}"], 22 | "smartStep": true, 23 | "console": "integratedTerminal" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "editor.insertSpaces": true, 4 | "editor.rulers": [84], 5 | "editor.formatOnSave": true, 6 | "files.encoding": "utf8", 7 | "files.trimTrailingWhitespace": true, 8 | "files.insertFinalNewline": true, 9 | "files.exclude": { 10 | "**/node_modules": true, 11 | "**/tsconfig.tsbuildinfo": true 12 | }, 13 | "search.exclude": { 14 | "dist/**": true, 15 | "lib/**": true, 16 | "node_modules/**": true, 17 | "package-lock.json": true 18 | }, 19 | "editor.quickSuggestionsDelay": 1000, 20 | "[javascript]": { 21 | "editor.formatOnSave": true, 22 | "editor.defaultFormatter": "esbenp.prettier-vscode" 23 | }, 24 | "[javascript-react]": { 25 | "editor.formatOnSave": true, 26 | "editor.defaultFormatter": "esbenp.prettier-vscode" 27 | }, 28 | "[typescript]": { 29 | "editor.formatOnSave": true, 30 | "editor.defaultFormatter": "esbenp.prettier-vscode" 31 | }, 32 | "[typescript-react]": { 33 | "editor.formatOnSave": true, 34 | "editor.defaultFormatter": "esbenp.prettier-vscode" 35 | }, 36 | "typescript.autoClosingTags": false, 37 | "typescript.suggest.completeJSDocs": false, 38 | "typescript.disableAutomaticTypeAcquisition": true, 39 | "cSpell.words": ["dev", "hastscript", "mdsvex", "rehype", "shiki"], 40 | "cSpell.ignorePaths": [ 41 | "**/package-lock.json", 42 | "**/.svelte-kit/**", 43 | "**/build/**", 44 | "**/node_modules/**", 45 | "**/vscode-extension/**", 46 | "**/.git/objects/**", 47 | "./vscode/**" 48 | ], 49 | "typescript.tsdk": "node_modules/typescript/lib" 50 | } 51 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [1.0.0-alpha.6](https://github.com/johnhooks/highlighter/compare/v1.0.0-alpha.5...v1.0.0-alpha.6) (2023-01-03) 2 | 3 | 4 | ### Features 5 | 6 | * simplify api ([b08ef67](https://github.com/johnhooks/highlighter/commit/b08ef67d7e399e5880c5436f4041a53dc477627a)) 7 | 8 | 9 | ### BREAKING CHANGES 10 | 11 | * public api has less exposed. 12 | 13 | 14 | 15 | # 1.0.0-alpha.5 (2023-01-02) 16 | 17 | - Fix double HTML escape issue. 18 | - Rename public types. 19 | - Add release github workflow 20 | 21 | # 1.0.0-alpha.4 (2022-12-29) 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022—2023 John Hooks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | The triple backtick highlighter logo 4 | 5 |

6 | 7 |

8 | Highlight code in MDsveX with Shiki 9 |

10 | 11 | > Use [Shiki](https://shiki.matsu.io/) to highlight code blocks in [MDSvex](https://mdsvex.com/) files. 12 | 13 | ## 📦 Install 14 | 15 | ```sh 16 | npm install @bitmachina/highlighter@alpha 17 | 18 | # or 19 | 20 | yarn add @bitmachina/highlighter@alpha 21 | ``` 22 | 23 | ## ⚡️ Quick start 24 | 25 | The `createHighlighter` function takes an argument of Shiki `HighlighterOptions`. 26 | 27 | Any [Shiki theme](https://github.com/shikijs/shiki/blob/main/docs/themes.md#all-themes) can be used. This example uses the `css-variables` theme, which is really flexible. 28 | 29 | ```js 30 | // mdsvex.config.js 31 | import { createHighlighter } from "@bitmachina/highlighter"; 32 | 33 | /** @type {import('mdsvex').MdsvexOptions} */ 34 | export default { 35 | extensions: [".svelte.md", ".md", ".svx"], 36 | highlight: { 37 | highlighter: await createHighlighter({ theme: "css-variables" }), 38 | }, 39 | }; 40 | ``` 41 | 42 | ## 📚 Documentation 43 | 44 | Visit the [full documentation](https://johnhooks.io/projects/highlighter) to know more. 45 | 46 | ## License 47 | 48 | [MIT](https://github.com/johnhooks/highlighter/blob/main/LICENSE) @ [John Hooks](https://github.com/johnhooks) 49 | -------------------------------------------------------------------------------- /api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 3 | "projectFolder": ".", 4 | "mainEntryPointFilePath": "/build/index.d.ts", 5 | "bundledPackages": [], 6 | "compiler": { 7 | "tsconfigFilePath": "./src/tsconfig.json" 8 | }, 9 | "apiReport": { 10 | "enabled": true 11 | }, 12 | "docModel": { 13 | "enabled": true 14 | }, 15 | "dtsRollup": { 16 | "enabled": true, 17 | "untrimmedFilePath": "", 18 | "publicTrimmedFilePath": "/dist/index.d.ts" 19 | }, 20 | "tsdocMetadata": { 21 | "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" 22 | }, 23 | "newlineKind": "lf", 24 | "messages": { 25 | "compilerMessageReporting": { 26 | "default": { 27 | "logLevel": "warning" 28 | } 29 | }, 30 | "extractorMessageReporting": { 31 | "default": { 32 | "logLevel": "warning" 33 | } 34 | }, 35 | "tsdocMessageReporting": { 36 | "default": { 37 | "logLevel": "warning" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/highlighter.createhighlighter.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [@bitmachina/highlighter](./highlighter.md) > [createHighlighter](./highlighter.createhighlighter.md) 4 | 5 | ## createHighlighter() function 6 | 7 | Create MDsveX code highlighting function. 8 | 9 | Signature: 10 | 11 | ```typescript 12 | export declare function createHighlighter(options: HighlighterOptions): Promise; 13 | ``` 14 | 15 | ## Parameters 16 | 17 | | Parameter | Type | Description | 18 | | --- | --- | --- | 19 | | options | HighlighterOptions | Shiki highlighter options object. | 20 | 21 | Returns: 22 | 23 | Promise<[MdvexHighlighter](./highlighter.mdvexhighlighter.md)> 24 | 25 | A Promise of a MDsvex highlighter function. 26 | 27 | -------------------------------------------------------------------------------- /docs/highlighter.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [@bitmachina/highlighter](./highlighter.md) 4 | 5 | ## highlighter package 6 | 7 | ## Functions 8 | 9 | | Function | Description | 10 | | --- | --- | 11 | | [createHighlighter(options)](./highlighter.createhighlighter.md) | Create MDsveX code highlighting function. | 12 | | [parseMetadata(metastring)](./highlighter.parsemetadata.md) | Parse Markdown code fence metadata. | 13 | 14 | ## Type Aliases 15 | 16 | | Type Alias | Description | 17 | | --- | --- | 18 | | [MdvexHighlighter](./highlighter.mdvexhighlighter.md) |

MDsveX highlighter type.

NOTE: not exported from mdsvex, so its copied here.

| 19 | | [TMetadata](./highlighter.tmetadata.md) | Markdown Code Block Metadata | 20 | 21 | -------------------------------------------------------------------------------- /docs/highlighter.mdvexhighlighter.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [@bitmachina/highlighter](./highlighter.md) > [MdvexHighlighter](./highlighter.mdvexhighlighter.md) 4 | 5 | ## MdvexHighlighter type 6 | 7 | MDsveX highlighter type. 8 | 9 | NOTE: not exported from `mdsvex`, so its copied here. 10 | 11 | Signature: 12 | 13 | ```typescript 14 | export type MdvexHighlighter = (code: string, lang: string | undefined, metastring?: string | undefined) => string | Promise; 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/highlighter.parsemetadata.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [@bitmachina/highlighter](./highlighter.md) > [parseMetadata](./highlighter.parsemetadata.md) 4 | 5 | ## parseMetadata() function 6 | 7 | Parse Markdown code fence metadata. 8 | 9 | Signature: 10 | 11 | ```typescript 12 | export declare function parseMetadata(metastring: string | undefined): TMetadata; 13 | ``` 14 | 15 | ## Parameters 16 | 17 | | Parameter | Type | Description | 18 | | --- | --- | --- | 19 | | metastring | string \| undefined | Code block metadata string. | 20 | 21 | Returns: 22 | 23 | [TMetadata](./highlighter.tmetadata.md) 24 | 25 | Parsed metadata values object. 26 | 27 | -------------------------------------------------------------------------------- /docs/highlighter.tmetadata.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [@bitmachina/highlighter](./highlighter.md) > [TMetadata](./highlighter.tmetadata.md) 4 | 5 | ## TMetadata type 6 | 7 | Markdown Code Block Metadata 8 | 9 | Signature: 10 | 11 | ```typescript 12 | export type TMetadata = { 13 | lineNumbers: number[]; 14 | lineNumbersStart: number; 15 | showLineNumbers: boolean; 16 | title?: string | undefined; 17 | lang?: string | undefined; 18 | }; 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) 4 | 5 | ## API Reference 6 | 7 | ## Packages 8 | 9 | | Package | Description | 10 | | --- | --- | 11 | | [@bitmachina/highlighter](./highlighter.md) | | 12 | 13 | -------------------------------------------------------------------------------- /etc/highlighter.api.md: -------------------------------------------------------------------------------- 1 | ## API Report File for "@bitmachina/highlighter" 2 | 3 | > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). 4 | 5 | ```ts 6 | 7 | import { HighlighterOptions } from 'shiki'; 8 | 9 | // @public 10 | export function createHighlighter(options: HighlighterOptions): Promise; 11 | 12 | // @public 13 | export type MdvexHighlighter = (code: string, lang: string | undefined, metastring?: string | undefined) => string | Promise; 14 | 15 | // @public 16 | export function parseMetadata(metastring: string | undefined): TMetadata; 17 | 18 | // @public 19 | export type TMetadata = { 20 | lineNumbers: number[]; 21 | lineNumbersStart: number; 22 | showLineNumbers: boolean; 23 | title?: string | undefined; 24 | lang?: string | undefined; 25 | }; 26 | 27 | // @public (undocumented) 28 | export type TMetaToken = { 29 | value: string; 30 | start: number; 31 | end: number; 32 | type: "identifier" | "literal" | "symbol"; 33 | }; 34 | 35 | // (No @packageDocumentation comment for this package) 36 | 37 | ``` 38 | -------------------------------------------------------------------------------- /lint-staged.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "**/*.ts": () => "yarn run check", 3 | "**/*.(js|cjs|mjs|ts)": (filenames) => [ 4 | `eslint --ext .js,.cjs,.mjs,.ts --fix ${filenames.join(" ")}`, 5 | `prettier --write ${filenames.join(" ")}`, 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@bitmachina/highlighter", 3 | "version": "1.0.0-alpha.7", 4 | "type": "module", 5 | "description": "Highlight MDsveX files with the Shiki highlighter", 6 | "keywords": [ 7 | "mdsvex", 8 | "shiki", 9 | "highlight", 10 | "svelte", 11 | "markdown" 12 | ], 13 | "homepage": "https://johnhooks/projects/highlighter", 14 | "bugs": "https://github.com/johnhooks/highlighter/issues", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/johnhooks/highlighter.git" 18 | }, 19 | "author": { 20 | "name": "John Hooks", 21 | "url": "https://johnhooks.io" 22 | }, 23 | "license": "MIT", 24 | "sideEffects": false, 25 | "main": "dist/esm/highlighter/index.js", 26 | "module": "dist/esm/highlighter/index.js", 27 | "source": "src/index.ts", 28 | "types": "dist/index.d.ts", 29 | "files": [ 30 | "dist/" 31 | ], 32 | "scripts": { 33 | "clean": "rimraf ./{dist,temp}", 34 | "clean:tsc": "rimraf ./build", 35 | "clean:all": "yarn clean && yarn clean:tsc", 36 | "build:all": "yarn build && yarn generate:docs", 37 | "build:esm": "./scripts/esm.sh", 38 | "build:tsc": "tsc --build ./src", 39 | "build:types": "./scripts/build-types.sh", 40 | "build:umd:cjs": "rollup --config", 41 | "build": "./scripts/build-pkg.sh", 42 | "check": "tsc --build ./src && tsc --project ./tests", 43 | "generate:docs": "./scripts/build-docs.sh", 44 | "lint": "eslint --ext .js,.ts .", 45 | "prepare": "husky install", 46 | "release": "shipjs prepare", 47 | "test": "vitest run" 48 | }, 49 | "dependencies": { 50 | "hast-util-to-string": "2.0.0", 51 | "parse-numeric-range": "1.3.0", 52 | "property-information": "6.2.0", 53 | "rehype-parse": "8.0.4", 54 | "shiki": "0.11.1", 55 | "unified": "10.1.2", 56 | "unist-util-visit": "4.1.1" 57 | }, 58 | "devDependencies": { 59 | "@microsoft/api-documenter": "7.19.27", 60 | "@microsoft/api-extractor": "7.33.7", 61 | "@rollup/plugin-json": "6.0.0", 62 | "@rollup/plugin-node-resolve": "15.0.1", 63 | "@rollup/plugin-replace": "5.0.2", 64 | "@rollup/plugin-sucrase": "5.0.1", 65 | "@rollup/plugin-terser": "0.2.1", 66 | "@testing-library/dom": "8.19.1", 67 | "@testing-library/jest-dom": "5.16.5", 68 | "@types/hast": "2.3.4", 69 | "@types/node": "18.11.11", 70 | "@types/testing-library__jest-dom": "5.14.5", 71 | "@typescript-eslint/eslint-plugin": "5.46.1", 72 | "@typescript-eslint/parser": "5.46.1", 73 | "eslint": "8.29.0", 74 | "eslint-config-prettier": "8.5.0", 75 | "eslint-import-resolver-typescript": "3.5.2", 76 | "eslint-plugin-import": "2.26.0", 77 | "eslint-plugin-jest-dom": "4.0.3", 78 | "eslint-plugin-testing-library": "5.9.1", 79 | "husky": "8.0.2", 80 | "jsdom": "20.0.3", 81 | "lint-staged": "13.1.0", 82 | "prettier": "2.8.1", 83 | "rollup-plugin-filesize": "9.1.2", 84 | "shipjs": "0.25.1", 85 | "ts-node": "10.9.1", 86 | "tslib": "2.4.1", 87 | "typescript": "4.9.4", 88 | "vite": "4.0.3", 89 | "vitest": "0.25.8" 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import pkg from "./package.json" assert { type: "json" }; 2 | import { createRollupConfigs } from "./scripts/rollup/config.js"; 3 | 4 | export default createRollupConfigs({ pkg, index: "./src/highlighter/index.ts" }); 5 | -------------------------------------------------------------------------------- /scripts/build-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! [ -e ./temp/highlighter.api.json ] ; then 4 | echo "api.json file missing, building package..." 5 | ./scripts/build-pkg.sh 6 | fi 7 | 8 | 9 | ./node_modules/.bin/api-documenter markdown -i ./temp -o ./docs 10 | -------------------------------------------------------------------------------- /scripts/build-pkg.js: -------------------------------------------------------------------------------- 1 | import { exec } from "./utils/exec.js"; 2 | 3 | if (!process.env.CI) { 4 | await exec("yarn", ["clean:all"]); 5 | } 6 | 7 | try { 8 | await exec("yarn", ["build:tsc"]); 9 | await exec("yarn", ["build:esm"]); 10 | await exec("yarn", ["build:types"]); 11 | } catch (code) { 12 | process.exit(code); 13 | } 14 | 15 | process.exit(0); 16 | -------------------------------------------------------------------------------- /scripts/build-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: Build the package. 4 | 5 | # If not in CI environment, clean for a fresh build. 6 | if [ -z $CI ] || [ $CI = false ] ; then 7 | yarn clean:all 8 | fi 9 | 10 | yarn build:tsc 11 | yarn build:esm 12 | yarn build:types 13 | -------------------------------------------------------------------------------- /scripts/build-types.js: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import * as url from "url"; 3 | 4 | import { exec } from "./utils/exec.js"; 5 | 6 | const apiExtractorPath = path.resolve( 7 | url.fileURLToPath(new URL(".", import.meta.url)), 8 | "../node_modules/.bin/api-extractor" 9 | ); 10 | 11 | // Strip `--local` out. It will be configured only by this script. 12 | const args = process.argv.slice(2).filter((arg) => arg !== "--local"); 13 | 14 | // When in CI, `api-extractor` shouldn't apply the local flag. This script will 15 | // error if an API change occurs without being committed in an `api.md` file. 16 | const localFlag = process.env.CI ? [] : ["--local"]; 17 | 18 | /** 19 | * ApiExtractor CLI arguments. 20 | */ 21 | const apiExtractorArgs = ["run", ...args, ...localFlag]; 22 | 23 | console.log(`api-extractor ${apiExtractorArgs.join(" ")}`); 24 | 25 | exec(apiExtractorPath, apiExtractorArgs) 26 | .then(() => process.exit(0)) 27 | .catch((code) => { 28 | process.exit(code); 29 | }); 30 | -------------------------------------------------------------------------------- /scripts/build-types.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | args=() 4 | 5 | if [ -z $CI ] || [ $CI = false ] ; then 6 | # Add `--local` flag if not present and not in CI 7 | args=$@ 8 | if [[ ! " ${args[*]} " =~ " --local " ]] ; then 9 | args+=("--local") 10 | fi 11 | elif [ $CI = true ] ; then 12 | # Strip out `--local` flag in CI 13 | for arg in "$@" ; do 14 | case "$arg" in 15 | '--local') 16 | true 17 | ;; 18 | *) 19 | args+=($arg) 20 | ;; 21 | esac 22 | done 23 | fi 24 | 25 | echo "api-extractor run ${args[@]}" 26 | ./node_modules/.bin/api-extractor run ${args[@]} 27 | -------------------------------------------------------------------------------- /scripts/esm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "copying ./build/**/*.js to ./dist/esm/" 4 | mkdir -p dist/esm 5 | rsync -a --prune-empty-dirs --include '*/' --include '*.js' --exclude '*' build/ dist/esm 6 | -------------------------------------------------------------------------------- /scripts/rollup/cjs.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV === "production") { 2 | module.exports = require(`./__BUNDLE__.production.js`); 3 | } else { 4 | module.exports = require(`./__BUNDLE__.development.js`); 5 | } 6 | -------------------------------------------------------------------------------- /scripts/rollup/config.js: -------------------------------------------------------------------------------- 1 | import json from "@rollup/plugin-json"; 2 | import resolve from "@rollup/plugin-node-resolve"; 3 | import replace from "@rollup/plugin-replace"; 4 | import sucrase from "@rollup/plugin-sucrase"; 5 | import terser from "@rollup/plugin-terser"; 6 | import filesize from "rollup-plugin-filesize"; 7 | 8 | import { getBundleBanner } from "./getBundleBanner.mjs"; 9 | 10 | const BUILD_MODES = ["development", "production"]; 11 | const extensions = [".js", ".ts", ".json"]; 12 | 13 | function createRollupConfig({ mode, format, input, pkg, config }) { 14 | if (!BUILD_MODES.includes(mode)) { 15 | throw new Error(`The Rollup configuration ${JSON.stringify(mode)} mode is not supported.`); 16 | } 17 | 18 | const bundles = []; 19 | 20 | if (format === "cjs") { 21 | bundles.push({ 22 | ...config, 23 | input: "../../scripts/rollup/cjs.js", 24 | output: { 25 | file: `dist/cjs/${input}.js`, 26 | format, 27 | sourcemap: false, 28 | ...config.output, 29 | }, 30 | plugins: [ 31 | replace({ 32 | preventAssignment: false, 33 | delimiters: ["", ""], 34 | values: { 35 | __BUNDLE__: input, 36 | }, 37 | }), 38 | json(), 39 | resolve({ 40 | extensions, 41 | }), 42 | sucrase({ 43 | exclude: ["node_modules/**"], 44 | transforms: ["typescript"], 45 | }), 46 | filesize({ 47 | showMinifiedSize: false, 48 | showGzippedSize: true, 49 | }), 50 | ...(config.plugins || []), 51 | ].filter(Boolean), 52 | }); 53 | } 54 | 55 | bundles.push({ 56 | ...config, 57 | input: `src/${input}.ts`, 58 | output: { 59 | file: `dist/${format}/${input}.${mode}.js`, 60 | format, 61 | sourcemap: true, 62 | name: pkg.name, 63 | banner: getBundleBanner(pkg), 64 | ...config.output, 65 | }, 66 | plugins: [ 67 | replace({ 68 | preventAssignment: false, 69 | delimiters: ["", ""], 70 | values: { 71 | "process.env.NODE_ENV": JSON.stringify(mode), 72 | "@dinerojs": "@dinero.js", 73 | }, 74 | }), 75 | json(), 76 | resolve({ 77 | extensions, 78 | }), 79 | sucrase({ 80 | exclude: ["node_modules/**"], 81 | transforms: ["typescript"], 82 | }), 83 | mode === "production" && terser({ sourceMap: true }), 84 | filesize({ 85 | showMinifiedSize: false, 86 | showGzippedSize: true, 87 | }), 88 | ...(config.plugins || []), 89 | ].filter(Boolean), 90 | }); 91 | 92 | return bundles; 93 | } 94 | 95 | export function createRollupConfigs({ pkg, inputs = ["index"], config = {} }) { 96 | return inputs 97 | .map((input) => { 98 | return [ 99 | createRollupConfig({ 100 | mode: "development", 101 | format: "umd", 102 | input, 103 | pkg, 104 | config, 105 | }), 106 | createRollupConfig({ 107 | mode: "production", 108 | format: "umd", 109 | input, 110 | pkg, 111 | config, 112 | }), 113 | createRollupConfig({ 114 | mode: "development", 115 | format: "cjs", 116 | input, 117 | pkg, 118 | config, 119 | }), 120 | createRollupConfig({ 121 | mode: "production", 122 | format: "cjs", 123 | input, 124 | pkg, 125 | config, 126 | }), 127 | ]; 128 | }) 129 | .flat(2); 130 | } 131 | -------------------------------------------------------------------------------- /scripts/rollup/getBundleBanner.mjs: -------------------------------------------------------------------------------- 1 | import { execSync } from "child_process"; 2 | 3 | export function getBundleBanner(pkg) { 4 | const lastCommitHash = execSync("git rev-parse --short HEAD").toString().trim(); 5 | const version = process.env.SHIPJS 6 | ? pkg.version 7 | : `${pkg.version} (UNRELEASED ${lastCommitHash})`; 8 | const authors = `© ${pkg.author.name} and contributors`; 9 | 10 | return `/*! ${pkg.name} ${version} | MIT License | ${authors} | ${pkg.homepage} */`; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/utils/exec.js: -------------------------------------------------------------------------------- 1 | import { spawn } from "node:child_process"; 2 | 3 | /** 4 | * Async `exec`. 5 | * 6 | * Inspired by `remix-run` build [scripts](https://github.com/remix-run/remix/blob/534e1ec071f17654a4db8622e30d6ff70548ce26/scripts/build.mjs). 7 | * 8 | * @param {string} command - Shell command to execute. 9 | * @param {string[]} [args] - Command arguments. 10 | * @param {import('node:child_process').SpawnOptions} options - Options to pass to `cross-spawn`. 11 | * @returns {Promise} Returns a Promise which resolves when `command` exits. If the exit code is non-zero, it rejects with the exit code. 12 | */ 13 | export function exec(command, args = [], options = {}) { 14 | /** @type {(data: Error) => any} */ 15 | const handleError = (data) => console.error(data.toString().trim()); 16 | 17 | return new Promise((resolve, reject) => { 18 | const child = spawn(command, args, { 19 | cwd: process.cwd(), 20 | stdio: "inherit", 21 | ...options, 22 | }); 23 | 24 | const onExit = () => child.kill("SIGINT"); 25 | 26 | process.on("SIGINT", onExit); 27 | process.on("SIGTERM", onExit); 28 | 29 | child.on("error", handleError); 30 | child.on("close", (code) => { 31 | if (code === 0) { 32 | resolve(void 0); 33 | } else { 34 | reject(code); 35 | } 36 | }); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /setupTests.js: -------------------------------------------------------------------------------- 1 | import matchers from "@testing-library/jest-dom/matchers"; 2 | import { expect } from "vitest"; 3 | 4 | expect.extend(matchers); 5 | -------------------------------------------------------------------------------- /ship.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | publishCommand({ tag }) { 3 | return `yarn publish --access public --tag ${tag}`; 4 | }, 5 | // Skip preparation if it contains only `chore` commits 6 | shouldPrepare({ releaseType, commitNumbersPerType }) { 7 | const { fix = 0 } = commitNumbersPerType; 8 | 9 | return releaseType !== "patch" || fix !== 0; 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /src/highlighter/default-render-options.ts: -------------------------------------------------------------------------------- 1 | import { h } from "./hast-utils.js"; 2 | import { TRenderOptions } from "./types.js"; 3 | 4 | /** 5 | * The default renderers for {@link ./render-to-hast#renderToHast} 6 | * 7 | * @internal 8 | */ 9 | export const defaultRenderOptions: TRenderOptions = { 10 | pre({ children, metadata: { title: dataCodeTitle } }) { 11 | return h("pre", { dataCodeTitle }, children); 12 | }, 13 | 14 | code({ children, metadata: { lang: dataLanguage, showLineNumbers: dataLineNumbers } }) { 15 | return h("code", { dataLanguage, dataLineNumbers }, children); 16 | }, 17 | 18 | line({ children, index, metadata: { lineNumbers, lineNumbersStart } }) { 19 | const dataLineNumber = String(index + lineNumbersStart); 20 | const dataHighlighted = lineNumbers?.includes(index + 1); 21 | return h("span", { dataHighlighted, dataLineNumber }, children); 22 | }, 23 | 24 | token({ style, children }) { 25 | return h("span", { style }, children); 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /src/highlighter/hast-utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A super simple, probably naive hast implementation. 3 | * 4 | * {@link https://github.com/syntax-tree/hast-util-to-html/tree/fa187494263aa1087ba1c307abce72b2413e452e#tohtmltree-options | toHtml} escapes `&` and `<` and doesn't allow 5 | * control of HTML entities. 6 | */ 7 | 8 | import { html, find } from "property-information"; 9 | 10 | import { escapeHtml } from "./utils.js"; 11 | 12 | export type TProperty = string | string[] | boolean | undefined; 13 | export type TProperties = Record; 14 | export type TText = { type: "text"; value: string }; 15 | export type TElement = { 16 | type: "element"; 17 | tagName: string; 18 | properties: TProperties; 19 | children: Array; 20 | }; 21 | export type TNode = TElement | TText; 22 | export type TChild = TNode | string; 23 | export type TChildren = TChild[]; 24 | 25 | /** 26 | * Render {@link TText} node. 27 | */ 28 | function renderText({ value }: TText): string { 29 | return escapeHtml(value); 30 | } 31 | 32 | /** 33 | * Render HTML attributes. 34 | */ 35 | function renderAttributes(attributes: TProperties): string { 36 | const result: string[] = []; 37 | 38 | for (const [name, value] of Object.entries(attributes)) { 39 | if (value === undefined || value === false) continue; 40 | 41 | const { attribute, booleanish, commaSeparated } = find(html, name); 42 | 43 | if (value === true) { 44 | if (booleanish || /^data-/.test(attribute)) { 45 | result.push(attribute); 46 | } 47 | } else if (Array.isArray(value)) { 48 | const seperator = commaSeparated ? "," : " "; 49 | result.push(`${attribute}="${value.join(seperator)}"`); 50 | } else { 51 | result.push(`${attribute}="${value}"`); 52 | } 53 | } 54 | 55 | if (result.length === 0) return ""; 56 | 57 | // Add a space to separate from the tag. 58 | return result.join(" "); 59 | } 60 | 61 | function renderNode(node: TNode) { 62 | if (node.type === "text") { 63 | return renderText(node); 64 | } else { 65 | // This is pretty hacky, but it works for now. 66 | const newline = "dataLineNumber" in node.properties ? "\n" : ""; 67 | const attributes = renderAttributes(node.properties); 68 | const children = node.children.map(renderNode).join(""); 69 | const opening = node.tagName + (attributes.length > 1 ? " " + attributes : ""); 70 | return `<${opening}>${children}${newline}`; 71 | } 72 | } 73 | 74 | export function toHtml(node: TElement) { 75 | return renderNode(node); 76 | } 77 | 78 | export function h(tagName: string, properties: TProperties, children?: TChildren): TElement { 79 | const nodes: Array = children 80 | ? children.map((child) => (typeof child === "string" ? { type: "text", value: child } : child)) 81 | : []; 82 | 83 | return { 84 | type: "element", 85 | tagName, 86 | properties, 87 | children: nodes, 88 | }; 89 | } 90 | -------------------------------------------------------------------------------- /src/highlighter/highlighter.ts: -------------------------------------------------------------------------------- 1 | import { getHighlighter, type HighlighterOptions } from "shiki"; 2 | 3 | import { parseMetadata } from "../parse-metadata/index.js"; 4 | 5 | import { toHtml } from "./hast-utils.js"; 6 | import { renderToHast } from "./render-to-hast.js"; 7 | 8 | /** 9 | * MDsveX highlighter type. 10 | * 11 | * NOTE: not exported from `mdsvex`, so its copied here. 12 | * @public 13 | */ 14 | export type MdvexHighlighter = ( 15 | code: string, 16 | lang: string | undefined, 17 | metastring?: string | undefined 18 | ) => string | Promise; 19 | 20 | /** 21 | * Create MDsveX code highlighting function. 22 | * 23 | * @param options - Shiki highlighter options object. 24 | * @returns A Promise of a MDsvex highlighter function. 25 | * @public 26 | */ 27 | export async function createHighlighter(options: HighlighterOptions): Promise { 28 | const shikiHighlighter = await getHighlighter(options); 29 | /** 30 | * Highlighter function for Mdsvex codeblocks. 31 | * 32 | * [reference](https://github.com/atomiks/rehype-pretty-code/blob/e24f8415c8264dc868006ced839d3cb7445e716a/src/index.js#L50) 33 | * @param code - Raw source code to highlight. 34 | * @param lang - Programming language. 35 | * @param metastring - Code block fence metadata. 36 | * @returns HTML string. 37 | */ 38 | return function highlighter( 39 | code: string, 40 | lang: string | undefined, 41 | metastring?: string | undefined 42 | ): string { 43 | const tokens = shikiHighlighter.codeToThemedTokens(code, lang || "txt"); 44 | const metadata = parseMetadata(metastring); 45 | const tree = renderToHast({ tokens, metadata }); 46 | return toHtml(tree); 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /src/highlighter/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./highlighter.js"; 2 | -------------------------------------------------------------------------------- /src/highlighter/render-to-hast.ts: -------------------------------------------------------------------------------- 1 | import { FontStyle } from "shiki"; 2 | 3 | import { defaultRenderOptions } from "./default-render-options.js"; 4 | import type { TElement } from "./hast-utils.js"; 5 | import { TRenderToHastParams } from "./types.js"; 6 | 7 | /** 8 | * Render Shiki tokens to hast, Hypertext Abstract Syntax Tree format. 9 | * 10 | * @param renderParams - The render {@link TRenderToHastParams | parameters} 11 | * @returns A hast syntax tree for a highlighted code block. 12 | * @public 13 | */ 14 | export function renderToHast({ 15 | tokens: lines, 16 | options = {}, 17 | metadata = { lineNumbers: [], lineNumbersStart: 1, showLineNumbers: false }, 18 | }: TRenderToHastParams): TElement { 19 | const { pre, code, line, token } = { ...defaultRenderOptions, ...options.elements }; 20 | 21 | return pre({ 22 | metadata, 23 | children: [ 24 | code({ 25 | metadata, 26 | children: lines.map((tokens, index) => 27 | line({ 28 | index, 29 | metadata, 30 | children: tokens.map((shikiToken, index) => { 31 | const cssDeclarations: string[] = []; 32 | 33 | if (shikiToken.color) { 34 | cssDeclarations.push(`color: ${shikiToken.color}`); 35 | } 36 | 37 | if (shikiToken.fontStyle) { 38 | if (shikiToken.fontStyle & FontStyle.Italic) { 39 | cssDeclarations.push("font-style: italic"); 40 | } 41 | if (shikiToken.fontStyle & FontStyle.Bold) { 42 | cssDeclarations.push("font-weight: bold"); 43 | } 44 | if (shikiToken.fontStyle & FontStyle.Underline) { 45 | cssDeclarations.push("text-decoration: underline"); 46 | } 47 | } 48 | 49 | const children = [shikiToken.content]; 50 | const style = cssDeclarations.length > 0 ? cssDeclarations.join("; ") : undefined; 51 | 52 | return token({ 53 | style, 54 | token: shikiToken, 55 | tokens, 56 | index, 57 | children, 58 | metadata, 59 | }); 60 | }), 61 | }) 62 | ), 63 | }), 64 | ], 65 | }); 66 | } 67 | -------------------------------------------------------------------------------- /src/highlighter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base", 3 | "compilerOptions": { 4 | "types": ["hast"], 5 | "sourceMap": true, 6 | "declarationMap": true, 7 | "emitDeclarationOnly": false 8 | }, 9 | 10 | "references": [{ "path": "../parse-metadata" }], 11 | 12 | "include": ["**/*"] 13 | } 14 | -------------------------------------------------------------------------------- /src/highlighter/types.ts: -------------------------------------------------------------------------------- 1 | import { IThemedToken } from "shiki"; 2 | 3 | import type { TMetadata } from "../parse-metadata/types.js"; 4 | 5 | import type { TChildren, TElement } from "./hast-utils.js"; 6 | 7 | /** 8 | * @public 9 | */ 10 | export interface TRenderToHastParams { 11 | /** 12 | * Optional code block metadata. 13 | */ 14 | metadata?: TMetadata; 15 | 16 | /** 17 | * Options to modify the render function. 18 | */ 19 | options?: THastRendererOptions; 20 | 21 | /** 22 | * Shiki highlighted tokens to render. 23 | */ 24 | tokens: IThemedToken[][]; 25 | } 26 | 27 | /** 28 | * Hast render options, slimmed down compared to Shiki {@link shiki#HtmlRendererOptions | HtmlRendererOptions}. 29 | * 30 | * @public 31 | */ 32 | export type THastRendererOptions = { 33 | /** 34 | * Directive to include a language identifier in the rendered output. 35 | */ 36 | fg?: string; 37 | 38 | /** 39 | * Optional elements override functions. 40 | * 41 | * Allows for fine grained control overrides for rendering of `pre` and `code` 42 | * tags, lines, or individual tokens. 43 | */ 44 | elements?: Partial; 45 | 46 | /** 47 | * Shiki theme name. 48 | */ 49 | themeName?: string; 50 | }; 51 | 52 | /** 53 | * To help add classes to specific line numbers. 54 | * 55 | * @public 56 | */ 57 | export type TLineOption = { 58 | /** 59 | * 1-based line number. 60 | */ 61 | line: number; 62 | 63 | /** 64 | * Class name/names to include. 65 | */ 66 | className?: string | string[]; 67 | }; 68 | 69 | /** 70 | * Common renderer props. 71 | * 72 | * @public 73 | */ 74 | type TRenderProps = { 75 | /** 76 | * Children of the renderer. 77 | * 78 | * IMPORTANT: It is necessary pass children down through the renderer, otherwise 79 | * the code block will not be properly rendered. 80 | */ 81 | children: TChildren; 82 | 83 | /** 84 | * Additional information about the code block. 85 | */ 86 | metadata: TMetadata; 87 | 88 | [key: string]: unknown; 89 | }; 90 | 91 | /** 92 | * `pre` tag renderer props. 93 | * 94 | * @public 95 | */ 96 | type TPreProps = TRenderProps; 97 | 98 | /** 99 | * `code` tag renderer props. 100 | * @public 101 | */ 102 | type TCodeProps = TRenderProps; 103 | 104 | /** 105 | * Line renderer props. 106 | * 107 | * @public 108 | */ 109 | type TLineProps = TRenderProps & { 110 | /** 111 | * Zero based index of the line number. 112 | */ 113 | index: number; 114 | }; 115 | 116 | /** 117 | * Token renderer props. 118 | * 119 | * @public 120 | */ 121 | type TTokenProps = TRenderProps & { 122 | /** 123 | * Styles applied to the token by Shiki. 124 | */ 125 | style: string | undefined; 126 | 127 | /** 128 | * An array of the entire line of tokens. 129 | */ 130 | tokens: IThemedToken[]; 131 | 132 | /** 133 | * The Shiki {@link shiki#IThemedToken| token} to render. 134 | */ 135 | token: IThemedToken; 136 | 137 | /** 138 | * Zero-based index of the token position in the line. 139 | */ 140 | index: number; 141 | }; 142 | 143 | /** 144 | * Options to modify the rendered HTML output. 145 | * 146 | * @public 147 | */ 148 | export type TRenderOptions = { 149 | /** 150 | * Override function for `pre` tags. 151 | */ 152 | 153 | readonly pre: (props: TPreProps) => TElement; 154 | /** 155 | * Override function for `code` tags. 156 | */ 157 | readonly code: (props: TCodeProps) => TElement; 158 | 159 | /** 160 | * Override function for code block lines. 161 | */ 162 | readonly line: (props: TLineProps) => TElement; 163 | 164 | /** 165 | * Override function for code block tokens. 166 | */ 167 | readonly token: (props: TTokenProps) => TElement; 168 | }; 169 | -------------------------------------------------------------------------------- /src/highlighter/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copy of internal utils not exported by `shiki`. 3 | * 4 | * [shiki/src/utils.ts](https://github.com/shikijs/shiki/blob/a585c9d6860334a6233ff1c035a42d023e016400/packages/shiki/src/types.ts#L203-L242) 5 | */ 6 | 7 | export function groupBy( 8 | elements: TElement[], 9 | keyGetter: (element: TElement) => TKey 10 | ): Map { 11 | const map = new Map(); 12 | for (const element of elements) { 13 | const key = keyGetter(element); 14 | if (map.has(key)) { 15 | const group = map.get(key); 16 | group?.push(element); 17 | } else { 18 | map.set(key, [element]); 19 | } 20 | } 21 | return map; 22 | } 23 | 24 | const htmlEscapes = { 25 | "&": "&", 26 | "<": "<", 27 | ">": ">", 28 | '"': """, 29 | "'": "'", 30 | // Svelty escapes 31 | "{": "{", 32 | "}": "}", 33 | "`": "`", 34 | }; 35 | 36 | export function escapeHtml(html: string) { 37 | return html 38 | .replace(/[&<>"'{}`]/g, (chr) => htmlEscapes[chr as keyof typeof htmlEscapes]) 39 | .replace(/\\([trn])/g, "\$1"); 40 | } 41 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./highlighter/index.js"; 2 | export * from "./parse-metadata/index.js"; 3 | -------------------------------------------------------------------------------- /src/parse-metadata/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./parse-metadata.js"; 2 | export * from "./types.js"; 3 | -------------------------------------------------------------------------------- /src/parse-metadata/lexer.ts: -------------------------------------------------------------------------------- 1 | type PairStart = "{" | "(" | '"' | "'" | "/"; 2 | type PairEnd = "}" | ")" | '"' | "'" | "/"; 3 | 4 | export type Token = { 5 | value: string; 6 | start: number; 7 | end: number; 8 | type: "identifier" | "literal" | "symbol"; 9 | }; 10 | 11 | type State = "identifier" | "literal" | null; 12 | 13 | /** 14 | * Lexer for Markdown code fence meta data parsing. 15 | * 16 | * @internal 17 | */ 18 | export function lexer(input: string): readonly Token[] { 19 | const tokens: Token[] = []; 20 | 21 | let pos = 0; 22 | let pair: PairEnd | null = null; 23 | let start = 0; 24 | let state: State = null; 25 | let accumulator: string[] = []; 26 | 27 | loop: while (pos <= input.length) { 28 | const char = input[pos]; 29 | 30 | if (state === "identifier") { 31 | if (isIdentifier(char)) { 32 | accumulator.push(char); 33 | } else { 34 | tokens.push({ type: "identifier", value: accumulator.join(""), start, end: pos }); 35 | accumulator = []; 36 | state = null; 37 | } 38 | } else if (state === "literal") { 39 | if (isPairEnd(char, pair)) { 40 | if (accumulator.length > 0) { 41 | tokens.push({ type: "literal", value: accumulator.join(""), start, end: pos }); 42 | } 43 | tokens.push({ type: "symbol", value: char, start: pos, end: pos + 1 }); 44 | accumulator = []; 45 | state = null; 46 | // The closing symbol was just lexed, need to break out before `isPairStart` 47 | pos = pos + 1; 48 | continue loop; 49 | } else { 50 | // Safety to break out of literal if no more `input` 51 | if (char === undefined) { 52 | tokens.push({ type: "literal", value: accumulator.join(""), start, end: pos }); 53 | break loop; 54 | } else { 55 | accumulator.push(char); 56 | } 57 | } 58 | } 59 | 60 | // Continue lexing `identifier` or `literal` 61 | if (state !== null) { 62 | pos = pos + 1; 63 | continue loop; 64 | } 65 | 66 | if (isPairStart(char)) { 67 | switch (char) { 68 | case "{": 69 | pair = "}"; 70 | break; 71 | case "(": 72 | pair = ")"; 73 | break; 74 | default: 75 | pair = char; 76 | } 77 | start = pos + 1; 78 | state = "literal"; 79 | tokens.push({ type: "symbol", value: char, start: pos, end: pos + 1 }); 80 | } else if (isSymbol(char)) { 81 | tokens.push({ type: "symbol", value: char, start: pos, end: pos + 1 }); 82 | } else if (isIdentifier(char)) { 83 | start = pos; 84 | state = "identifier"; 85 | accumulator = [char]; 86 | } 87 | 88 | // Always advance. 89 | pos = pos + 1; 90 | } 91 | 92 | return tokens; 93 | } 94 | 95 | function isPairEnd(char: unknown, pairEnd: PairEnd | null): boolean { 96 | return typeof char === "string" && char === pairEnd; 97 | } 98 | 99 | function isPairStart(char: unknown): char is PairStart { 100 | return typeof char === "string" && /^[{("'/]/.test(char); 101 | } 102 | 103 | function isIdentifier(char: unknown): boolean { 104 | return typeof char === "string" && /^[A-Za-z]/.test(char); 105 | } 106 | 107 | function isSymbol(char: unknown): boolean { 108 | return typeof char === "string" && /^[=]/.test(char); 109 | } 110 | -------------------------------------------------------------------------------- /src/parse-metadata/parse-metadata.ts: -------------------------------------------------------------------------------- 1 | import rangeParser from "parse-numeric-range"; 2 | 3 | import { TMetadata } from "./types.js"; 4 | 5 | /** 6 | * Parse Markdown code fence metadata. 7 | * 8 | * @param metastring - Code block metadata string. 9 | * @returns Parsed metadata values object. 10 | * @public 11 | */ 12 | export function parseMetadata(metastring: string | undefined): TMetadata { 13 | if (metastring === undefined) { 14 | return { lineNumbers: [], lineNumbersStart: 1, showLineNumbers: false }; 15 | } 16 | const titleMatch = metastring?.match(/title="(.+)"/); 17 | const title = titleMatch?.[1] ?? undefined; 18 | // full title string `title="..."` 19 | const titleString = titleMatch?.[0] ?? ""; 20 | const metaWithoutTitle = metastring?.replace(titleString, ""); 21 | 22 | const lineNumbers = metastring ? rangeParser(metaWithoutTitle.match(/{(.*)}/)?.[1] ?? "") : []; 23 | 24 | const showLineNumbers = /srebmuNeniLwohs(?!(.*)(\/))/.test(reverseString(metastring)); 25 | 26 | const lineNumbersStartAtMatch = reverseString(metastring)?.match( 27 | /(?:\}(\d+){)?srebmuNeniLwohs(?!(.*)(\/))/ 28 | ); 29 | 30 | const lineNumbersStart = lineNumbersStartAtMatch?.[1] 31 | ? parseInt(reverseString(lineNumbersStartAtMatch[1])) 32 | : 1; 33 | 34 | return { lineNumbers, lineNumbersStart, showLineNumbers, title }; 35 | } 36 | 37 | /** 38 | * Reverse a string; 39 | * 40 | * @param s - String to reverse. 41 | * I don't know why Rehype Pretty Code reverses the string like this 42 | */ 43 | function reverseString(s: string): string; 44 | function reverseString(s: string | undefined): string | undefined { 45 | return s?.split("").reverse().join(""); 46 | } 47 | -------------------------------------------------------------------------------- /src/parse-metadata/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base", 3 | "compilerOptions": { 4 | "sourceMap": true, 5 | "declarationMap": true, 6 | "emitDeclarationOnly": false 7 | }, 8 | 9 | "references": [], 10 | 11 | "include": ["**/*"] 12 | } 13 | -------------------------------------------------------------------------------- /src/parse-metadata/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Markdown Code Block Metadata 3 | * 4 | * @public 5 | */ 6 | export type TMetadata = { 7 | /** 8 | * The lines to highlight. 9 | */ 10 | lineNumbers: number[]; 11 | 12 | /** 13 | * The initial line number to start from. 14 | */ 15 | lineNumbersStart: number; 16 | 17 | /** 18 | * Boolean indicating where or not to show line numbers. 19 | */ 20 | showLineNumbers: boolean; 21 | 22 | /** 23 | * The title of the code block. 24 | */ 25 | title?: string | undefined; 26 | 27 | /** 28 | * The language of the code block. 29 | */ 30 | lang?: string | undefined; 31 | }; 32 | 33 | /** 34 | * @public 35 | */ 36 | export type TMetaToken = { 37 | value: string; 38 | start: number; 39 | end: number; 40 | type: "identifier" | "literal" | "symbol"; 41 | }; 42 | -------------------------------------------------------------------------------- /src/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": ".", 4 | "outDir": "../build", 5 | 6 | "lib": ["DOM", "DOM.Iterable", "ES2018"], 7 | "target": "ES2018", 8 | "module": "ES2015", 9 | "moduleResolution": "node", 10 | "jsx": "react-jsx", 11 | "jsxImportSource": "hastscript", 12 | 13 | "declaration": true, 14 | "composite": true, 15 | "noEmitOnError": true, 16 | "emitDeclarationOnly": true, 17 | 18 | "strictNullChecks": true, 19 | // "noImplicitAny": true, 20 | "noImplicitThis": true, 21 | "strictPropertyInitialization": true, 22 | "noUnusedLocals": true, 23 | "noUnusedParameters": true, 24 | 25 | "allowSyntheticDefaultImports": true, 26 | "skipLibCheck": true, 27 | 28 | "alwaysStrict": true, 29 | "newLine": "lf" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base", 3 | "files": ["./index.ts"], 4 | "compilerOptions": { 5 | "emitDeclarationOnly": false 6 | }, 7 | "references": [{ "path": "./highlighter" }, { "path": "./parse-metadata" }] 8 | } 9 | -------------------------------------------------------------------------------- /tests/__snapshots__/highlighter-fixtures.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`createHighlighter > should render fixture: fixture.c 1`] = ` 4 | "
  5 |   
  6 |     
  7 |       #include
  8 |        
  9 |       <stdio.h>
 10 |     
 11 |     
 12 |     
 13 |       int
 14 |        
 15 |       main
 16 |       ()
 17 |     
 18 |     
 19 |       {
 20 |     
 21 |     
 22 |        
 23 |       printf(
 24 |       "Hello World"
 25 |       )
 26 |       ;
 27 |     
 28 |     
 29 |        
 30 |       return
 31 |        
 32 |       0
 33 |       ;
 34 |     
 35 |     
 36 |       }
 37 |     
 38 |     
 39 |   
 40 | 
; 41 | " 42 | `; 43 | 44 | exports[`createHighlighter > should render fixture: fixture.cpp 1`] = ` 45 | "
 46 |   
 47 |     
 48 |       #include
 49 |        
 50 |       <iostream>
 51 |     
 52 |     
 53 |     
 54 |       int
 55 |        
 56 |       main
 57 |       ()
 58 |     
 59 |     
 60 |       {
 61 |     
 62 |     
 63 |        std
 64 |       ::
 65 |       cout 
 66 |       <<
 67 |        
 68 |       "Hello World"
 69 |       ;
 70 |     
 71 |     
 72 |        
 73 |       return
 74 |        
 75 |       0
 76 |       ;
 77 |     
 78 |     
 79 |       }
 80 |     
 81 |     
 82 |   
 83 | 
; 84 | " 85 | `; 86 | 87 | exports[`createHighlighter > should render fixture: fixture.css 1`] = ` 88 | "
 89 |   
 90 |     
 91 |       .fixture::after
 92 |        {
 93 |     
 94 |     
 95 |        
 96 |       content
 97 |       :
 98 |        
 99 |       "hello world"
100 |       ;
101 |     
102 |     
103 |       }
104 |     
105 |     
106 |   
107 | 
; 108 | " 109 | `; 110 | 111 | exports[`createHighlighter > should render fixture: fixture.html 1`] = ` 112 | "
113 |   
114 |     
115 |       <!
116 |       DOCTYPE
117 |        
118 |       html
119 |       >
120 |     
121 |     
122 |       <
123 |       html
124 |       >
125 |     
126 |     
127 |        <
128 |       head
129 |       >
130 |     
131 |     
132 |        </
133 |       head
134 |       >
135 |     
136 |     
137 |        <
138 |       body
139 |       >
140 |     
141 |     
142 |        <
143 |       h1
144 |       >Hello World<
145 |       h1
146 |       >
147 |     
148 |     
149 |        </
150 |       body
151 |       >
152 |     
153 |     
154 |       </
155 |       html
156 |       >
157 |     
158 |     
159 |   
160 | 
; 161 | " 162 | `; 163 | 164 | exports[`createHighlighter > should render fixture: fixture.js 1`] = ` 165 | "
166 |   
167 |     
168 |       function
169 |        
170 |       hello
171 |       (value) {
172 |     
173 |     
174 |        
175 |       if
176 |        (
177 |       typeof
178 |        value 
179 |       ===
180 |        
181 |       "string"
182 |       ) {
183 |     
184 |     
185 |        
186 |       console
187 |       .log
188 |       (
189 |       `Hello 
190 |       ${
191 |       value
192 |       }
193 |       `
194 |       );
195 |     
196 |     
197 |        } 
198 |       else
199 |        {
200 |     
201 |     
202 |        
203 |       throw
204 |        
205 |       new
206 |        
207 |       Error
208 |       (
209 |       
210 |         `Can not greet 'undefined'!`
211 |       
212 |       );
213 |     
214 |     
215 |        }
216 |     
217 |     
218 |       }
219 |     
220 |     
221 |     
222 |       hello
223 |       (
224 |       "world!"
225 |       );
226 |     
227 |     
228 |   
229 | 
; 230 | " 231 | `; 232 | 233 | exports[`createHighlighter > should render fixture: fixture.rb 1`] = ` 234 | "
235 |   
236 |     
237 |       puts
238 |        
239 |       'Hello World'
240 |     
241 |     
242 |   
243 | 
; 244 | " 245 | `; 246 | 247 | exports[`createHighlighter > should render fixture: fixture.sh 1`] = ` 248 | "
249 |   
250 |     
251 |       file=
252 |       "fixture"
253 |     
254 |     
255 |       extensions=(
256 |       "css"
257 |        
258 |       "js"
259 |        
260 |       "sh"
261 |        
262 |       "sh"
263 |       )
264 |     
265 |     
266 |     
267 |       for
268 |        ext 
269 |       in
270 |        ${extensions[*]} 
271 |       ;
272 |        
273 |       do
274 |     
275 |     
276 |        
277 |       echo
278 |        
279 |       
280 |         "$file.${ext}"
281 |       
282 |     
283 |     
284 |       done
285 |     
286 |     
287 |     
288 |   
289 | 
; 290 | " 291 | `; 292 | 293 | exports[`createHighlighter > should render fixture: fixture.ts 1`] = ` 294 | "
295 |   
296 |     
297 |       function
298 |        
299 |       hello
300 |       (value
301 |       :
302 |        
303 |       string
304 |        
305 |       |
306 |        
307 |       undefined
308 |       ) {
309 |     
310 |     
311 |        
312 |       if
313 |        (
314 |       typeof
315 |        value 
316 |       ===
317 |        
318 |       "string"
319 |       ) {
320 |     
321 |     
322 |        
323 |       console
324 |       .log
325 |       (
326 |       `Hello 
327 |       ${
328 |       value
329 |       }
330 |       `
331 |       );
332 |     
333 |     
334 |        } 
335 |       else
336 |        {
337 |     
338 |     
339 |        
340 |       throw
341 |        
342 |       new
343 |        
344 |       Error
345 |       (
346 |       
347 |         `Can not greet 'undefined'!`
348 |       
349 |       );
350 |     
351 |     
352 |        }
353 |     
354 |     
355 |       }
356 |     
357 |     
358 |     
359 |       hello
360 |       (
361 |       "world!"
362 |       );
363 |     
364 |     
365 |   
366 | 
; 367 | " 368 | `; 369 | 370 | exports[`createHighlighter > should render fixture: fixture.txt 1`] = ` 371 | "
372 |   
373 |     
374 |       Hello World
375 |     
376 |     
377 |       
378 |     
379 |   
380 | 
; 381 | " 382 | `; 383 | -------------------------------------------------------------------------------- /tests/__snapshots__/metadata-lexer.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`lexer > snapshots > should lex a \`showLineNumbers \`identifier 1`] = ` 4 | [ 5 | { 6 | "end": 15, 7 | "start": 0, 8 | "type": "identifier", 9 | "value": "showLineNumbers", 10 | }, 11 | ] 12 | `; 13 | 14 | exports[`lexer > snapshots > should lex a brace pair 1`] = ` 15 | [ 16 | { 17 | "end": 1, 18 | "start": 0, 19 | "type": "symbol", 20 | "value": "{", 21 | }, 22 | { 23 | "end": 6, 24 | "start": 1, 25 | "type": "literal", 26 | "value": "range", 27 | }, 28 | { 29 | "end": 7, 30 | "start": 6, 31 | "type": "symbol", 32 | "value": "}", 33 | }, 34 | ] 35 | `; 36 | 37 | exports[`lexer > snapshots > should lex a dash pair 1`] = ` 38 | [ 39 | { 40 | "end": 1, 41 | "start": 0, 42 | "type": "symbol", 43 | "value": "/", 44 | }, 45 | { 46 | "end": 5, 47 | "start": 1, 48 | "type": "literal", 49 | "value": "word", 50 | }, 51 | { 52 | "end": 6, 53 | "start": 5, 54 | "type": "symbol", 55 | "value": "/", 56 | }, 57 | ] 58 | `; 59 | 60 | exports[`lexer > snapshots > should lex a double quote pair 1`] = ` 61 | [ 62 | { 63 | "end": 1, 64 | "start": 0, 65 | "type": "symbol", 66 | "value": "\\"", 67 | }, 68 | { 69 | "end": 7, 70 | "start": 1, 71 | "type": "literal", 72 | "value": "double", 73 | }, 74 | { 75 | "end": 8, 76 | "start": 7, 77 | "type": "symbol", 78 | "value": "\\"", 79 | }, 80 | ] 81 | `; 82 | 83 | exports[`lexer > snapshots > should lex a paren pair 1`] = ` 84 | [ 85 | { 86 | "end": 1, 87 | "start": 0, 88 | "type": "symbol", 89 | "value": "(", 90 | }, 91 | { 92 | "end": 9, 93 | "start": 1, 94 | "type": "literal", 95 | "value": "argument", 96 | }, 97 | { 98 | "end": 10, 99 | "start": 9, 100 | "type": "symbol", 101 | "value": ")", 102 | }, 103 | ] 104 | `; 105 | 106 | exports[`lexer > snapshots > should lex a range 1`] = ` 107 | [ 108 | { 109 | "end": 1, 110 | "start": 0, 111 | "type": "symbol", 112 | "value": "{", 113 | }, 114 | { 115 | "end": 7, 116 | "start": 1, 117 | "type": "literal", 118 | "value": "3..5,7", 119 | }, 120 | { 121 | "end": 8, 122 | "start": 7, 123 | "type": "symbol", 124 | "value": "}", 125 | }, 126 | ] 127 | `; 128 | 129 | exports[`lexer > snapshots > should lex a single identifier 1`] = ` 130 | [ 131 | { 132 | "end": 10, 133 | "start": 0, 134 | "type": "identifier", 135 | "value": "javascript", 136 | }, 137 | ] 138 | `; 139 | 140 | exports[`lexer > snapshots > should lex a single quote pair 1`] = ` 141 | [ 142 | { 143 | "end": 1, 144 | "start": 0, 145 | "type": "symbol", 146 | "value": "'", 147 | }, 148 | { 149 | "end": 7, 150 | "start": 1, 151 | "type": "literal", 152 | "value": "single", 153 | }, 154 | { 155 | "end": 8, 156 | "start": 7, 157 | "type": "symbol", 158 | "value": "'", 159 | }, 160 | ] 161 | `; 162 | 163 | exports[`lexer > snapshots > should lex a starting line number 1`] = ` 164 | [ 165 | { 166 | "end": 15, 167 | "start": 0, 168 | "type": "identifier", 169 | "value": "showLineNumbers", 170 | }, 171 | { 172 | "end": 16, 173 | "start": 15, 174 | "type": "symbol", 175 | "value": "{", 176 | }, 177 | { 178 | "end": 17, 179 | "start": 16, 180 | "type": "literal", 181 | "value": "5", 182 | }, 183 | { 184 | "end": 18, 185 | "start": 17, 186 | "type": "symbol", 187 | "value": "}", 188 | }, 189 | ] 190 | `; 191 | 192 | exports[`lexer > snapshots > should lex a title 1`] = ` 193 | [ 194 | { 195 | "end": 5, 196 | "start": 0, 197 | "type": "identifier", 198 | "value": "title", 199 | }, 200 | { 201 | "end": 6, 202 | "start": 5, 203 | "type": "symbol", 204 | "value": "=", 205 | }, 206 | { 207 | "end": 7, 208 | "start": 6, 209 | "type": "symbol", 210 | "value": "\\"", 211 | }, 212 | { 213 | "end": 18, 214 | "start": 7, 215 | "type": "literal", 216 | "value": "hello lexer", 217 | }, 218 | { 219 | "end": 19, 220 | "start": 18, 221 | "type": "symbol", 222 | "value": "\\"", 223 | }, 224 | ] 225 | `; 226 | -------------------------------------------------------------------------------- /tests/__snapshots__/render-to-hast.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`renderToHast > should render fixture: fixture.c 1`] = ` 4 | { 5 | "children": [ 6 | { 7 | "children": [ 8 | { 9 | "children": [ 10 | { 11 | "children": [ 12 | { 13 | "type": "text", 14 | "value": "#include", 15 | }, 16 | ], 17 | "properties": { 18 | "style": "color: var(--shiki-token-keyword)", 19 | }, 20 | "tagName": "span", 21 | "type": "element", 22 | }, 23 | { 24 | "children": [ 25 | { 26 | "type": "text", 27 | "value": " ", 28 | }, 29 | ], 30 | "properties": { 31 | "style": "color: var(--shiki-color-text)", 32 | }, 33 | "tagName": "span", 34 | "type": "element", 35 | }, 36 | { 37 | "children": [ 38 | { 39 | "type": "text", 40 | "value": "", 41 | }, 42 | ], 43 | "properties": { 44 | "style": "color: var(--shiki-token-string-expression)", 45 | }, 46 | "tagName": "span", 47 | "type": "element", 48 | }, 49 | ], 50 | "properties": { 51 | "dataHighlighted": false, 52 | "dataLineNumber": "1", 53 | }, 54 | "tagName": "span", 55 | "type": "element", 56 | }, 57 | { 58 | "children": [], 59 | "properties": { 60 | "dataHighlighted": false, 61 | "dataLineNumber": "2", 62 | }, 63 | "tagName": "span", 64 | "type": "element", 65 | }, 66 | { 67 | "children": [ 68 | { 69 | "children": [ 70 | { 71 | "type": "text", 72 | "value": "int", 73 | }, 74 | ], 75 | "properties": { 76 | "style": "color: var(--shiki-token-keyword)", 77 | }, 78 | "tagName": "span", 79 | "type": "element", 80 | }, 81 | { 82 | "children": [ 83 | { 84 | "type": "text", 85 | "value": " ", 86 | }, 87 | ], 88 | "properties": { 89 | "style": "color: var(--shiki-color-text)", 90 | }, 91 | "tagName": "span", 92 | "type": "element", 93 | }, 94 | { 95 | "children": [ 96 | { 97 | "type": "text", 98 | "value": "main", 99 | }, 100 | ], 101 | "properties": { 102 | "style": "color: var(--shiki-token-function)", 103 | }, 104 | "tagName": "span", 105 | "type": "element", 106 | }, 107 | { 108 | "children": [ 109 | { 110 | "type": "text", 111 | "value": "()", 112 | }, 113 | ], 114 | "properties": { 115 | "style": "color: var(--shiki-color-text)", 116 | }, 117 | "tagName": "span", 118 | "type": "element", 119 | }, 120 | ], 121 | "properties": { 122 | "dataHighlighted": false, 123 | "dataLineNumber": "3", 124 | }, 125 | "tagName": "span", 126 | "type": "element", 127 | }, 128 | { 129 | "children": [ 130 | { 131 | "children": [ 132 | { 133 | "type": "text", 134 | "value": "{", 135 | }, 136 | ], 137 | "properties": { 138 | "style": "color: var(--shiki-color-text)", 139 | }, 140 | "tagName": "span", 141 | "type": "element", 142 | }, 143 | ], 144 | "properties": { 145 | "dataHighlighted": false, 146 | "dataLineNumber": "4", 147 | }, 148 | "tagName": "span", 149 | "type": "element", 150 | }, 151 | { 152 | "children": [ 153 | { 154 | "children": [ 155 | { 156 | "type": "text", 157 | "value": " ", 158 | }, 159 | ], 160 | "properties": { 161 | "style": "color: var(--shiki-color-text)", 162 | }, 163 | "tagName": "span", 164 | "type": "element", 165 | }, 166 | { 167 | "children": [ 168 | { 169 | "type": "text", 170 | "value": "printf(", 171 | }, 172 | ], 173 | "properties": { 174 | "style": "color: var(--shiki-token-function)", 175 | }, 176 | "tagName": "span", 177 | "type": "element", 178 | }, 179 | { 180 | "children": [ 181 | { 182 | "type": "text", 183 | "value": "\\"Hello World\\"", 184 | }, 185 | ], 186 | "properties": { 187 | "style": "color: var(--shiki-token-string-expression)", 188 | }, 189 | "tagName": "span", 190 | "type": "element", 191 | }, 192 | { 193 | "children": [ 194 | { 195 | "type": "text", 196 | "value": ")", 197 | }, 198 | ], 199 | "properties": { 200 | "style": "color: var(--shiki-token-function)", 201 | }, 202 | "tagName": "span", 203 | "type": "element", 204 | }, 205 | { 206 | "children": [ 207 | { 208 | "type": "text", 209 | "value": ";", 210 | }, 211 | ], 212 | "properties": { 213 | "style": "color: var(--shiki-color-text)", 214 | }, 215 | "tagName": "span", 216 | "type": "element", 217 | }, 218 | ], 219 | "properties": { 220 | "dataHighlighted": false, 221 | "dataLineNumber": "5", 222 | }, 223 | "tagName": "span", 224 | "type": "element", 225 | }, 226 | { 227 | "children": [ 228 | { 229 | "children": [ 230 | { 231 | "type": "text", 232 | "value": " ", 233 | }, 234 | ], 235 | "properties": { 236 | "style": "color: var(--shiki-color-text)", 237 | }, 238 | "tagName": "span", 239 | "type": "element", 240 | }, 241 | { 242 | "children": [ 243 | { 244 | "type": "text", 245 | "value": "return", 246 | }, 247 | ], 248 | "properties": { 249 | "style": "color: var(--shiki-token-keyword)", 250 | }, 251 | "tagName": "span", 252 | "type": "element", 253 | }, 254 | { 255 | "children": [ 256 | { 257 | "type": "text", 258 | "value": " ", 259 | }, 260 | ], 261 | "properties": { 262 | "style": "color: var(--shiki-color-text)", 263 | }, 264 | "tagName": "span", 265 | "type": "element", 266 | }, 267 | { 268 | "children": [ 269 | { 270 | "type": "text", 271 | "value": "0", 272 | }, 273 | ], 274 | "properties": { 275 | "style": "color: var(--shiki-token-constant)", 276 | }, 277 | "tagName": "span", 278 | "type": "element", 279 | }, 280 | { 281 | "children": [ 282 | { 283 | "type": "text", 284 | "value": ";", 285 | }, 286 | ], 287 | "properties": { 288 | "style": "color: var(--shiki-color-text)", 289 | }, 290 | "tagName": "span", 291 | "type": "element", 292 | }, 293 | ], 294 | "properties": { 295 | "dataHighlighted": false, 296 | "dataLineNumber": "6", 297 | }, 298 | "tagName": "span", 299 | "type": "element", 300 | }, 301 | { 302 | "children": [ 303 | { 304 | "children": [ 305 | { 306 | "type": "text", 307 | "value": "}", 308 | }, 309 | ], 310 | "properties": { 311 | "style": "color: var(--shiki-color-text)", 312 | }, 313 | "tagName": "span", 314 | "type": "element", 315 | }, 316 | ], 317 | "properties": { 318 | "dataHighlighted": false, 319 | "dataLineNumber": "7", 320 | }, 321 | "tagName": "span", 322 | "type": "element", 323 | }, 324 | { 325 | "children": [], 326 | "properties": { 327 | "dataHighlighted": false, 328 | "dataLineNumber": "8", 329 | }, 330 | "tagName": "span", 331 | "type": "element", 332 | }, 333 | ], 334 | "properties": { 335 | "dataLanguage": undefined, 336 | "dataLineNumbers": false, 337 | }, 338 | "tagName": "code", 339 | "type": "element", 340 | }, 341 | ], 342 | "properties": { 343 | "dataCodeTitle": undefined, 344 | }, 345 | "tagName": "pre", 346 | "type": "element", 347 | } 348 | `; 349 | 350 | exports[`renderToHast > should render fixture: fixture.cpp 1`] = ` 351 | { 352 | "children": [ 353 | { 354 | "children": [ 355 | { 356 | "children": [ 357 | { 358 | "children": [ 359 | { 360 | "type": "text", 361 | "value": "#include", 362 | }, 363 | ], 364 | "properties": { 365 | "style": "color: var(--shiki-token-keyword)", 366 | }, 367 | "tagName": "span", 368 | "type": "element", 369 | }, 370 | { 371 | "children": [ 372 | { 373 | "type": "text", 374 | "value": " ", 375 | }, 376 | ], 377 | "properties": { 378 | "style": "color: var(--shiki-color-text)", 379 | }, 380 | "tagName": "span", 381 | "type": "element", 382 | }, 383 | { 384 | "children": [ 385 | { 386 | "type": "text", 387 | "value": "", 388 | }, 389 | ], 390 | "properties": { 391 | "style": "color: var(--shiki-token-string-expression)", 392 | }, 393 | "tagName": "span", 394 | "type": "element", 395 | }, 396 | ], 397 | "properties": { 398 | "dataHighlighted": false, 399 | "dataLineNumber": "1", 400 | }, 401 | "tagName": "span", 402 | "type": "element", 403 | }, 404 | { 405 | "children": [], 406 | "properties": { 407 | "dataHighlighted": false, 408 | "dataLineNumber": "2", 409 | }, 410 | "tagName": "span", 411 | "type": "element", 412 | }, 413 | { 414 | "children": [ 415 | { 416 | "children": [ 417 | { 418 | "type": "text", 419 | "value": "int", 420 | }, 421 | ], 422 | "properties": { 423 | "style": "color: var(--shiki-token-keyword)", 424 | }, 425 | "tagName": "span", 426 | "type": "element", 427 | }, 428 | { 429 | "children": [ 430 | { 431 | "type": "text", 432 | "value": " ", 433 | }, 434 | ], 435 | "properties": { 436 | "style": "color: var(--shiki-color-text)", 437 | }, 438 | "tagName": "span", 439 | "type": "element", 440 | }, 441 | { 442 | "children": [ 443 | { 444 | "type": "text", 445 | "value": "main", 446 | }, 447 | ], 448 | "properties": { 449 | "style": "color: var(--shiki-token-function)", 450 | }, 451 | "tagName": "span", 452 | "type": "element", 453 | }, 454 | { 455 | "children": [ 456 | { 457 | "type": "text", 458 | "value": "()", 459 | }, 460 | ], 461 | "properties": { 462 | "style": "color: var(--shiki-color-text)", 463 | }, 464 | "tagName": "span", 465 | "type": "element", 466 | }, 467 | ], 468 | "properties": { 469 | "dataHighlighted": false, 470 | "dataLineNumber": "3", 471 | }, 472 | "tagName": "span", 473 | "type": "element", 474 | }, 475 | { 476 | "children": [ 477 | { 478 | "children": [ 479 | { 480 | "type": "text", 481 | "value": "{", 482 | }, 483 | ], 484 | "properties": { 485 | "style": "color: var(--shiki-color-text)", 486 | }, 487 | "tagName": "span", 488 | "type": "element", 489 | }, 490 | ], 491 | "properties": { 492 | "dataHighlighted": false, 493 | "dataLineNumber": "4", 494 | }, 495 | "tagName": "span", 496 | "type": "element", 497 | }, 498 | { 499 | "children": [ 500 | { 501 | "children": [ 502 | { 503 | "type": "text", 504 | "value": " std", 505 | }, 506 | ], 507 | "properties": { 508 | "style": "color: var(--shiki-color-text)", 509 | }, 510 | "tagName": "span", 511 | "type": "element", 512 | }, 513 | { 514 | "children": [ 515 | { 516 | "type": "text", 517 | "value": "::", 518 | }, 519 | ], 520 | "properties": { 521 | "style": "color: var(--shiki-token-punctuation)", 522 | }, 523 | "tagName": "span", 524 | "type": "element", 525 | }, 526 | { 527 | "children": [ 528 | { 529 | "type": "text", 530 | "value": "cout ", 531 | }, 532 | ], 533 | "properties": { 534 | "style": "color: var(--shiki-color-text)", 535 | }, 536 | "tagName": "span", 537 | "type": "element", 538 | }, 539 | { 540 | "children": [ 541 | { 542 | "type": "text", 543 | "value": "<<", 544 | }, 545 | ], 546 | "properties": { 547 | "style": "color: var(--shiki-token-keyword)", 548 | }, 549 | "tagName": "span", 550 | "type": "element", 551 | }, 552 | { 553 | "children": [ 554 | { 555 | "type": "text", 556 | "value": " ", 557 | }, 558 | ], 559 | "properties": { 560 | "style": "color: var(--shiki-color-text)", 561 | }, 562 | "tagName": "span", 563 | "type": "element", 564 | }, 565 | { 566 | "children": [ 567 | { 568 | "type": "text", 569 | "value": "\\"Hello World\\"", 570 | }, 571 | ], 572 | "properties": { 573 | "style": "color: var(--shiki-token-string-expression)", 574 | }, 575 | "tagName": "span", 576 | "type": "element", 577 | }, 578 | { 579 | "children": [ 580 | { 581 | "type": "text", 582 | "value": ";", 583 | }, 584 | ], 585 | "properties": { 586 | "style": "color: var(--shiki-color-text)", 587 | }, 588 | "tagName": "span", 589 | "type": "element", 590 | }, 591 | ], 592 | "properties": { 593 | "dataHighlighted": false, 594 | "dataLineNumber": "5", 595 | }, 596 | "tagName": "span", 597 | "type": "element", 598 | }, 599 | { 600 | "children": [ 601 | { 602 | "children": [ 603 | { 604 | "type": "text", 605 | "value": " ", 606 | }, 607 | ], 608 | "properties": { 609 | "style": "color: var(--shiki-color-text)", 610 | }, 611 | "tagName": "span", 612 | "type": "element", 613 | }, 614 | { 615 | "children": [ 616 | { 617 | "type": "text", 618 | "value": "return", 619 | }, 620 | ], 621 | "properties": { 622 | "style": "color: var(--shiki-token-keyword)", 623 | }, 624 | "tagName": "span", 625 | "type": "element", 626 | }, 627 | { 628 | "children": [ 629 | { 630 | "type": "text", 631 | "value": " ", 632 | }, 633 | ], 634 | "properties": { 635 | "style": "color: var(--shiki-color-text)", 636 | }, 637 | "tagName": "span", 638 | "type": "element", 639 | }, 640 | { 641 | "children": [ 642 | { 643 | "type": "text", 644 | "value": "0", 645 | }, 646 | ], 647 | "properties": { 648 | "style": "color: var(--shiki-token-constant)", 649 | }, 650 | "tagName": "span", 651 | "type": "element", 652 | }, 653 | { 654 | "children": [ 655 | { 656 | "type": "text", 657 | "value": ";", 658 | }, 659 | ], 660 | "properties": { 661 | "style": "color: var(--shiki-color-text)", 662 | }, 663 | "tagName": "span", 664 | "type": "element", 665 | }, 666 | ], 667 | "properties": { 668 | "dataHighlighted": false, 669 | "dataLineNumber": "6", 670 | }, 671 | "tagName": "span", 672 | "type": "element", 673 | }, 674 | { 675 | "children": [ 676 | { 677 | "children": [ 678 | { 679 | "type": "text", 680 | "value": "}", 681 | }, 682 | ], 683 | "properties": { 684 | "style": "color: var(--shiki-color-text)", 685 | }, 686 | "tagName": "span", 687 | "type": "element", 688 | }, 689 | ], 690 | "properties": { 691 | "dataHighlighted": false, 692 | "dataLineNumber": "7", 693 | }, 694 | "tagName": "span", 695 | "type": "element", 696 | }, 697 | { 698 | "children": [], 699 | "properties": { 700 | "dataHighlighted": false, 701 | "dataLineNumber": "8", 702 | }, 703 | "tagName": "span", 704 | "type": "element", 705 | }, 706 | ], 707 | "properties": { 708 | "dataLanguage": undefined, 709 | "dataLineNumbers": false, 710 | }, 711 | "tagName": "code", 712 | "type": "element", 713 | }, 714 | ], 715 | "properties": { 716 | "dataCodeTitle": undefined, 717 | }, 718 | "tagName": "pre", 719 | "type": "element", 720 | } 721 | `; 722 | 723 | exports[`renderToHast > should render fixture: fixture.css 1`] = ` 724 | { 725 | "children": [ 726 | { 727 | "children": [ 728 | { 729 | "children": [ 730 | { 731 | "children": [ 732 | { 733 | "type": "text", 734 | "value": ".fixture::after", 735 | }, 736 | ], 737 | "properties": { 738 | "style": "color: var(--shiki-token-function)", 739 | }, 740 | "tagName": "span", 741 | "type": "element", 742 | }, 743 | { 744 | "children": [ 745 | { 746 | "type": "text", 747 | "value": " {", 748 | }, 749 | ], 750 | "properties": { 751 | "style": "color: var(--shiki-color-text)", 752 | }, 753 | "tagName": "span", 754 | "type": "element", 755 | }, 756 | ], 757 | "properties": { 758 | "dataHighlighted": false, 759 | "dataLineNumber": "1", 760 | }, 761 | "tagName": "span", 762 | "type": "element", 763 | }, 764 | { 765 | "children": [ 766 | { 767 | "children": [ 768 | { 769 | "type": "text", 770 | "value": " ", 771 | }, 772 | ], 773 | "properties": { 774 | "style": "color: var(--shiki-color-text)", 775 | }, 776 | "tagName": "span", 777 | "type": "element", 778 | }, 779 | { 780 | "children": [ 781 | { 782 | "type": "text", 783 | "value": "content", 784 | }, 785 | ], 786 | "properties": { 787 | "style": "color: var(--shiki-token-constant)", 788 | }, 789 | "tagName": "span", 790 | "type": "element", 791 | }, 792 | { 793 | "children": [ 794 | { 795 | "type": "text", 796 | "value": ":", 797 | }, 798 | ], 799 | "properties": { 800 | "style": "color: var(--shiki-token-keyword)", 801 | }, 802 | "tagName": "span", 803 | "type": "element", 804 | }, 805 | { 806 | "children": [ 807 | { 808 | "type": "text", 809 | "value": " ", 810 | }, 811 | ], 812 | "properties": { 813 | "style": "color: var(--shiki-color-text)", 814 | }, 815 | "tagName": "span", 816 | "type": "element", 817 | }, 818 | { 819 | "children": [ 820 | { 821 | "type": "text", 822 | "value": "\\"hello world\\"", 823 | }, 824 | ], 825 | "properties": { 826 | "style": "color: var(--shiki-token-string-expression)", 827 | }, 828 | "tagName": "span", 829 | "type": "element", 830 | }, 831 | { 832 | "children": [ 833 | { 834 | "type": "text", 835 | "value": ";", 836 | }, 837 | ], 838 | "properties": { 839 | "style": "color: var(--shiki-color-text)", 840 | }, 841 | "tagName": "span", 842 | "type": "element", 843 | }, 844 | ], 845 | "properties": { 846 | "dataHighlighted": false, 847 | "dataLineNumber": "2", 848 | }, 849 | "tagName": "span", 850 | "type": "element", 851 | }, 852 | { 853 | "children": [ 854 | { 855 | "children": [ 856 | { 857 | "type": "text", 858 | "value": "}", 859 | }, 860 | ], 861 | "properties": { 862 | "style": "color: var(--shiki-color-text)", 863 | }, 864 | "tagName": "span", 865 | "type": "element", 866 | }, 867 | ], 868 | "properties": { 869 | "dataHighlighted": false, 870 | "dataLineNumber": "3", 871 | }, 872 | "tagName": "span", 873 | "type": "element", 874 | }, 875 | { 876 | "children": [], 877 | "properties": { 878 | "dataHighlighted": false, 879 | "dataLineNumber": "4", 880 | }, 881 | "tagName": "span", 882 | "type": "element", 883 | }, 884 | ], 885 | "properties": { 886 | "dataLanguage": undefined, 887 | "dataLineNumbers": false, 888 | }, 889 | "tagName": "code", 890 | "type": "element", 891 | }, 892 | ], 893 | "properties": { 894 | "dataCodeTitle": undefined, 895 | }, 896 | "tagName": "pre", 897 | "type": "element", 898 | } 899 | `; 900 | 901 | exports[`renderToHast > should render fixture: fixture.html 1`] = ` 902 | { 903 | "children": [ 904 | { 905 | "children": [ 906 | { 907 | "children": [ 908 | { 909 | "children": [ 910 | { 911 | "type": "text", 912 | "value": "", 965 | }, 966 | ], 967 | "properties": { 968 | "style": "color: var(--shiki-color-text)", 969 | }, 970 | "tagName": "span", 971 | "type": "element", 972 | }, 973 | ], 974 | "properties": { 975 | "dataHighlighted": false, 976 | "dataLineNumber": "1", 977 | }, 978 | "tagName": "span", 979 | "type": "element", 980 | }, 981 | { 982 | "children": [ 983 | { 984 | "children": [ 985 | { 986 | "type": "text", 987 | "value": "<", 988 | }, 989 | ], 990 | "properties": { 991 | "style": "color: var(--shiki-color-text)", 992 | }, 993 | "tagName": "span", 994 | "type": "element", 995 | }, 996 | { 997 | "children": [ 998 | { 999 | "type": "text", 1000 | "value": "html", 1001 | }, 1002 | ], 1003 | "properties": { 1004 | "style": "color: var(--shiki-token-string-expression)", 1005 | }, 1006 | "tagName": "span", 1007 | "type": "element", 1008 | }, 1009 | { 1010 | "children": [ 1011 | { 1012 | "type": "text", 1013 | "value": ">", 1014 | }, 1015 | ], 1016 | "properties": { 1017 | "style": "color: var(--shiki-color-text)", 1018 | }, 1019 | "tagName": "span", 1020 | "type": "element", 1021 | }, 1022 | ], 1023 | "properties": { 1024 | "dataHighlighted": false, 1025 | "dataLineNumber": "2", 1026 | }, 1027 | "tagName": "span", 1028 | "type": "element", 1029 | }, 1030 | { 1031 | "children": [ 1032 | { 1033 | "children": [ 1034 | { 1035 | "type": "text", 1036 | "value": " <", 1037 | }, 1038 | ], 1039 | "properties": { 1040 | "style": "color: var(--shiki-color-text)", 1041 | }, 1042 | "tagName": "span", 1043 | "type": "element", 1044 | }, 1045 | { 1046 | "children": [ 1047 | { 1048 | "type": "text", 1049 | "value": "head", 1050 | }, 1051 | ], 1052 | "properties": { 1053 | "style": "color: var(--shiki-token-string-expression)", 1054 | }, 1055 | "tagName": "span", 1056 | "type": "element", 1057 | }, 1058 | { 1059 | "children": [ 1060 | { 1061 | "type": "text", 1062 | "value": ">", 1063 | }, 1064 | ], 1065 | "properties": { 1066 | "style": "color: var(--shiki-color-text)", 1067 | }, 1068 | "tagName": "span", 1069 | "type": "element", 1070 | }, 1071 | ], 1072 | "properties": { 1073 | "dataHighlighted": false, 1074 | "dataLineNumber": "3", 1075 | }, 1076 | "tagName": "span", 1077 | "type": "element", 1078 | }, 1079 | { 1080 | "children": [ 1081 | { 1082 | "children": [ 1083 | { 1084 | "type": "text", 1085 | "value": " ", 1112 | }, 1113 | ], 1114 | "properties": { 1115 | "style": "color: var(--shiki-color-text)", 1116 | }, 1117 | "tagName": "span", 1118 | "type": "element", 1119 | }, 1120 | ], 1121 | "properties": { 1122 | "dataHighlighted": false, 1123 | "dataLineNumber": "4", 1124 | }, 1125 | "tagName": "span", 1126 | "type": "element", 1127 | }, 1128 | { 1129 | "children": [ 1130 | { 1131 | "children": [ 1132 | { 1133 | "type": "text", 1134 | "value": " <", 1135 | }, 1136 | ], 1137 | "properties": { 1138 | "style": "color: var(--shiki-color-text)", 1139 | }, 1140 | "tagName": "span", 1141 | "type": "element", 1142 | }, 1143 | { 1144 | "children": [ 1145 | { 1146 | "type": "text", 1147 | "value": "body", 1148 | }, 1149 | ], 1150 | "properties": { 1151 | "style": "color: var(--shiki-token-string-expression)", 1152 | }, 1153 | "tagName": "span", 1154 | "type": "element", 1155 | }, 1156 | { 1157 | "children": [ 1158 | { 1159 | "type": "text", 1160 | "value": ">", 1161 | }, 1162 | ], 1163 | "properties": { 1164 | "style": "color: var(--shiki-color-text)", 1165 | }, 1166 | "tagName": "span", 1167 | "type": "element", 1168 | }, 1169 | ], 1170 | "properties": { 1171 | "dataHighlighted": false, 1172 | "dataLineNumber": "5", 1173 | }, 1174 | "tagName": "span", 1175 | "type": "element", 1176 | }, 1177 | { 1178 | "children": [ 1179 | { 1180 | "children": [ 1181 | { 1182 | "type": "text", 1183 | "value": " <", 1184 | }, 1185 | ], 1186 | "properties": { 1187 | "style": "color: var(--shiki-color-text)", 1188 | }, 1189 | "tagName": "span", 1190 | "type": "element", 1191 | }, 1192 | { 1193 | "children": [ 1194 | { 1195 | "type": "text", 1196 | "value": "h1", 1197 | }, 1198 | ], 1199 | "properties": { 1200 | "style": "color: var(--shiki-token-string-expression)", 1201 | }, 1202 | "tagName": "span", 1203 | "type": "element", 1204 | }, 1205 | { 1206 | "children": [ 1207 | { 1208 | "type": "text", 1209 | "value": ">Hello World<", 1210 | }, 1211 | ], 1212 | "properties": { 1213 | "style": "color: var(--shiki-color-text)", 1214 | }, 1215 | "tagName": "span", 1216 | "type": "element", 1217 | }, 1218 | { 1219 | "children": [ 1220 | { 1221 | "type": "text", 1222 | "value": "h1", 1223 | }, 1224 | ], 1225 | "properties": { 1226 | "style": "color: var(--shiki-token-string-expression)", 1227 | }, 1228 | "tagName": "span", 1229 | "type": "element", 1230 | }, 1231 | { 1232 | "children": [ 1233 | { 1234 | "type": "text", 1235 | "value": ">", 1236 | }, 1237 | ], 1238 | "properties": { 1239 | "style": "color: var(--shiki-color-text)", 1240 | }, 1241 | "tagName": "span", 1242 | "type": "element", 1243 | }, 1244 | ], 1245 | "properties": { 1246 | "dataHighlighted": false, 1247 | "dataLineNumber": "6", 1248 | }, 1249 | "tagName": "span", 1250 | "type": "element", 1251 | }, 1252 | { 1253 | "children": [ 1254 | { 1255 | "children": [ 1256 | { 1257 | "type": "text", 1258 | "value": " ", 1285 | }, 1286 | ], 1287 | "properties": { 1288 | "style": "color: var(--shiki-color-text)", 1289 | }, 1290 | "tagName": "span", 1291 | "type": "element", 1292 | }, 1293 | ], 1294 | "properties": { 1295 | "dataHighlighted": false, 1296 | "dataLineNumber": "7", 1297 | }, 1298 | "tagName": "span", 1299 | "type": "element", 1300 | }, 1301 | { 1302 | "children": [ 1303 | { 1304 | "children": [ 1305 | { 1306 | "type": "text", 1307 | "value": "", 1334 | }, 1335 | ], 1336 | "properties": { 1337 | "style": "color: var(--shiki-color-text)", 1338 | }, 1339 | "tagName": "span", 1340 | "type": "element", 1341 | }, 1342 | ], 1343 | "properties": { 1344 | "dataHighlighted": false, 1345 | "dataLineNumber": "8", 1346 | }, 1347 | "tagName": "span", 1348 | "type": "element", 1349 | }, 1350 | { 1351 | "children": [], 1352 | "properties": { 1353 | "dataHighlighted": false, 1354 | "dataLineNumber": "9", 1355 | }, 1356 | "tagName": "span", 1357 | "type": "element", 1358 | }, 1359 | ], 1360 | "properties": { 1361 | "dataLanguage": undefined, 1362 | "dataLineNumbers": false, 1363 | }, 1364 | "tagName": "code", 1365 | "type": "element", 1366 | }, 1367 | ], 1368 | "properties": { 1369 | "dataCodeTitle": undefined, 1370 | }, 1371 | "tagName": "pre", 1372 | "type": "element", 1373 | } 1374 | `; 1375 | 1376 | exports[`renderToHast > should render fixture: fixture.js 1`] = ` 1377 | { 1378 | "children": [ 1379 | { 1380 | "children": [ 1381 | { 1382 | "children": [ 1383 | { 1384 | "children": [ 1385 | { 1386 | "type": "text", 1387 | "value": "function", 1388 | }, 1389 | ], 1390 | "properties": { 1391 | "style": "color: var(--shiki-token-keyword)", 1392 | }, 1393 | "tagName": "span", 1394 | "type": "element", 1395 | }, 1396 | { 1397 | "children": [ 1398 | { 1399 | "type": "text", 1400 | "value": " ", 1401 | }, 1402 | ], 1403 | "properties": { 1404 | "style": "color: var(--shiki-color-text)", 1405 | }, 1406 | "tagName": "span", 1407 | "type": "element", 1408 | }, 1409 | { 1410 | "children": [ 1411 | { 1412 | "type": "text", 1413 | "value": "hello", 1414 | }, 1415 | ], 1416 | "properties": { 1417 | "style": "color: var(--shiki-token-function)", 1418 | }, 1419 | "tagName": "span", 1420 | "type": "element", 1421 | }, 1422 | { 1423 | "children": [ 1424 | { 1425 | "type": "text", 1426 | "value": "(value) {", 1427 | }, 1428 | ], 1429 | "properties": { 1430 | "style": "color: var(--shiki-color-text)", 1431 | }, 1432 | "tagName": "span", 1433 | "type": "element", 1434 | }, 1435 | ], 1436 | "properties": { 1437 | "dataHighlighted": false, 1438 | "dataLineNumber": "1", 1439 | }, 1440 | "tagName": "span", 1441 | "type": "element", 1442 | }, 1443 | { 1444 | "children": [ 1445 | { 1446 | "children": [ 1447 | { 1448 | "type": "text", 1449 | "value": " ", 1450 | }, 1451 | ], 1452 | "properties": { 1453 | "style": "color: var(--shiki-color-text)", 1454 | }, 1455 | "tagName": "span", 1456 | "type": "element", 1457 | }, 1458 | { 1459 | "children": [ 1460 | { 1461 | "type": "text", 1462 | "value": "if", 1463 | }, 1464 | ], 1465 | "properties": { 1466 | "style": "color: var(--shiki-token-keyword)", 1467 | }, 1468 | "tagName": "span", 1469 | "type": "element", 1470 | }, 1471 | { 1472 | "children": [ 1473 | { 1474 | "type": "text", 1475 | "value": " (", 1476 | }, 1477 | ], 1478 | "properties": { 1479 | "style": "color: var(--shiki-color-text)", 1480 | }, 1481 | "tagName": "span", 1482 | "type": "element", 1483 | }, 1484 | { 1485 | "children": [ 1486 | { 1487 | "type": "text", 1488 | "value": "typeof", 1489 | }, 1490 | ], 1491 | "properties": { 1492 | "style": "color: var(--shiki-token-keyword)", 1493 | }, 1494 | "tagName": "span", 1495 | "type": "element", 1496 | }, 1497 | { 1498 | "children": [ 1499 | { 1500 | "type": "text", 1501 | "value": " value ", 1502 | }, 1503 | ], 1504 | "properties": { 1505 | "style": "color: var(--shiki-color-text)", 1506 | }, 1507 | "tagName": "span", 1508 | "type": "element", 1509 | }, 1510 | { 1511 | "children": [ 1512 | { 1513 | "type": "text", 1514 | "value": "===", 1515 | }, 1516 | ], 1517 | "properties": { 1518 | "style": "color: var(--shiki-token-keyword)", 1519 | }, 1520 | "tagName": "span", 1521 | "type": "element", 1522 | }, 1523 | { 1524 | "children": [ 1525 | { 1526 | "type": "text", 1527 | "value": " ", 1528 | }, 1529 | ], 1530 | "properties": { 1531 | "style": "color: var(--shiki-color-text)", 1532 | }, 1533 | "tagName": "span", 1534 | "type": "element", 1535 | }, 1536 | { 1537 | "children": [ 1538 | { 1539 | "type": "text", 1540 | "value": "\\"string\\"", 1541 | }, 1542 | ], 1543 | "properties": { 1544 | "style": "color: var(--shiki-token-string-expression)", 1545 | }, 1546 | "tagName": "span", 1547 | "type": "element", 1548 | }, 1549 | { 1550 | "children": [ 1551 | { 1552 | "type": "text", 1553 | "value": ") {", 1554 | }, 1555 | ], 1556 | "properties": { 1557 | "style": "color: var(--shiki-color-text)", 1558 | }, 1559 | "tagName": "span", 1560 | "type": "element", 1561 | }, 1562 | ], 1563 | "properties": { 1564 | "dataHighlighted": false, 1565 | "dataLineNumber": "2", 1566 | }, 1567 | "tagName": "span", 1568 | "type": "element", 1569 | }, 1570 | { 1571 | "children": [ 1572 | { 1573 | "children": [ 1574 | { 1575 | "type": "text", 1576 | "value": " ", 1577 | }, 1578 | ], 1579 | "properties": { 1580 | "style": "color: var(--shiki-color-text)", 1581 | }, 1582 | "tagName": "span", 1583 | "type": "element", 1584 | }, 1585 | { 1586 | "children": [ 1587 | { 1588 | "type": "text", 1589 | "value": "console", 1590 | }, 1591 | ], 1592 | "properties": { 1593 | "style": "color: var(--shiki-token-constant)", 1594 | }, 1595 | "tagName": "span", 1596 | "type": "element", 1597 | }, 1598 | { 1599 | "children": [ 1600 | { 1601 | "type": "text", 1602 | "value": ".log", 1603 | }, 1604 | ], 1605 | "properties": { 1606 | "style": "color: var(--shiki-token-function)", 1607 | }, 1608 | "tagName": "span", 1609 | "type": "element", 1610 | }, 1611 | { 1612 | "children": [ 1613 | { 1614 | "type": "text", 1615 | "value": "(", 1616 | }, 1617 | ], 1618 | "properties": { 1619 | "style": "color: var(--shiki-color-text)", 1620 | }, 1621 | "tagName": "span", 1622 | "type": "element", 1623 | }, 1624 | { 1625 | "children": [ 1626 | { 1627 | "type": "text", 1628 | "value": "\`Hello ", 1629 | }, 1630 | ], 1631 | "properties": { 1632 | "style": "color: var(--shiki-token-string-expression)", 1633 | }, 1634 | "tagName": "span", 1635 | "type": "element", 1636 | }, 1637 | { 1638 | "children": [ 1639 | { 1640 | "type": "text", 1641 | "value": "\${", 1642 | }, 1643 | ], 1644 | "properties": { 1645 | "style": "color: var(--shiki-token-keyword)", 1646 | }, 1647 | "tagName": "span", 1648 | "type": "element", 1649 | }, 1650 | { 1651 | "children": [ 1652 | { 1653 | "type": "text", 1654 | "value": "value", 1655 | }, 1656 | ], 1657 | "properties": { 1658 | "style": "color: var(--shiki-color-text)", 1659 | }, 1660 | "tagName": "span", 1661 | "type": "element", 1662 | }, 1663 | { 1664 | "children": [ 1665 | { 1666 | "type": "text", 1667 | "value": "}", 1668 | }, 1669 | ], 1670 | "properties": { 1671 | "style": "color: var(--shiki-token-keyword)", 1672 | }, 1673 | "tagName": "span", 1674 | "type": "element", 1675 | }, 1676 | { 1677 | "children": [ 1678 | { 1679 | "type": "text", 1680 | "value": "\`", 1681 | }, 1682 | ], 1683 | "properties": { 1684 | "style": "color: var(--shiki-token-string-expression)", 1685 | }, 1686 | "tagName": "span", 1687 | "type": "element", 1688 | }, 1689 | { 1690 | "children": [ 1691 | { 1692 | "type": "text", 1693 | "value": ");", 1694 | }, 1695 | ], 1696 | "properties": { 1697 | "style": "color: var(--shiki-color-text)", 1698 | }, 1699 | "tagName": "span", 1700 | "type": "element", 1701 | }, 1702 | ], 1703 | "properties": { 1704 | "dataHighlighted": false, 1705 | "dataLineNumber": "3", 1706 | }, 1707 | "tagName": "span", 1708 | "type": "element", 1709 | }, 1710 | { 1711 | "children": [ 1712 | { 1713 | "children": [ 1714 | { 1715 | "type": "text", 1716 | "value": " } ", 1717 | }, 1718 | ], 1719 | "properties": { 1720 | "style": "color: var(--shiki-color-text)", 1721 | }, 1722 | "tagName": "span", 1723 | "type": "element", 1724 | }, 1725 | { 1726 | "children": [ 1727 | { 1728 | "type": "text", 1729 | "value": "else", 1730 | }, 1731 | ], 1732 | "properties": { 1733 | "style": "color: var(--shiki-token-keyword)", 1734 | }, 1735 | "tagName": "span", 1736 | "type": "element", 1737 | }, 1738 | { 1739 | "children": [ 1740 | { 1741 | "type": "text", 1742 | "value": " {", 1743 | }, 1744 | ], 1745 | "properties": { 1746 | "style": "color: var(--shiki-color-text)", 1747 | }, 1748 | "tagName": "span", 1749 | "type": "element", 1750 | }, 1751 | ], 1752 | "properties": { 1753 | "dataHighlighted": false, 1754 | "dataLineNumber": "4", 1755 | }, 1756 | "tagName": "span", 1757 | "type": "element", 1758 | }, 1759 | { 1760 | "children": [ 1761 | { 1762 | "children": [ 1763 | { 1764 | "type": "text", 1765 | "value": " ", 1766 | }, 1767 | ], 1768 | "properties": { 1769 | "style": "color: var(--shiki-color-text)", 1770 | }, 1771 | "tagName": "span", 1772 | "type": "element", 1773 | }, 1774 | { 1775 | "children": [ 1776 | { 1777 | "type": "text", 1778 | "value": "throw", 1779 | }, 1780 | ], 1781 | "properties": { 1782 | "style": "color: var(--shiki-token-keyword)", 1783 | }, 1784 | "tagName": "span", 1785 | "type": "element", 1786 | }, 1787 | { 1788 | "children": [ 1789 | { 1790 | "type": "text", 1791 | "value": " ", 1792 | }, 1793 | ], 1794 | "properties": { 1795 | "style": "color: var(--shiki-color-text)", 1796 | }, 1797 | "tagName": "span", 1798 | "type": "element", 1799 | }, 1800 | { 1801 | "children": [ 1802 | { 1803 | "type": "text", 1804 | "value": "new", 1805 | }, 1806 | ], 1807 | "properties": { 1808 | "style": "color: var(--shiki-token-keyword)", 1809 | }, 1810 | "tagName": "span", 1811 | "type": "element", 1812 | }, 1813 | { 1814 | "children": [ 1815 | { 1816 | "type": "text", 1817 | "value": " ", 1818 | }, 1819 | ], 1820 | "properties": { 1821 | "style": "color: var(--shiki-color-text)", 1822 | }, 1823 | "tagName": "span", 1824 | "type": "element", 1825 | }, 1826 | { 1827 | "children": [ 1828 | { 1829 | "type": "text", 1830 | "value": "Error", 1831 | }, 1832 | ], 1833 | "properties": { 1834 | "style": "color: var(--shiki-token-function)", 1835 | }, 1836 | "tagName": "span", 1837 | "type": "element", 1838 | }, 1839 | { 1840 | "children": [ 1841 | { 1842 | "type": "text", 1843 | "value": "(", 1844 | }, 1845 | ], 1846 | "properties": { 1847 | "style": "color: var(--shiki-color-text)", 1848 | }, 1849 | "tagName": "span", 1850 | "type": "element", 1851 | }, 1852 | { 1853 | "children": [ 1854 | { 1855 | "type": "text", 1856 | "value": "\`Can not greet 'undefined'!\`", 1857 | }, 1858 | ], 1859 | "properties": { 1860 | "style": "color: var(--shiki-token-string-expression)", 1861 | }, 1862 | "tagName": "span", 1863 | "type": "element", 1864 | }, 1865 | { 1866 | "children": [ 1867 | { 1868 | "type": "text", 1869 | "value": ");", 1870 | }, 1871 | ], 1872 | "properties": { 1873 | "style": "color: var(--shiki-color-text)", 1874 | }, 1875 | "tagName": "span", 1876 | "type": "element", 1877 | }, 1878 | ], 1879 | "properties": { 1880 | "dataHighlighted": false, 1881 | "dataLineNumber": "5", 1882 | }, 1883 | "tagName": "span", 1884 | "type": "element", 1885 | }, 1886 | { 1887 | "children": [ 1888 | { 1889 | "children": [ 1890 | { 1891 | "type": "text", 1892 | "value": " }", 1893 | }, 1894 | ], 1895 | "properties": { 1896 | "style": "color: var(--shiki-color-text)", 1897 | }, 1898 | "tagName": "span", 1899 | "type": "element", 1900 | }, 1901 | ], 1902 | "properties": { 1903 | "dataHighlighted": false, 1904 | "dataLineNumber": "6", 1905 | }, 1906 | "tagName": "span", 1907 | "type": "element", 1908 | }, 1909 | { 1910 | "children": [ 1911 | { 1912 | "children": [ 1913 | { 1914 | "type": "text", 1915 | "value": "}", 1916 | }, 1917 | ], 1918 | "properties": { 1919 | "style": "color: var(--shiki-color-text)", 1920 | }, 1921 | "tagName": "span", 1922 | "type": "element", 1923 | }, 1924 | ], 1925 | "properties": { 1926 | "dataHighlighted": false, 1927 | "dataLineNumber": "7", 1928 | }, 1929 | "tagName": "span", 1930 | "type": "element", 1931 | }, 1932 | { 1933 | "children": [], 1934 | "properties": { 1935 | "dataHighlighted": false, 1936 | "dataLineNumber": "8", 1937 | }, 1938 | "tagName": "span", 1939 | "type": "element", 1940 | }, 1941 | { 1942 | "children": [ 1943 | { 1944 | "children": [ 1945 | { 1946 | "type": "text", 1947 | "value": "hello", 1948 | }, 1949 | ], 1950 | "properties": { 1951 | "style": "color: var(--shiki-token-function)", 1952 | }, 1953 | "tagName": "span", 1954 | "type": "element", 1955 | }, 1956 | { 1957 | "children": [ 1958 | { 1959 | "type": "text", 1960 | "value": "(", 1961 | }, 1962 | ], 1963 | "properties": { 1964 | "style": "color: var(--shiki-color-text)", 1965 | }, 1966 | "tagName": "span", 1967 | "type": "element", 1968 | }, 1969 | { 1970 | "children": [ 1971 | { 1972 | "type": "text", 1973 | "value": "\\"world!\\"", 1974 | }, 1975 | ], 1976 | "properties": { 1977 | "style": "color: var(--shiki-token-string-expression)", 1978 | }, 1979 | "tagName": "span", 1980 | "type": "element", 1981 | }, 1982 | { 1983 | "children": [ 1984 | { 1985 | "type": "text", 1986 | "value": ");", 1987 | }, 1988 | ], 1989 | "properties": { 1990 | "style": "color: var(--shiki-color-text)", 1991 | }, 1992 | "tagName": "span", 1993 | "type": "element", 1994 | }, 1995 | ], 1996 | "properties": { 1997 | "dataHighlighted": false, 1998 | "dataLineNumber": "9", 1999 | }, 2000 | "tagName": "span", 2001 | "type": "element", 2002 | }, 2003 | { 2004 | "children": [], 2005 | "properties": { 2006 | "dataHighlighted": false, 2007 | "dataLineNumber": "10", 2008 | }, 2009 | "tagName": "span", 2010 | "type": "element", 2011 | }, 2012 | ], 2013 | "properties": { 2014 | "dataLanguage": undefined, 2015 | "dataLineNumbers": false, 2016 | }, 2017 | "tagName": "code", 2018 | "type": "element", 2019 | }, 2020 | ], 2021 | "properties": { 2022 | "dataCodeTitle": undefined, 2023 | }, 2024 | "tagName": "pre", 2025 | "type": "element", 2026 | } 2027 | `; 2028 | 2029 | exports[`renderToHast > should render fixture: fixture.rb 1`] = ` 2030 | { 2031 | "children": [ 2032 | { 2033 | "children": [ 2034 | { 2035 | "children": [ 2036 | { 2037 | "children": [ 2038 | { 2039 | "type": "text", 2040 | "value": "puts", 2041 | }, 2042 | ], 2043 | "properties": { 2044 | "style": "color: var(--shiki-token-function)", 2045 | }, 2046 | "tagName": "span", 2047 | "type": "element", 2048 | }, 2049 | { 2050 | "children": [ 2051 | { 2052 | "type": "text", 2053 | "value": " ", 2054 | }, 2055 | ], 2056 | "properties": { 2057 | "style": "color: var(--shiki-color-text)", 2058 | }, 2059 | "tagName": "span", 2060 | "type": "element", 2061 | }, 2062 | { 2063 | "children": [ 2064 | { 2065 | "type": "text", 2066 | "value": "'Hello World'", 2067 | }, 2068 | ], 2069 | "properties": { 2070 | "style": "color: var(--shiki-token-string-expression)", 2071 | }, 2072 | "tagName": "span", 2073 | "type": "element", 2074 | }, 2075 | ], 2076 | "properties": { 2077 | "dataHighlighted": false, 2078 | "dataLineNumber": "1", 2079 | }, 2080 | "tagName": "span", 2081 | "type": "element", 2082 | }, 2083 | { 2084 | "children": [], 2085 | "properties": { 2086 | "dataHighlighted": false, 2087 | "dataLineNumber": "2", 2088 | }, 2089 | "tagName": "span", 2090 | "type": "element", 2091 | }, 2092 | ], 2093 | "properties": { 2094 | "dataLanguage": undefined, 2095 | "dataLineNumbers": false, 2096 | }, 2097 | "tagName": "code", 2098 | "type": "element", 2099 | }, 2100 | ], 2101 | "properties": { 2102 | "dataCodeTitle": undefined, 2103 | }, 2104 | "tagName": "pre", 2105 | "type": "element", 2106 | } 2107 | `; 2108 | 2109 | exports[`renderToHast > should render fixture: fixture.sh 1`] = ` 2110 | { 2111 | "children": [ 2112 | { 2113 | "children": [ 2114 | { 2115 | "children": [ 2116 | { 2117 | "children": [ 2118 | { 2119 | "type": "text", 2120 | "value": "file=", 2121 | }, 2122 | ], 2123 | "properties": { 2124 | "style": "color: var(--shiki-color-text)", 2125 | }, 2126 | "tagName": "span", 2127 | "type": "element", 2128 | }, 2129 | { 2130 | "children": [ 2131 | { 2132 | "type": "text", 2133 | "value": "\\"fixture\\"", 2134 | }, 2135 | ], 2136 | "properties": { 2137 | "style": "color: var(--shiki-token-string-expression)", 2138 | }, 2139 | "tagName": "span", 2140 | "type": "element", 2141 | }, 2142 | ], 2143 | "properties": { 2144 | "dataHighlighted": false, 2145 | "dataLineNumber": "1", 2146 | }, 2147 | "tagName": "span", 2148 | "type": "element", 2149 | }, 2150 | { 2151 | "children": [ 2152 | { 2153 | "children": [ 2154 | { 2155 | "type": "text", 2156 | "value": "extensions=(", 2157 | }, 2158 | ], 2159 | "properties": { 2160 | "style": "color: var(--shiki-color-text)", 2161 | }, 2162 | "tagName": "span", 2163 | "type": "element", 2164 | }, 2165 | { 2166 | "children": [ 2167 | { 2168 | "type": "text", 2169 | "value": "\\"css\\"", 2170 | }, 2171 | ], 2172 | "properties": { 2173 | "style": "color: var(--shiki-token-string-expression)", 2174 | }, 2175 | "tagName": "span", 2176 | "type": "element", 2177 | }, 2178 | { 2179 | "children": [ 2180 | { 2181 | "type": "text", 2182 | "value": " ", 2183 | }, 2184 | ], 2185 | "properties": { 2186 | "style": "color: var(--shiki-color-text)", 2187 | }, 2188 | "tagName": "span", 2189 | "type": "element", 2190 | }, 2191 | { 2192 | "children": [ 2193 | { 2194 | "type": "text", 2195 | "value": "\\"js\\"", 2196 | }, 2197 | ], 2198 | "properties": { 2199 | "style": "color: var(--shiki-token-string-expression)", 2200 | }, 2201 | "tagName": "span", 2202 | "type": "element", 2203 | }, 2204 | { 2205 | "children": [ 2206 | { 2207 | "type": "text", 2208 | "value": " ", 2209 | }, 2210 | ], 2211 | "properties": { 2212 | "style": "color: var(--shiki-color-text)", 2213 | }, 2214 | "tagName": "span", 2215 | "type": "element", 2216 | }, 2217 | { 2218 | "children": [ 2219 | { 2220 | "type": "text", 2221 | "value": "\\"sh\\"", 2222 | }, 2223 | ], 2224 | "properties": { 2225 | "style": "color: var(--shiki-token-string-expression)", 2226 | }, 2227 | "tagName": "span", 2228 | "type": "element", 2229 | }, 2230 | { 2231 | "children": [ 2232 | { 2233 | "type": "text", 2234 | "value": " ", 2235 | }, 2236 | ], 2237 | "properties": { 2238 | "style": "color: var(--shiki-color-text)", 2239 | }, 2240 | "tagName": "span", 2241 | "type": "element", 2242 | }, 2243 | { 2244 | "children": [ 2245 | { 2246 | "type": "text", 2247 | "value": "\\"sh\\"", 2248 | }, 2249 | ], 2250 | "properties": { 2251 | "style": "color: var(--shiki-token-string-expression)", 2252 | }, 2253 | "tagName": "span", 2254 | "type": "element", 2255 | }, 2256 | { 2257 | "children": [ 2258 | { 2259 | "type": "text", 2260 | "value": ")", 2261 | }, 2262 | ], 2263 | "properties": { 2264 | "style": "color: var(--shiki-color-text)", 2265 | }, 2266 | "tagName": "span", 2267 | "type": "element", 2268 | }, 2269 | ], 2270 | "properties": { 2271 | "dataHighlighted": false, 2272 | "dataLineNumber": "2", 2273 | }, 2274 | "tagName": "span", 2275 | "type": "element", 2276 | }, 2277 | { 2278 | "children": [], 2279 | "properties": { 2280 | "dataHighlighted": false, 2281 | "dataLineNumber": "3", 2282 | }, 2283 | "tagName": "span", 2284 | "type": "element", 2285 | }, 2286 | { 2287 | "children": [ 2288 | { 2289 | "children": [ 2290 | { 2291 | "type": "text", 2292 | "value": "for", 2293 | }, 2294 | ], 2295 | "properties": { 2296 | "style": "color: var(--shiki-token-keyword)", 2297 | }, 2298 | "tagName": "span", 2299 | "type": "element", 2300 | }, 2301 | { 2302 | "children": [ 2303 | { 2304 | "type": "text", 2305 | "value": " ext ", 2306 | }, 2307 | ], 2308 | "properties": { 2309 | "style": "color: var(--shiki-color-text)", 2310 | }, 2311 | "tagName": "span", 2312 | "type": "element", 2313 | }, 2314 | { 2315 | "children": [ 2316 | { 2317 | "type": "text", 2318 | "value": "in", 2319 | }, 2320 | ], 2321 | "properties": { 2322 | "style": "color: var(--shiki-token-keyword)", 2323 | }, 2324 | "tagName": "span", 2325 | "type": "element", 2326 | }, 2327 | { 2328 | "children": [ 2329 | { 2330 | "type": "text", 2331 | "value": " \${extensions[*]} ", 2332 | }, 2333 | ], 2334 | "properties": { 2335 | "style": "color: var(--shiki-color-text)", 2336 | }, 2337 | "tagName": "span", 2338 | "type": "element", 2339 | }, 2340 | { 2341 | "children": [ 2342 | { 2343 | "type": "text", 2344 | "value": ";", 2345 | }, 2346 | ], 2347 | "properties": { 2348 | "style": "color: var(--shiki-token-keyword)", 2349 | }, 2350 | "tagName": "span", 2351 | "type": "element", 2352 | }, 2353 | { 2354 | "children": [ 2355 | { 2356 | "type": "text", 2357 | "value": " ", 2358 | }, 2359 | ], 2360 | "properties": { 2361 | "style": "color: var(--shiki-color-text)", 2362 | }, 2363 | "tagName": "span", 2364 | "type": "element", 2365 | }, 2366 | { 2367 | "children": [ 2368 | { 2369 | "type": "text", 2370 | "value": "do", 2371 | }, 2372 | ], 2373 | "properties": { 2374 | "style": "color: var(--shiki-token-keyword)", 2375 | }, 2376 | "tagName": "span", 2377 | "type": "element", 2378 | }, 2379 | ], 2380 | "properties": { 2381 | "dataHighlighted": false, 2382 | "dataLineNumber": "4", 2383 | }, 2384 | "tagName": "span", 2385 | "type": "element", 2386 | }, 2387 | { 2388 | "children": [ 2389 | { 2390 | "children": [ 2391 | { 2392 | "type": "text", 2393 | "value": " ", 2394 | }, 2395 | ], 2396 | "properties": { 2397 | "style": "color: var(--shiki-color-text)", 2398 | }, 2399 | "tagName": "span", 2400 | "type": "element", 2401 | }, 2402 | { 2403 | "children": [ 2404 | { 2405 | "type": "text", 2406 | "value": "echo", 2407 | }, 2408 | ], 2409 | "properties": { 2410 | "style": "color: var(--shiki-token-function)", 2411 | }, 2412 | "tagName": "span", 2413 | "type": "element", 2414 | }, 2415 | { 2416 | "children": [ 2417 | { 2418 | "type": "text", 2419 | "value": " ", 2420 | }, 2421 | ], 2422 | "properties": { 2423 | "style": "color: var(--shiki-color-text)", 2424 | }, 2425 | "tagName": "span", 2426 | "type": "element", 2427 | }, 2428 | { 2429 | "children": [ 2430 | { 2431 | "type": "text", 2432 | "value": "\\"$file.\${ext}\\"", 2433 | }, 2434 | ], 2435 | "properties": { 2436 | "style": "color: var(--shiki-token-string-expression)", 2437 | }, 2438 | "tagName": "span", 2439 | "type": "element", 2440 | }, 2441 | ], 2442 | "properties": { 2443 | "dataHighlighted": false, 2444 | "dataLineNumber": "5", 2445 | }, 2446 | "tagName": "span", 2447 | "type": "element", 2448 | }, 2449 | { 2450 | "children": [ 2451 | { 2452 | "children": [ 2453 | { 2454 | "type": "text", 2455 | "value": "done", 2456 | }, 2457 | ], 2458 | "properties": { 2459 | "style": "color: var(--shiki-token-keyword)", 2460 | }, 2461 | "tagName": "span", 2462 | "type": "element", 2463 | }, 2464 | ], 2465 | "properties": { 2466 | "dataHighlighted": false, 2467 | "dataLineNumber": "6", 2468 | }, 2469 | "tagName": "span", 2470 | "type": "element", 2471 | }, 2472 | { 2473 | "children": [], 2474 | "properties": { 2475 | "dataHighlighted": false, 2476 | "dataLineNumber": "7", 2477 | }, 2478 | "tagName": "span", 2479 | "type": "element", 2480 | }, 2481 | { 2482 | "children": [], 2483 | "properties": { 2484 | "dataHighlighted": false, 2485 | "dataLineNumber": "8", 2486 | }, 2487 | "tagName": "span", 2488 | "type": "element", 2489 | }, 2490 | ], 2491 | "properties": { 2492 | "dataLanguage": undefined, 2493 | "dataLineNumbers": false, 2494 | }, 2495 | "tagName": "code", 2496 | "type": "element", 2497 | }, 2498 | ], 2499 | "properties": { 2500 | "dataCodeTitle": undefined, 2501 | }, 2502 | "tagName": "pre", 2503 | "type": "element", 2504 | } 2505 | `; 2506 | 2507 | exports[`renderToHast > should render fixture: fixture.ts 1`] = ` 2508 | { 2509 | "children": [ 2510 | { 2511 | "children": [ 2512 | { 2513 | "children": [ 2514 | { 2515 | "children": [ 2516 | { 2517 | "type": "text", 2518 | "value": "function", 2519 | }, 2520 | ], 2521 | "properties": { 2522 | "style": "color: var(--shiki-token-keyword)", 2523 | }, 2524 | "tagName": "span", 2525 | "type": "element", 2526 | }, 2527 | { 2528 | "children": [ 2529 | { 2530 | "type": "text", 2531 | "value": " ", 2532 | }, 2533 | ], 2534 | "properties": { 2535 | "style": "color: var(--shiki-color-text)", 2536 | }, 2537 | "tagName": "span", 2538 | "type": "element", 2539 | }, 2540 | { 2541 | "children": [ 2542 | { 2543 | "type": "text", 2544 | "value": "hello", 2545 | }, 2546 | ], 2547 | "properties": { 2548 | "style": "color: var(--shiki-token-function)", 2549 | }, 2550 | "tagName": "span", 2551 | "type": "element", 2552 | }, 2553 | { 2554 | "children": [ 2555 | { 2556 | "type": "text", 2557 | "value": "(value", 2558 | }, 2559 | ], 2560 | "properties": { 2561 | "style": "color: var(--shiki-color-text)", 2562 | }, 2563 | "tagName": "span", 2564 | "type": "element", 2565 | }, 2566 | { 2567 | "children": [ 2568 | { 2569 | "type": "text", 2570 | "value": ":", 2571 | }, 2572 | ], 2573 | "properties": { 2574 | "style": "color: var(--shiki-token-keyword)", 2575 | }, 2576 | "tagName": "span", 2577 | "type": "element", 2578 | }, 2579 | { 2580 | "children": [ 2581 | { 2582 | "type": "text", 2583 | "value": " ", 2584 | }, 2585 | ], 2586 | "properties": { 2587 | "style": "color: var(--shiki-color-text)", 2588 | }, 2589 | "tagName": "span", 2590 | "type": "element", 2591 | }, 2592 | { 2593 | "children": [ 2594 | { 2595 | "type": "text", 2596 | "value": "string", 2597 | }, 2598 | ], 2599 | "properties": { 2600 | "style": "color: var(--shiki-token-constant)", 2601 | }, 2602 | "tagName": "span", 2603 | "type": "element", 2604 | }, 2605 | { 2606 | "children": [ 2607 | { 2608 | "type": "text", 2609 | "value": " ", 2610 | }, 2611 | ], 2612 | "properties": { 2613 | "style": "color: var(--shiki-color-text)", 2614 | }, 2615 | "tagName": "span", 2616 | "type": "element", 2617 | }, 2618 | { 2619 | "children": [ 2620 | { 2621 | "type": "text", 2622 | "value": "|", 2623 | }, 2624 | ], 2625 | "properties": { 2626 | "style": "color: var(--shiki-token-keyword)", 2627 | }, 2628 | "tagName": "span", 2629 | "type": "element", 2630 | }, 2631 | { 2632 | "children": [ 2633 | { 2634 | "type": "text", 2635 | "value": " ", 2636 | }, 2637 | ], 2638 | "properties": { 2639 | "style": "color: var(--shiki-color-text)", 2640 | }, 2641 | "tagName": "span", 2642 | "type": "element", 2643 | }, 2644 | { 2645 | "children": [ 2646 | { 2647 | "type": "text", 2648 | "value": "undefined", 2649 | }, 2650 | ], 2651 | "properties": { 2652 | "style": "color: var(--shiki-token-constant)", 2653 | }, 2654 | "tagName": "span", 2655 | "type": "element", 2656 | }, 2657 | { 2658 | "children": [ 2659 | { 2660 | "type": "text", 2661 | "value": ") {", 2662 | }, 2663 | ], 2664 | "properties": { 2665 | "style": "color: var(--shiki-color-text)", 2666 | }, 2667 | "tagName": "span", 2668 | "type": "element", 2669 | }, 2670 | ], 2671 | "properties": { 2672 | "dataHighlighted": false, 2673 | "dataLineNumber": "1", 2674 | }, 2675 | "tagName": "span", 2676 | "type": "element", 2677 | }, 2678 | { 2679 | "children": [ 2680 | { 2681 | "children": [ 2682 | { 2683 | "type": "text", 2684 | "value": " ", 2685 | }, 2686 | ], 2687 | "properties": { 2688 | "style": "color: var(--shiki-color-text)", 2689 | }, 2690 | "tagName": "span", 2691 | "type": "element", 2692 | }, 2693 | { 2694 | "children": [ 2695 | { 2696 | "type": "text", 2697 | "value": "if", 2698 | }, 2699 | ], 2700 | "properties": { 2701 | "style": "color: var(--shiki-token-keyword)", 2702 | }, 2703 | "tagName": "span", 2704 | "type": "element", 2705 | }, 2706 | { 2707 | "children": [ 2708 | { 2709 | "type": "text", 2710 | "value": " (", 2711 | }, 2712 | ], 2713 | "properties": { 2714 | "style": "color: var(--shiki-color-text)", 2715 | }, 2716 | "tagName": "span", 2717 | "type": "element", 2718 | }, 2719 | { 2720 | "children": [ 2721 | { 2722 | "type": "text", 2723 | "value": "typeof", 2724 | }, 2725 | ], 2726 | "properties": { 2727 | "style": "color: var(--shiki-token-keyword)", 2728 | }, 2729 | "tagName": "span", 2730 | "type": "element", 2731 | }, 2732 | { 2733 | "children": [ 2734 | { 2735 | "type": "text", 2736 | "value": " value ", 2737 | }, 2738 | ], 2739 | "properties": { 2740 | "style": "color: var(--shiki-color-text)", 2741 | }, 2742 | "tagName": "span", 2743 | "type": "element", 2744 | }, 2745 | { 2746 | "children": [ 2747 | { 2748 | "type": "text", 2749 | "value": "===", 2750 | }, 2751 | ], 2752 | "properties": { 2753 | "style": "color: var(--shiki-token-keyword)", 2754 | }, 2755 | "tagName": "span", 2756 | "type": "element", 2757 | }, 2758 | { 2759 | "children": [ 2760 | { 2761 | "type": "text", 2762 | "value": " ", 2763 | }, 2764 | ], 2765 | "properties": { 2766 | "style": "color: var(--shiki-color-text)", 2767 | }, 2768 | "tagName": "span", 2769 | "type": "element", 2770 | }, 2771 | { 2772 | "children": [ 2773 | { 2774 | "type": "text", 2775 | "value": "\\"string\\"", 2776 | }, 2777 | ], 2778 | "properties": { 2779 | "style": "color: var(--shiki-token-string-expression)", 2780 | }, 2781 | "tagName": "span", 2782 | "type": "element", 2783 | }, 2784 | { 2785 | "children": [ 2786 | { 2787 | "type": "text", 2788 | "value": ") {", 2789 | }, 2790 | ], 2791 | "properties": { 2792 | "style": "color: var(--shiki-color-text)", 2793 | }, 2794 | "tagName": "span", 2795 | "type": "element", 2796 | }, 2797 | ], 2798 | "properties": { 2799 | "dataHighlighted": false, 2800 | "dataLineNumber": "2", 2801 | }, 2802 | "tagName": "span", 2803 | "type": "element", 2804 | }, 2805 | { 2806 | "children": [ 2807 | { 2808 | "children": [ 2809 | { 2810 | "type": "text", 2811 | "value": " ", 2812 | }, 2813 | ], 2814 | "properties": { 2815 | "style": "color: var(--shiki-color-text)", 2816 | }, 2817 | "tagName": "span", 2818 | "type": "element", 2819 | }, 2820 | { 2821 | "children": [ 2822 | { 2823 | "type": "text", 2824 | "value": "console", 2825 | }, 2826 | ], 2827 | "properties": { 2828 | "style": "color: var(--shiki-token-constant)", 2829 | }, 2830 | "tagName": "span", 2831 | "type": "element", 2832 | }, 2833 | { 2834 | "children": [ 2835 | { 2836 | "type": "text", 2837 | "value": ".log", 2838 | }, 2839 | ], 2840 | "properties": { 2841 | "style": "color: var(--shiki-token-function)", 2842 | }, 2843 | "tagName": "span", 2844 | "type": "element", 2845 | }, 2846 | { 2847 | "children": [ 2848 | { 2849 | "type": "text", 2850 | "value": "(", 2851 | }, 2852 | ], 2853 | "properties": { 2854 | "style": "color: var(--shiki-color-text)", 2855 | }, 2856 | "tagName": "span", 2857 | "type": "element", 2858 | }, 2859 | { 2860 | "children": [ 2861 | { 2862 | "type": "text", 2863 | "value": "\`Hello ", 2864 | }, 2865 | ], 2866 | "properties": { 2867 | "style": "color: var(--shiki-token-string-expression)", 2868 | }, 2869 | "tagName": "span", 2870 | "type": "element", 2871 | }, 2872 | { 2873 | "children": [ 2874 | { 2875 | "type": "text", 2876 | "value": "\${", 2877 | }, 2878 | ], 2879 | "properties": { 2880 | "style": "color: var(--shiki-token-keyword)", 2881 | }, 2882 | "tagName": "span", 2883 | "type": "element", 2884 | }, 2885 | { 2886 | "children": [ 2887 | { 2888 | "type": "text", 2889 | "value": "value", 2890 | }, 2891 | ], 2892 | "properties": { 2893 | "style": "color: var(--shiki-color-text)", 2894 | }, 2895 | "tagName": "span", 2896 | "type": "element", 2897 | }, 2898 | { 2899 | "children": [ 2900 | { 2901 | "type": "text", 2902 | "value": "}", 2903 | }, 2904 | ], 2905 | "properties": { 2906 | "style": "color: var(--shiki-token-keyword)", 2907 | }, 2908 | "tagName": "span", 2909 | "type": "element", 2910 | }, 2911 | { 2912 | "children": [ 2913 | { 2914 | "type": "text", 2915 | "value": "\`", 2916 | }, 2917 | ], 2918 | "properties": { 2919 | "style": "color: var(--shiki-token-string-expression)", 2920 | }, 2921 | "tagName": "span", 2922 | "type": "element", 2923 | }, 2924 | { 2925 | "children": [ 2926 | { 2927 | "type": "text", 2928 | "value": ");", 2929 | }, 2930 | ], 2931 | "properties": { 2932 | "style": "color: var(--shiki-color-text)", 2933 | }, 2934 | "tagName": "span", 2935 | "type": "element", 2936 | }, 2937 | ], 2938 | "properties": { 2939 | "dataHighlighted": false, 2940 | "dataLineNumber": "3", 2941 | }, 2942 | "tagName": "span", 2943 | "type": "element", 2944 | }, 2945 | { 2946 | "children": [ 2947 | { 2948 | "children": [ 2949 | { 2950 | "type": "text", 2951 | "value": " } ", 2952 | }, 2953 | ], 2954 | "properties": { 2955 | "style": "color: var(--shiki-color-text)", 2956 | }, 2957 | "tagName": "span", 2958 | "type": "element", 2959 | }, 2960 | { 2961 | "children": [ 2962 | { 2963 | "type": "text", 2964 | "value": "else", 2965 | }, 2966 | ], 2967 | "properties": { 2968 | "style": "color: var(--shiki-token-keyword)", 2969 | }, 2970 | "tagName": "span", 2971 | "type": "element", 2972 | }, 2973 | { 2974 | "children": [ 2975 | { 2976 | "type": "text", 2977 | "value": " {", 2978 | }, 2979 | ], 2980 | "properties": { 2981 | "style": "color: var(--shiki-color-text)", 2982 | }, 2983 | "tagName": "span", 2984 | "type": "element", 2985 | }, 2986 | ], 2987 | "properties": { 2988 | "dataHighlighted": false, 2989 | "dataLineNumber": "4", 2990 | }, 2991 | "tagName": "span", 2992 | "type": "element", 2993 | }, 2994 | { 2995 | "children": [ 2996 | { 2997 | "children": [ 2998 | { 2999 | "type": "text", 3000 | "value": " ", 3001 | }, 3002 | ], 3003 | "properties": { 3004 | "style": "color: var(--shiki-color-text)", 3005 | }, 3006 | "tagName": "span", 3007 | "type": "element", 3008 | }, 3009 | { 3010 | "children": [ 3011 | { 3012 | "type": "text", 3013 | "value": "throw", 3014 | }, 3015 | ], 3016 | "properties": { 3017 | "style": "color: var(--shiki-token-keyword)", 3018 | }, 3019 | "tagName": "span", 3020 | "type": "element", 3021 | }, 3022 | { 3023 | "children": [ 3024 | { 3025 | "type": "text", 3026 | "value": " ", 3027 | }, 3028 | ], 3029 | "properties": { 3030 | "style": "color: var(--shiki-color-text)", 3031 | }, 3032 | "tagName": "span", 3033 | "type": "element", 3034 | }, 3035 | { 3036 | "children": [ 3037 | { 3038 | "type": "text", 3039 | "value": "new", 3040 | }, 3041 | ], 3042 | "properties": { 3043 | "style": "color: var(--shiki-token-keyword)", 3044 | }, 3045 | "tagName": "span", 3046 | "type": "element", 3047 | }, 3048 | { 3049 | "children": [ 3050 | { 3051 | "type": "text", 3052 | "value": " ", 3053 | }, 3054 | ], 3055 | "properties": { 3056 | "style": "color: var(--shiki-color-text)", 3057 | }, 3058 | "tagName": "span", 3059 | "type": "element", 3060 | }, 3061 | { 3062 | "children": [ 3063 | { 3064 | "type": "text", 3065 | "value": "Error", 3066 | }, 3067 | ], 3068 | "properties": { 3069 | "style": "color: var(--shiki-token-function)", 3070 | }, 3071 | "tagName": "span", 3072 | "type": "element", 3073 | }, 3074 | { 3075 | "children": [ 3076 | { 3077 | "type": "text", 3078 | "value": "(", 3079 | }, 3080 | ], 3081 | "properties": { 3082 | "style": "color: var(--shiki-color-text)", 3083 | }, 3084 | "tagName": "span", 3085 | "type": "element", 3086 | }, 3087 | { 3088 | "children": [ 3089 | { 3090 | "type": "text", 3091 | "value": "\`Can not greet 'undefined'!\`", 3092 | }, 3093 | ], 3094 | "properties": { 3095 | "style": "color: var(--shiki-token-string-expression)", 3096 | }, 3097 | "tagName": "span", 3098 | "type": "element", 3099 | }, 3100 | { 3101 | "children": [ 3102 | { 3103 | "type": "text", 3104 | "value": ");", 3105 | }, 3106 | ], 3107 | "properties": { 3108 | "style": "color: var(--shiki-color-text)", 3109 | }, 3110 | "tagName": "span", 3111 | "type": "element", 3112 | }, 3113 | ], 3114 | "properties": { 3115 | "dataHighlighted": false, 3116 | "dataLineNumber": "5", 3117 | }, 3118 | "tagName": "span", 3119 | "type": "element", 3120 | }, 3121 | { 3122 | "children": [ 3123 | { 3124 | "children": [ 3125 | { 3126 | "type": "text", 3127 | "value": " }", 3128 | }, 3129 | ], 3130 | "properties": { 3131 | "style": "color: var(--shiki-color-text)", 3132 | }, 3133 | "tagName": "span", 3134 | "type": "element", 3135 | }, 3136 | ], 3137 | "properties": { 3138 | "dataHighlighted": false, 3139 | "dataLineNumber": "6", 3140 | }, 3141 | "tagName": "span", 3142 | "type": "element", 3143 | }, 3144 | { 3145 | "children": [ 3146 | { 3147 | "children": [ 3148 | { 3149 | "type": "text", 3150 | "value": "}", 3151 | }, 3152 | ], 3153 | "properties": { 3154 | "style": "color: var(--shiki-color-text)", 3155 | }, 3156 | "tagName": "span", 3157 | "type": "element", 3158 | }, 3159 | ], 3160 | "properties": { 3161 | "dataHighlighted": false, 3162 | "dataLineNumber": "7", 3163 | }, 3164 | "tagName": "span", 3165 | "type": "element", 3166 | }, 3167 | { 3168 | "children": [], 3169 | "properties": { 3170 | "dataHighlighted": false, 3171 | "dataLineNumber": "8", 3172 | }, 3173 | "tagName": "span", 3174 | "type": "element", 3175 | }, 3176 | { 3177 | "children": [ 3178 | { 3179 | "children": [ 3180 | { 3181 | "type": "text", 3182 | "value": "hello", 3183 | }, 3184 | ], 3185 | "properties": { 3186 | "style": "color: var(--shiki-token-function)", 3187 | }, 3188 | "tagName": "span", 3189 | "type": "element", 3190 | }, 3191 | { 3192 | "children": [ 3193 | { 3194 | "type": "text", 3195 | "value": "(", 3196 | }, 3197 | ], 3198 | "properties": { 3199 | "style": "color: var(--shiki-color-text)", 3200 | }, 3201 | "tagName": "span", 3202 | "type": "element", 3203 | }, 3204 | { 3205 | "children": [ 3206 | { 3207 | "type": "text", 3208 | "value": "\\"world!\\"", 3209 | }, 3210 | ], 3211 | "properties": { 3212 | "style": "color: var(--shiki-token-string-expression)", 3213 | }, 3214 | "tagName": "span", 3215 | "type": "element", 3216 | }, 3217 | { 3218 | "children": [ 3219 | { 3220 | "type": "text", 3221 | "value": ");", 3222 | }, 3223 | ], 3224 | "properties": { 3225 | "style": "color: var(--shiki-color-text)", 3226 | }, 3227 | "tagName": "span", 3228 | "type": "element", 3229 | }, 3230 | ], 3231 | "properties": { 3232 | "dataHighlighted": false, 3233 | "dataLineNumber": "9", 3234 | }, 3235 | "tagName": "span", 3236 | "type": "element", 3237 | }, 3238 | { 3239 | "children": [], 3240 | "properties": { 3241 | "dataHighlighted": false, 3242 | "dataLineNumber": "10", 3243 | }, 3244 | "tagName": "span", 3245 | "type": "element", 3246 | }, 3247 | ], 3248 | "properties": { 3249 | "dataLanguage": undefined, 3250 | "dataLineNumbers": false, 3251 | }, 3252 | "tagName": "code", 3253 | "type": "element", 3254 | }, 3255 | ], 3256 | "properties": { 3257 | "dataCodeTitle": undefined, 3258 | }, 3259 | "tagName": "pre", 3260 | "type": "element", 3261 | } 3262 | `; 3263 | 3264 | exports[`renderToHast > should render fixture: fixture.txt 1`] = ` 3265 | { 3266 | "children": [ 3267 | { 3268 | "children": [ 3269 | { 3270 | "children": [ 3271 | { 3272 | "children": [ 3273 | { 3274 | "type": "text", 3275 | "value": "Hello World", 3276 | }, 3277 | ], 3278 | "properties": { 3279 | "style": undefined, 3280 | }, 3281 | "tagName": "span", 3282 | "type": "element", 3283 | }, 3284 | ], 3285 | "properties": { 3286 | "dataHighlighted": false, 3287 | "dataLineNumber": "1", 3288 | }, 3289 | "tagName": "span", 3290 | "type": "element", 3291 | }, 3292 | { 3293 | "children": [ 3294 | { 3295 | "children": [ 3296 | { 3297 | "type": "text", 3298 | "value": "", 3299 | }, 3300 | ], 3301 | "properties": { 3302 | "style": undefined, 3303 | }, 3304 | "tagName": "span", 3305 | "type": "element", 3306 | }, 3307 | ], 3308 | "properties": { 3309 | "dataHighlighted": false, 3310 | "dataLineNumber": "2", 3311 | }, 3312 | "tagName": "span", 3313 | "type": "element", 3314 | }, 3315 | ], 3316 | "properties": { 3317 | "dataLanguage": undefined, 3318 | "dataLineNumbers": false, 3319 | }, 3320 | "tagName": "code", 3321 | "type": "element", 3322 | }, 3323 | ], 3324 | "properties": { 3325 | "dataCodeTitle": undefined, 3326 | }, 3327 | "tagName": "pre", 3328 | "type": "element", 3329 | } 3330 | `; 3331 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | printf("Hello World"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::cout << "Hello World"; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.css: -------------------------------------------------------------------------------- 1 | .fixture::after { 2 | content: "hello world"; 3 | } 4 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

Hello World

7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.js: -------------------------------------------------------------------------------- 1 | function hello(value) { 2 | if (typeof value === "string") { 3 | console.log(`Hello ${value}`); 4 | } else { 5 | throw new Error(`Can not greet 'undefined'!`); 6 | } 7 | } 8 | 9 | hello("world!"); 10 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.rb: -------------------------------------------------------------------------------- 1 | puts 'Hello World' 2 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.sh: -------------------------------------------------------------------------------- 1 | file="fixture" 2 | extensions=("css" "js" "sh" "sh") 3 | 4 | for ext in ${extensions[*]} ; do 5 | echo "$file.${ext}" 6 | done 7 | 8 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.ts: -------------------------------------------------------------------------------- 1 | function hello(value: string | undefined) { 2 | if (typeof value === "string") { 3 | console.log(`Hello ${value}`); 4 | } else { 5 | throw new Error(`Can not greet 'undefined'!`); 6 | } 7 | } 8 | 9 | hello("world!"); 10 | -------------------------------------------------------------------------------- /tests/fixtures/fixture.txt: -------------------------------------------------------------------------------- 1 | Hello World 2 | -------------------------------------------------------------------------------- /tests/highlighter-fixtures.test.ts: -------------------------------------------------------------------------------- 1 | import { readdirSync, lstatSync } from "node:fs"; 2 | import { join, dirname, extname } from "node:path"; 3 | import { fileURLToPath } from "node:url"; 4 | 5 | import { vi } from "vitest"; 6 | 7 | import { createHighlighter } from "../src/highlighter/highlighter.js"; 8 | 9 | import { runHighlighterFixture } from "./utils/run-fixture.js"; 10 | 11 | const __filename = fileURLToPath(import.meta.url); 12 | const __dirname = dirname(__filename); 13 | 14 | const fixturesFolder = join(__dirname, "fixtures"); 15 | 16 | const bitmachinaHighlighter = await createHighlighter({ theme: "css-variables" }); 17 | 18 | describe("createHighlighter", () => { 19 | const highlighter = vi.fn(bitmachinaHighlighter); 20 | 21 | readdirSync(fixturesFolder).forEach((fixtureName) => { 22 | const fixture = join(fixturesFolder, fixtureName); 23 | if (lstatSync(fixture).isDirectory()) { 24 | return; 25 | } 26 | 27 | const ext = extname(fixture); 28 | const lang = ext.length > 1 ? ext.slice(1) : "txt"; 29 | 30 | it("should render fixture: " + fixtureName, async () => { 31 | const html = await runHighlighterFixture(fixture, lang, highlighter); 32 | expect(html).toMatchSnapshot(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/highlighter.test.ts: -------------------------------------------------------------------------------- 1 | import { vi } from "vitest"; 2 | 3 | import { createHighlighter } from "../src/highlighter/highlighter.js"; 4 | 5 | const bitmachinaHighlighter = await createHighlighter({ theme: "css-variables" }); 6 | const highlighter = vi.fn(bitmachinaHighlighter); 7 | 8 | describe("highlighter", () => { 9 | describe("render options", async () => { 10 | describe("line numbers", async () => { 11 | beforeEach(async () => { 12 | const code = `let line = 1;\nline = 2;\nline = 3;`; 13 | const html = await highlighter(code, "js"); 14 | document.body.innerHTML = html; 15 | }); 16 | 17 | describe("default", async () => { 18 | it("should add data-line-number properties", () => { 19 | const lines = document.querySelectorAll("span[data-line-number]"); 20 | expect(lines.length).toEqual(3); 21 | }); 22 | 23 | it("should start at the right line number", () => { 24 | const line = document.querySelector("span[data-line-number]"); 25 | expect(line).toBeVisible(); 26 | expect(line.getAttribute("data-line-number")).toEqual("1"); 27 | }); 28 | }); 29 | 30 | describe("metadata provided", async () => { 31 | beforeEach(async () => { 32 | const code = `let line = 1;\nline = 2;\nline = 3;`; 33 | const html = await highlighter(code, "js", "js showLineNumbers{10}"); 34 | document.body.innerHTML = html; 35 | }); 36 | 37 | it("should add data-line-number properties", () => { 38 | const lines = document.querySelectorAll("span[data-line-number]"); 39 | expect(lines.length).toEqual(3); 40 | }); 41 | 42 | it("should start at the right line number", () => { 43 | const line = document.querySelector("span[data-line-number]"); 44 | expect(line).toBeVisible(); 45 | expect(line.getAttribute("data-line-number")).toEqual("10"); 46 | }); 47 | }); 48 | }); 49 | }); 50 | 51 | describe("highlighted lines", async () => { 52 | const code = `let line = 1;\nline = 2;\nline = 3;\nline=4\nline=5\nline=6`; 53 | 54 | it("should highlight a single line", async () => { 55 | const lines = await injectThenQueryLines(code, "js", "js highlight{2}"); 56 | lines.forEach((line, index) => { 57 | expect(line.getAttribute("data-highlighted")).toBe(index === 1); 58 | }); 59 | }); 60 | 61 | it("should highlight a range of lines", async () => { 62 | const lines = await injectThenQueryLines(code, "js", "js highlight{2-4}"); 63 | lines.forEach((line, index) => { 64 | expect(line.getAttribute("data-highlighted")).toBe([1, 2, 3].includes(index)); 65 | }); 66 | }); 67 | 68 | it("should highlight a single line and a range of lines", async () => { 69 | const lines = await injectThenQueryLines(code, "js", "js highlight{2-4,6}"); 70 | lines.forEach((line, index) => { 71 | expect(line.getAttribute("data-highlighted")).toBe([1, 2, 3, 5].includes(index)); 72 | }); 73 | }); 74 | 75 | describe("passing negative ranges", async () => { 76 | it("should not throw error and ignore negative range", async () => { 77 | const lines = await injectThenQueryLines(code, "js", "js highlight{-4..-1}"); 78 | lines.forEach((line) => { 79 | expect(line.getAttribute("data-highlighted")).toBe(false); 80 | }); 81 | }); 82 | }); 83 | }); 84 | }); 85 | 86 | async function injectThenQueryLines(code: string, lang: string, metadata: string) { 87 | const html = await highlighter(code, lang, metadata); 88 | document.body.innerHTML = html; 89 | return document.querySelectorAll("span[data-line-numbers]"); 90 | } 91 | -------------------------------------------------------------------------------- /tests/metadata-lexer.test.ts: -------------------------------------------------------------------------------- 1 | import { lexer } from "../src/parse-metadata/lexer.js"; 2 | 3 | describe("lexer", () => { 4 | describe("tokens", () => { 5 | const tokens = lexer('title="testing lexer"'); 6 | it("should lex an identifier token", () => { 7 | const [identifier] = tokens; 8 | expect(identifier).toEqual({ value: "title", type: "identifier", start: 0, end: 5 }); 9 | }); 10 | 11 | it("should lex symbol tokens", () => { 12 | const [, equal, leftQuote, , rightQuote] = tokens; 13 | expect(equal).toEqual({ value: "=", type: "symbol", start: 5, end: 6 }); 14 | expect(leftQuote).toEqual({ value: '"', type: "symbol", start: 6, end: 7 }); 15 | expect(rightQuote).toEqual({ value: '"', type: "symbol", start: 20, end: 21 }); 16 | }); 17 | 18 | it("should lex a literal token", () => { 19 | const [, , , literal] = tokens; 20 | expect(literal).toEqual({ value: "testing lexer", type: "literal", start: 7, end: 20 }); 21 | }); 22 | }); 23 | 24 | describe("snapshots", () => { 25 | it("should lex a single identifier", () => { 26 | const tokens = lexer(`javascript`); 27 | expect(tokens).toMatchSnapshot(); 28 | }); 29 | 30 | it("should lex a single quote pair", () => { 31 | const tokens = lexer("'single'"); 32 | expect(tokens).toMatchSnapshot(); 33 | }); 34 | 35 | it("should lex a double quote pair", () => { 36 | const tokens = lexer('"double"'); 37 | expect(tokens).toMatchSnapshot(); 38 | }); 39 | 40 | it("should lex a dash pair", () => { 41 | const tokens = lexer("/word/"); 42 | expect(tokens).toMatchSnapshot(); 43 | }); 44 | 45 | it("should lex a paren pair", () => { 46 | const tokens = lexer("(argument)"); 47 | expect(tokens).toMatchSnapshot(); 48 | }); 49 | 50 | it("should lex a brace pair", () => { 51 | const tokens = lexer("{range}"); 52 | expect(tokens).toMatchSnapshot(); 53 | }); 54 | 55 | it("should lex a title", () => { 56 | const tokens = lexer('title="hello lexer"'); 57 | expect(tokens).toMatchSnapshot(); 58 | }); 59 | 60 | it("should lex a range", () => { 61 | const tokens = lexer("{3..5,7}"); 62 | expect(tokens).toMatchSnapshot(); 63 | }); 64 | 65 | it("should lex a `showLineNumbers `identifier", () => { 66 | const tokens = lexer("showLineNumbers"); 67 | expect(tokens).toMatchSnapshot(); 68 | }); 69 | 70 | it("should lex a starting line number", () => { 71 | const tokens = lexer("showLineNumbers{5}"); 72 | expect(tokens).toMatchSnapshot(); 73 | }); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /tests/parse-metadata.test.ts: -------------------------------------------------------------------------------- 1 | import { parseMetadata } from "../src/parse-metadata/index.js"; 2 | 3 | describe("parseMetadata", () => { 4 | describe("code fence", () => { 5 | describe("with title", () => { 6 | const title = "hello testing"; 7 | const metastring = `js title="${title}"`; 8 | 9 | it("should return an object with a title property of type string", () => { 10 | const metadata = parseMetadata(metastring); 11 | expect(typeof metadata.title).toEqual("string"); 12 | }); 13 | 14 | it("should return an object with the correct title property value", () => { 15 | const metadata = parseMetadata(metastring); 16 | expect(metadata.title).toEqual(title); 17 | }); 18 | }); 19 | 20 | describe("without a title property", () => { 21 | it("should return an object with an undefined title property", () => { 22 | const metadata = parseMetadata(`js`); 23 | expect(typeof metadata.title).toEqual("undefined"); 24 | }); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/render-to-hast.test.ts: -------------------------------------------------------------------------------- 1 | import { readdirSync, lstatSync } from "node:fs"; 2 | import { join, dirname, extname } from "node:path"; 3 | import { fileURLToPath } from "node:url"; 4 | 5 | import { getHighlighter } from "shiki"; 6 | import { vi } from "vitest"; 7 | 8 | import { runHastFixture } from "./utils/run-fixture.js"; 9 | 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = dirname(__filename); 12 | 13 | const fixturesFolder = join(__dirname, "fixtures"); 14 | 15 | const shikiHighlighter = await getHighlighter({ theme: "css-variables" }); 16 | 17 | describe("renderToHast", () => { 18 | const tokenizer = vi.fn(shikiHighlighter.codeToThemedTokens); 19 | 20 | readdirSync(fixturesFolder).forEach((fixtureName) => { 21 | const fixture = join(fixturesFolder, fixtureName); 22 | if (lstatSync(fixture).isDirectory()) { 23 | return; 24 | } 25 | 26 | const ext = extname(fixture); 27 | const lang = ext.length > 1 ? ext.slice(1) : "txt"; 28 | 29 | it("should render fixture: " + fixtureName, async () => { 30 | const hast = await runHastFixture(fixture, lang, tokenizer); 31 | expect(hast).toMatchSnapshot(); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "../", 4 | "outDir": "./build", 5 | 6 | "target": "esnext", 7 | "module": "NodeNext", 8 | "moduleResolution": "nodenext", 9 | "jsx": "react-jsx", 10 | "jsxImportSource": "hastscript", 11 | 12 | "strict": false, 13 | "noEmit": true, 14 | 15 | "esModuleInterop": true, 16 | "skipLibCheck": true, 17 | 18 | "types": ["vitest/globals", "@testing-library/dom", "@testing-library/jest-dom"] 19 | }, 20 | "include": ["**/*", "../src"], 21 | "references": [{ "path": "../src/highlighter" }, { "path": "../src/parse-metadata" }] 22 | } 23 | -------------------------------------------------------------------------------- /tests/utils/run-fixture.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from "node:fs/promises"; 2 | 3 | // eslint-disable-next-line import/default 4 | import prettier from "prettier"; 5 | 6 | import { renderToHast } from "../../src/highlighter/render-to-hast.js"; 7 | 8 | // prettier requires this to import into an es module without error. 9 | // eslint-disable-next-line import/no-named-as-default-member 10 | const { format, resolveConfig } = prettier; 11 | 12 | const prettierOptions = { 13 | ...(await resolveConfig(process.cwd())), 14 | parser: "babel", 15 | }; 16 | 17 | // To add a test, create a source code file in the fixtures folder 18 | export async function runHastFixture(fixture, lang, tokenizer) { 19 | const code = await readFile(fixture, "utf8"); 20 | const tokens = tokenizer(code, lang); 21 | return renderToHast({ tokens }); 22 | } 23 | 24 | export async function runHighlighterFixture(fixture, lang, highlighter) { 25 | const raw = await readFile(fixture, "utf8"); 26 | const code = highlighter(raw, lang); 27 | return format(code, prettierOptions); 28 | } 29 | -------------------------------------------------------------------------------- /tsconfig.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"program":{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/@types/unist/index.d.ts","./node_modules/@types/hast/index.d.ts","./node_modules/stringify-entities/lib/util/format-smart.d.ts","./node_modules/stringify-entities/lib/core.d.ts","./node_modules/stringify-entities/lib/index.d.ts","./node_modules/stringify-entities/index.d.ts","./node_modules/property-information/lib/util/info.d.ts","./node_modules/property-information/lib/util/schema.d.ts","./node_modules/property-information/lib/find.d.ts","./node_modules/property-information/lib/hast-to-react.d.ts","./node_modules/property-information/lib/normalize.d.ts","./node_modules/property-information/index.d.ts","./node_modules/hast-util-to-html/lib/types.d.ts","./node_modules/hast-util-to-html/lib/index.d.ts","./node_modules/hast-util-to-html/index.d.ts","./node_modules/parse-numeric-range/index.d.ts","./node_modules/vfile-message/index.d.ts","./node_modules/vfile/lib/minurl.shared.d.ts","./node_modules/vfile/lib/index.d.ts","./node_modules/vfile/index.d.ts","./node_modules/@types/parse5/lib/tree-adapters/default.d.ts","./node_modules/@types/parse5/index.d.ts","./node_modules/hast-util-from-parse5/lib/index.d.ts","./node_modules/hast-util-from-parse5/index.d.ts","./node_modules/rehype-parse/lib/index.d.ts","./node_modules/unified/index.d.ts","./node_modules/rehype-parse/index.d.ts","./node_modules/vscode-textmate/release/types.d.ts","./node_modules/vscode-textmate/release/main.d.ts","./node_modules/shiki/dist/index.d.ts","./node_modules/unist-util-is/index.d.ts","./node_modules/unist-util-visit-parents/complex-types.d.ts","./node_modules/unist-util-visit-parents/index.d.ts","./node_modules/unist-util-visit/complex-types.d.ts","./node_modules/unist-util-visit/index.d.ts","./src/highlighter.ts","./src/index.ts","./node_modules/@types/argparse/index.d.ts","./node_modules/@types/chai/index.d.ts","./node_modules/@types/chai-subset/index.d.ts","./node_modules/@types/estree/index.d.ts","./node_modules/@types/json-schema/index.d.ts","./node_modules/@types/json5/index.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/dom-events.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/globals.global.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/resolve/index.d.ts","./node_modules/@types/semver/classes/semver.d.ts","./node_modules/@types/semver/functions/parse.d.ts","./node_modules/@types/semver/functions/valid.d.ts","./node_modules/@types/semver/functions/clean.d.ts","./node_modules/@types/semver/functions/inc.d.ts","./node_modules/@types/semver/functions/diff.d.ts","./node_modules/@types/semver/functions/major.d.ts","./node_modules/@types/semver/functions/minor.d.ts","./node_modules/@types/semver/functions/patch.d.ts","./node_modules/@types/semver/functions/prerelease.d.ts","./node_modules/@types/semver/functions/compare.d.ts","./node_modules/@types/semver/functions/rcompare.d.ts","./node_modules/@types/semver/functions/compare-loose.d.ts","./node_modules/@types/semver/functions/compare-build.d.ts","./node_modules/@types/semver/functions/sort.d.ts","./node_modules/@types/semver/functions/rsort.d.ts","./node_modules/@types/semver/functions/gt.d.ts","./node_modules/@types/semver/functions/lt.d.ts","./node_modules/@types/semver/functions/eq.d.ts","./node_modules/@types/semver/functions/neq.d.ts","./node_modules/@types/semver/functions/gte.d.ts","./node_modules/@types/semver/functions/lte.d.ts","./node_modules/@types/semver/functions/cmp.d.ts","./node_modules/@types/semver/functions/coerce.d.ts","./node_modules/@types/semver/classes/comparator.d.ts","./node_modules/@types/semver/classes/range.d.ts","./node_modules/@types/semver/functions/satisfies.d.ts","./node_modules/@types/semver/ranges/max-satisfying.d.ts","./node_modules/@types/semver/ranges/min-satisfying.d.ts","./node_modules/@types/semver/ranges/to-comparators.d.ts","./node_modules/@types/semver/ranges/min-version.d.ts","./node_modules/@types/semver/ranges/valid.d.ts","./node_modules/@types/semver/ranges/outside.d.ts","./node_modules/@types/semver/ranges/gtr.d.ts","./node_modules/@types/semver/ranges/ltr.d.ts","./node_modules/@types/semver/ranges/intersects.d.ts","./node_modules/@types/semver/ranges/simplify.d.ts","./node_modules/@types/semver/ranges/subset.d.ts","./node_modules/@types/semver/internals/identifiers.d.ts","./node_modules/@types/semver/index.d.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18","1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9","746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f","d11a03592451da2d1065e09e61f4e2a9bf68f780f4f6623c18b57816a9679d17",{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"f3d4da15233e593eacb3965cde7960f3fddf5878528d882bcedd5cbaba0193c7","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true},{"version":"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87","affectsGlobalScope":true},{"version":"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe","affectsGlobalScope":true},{"version":"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7","affectsGlobalScope":true},{"version":"34c839eaaa6d78c8674ae2c37af2236dee6831b13db7b4ef4df3ec889a04d4f2","affectsGlobalScope":true},{"version":"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed","affectsGlobalScope":true},{"version":"ab7d58e6161a550ff92e5aff755dc37fe896245348332cd5f1e1203479fe0ed1","affectsGlobalScope":true},{"version":"6bda95ea27a59a276e46043b7065b55bd4b316c25e70e29b572958fa77565d43","affectsGlobalScope":true},{"version":"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66","affectsGlobalScope":true},{"version":"a4da0551fd39b90ca7ce5f68fb55d4dc0c1396d589b612e1902f68ee090aaada","affectsGlobalScope":true},{"version":"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},"cddf5c26907c0b8378bc05543161c11637b830da9fadf59e02a11e675d11e180","3d2cd8f3047fff04a71e7037a6a4cb9f4accb28dbd8c0d83164d414811025af0","c19d7ac12ed3eba32c4a5de206abad95aff3076b9fca167964c0962796fa2ac7","5e60773fa7b8dd70abf9674592cad48ae23ca0c0c3461bcab2631233ea39db84","3f1434a62a74403ce9c0be66761cb6ee5029b25a4701ab3ababd55b1cc7a71e5","30b3c98174546f26a9c63a622fac4e6dee716dd7a30271a8a6eaf79e467fa702","7bd32cd2e05737c6a5041ca7a31ceca0c14ce065661c5d1ae5f7bfa35ff3fc5e","bdbb3f4e3f608f6034a78af17466f05ee85b1f1414f5e6f25f591c73a2f9b015","74e27c864416d1ad8947d13cef35e7c9afe0608255eb455096026e988c962295","46ab5ea5cdbc0ce75ade44ec0d9aa164f81e42b061d8e573b832a73ed181da57","d752d4dde165ab9bd56ddd111f59a6bf46eebbc6d4ba4e433f2ea21d1d0599e6","6527f50c0513ce908927055546f39578b9aaed6f1a69dec209b9101fd2d41017","0571110f2ac62f8b755fbbb8a6c5913dc4d465ab618187ca22071f6672e2ad6a","b0b15141888a86b2b2a47816dd43d371df06d96f9f937398bbfa67b121009c7a","8b165becbebe83d49ac8999db5f93aab34e0c826613b541d651ef38f84b6825a","371208e5ccc4d221c0f7ffeee80b17ebac1e3e18e7bbfc625b25bf69fb1802de","0088fda67e4f1020b53917ff8dae6a44bdcb8b6b06b98991ee47a03db8d103f0","3706ce5f7daa3461e02dd6dc33083b8e22cb9691e9348b8e481a5d049e62d897","6b73f1fedbf355da2da03681437d280d1b17aee4da19b500a4691cf2e2624634","bbdbb56370da21c64b4895839aa876354990ce1637a86112c9e6da494b9c4074","fc37aca06f6b8b296c42412a2e75ab53d30cd1fa8a340a3bb328a723fd678377","5f2c582b9ef260cb9559a64221b38606378c1fabe17694592cdfe5975a6d7efa","346417b2585139fb6afaf6c3da71b0103f11a7f46193a5787339e17e7e26e78f","f012ff29417d4e2277e71eda9c1bb36f47357a3926483364ca83177e9827bb44","efa404d15759d3c1c59762060e4c7aa894fb20b01db4741055958a4b9685a9da","af79b166f5d41ec2ebae57e9b67df564452b90ae3f0af4cb3c2d8ad5adbfd2db","2122a30a5b62d74161b6260f49ec37ef3462d383320ca7aff48bbd1d78274037","7a5dda11bfe8c8eb75faff8cc8ab9f7efb2eb871f1de46c7d68bd8bd4c93cd68","84e160a3eae2d7534ef3fc72b068d345d953169acf4d32c148b4836464d313e3","ed8d8acdea8e459bec88b12ad8aa91df7cb4bd313e5d1066fb07843221e9c098","35bee4b8318b9fdca9f037001f565220e8451e031e3f5ce5dcfb29918c1f26d3","fc579133bd2eb7ba59ef5867b64eee7bf0665b1ac578d9df7f68874c3431e304","5e8c8543f346971e0fcf56f4605d527c8720367eecdec5be5bc7c62205686817","41663186993c187c3bc10d430042d374dfde4bb4a1c29136add6eb420d05463a","102fd728d728d8c6a5b4728aed42bb179b1ee3ed10d195bd57d31272839a3fc6",{"version":"43f6c051ab2e063a2942298354d1214e97431d69466ece8a5bcc1e048097bb7f","signature":"8fe677f0b18a9ec4455c8fa4a3aa0ed50d80043dd9e1a4a55725a3d643ab593c"},"ed2ee4a6b81dba23c90781ab06960aa22e60d5ba5abcf813c548350f9d28ae62","dc3b172ee27054dbcedcf5007b78c256021db936f6313a9ce9a3ecbb503fd646",{"version":"b9734142a4b241cfb505be4a2eb0261d211647df7c73043f817f4fdd8d96c846","affectsGlobalScope":true},{"version":"f4c0db3a49cea9babd5d224ba14243a6a6119bf65a65198994033aaea3a60a71","affectsGlobalScope":true},"946bd1737d9412395a8f24414c70f18660b84a75a12b0b448e6eb1a2161d06dd","f3e604694b624fa3f83f6684185452992088f5efb2cf136b62474aa106d6f1b6","96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","7e771891adaa85b690266bc37bd6eb43bc57eecc4b54693ead36467e7369952a","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"ca72190df0eb9b09d4b600821c8c7b6c9747b75a1c700c4d57dc0bb72abc074c","affectsGlobalScope":true},"21a167fec8f933752fb8157f06d28fab6817af3ad9b0bdb1908a10762391eab9",{"version":"bb65c6267c5d6676be61acbf6604cf0a4555ac4b505df58ac15c831fcbff4e3e","affectsGlobalScope":true},"0c0cee62cb619aed81133b904f644515ba3064487002a7da83fd8aa07b1b4abd","5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713",{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","afcc1c426b76db7ec80e563d4fb0ba9e6bcc6e63c2d7e9342e649dc56d26347f","bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","489532ff54b714f0e0939947a1c560e516d3ae93d51d639ab02e907a0e950114","f30bb836526d930a74593f7b0f5c1c46d10856415a8f69e5e2fc3db80371e362","14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea",{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true},{"version":"816ad2e607a96de5bcac7d437f843f5afd8957f1fa5eefa6bba8e4ed7ca8fd84","affectsGlobalScope":true},"cec36af22f514322f870e81d30675c78df82ae8bf4863f5fd4e4424c040c678d","d903fafe96674bc0b2ac38a5be4a8fc07b14c2548d1cdb165a80ea24c44c0c54","b01a80007e448d035a16c74b5c95a5405b2e81b12fabcf18b75aa9eb9ef28990","04eb6578a588d6a46f50299b55f30e3a04ef27d0c5a46c57d8fcc211cd530faa","dbe5aa5a5dd8bd1c6a8d11b1310c3f0cdabaacc78a37b394a8c7b14faeb5fb84","2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"d076fede3cb042e7b13fc29442aaa03a57806bc51e2b26a67a01fbc66a7c0c12","7c013aa892414a7fdcfd861ae524a668eaa3ede8c7c0acafaf611948122c8d93","b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30",{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true},{"version":"b3624aed92dab6da8484280d3cb3e2f4130ec3f4ef3f8201c95144ae9e898bb6","affectsGlobalScope":true},"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","fd93cee2621ff42dabe57b7be402783fd1aa69ece755bcba1e0290547ae60513","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","213fc4f2b172d8beb74b77d7c1b41488d67348066d185e4263470cbb010cd6e8",{"version":"970a90f76d4d219ad60819d61f5994514087ba94c985647a3474a5a3d12714ed","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","4c8525f256873c7ba3135338c647eaf0ca7115a1a2805ae2d0056629461186ce","3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2",{"version":"f0900cd5d00fe1263ff41201fb8073dbeb984397e4af3b8002a5c207a30bdc33","affectsGlobalScope":true},{"version":"f7db71191aa7aac5d6bc927ed6e7075c2763d22c7238227ec0c63c8cf5cb6a8b","affectsGlobalScope":true},"06d7c42d256f0ce6afe1b2b6cfbc97ab391f29dadb00dd0ae8e8f23f5bc916c3","ec4bd1b200670fb567920db572d6701ed42a9641d09c4ff6869768c8f81b404c","e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa",{"version":"da26af7362f53d122283bc69fed862b9a9fe27e01bc6a69d1d682e0e5a4df3e6","affectsGlobalScope":true},"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"e9a8d4274033cb520ee12d6f68d161ba2b9128b87399645d3916b71187032836","8baa5d0febc68db886c40bf341e5c90dc215a90cd64552e47e8184be6b7e3358","2b93035328f7778d200252681c1d86285d501ed424825a18f81e4c3028aa51d9","2ac9c8332c5f8510b8bdd571f8271e0f39b0577714d5e95c1e79a12b2616f069","42c21aa963e7b86fa00801d96e88b36803188018d5ad91db2a9101bccd40b3ff","d31eb848cdebb4c55b4893b335a7c0cca95ad66dee13cbb7d0893810c0a9c301","77c1d91a129ba60b8c405f9f539e42df834afb174fe0785f89d92a2c7c16b77a","7a9e0a564fee396cacf706523b5aeed96e04c6b871a8bebefad78499fbffc5bc","906c751ef5822ec0dadcea2f0e9db64a33fb4ee926cc9f7efa38afe5d5371b2a","5387c049e9702f2d2d7ece1a74836a14b47fbebe9bbeb19f94c580a37c855351","c68391fb9efad5d99ff332c65b1606248c4e4a9f1dd9a087204242b56c7126d6","e9cf02252d3a0ced987d24845dcb1f11c1be5541f17e5daa44c6de2d18138d0c","e8b02b879754d85f48489294f99147aeccc352c760d95a6fe2b6e49cd400b2fe","9f6908ab3d8a86c68b86e38578afc7095114e66b2fc36a2a96e9252aac3998e0","0eedb2344442b143ddcd788f87096961cd8572b64f10b4afc3356aa0460171c6","71405cc70f183d029cc5018375f6c35117ffdaf11846c35ebf85ee3956b1b2a6","c68baff4d8ba346130e9753cefe2e487a16731bf17e05fdacc81e8c9a26aae9d","2cd15528d8bb5d0453aa339b4b52e0696e8b07e790c153831c642c3dea5ac8af","479d622e66283ffa9883fbc33e441f7fc928b2277ff30aacbec7b7761b4e9579","ade307876dc5ca267ca308d09e737b611505e015c535863f22420a11fffc1c54","f8cdefa3e0dee639eccbe9794b46f90291e5fd3989fcba60d2f08fde56179fb9","86c5a62f99aac7053976e317dbe9acb2eaf903aaf3d2e5bb1cafe5c2df7b37a8","2b300954ce01a8343866f737656e13243e86e5baef51bd0631b21dcef1f6e954","a2d409a9ffd872d6b9d78ead00baa116bbc73cfa959fce9a2f29d3227876b2a1","b288936f560cd71f4a6002953290de9ff8dfbfbf37f5a9391be5c83322324898","61178a781ef82e0ff54f9430397e71e8f365fc1e3725e0e5346f2de7b0d50dfa","6a6ccb37feb3aad32d9be026a3337db195979cd5727a616fc0f557e974101a54","c649ea79205c029a02272ef55b7ab14ada0903db26144d2205021f24727ac7a3","38e2b02897c6357bbcff729ef84c736727b45cc152abe95a7567caccdfad2a1d","d6610ea7e0b1a7686dba062a1e5544dd7d34140f4545305b7c6afaebfb348341","3dee35db743bdba2c8d19aece7ac049bde6fa587e195d86547c882784e6ba34c","b15e55c5fa977c2f25ca0b1db52cfa2d1fd4bf0baf90a8b90d4a7678ca462ff1","f41d30972724714763a2698ae949fbc463afb203b5fa7c4ad7e4de0871129a17","843dd7b6a7c6269fd43827303f5cbe65c1fecabc30b4670a50d5a15d57daeeb9","f06d8b8567ee9fd799bf7f806efe93b67683ef24f4dea5b23ef12edff4434d9d","6017384f697ff38bc3ef6a546df5b230c3c31329db84cbfe686c83bec011e2b2","e1a5b30d9248549ca0c0bb1d653bafae20c64c4aa5928cc4cd3017b55c2177b0","a593632d5878f17295bd53e1c77f27bf4c15212822f764a2bfc1702f4b413fa0","a868a534ba1c2ca9060b8a13b0ffbbbf78b4be7b0ff80d8c75b02773f7192c29","da7545aba8f54a50fde23e2ede00158dc8112560d934cee58098dfb03aae9b9d","34baf65cfee92f110d6653322e2120c2d368ee64b3c7981dff08ed105c4f19b0","6aee496bf0ecfbf6731aa8cca32f4b6e92cdc0a444911a7d88410408a45ecc5d"],"options":{"allowSyntheticDefaultImports":true,"composite":true,"declaration":true,"module":5,"noFallthroughCasesInSwitch":true,"noImplicitAny":false,"noImplicitReturns":true,"noUnusedLocals":false,"noUnusedParameters":false,"skipLibCheck":true,"strict":true,"target":4},"fileIdsList":[[145],[94,145],[56,145],[99,145],[102,145],[103,108,136,145],[104,115,116,123,133,144,145],[104,105,115,123,145],[106,145],[107,108,116,124,145],[108,133,141,145],[109,111,115,123,145],[110,145],[111,112,145],[115,145],[113,115,145],[115,116,117,133,144,145],[115,116,117,130,133,136,145],[145,149],[118,123,133,144,145],[115,116,118,119,123,133,141,144,145],[118,120,133,141,144,145],[99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151],[115,121,145],[122,144,145],[111,115,123,133,145],[124,145],[125,145],[102,126,145],[127,143,145,149],[128,145],[129,145],[115,130,131,145],[130,132,145,147],[103,115,133,134,135,136,145],[103,133,135,145],[133,134,145],[136,145],[137,145],[115,139,140,145],[139,140,145],[108,123,133,141,145],[142,145],[123,143,145],[103,118,129,144,145],[108,145],[133,145,146],[145,147],[145,148],[103,108,115,117,126,133,144,145,147,149],[133,145,150],[76,145],[77,145],[145,154,193],[145,154,178,193],[145,193],[145,154],[145,154,179,193],[145,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192],[145,179,193],[78,145],[56,57,67,75,77,145],[68,69,145],[68,145],[57,61,67,145],[62,63,64,65,66,145],[62,63,145],[62,145],[57,80,81,145],[57,79,145],[84,145],[60,145],[58,145],[58,59,145],[56,75,145],[56,86,145],[56,86,87,145],[56,86,88,89,145],[74,145],[56,72,73,75,145],[83,145],[57,70,71,81,82,85,90,145],[91,145],[85]],"referencedMap":[[93,1],[95,2],[94,1],[96,1],[57,3],[97,1],[98,1],[99,4],[100,4],[102,5],[103,6],[104,7],[105,8],[106,9],[107,10],[108,11],[109,12],[110,13],[111,14],[112,14],[114,15],[113,16],[115,15],[116,17],[117,18],[101,19],[151,1],[118,20],[119,21],[120,22],[152,23],[121,24],[122,25],[123,26],[124,27],[125,28],[126,29],[127,30],[128,31],[129,32],[130,33],[131,33],[132,34],[133,35],[135,36],[134,37],[136,38],[137,39],[138,1],[139,40],[140,41],[141,42],[142,43],[143,44],[144,45],[145,46],[146,47],[147,48],[148,49],[149,50],[150,51],[77,52],[76,53],[153,1],[178,54],[179,55],[154,56],[157,56],[176,54],[177,54],[167,54],[166,57],[164,54],[159,54],[172,54],[170,54],[174,54],[158,54],[171,54],[175,54],[160,54],[161,54],[173,54],[155,54],[162,54],[163,54],[165,54],[169,54],[180,58],[168,54],[156,54],[193,59],[192,1],[187,58],[189,60],[188,58],[181,58],[182,58],[184,58],[186,58],[190,60],[191,60],[183,60],[185,60],[56,1],[79,61],[78,62],[70,63],[69,64],[68,65],[71,1],[67,66],[64,67],[65,1],[66,1],[62,1],[63,68],[82,69],[80,70],[85,71],[61,72],[59,73],[60,74],[58,1],[10,1],[11,1],[13,1],[12,1],[2,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[3,1],[4,1],[25,1],[22,1],[23,1],[24,1],[26,1],[27,1],[28,1],[5,1],[29,1],[30,1],[31,1],[32,1],[6,1],[36,1],[33,1],[34,1],[35,1],[37,1],[7,1],[38,1],[43,1],[44,1],[39,1],[40,1],[41,1],[42,1],[8,1],[48,1],[45,1],[46,1],[47,1],[49,1],[9,1],[50,1],[51,1],[52,1],[53,1],[54,1],[1,1],[55,1],[81,75],[86,3],[87,76],[88,77],[89,77],[90,78],[72,3],[75,79],[74,80],[73,1],[84,81],[83,1],[91,82],[92,83]],"exportedModulesMap":[[93,1],[95,2],[94,1],[96,1],[57,3],[97,1],[98,1],[99,4],[100,4],[102,5],[103,6],[104,7],[105,8],[106,9],[107,10],[108,11],[109,12],[110,13],[111,14],[112,14],[114,15],[113,16],[115,15],[116,17],[117,18],[101,19],[151,1],[118,20],[119,21],[120,22],[152,23],[121,24],[122,25],[123,26],[124,27],[125,28],[126,29],[127,30],[128,31],[129,32],[130,33],[131,33],[132,34],[133,35],[135,36],[134,37],[136,38],[137,39],[138,1],[139,40],[140,41],[141,42],[142,43],[143,44],[144,45],[145,46],[146,47],[147,48],[148,49],[149,50],[150,51],[77,52],[76,53],[153,1],[178,54],[179,55],[154,56],[157,56],[176,54],[177,54],[167,54],[166,57],[164,54],[159,54],[172,54],[170,54],[174,54],[158,54],[171,54],[175,54],[160,54],[161,54],[173,54],[155,54],[162,54],[163,54],[165,54],[169,54],[180,58],[168,54],[156,54],[193,59],[192,1],[187,58],[189,60],[188,58],[181,58],[182,58],[184,58],[186,58],[190,60],[191,60],[183,60],[185,60],[56,1],[79,61],[78,62],[70,63],[69,64],[68,65],[71,1],[67,66],[64,67],[65,1],[66,1],[62,1],[63,68],[82,69],[80,70],[85,71],[61,72],[59,73],[60,74],[58,1],[10,1],[11,1],[13,1],[12,1],[2,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[3,1],[4,1],[25,1],[22,1],[23,1],[24,1],[26,1],[27,1],[28,1],[5,1],[29,1],[30,1],[31,1],[32,1],[6,1],[36,1],[33,1],[34,1],[35,1],[37,1],[7,1],[38,1],[43,1],[44,1],[39,1],[40,1],[41,1],[42,1],[8,1],[48,1],[45,1],[46,1],[47,1],[49,1],[9,1],[50,1],[51,1],[52,1],[53,1],[54,1],[1,1],[55,1],[81,75],[86,3],[87,76],[88,77],[89,77],[90,78],[72,3],[75,79],[74,80],[73,1],[84,81],[83,1],[91,84],[92,83]],"semanticDiagnosticsPerFile":[93,95,94,96,57,97,98,99,100,102,103,104,105,106,107,108,109,110,111,112,114,113,115,116,117,101,151,118,119,120,152,121,122,123,124,125,126,127,128,129,130,131,132,133,135,134,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,77,76,153,178,179,154,157,176,177,167,166,164,159,172,170,174,158,171,175,160,161,173,155,162,163,165,169,180,168,156,193,192,187,189,188,181,182,184,186,190,191,183,185,56,79,78,70,69,68,71,67,64,65,66,62,63,82,80,85,61,59,60,58,10,11,13,12,2,14,15,16,17,18,19,20,21,3,4,25,22,23,24,26,27,28,5,29,30,31,32,6,36,33,34,35,37,7,38,43,44,39,40,41,42,8,48,45,46,47,49,9,50,51,52,53,54,1,55,81,86,87,88,89,90,72,75,74,73,84,83,91,92],"latestChangedDtsFile":"./src/index.d.ts"},"version":"4.9.4"} -------------------------------------------------------------------------------- /vitest.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | 3 | export default defineConfig({ 4 | test: { 5 | include: ["tests/**/*.{test,spec}.{js,mjs,cjs,ts}"], 6 | globals: true, 7 | environment: "jsdom", 8 | setupFiles: ["./setupTests.js"], 9 | }, 10 | }); 11 | --------------------------------------------------------------------------------