├── .eslintignore ├── .eslintrc.json ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc.json ├── .vscode └── launch.json ├── CHAGNELOG.md ├── LICENSE ├── README.md ├── demo ├── commonjs │ ├── package.json │ └── run.js └── es6 │ └── run.js ├── image ├── code_blocks.png └── named_code_blocks.png ├── jest.config.ts ├── package-lock.json ├── package.json ├── src └── index.ts ├── test ├── fixture │ ├── hljs10 │ │ ├── codeblock.txt │ │ ├── codeblock_highlightjs.txt │ │ ├── codeblock_highlightjs_full_override.txt │ │ └── codeblock_inline_css.txt │ └── hljs11 │ │ ├── codeblock.txt │ │ ├── codeblock_highlightjs.txt │ │ ├── codeblock_highlightjs_full_override.txt │ │ └── codeblock_inline_css.txt └── index.test.ts └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | demo 3 | jest.config.ts 4 | test -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "es6": true, 5 | "node": true, 6 | "jest": true, 7 | "browser": true 8 | }, 9 | "extends": [ 10 | "eslint:recommended", 11 | "plugin:@typescript-eslint/recommended", 12 | "prettier" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "ecmaVersion": 2020, 17 | "sourceType": "module", 18 | "project": "./tsconfig.json" 19 | }, 20 | "plugins": ["@typescript-eslint"] 21 | } 22 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | groups: 8 | dependencies: 9 | patterns: 10 | - "*" 11 | - package-ecosystem: "npm" 12 | directory: "/" 13 | schedule: 14 | interval: "weekly" 15 | groups: 16 | dependencies: 17 | patterns: 18 | - "*" 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | tags: 7 | - "v[0-9]+.[0-9]+.[0-9]+*" 8 | pull_request: 9 | branches: [master] 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | node-version: [18.x, 20.x, 22.x] 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: npm ci 24 | - run: npm run build --if-present 25 | - run: npm run test:all 26 | - name: Upload coverage reports to Codecov 27 | if: matrix.node-version == '20.x' && github.repository == 'tsutsu3/markdown-it-named-code-blocks' 28 | uses: codecov/codecov-action@v5 29 | env: 30 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 31 | fail_ci_if_error: true 32 | 33 | publish: 34 | needs: [test] 35 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') 36 | runs-on: ubuntu-latest 37 | steps: 38 | - uses: actions/checkout@v4 39 | # Setup .npmrc file to publish to npm 40 | - uses: actions/setup-node@v4 41 | with: 42 | node-version: "18.x" 43 | registry-url: "https://registry.npmjs.org" 44 | - run: npm ci 45 | - run: npm run build 46 | - run: npm publish 47 | env: 48 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | .DS_Store -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .git 2 | .github 3 | .vscode 4 | demo 5 | image 6 | node_modules 7 | test 8 | tsconfig.json 9 | jest.config.ts 10 | package-lock.json 11 | CHAGNELOG.md 12 | .eslintignore 13 | .eslintrc.json 14 | .prettierignore 15 | .prettierrc.json -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /dist 2 | node_modules 3 | package.json 4 | package-lock.json 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none" 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "args": ["--extensionDevelopmentPath=${workspaceFolder}"] 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /CHAGNELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 1.0.6 (2024/11/10) 4 | 5 | - Update dev packages version 6 | 7 | ## 1.0.5 (2023/06/18) 8 | 9 | - Update 3rd libs version 10 | 11 | ## 1.0.4 (2023/12/24) 12 | 13 | - Fix missing dist in npm package 14 | 15 | ## 1.0.3 (2023/12/24) 16 | 17 | - Add npmignore 18 | 19 | ## 1.0.2 (2023/12/23) 20 | 21 | - Migrated implementation to typescript (#31) 22 | 23 | ## 0.2.0 (2023/06/17) 24 | 25 | - Update dev dependencies version (#9, #10, #12, #13) 26 | - Update dependencies version (#11) 27 | - Add dependabot (#7, #8) 28 | - Add type support (#1) [@KyleSmith0905](https://github.com/KyleSmith0905) 29 | - Add CI (#5, #6) 30 | - Fix npm audit (#4) 31 | - Change to use const instead of var in samples (#2) [@KyleSmith0905](https://github.com/KyleSmith0905) 32 | - Fix typos in README.md (#3) [@KyleSmith0905](https://github.com/KyleSmith0905) 33 | 34 | ## 0.1.0 (2020/10/16) 35 | 36 | - First release 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 tsutsu3 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 | # markdown-it-named-code-blocks 2 | 3 | A [markdown-it](https://github.com/markdown-it/markdown-it#readme) plugin to create named code blocks. 4 | 5 | [](https://github.com/tsutsu3/markdown-it-named-code-blocks/actions/workflows/ci.yml) 6 | [](https://www.npmjs.org/package/markdown-it-named-code-blocks) 7 | [](https://codeclimate.com/github/tsutsu3/markdown-it-named-code-blocks) 8 | [](https://codecov.io/gh/tsutsu3/markdown-it-named-code-blocks) 9 | [](https://github.com/tsutsu3/markdown-it-named-code-blocks/LICENSE) 10 | 11 | ## 🧐 About 12 | 13 | With this plugin you can create named code blocks like: 14 | 15 | ````txt 16 | ```js:hello.js 17 | console.log("Hello World!") 18 | ``` 19 | ```` 20 | 21 | Rendered as: 22 | 23 | ```html 24 |
26 | ``` 27 | 28 | After applying the css, it looks like this: 29 | 30 |  31 | 32 | ## 🏁 Getting Started 33 | 34 | ### Prerequisites 35 | 36 | - [Node.js](https://nodejs.org/) 37 | 38 | ### Installing 39 | 40 | ```bash 41 | npm install markdown-it-named-code-blocks 42 | ``` 43 | 44 | ## 🎈 Usage 45 | 46 | Use this same as a normal markdown-it plugin: 47 | 48 | ```js 49 | const md = require("markdown-it"); 50 | const hljs = require("highlight.js"); 51 | const namedCodeBlocks = require("."); 52 | 53 | const parser = md({ 54 | highlight: function (str, lang) { 55 | if (lang && hljs.getLanguage(lang)) { 56 | return ( 57 | 'console.log("Hello World!"); 25 |
hello.js
' +
58 | hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
59 | "
"
60 | );
61 | }
62 |
63 | return (
64 | '' + md.utils.escapeHtml(str) + "
"
65 | );
66 | }
67 | }).use(namedCodeBlocks);
68 |
69 | const str = '```js:hello.js\nconsole.log("Hello World!");\n```';
70 |
71 | const result = parser.render(str);
72 |
73 | console.log(result);
74 | ```
75 |
76 | Output:
77 |
78 | ```html
79 | console.log("Hello World!");
80 |
hello.js
81 | ```
82 |
83 | Apply CSS like this:
84 |
85 | ```css
86 | .named-fence-block {
87 | position: relative;
88 | padding-top: 2em;
89 | }
90 |
91 | .named-fence-filename {
92 | position: absolute;
93 | top: 0;
94 | left: 0;
95 | padding: 0 4px;
96 | font-weight: bold;
97 | color: #000000;
98 | background: #c0c0c0;
99 | opacity: 0.6;
100 | }
101 | ```
102 |
103 | Rendered:
104 |
105 | 
106 |
107 | If you want to enable inline CSS:
108 |
109 | ```js
110 | const parser = md().use(namedCodeBlocks, {isEnableInlineCss: true});
111 | ```
112 |
113 | Output:
114 |
115 | ```html
116 | console.log("Hello World!");
117 |
hello.js
118 | ```
119 |
120 | ## 🎉 License
121 |
122 | Distributed under the `MIT` License. See [LICENSE](https://github.com/tsutsu3/markdown-it-named-code-blocks/blob/master/LICENSE) for more information.
123 |
--------------------------------------------------------------------------------
/demo/commonjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module"
3 | }
--------------------------------------------------------------------------------
/demo/commonjs/run.js:
--------------------------------------------------------------------------------
1 | import MarkdownIt from "markdown-it";
2 | import namedCodeBlocks from "../../dist/index.js";
3 |
4 | const parser = new MarkdownIt().use(namedCodeBlocks);
5 |
6 | const str = '```js:hello.js\nconsole.log("Hello World!);```';
7 |
8 | const result = parser.render(str);
9 | console.log(result);
10 |
--------------------------------------------------------------------------------
/demo/es6/run.js:
--------------------------------------------------------------------------------
1 | const md = require("markdown-it");
2 | const namedCodeBlocks = require("../../dist");
3 |
4 | const parser = md().use(namedCodeBlocks);
5 |
6 | const str = '```js:hello.js\nconsole.log("Hello World!);```';
7 |
8 | const result = parser.render(str);
9 | console.log(result);
10 |
--------------------------------------------------------------------------------
/image/code_blocks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsutsu3/markdown-it-named-code-blocks/b55572ca1c2e63329411f9582138e1d069f00730/image/code_blocks.png
--------------------------------------------------------------------------------
/image/named_code_blocks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsutsu3/markdown-it-named-code-blocks/b55572ca1c2e63329411f9582138e1d069f00730/image/named_code_blocks.png
--------------------------------------------------------------------------------
/jest.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "@jest/types";
2 |
3 | const config: Config.InitialOptions = {
4 | preset: "ts-jest",
5 | testEnvironment: "node",
6 | moduleFileExtensions: ["ts", "js", "json", "node"],
7 | testMatch: ["**/test/**/*.ts"],
8 | transform: {
9 | "^.+\\.ts$": "ts-jest"
10 | },
11 | moduleNameMapper: {
12 | "^@/(.*)$": "./src/$1"
13 | },
14 | testPathIgnorePatterns: ["/node_modules/", "/dist/"]
15 | };
16 |
17 | export default config;
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "markdown-it-named-code-blocks",
3 | "version": "1.0.6",
4 | "description": "A markdown-it plugin to create named code blocks.",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "lint": "eslint . --ext .ts",
9 | "format": "prettier --write \"**/*.ts\"",
10 | "install-hljs10": "npm install highlight.js@^10.7.3 --no-save",
11 | "install-hljs11": "npm install highlight.js@^11.0.0 --no-save",
12 | "test-hljs10": "npm run install-hljs10 && jest --coverage",
13 | "test-hljs11": "npm run install-hljs11 && jest --coverage",
14 | "test:all": "npm run test-hljs10 && npm run test-hljs11",
15 | "test": "jest --coverage",
16 | "build": "tsc && npm run minify",
17 | "minify": "terser dist/index.js -o dist/index.min.js --compress --mangle",
18 | "clean": "npm run clean:os",
19 | "clean:os": "npm run clean:windows || npm run clean:linux",
20 | "clean:windows": "rimraf dist",
21 | "clean:linux": "rm -rf dist || true"
22 | },
23 | "repository": {
24 | "type": "git",
25 | "url": "git+https://github.com/tsutsu3/markdown-it-named-code-blocks.git"
26 | },
27 | "keywords": [
28 | "markdown",
29 | "markdown-it",
30 | "markdown-it-plugin",
31 | "code-blocks",
32 | "fence"
33 | ],
34 | "author": "tsutsu3",
35 | "license": "MIT",
36 | "bugs": {
37 | "url": "https://github.com/tsutsu3/markdown-it-named-code-blocks/issues"
38 | },
39 | "homepage": "https://github.com/tsutsu3/markdown-it-named-code-blocks#readme",
40 | "devDependencies": {
41 | "@types/jest": "^29.5.11",
42 | "@types/markdown-it": "^14.1.2",
43 | "@typescript-eslint/eslint-plugin": "^8.13.0",
44 | "@typescript-eslint/parser": "^8.13.0",
45 | "eslint": "^9.14.0",
46 | "eslint-config-prettier": "^10.0.1",
47 | "highlight.js": "^11.10.0",
48 | "jest": "^29.7.0",
49 | "markdown-it": "^14.0.0",
50 | "markdown-it-testgen": "^0.1.6",
51 | "path": "^0.12.7",
52 | "prettier": "^3.1.1",
53 | "terser": "^5.26.0",
54 | "ts-jest": "^29.1.1",
55 | "ts-node": "^10.9.2",
56 | "typescript": "^5.3.3"
57 | },
58 | "dependencies": {
59 | "node-html-parser": "^7.0.1"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | import { parse, HTMLElement } from "node-html-parser";
4 | import { Token, Options, PluginWithOptions } from "markdown-it";
5 | import Renderer from "markdown-it/lib/renderer.mjs";
6 |
7 | type ParsedFenceInfo = {
8 | langName: string;
9 | fileName: string;
10 | langAttrs: string;
11 | };
12 |
13 | type CssOptions = {
14 | isEnableInlineCss: boolean;
15 | };
16 |
17 | type Env = {
18 | [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
19 | };
20 |
21 | const fencBlockName = "named-fence-block";
22 | const fenceFileName = "named-fence-filename";
23 | const defaultStyleOptions = {
24 | mincbBlock: "position: relative; padding-top: 2em;",
25 | mincbName:
26 | "position: absolute; top: 0; left: 0; padding: 0 4px; " +
27 | "font-weight: bold; color: #000000; background: #c0c0c0; opacity: .6;"
28 | };
29 |
30 | const namedCodeBlocks: PluginWithOptionsconsole.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | 39 | . 40 | 41 | :hello.js 42 | . 43 | ```:hello.js 44 | console.log("Hello World!"); 45 | ``` 46 | . 47 |console.log("Hello World!"); 38 |
hello.js
console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | 99 | . -------------------------------------------------------------------------------- /test/fixture/hljs10/codeblock_highlightjs.txt: -------------------------------------------------------------------------------- 1 | none 2 | . 3 | ``` 4 | console.log("Hello World!"); 5 | ``` 6 | . 7 |console.log("Hello World!"); 98 |
hello.js
console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | console.log("Hello World!");
38 |
hello.js
39 | .
40 |
41 | :hello.js
42 | .
43 | ```:hello.js
44 | console.log("Hello World!");
45 | ```
46 | .
47 | console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | console.log("Hello World!");
98 |
hello.js
99 | .
--------------------------------------------------------------------------------
/test/fixture/hljs10/codeblock_highlightjs_full_override.txt:
--------------------------------------------------------------------------------
1 | none
2 | .
3 | ```
4 | console.log("Hello World!");
5 | ```
6 | .
7 | console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | console.log("Hello World!");
38 |
hello.js
39 | .
40 |
41 | :hello.js
42 | .
43 | ```:hello.js
44 | console.log("Hello World!");
45 | ```
46 | .
47 | console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | console.log("Hello World!");
98 |
hello.js
99 | .
--------------------------------------------------------------------------------
/test/fixture/hljs10/codeblock_inline_css.txt:
--------------------------------------------------------------------------------
1 | none
2 | .
3 | ```
4 | console.log("Hello World!");
5 | ```
6 | .
7 | console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | 39 | . 40 | 41 | :hello.js 42 | . 43 | ```:hello.js 44 | console.log("Hello World!"); 45 | ``` 46 | . 47 |console.log("Hello World!"); 38 |
hello.js
console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | 99 | . -------------------------------------------------------------------------------- /test/fixture/hljs11/codeblock.txt: -------------------------------------------------------------------------------- 1 | none 2 | . 3 | ``` 4 | console.log("Hello World!"); 5 | ``` 6 | . 7 |console.log("Hello World!"); 98 |
hello.js
console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | 39 | . 40 | 41 | :hello.js 42 | . 43 | ```:hello.js 44 | console.log("Hello World!"); 45 | ``` 46 | . 47 |console.log("Hello World!"); 38 |
hello.js
console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | 99 | . -------------------------------------------------------------------------------- /test/fixture/hljs11/codeblock_highlightjs.txt: -------------------------------------------------------------------------------- 1 | none 2 | . 3 | ``` 4 | console.log("Hello World!"); 5 | ``` 6 | . 7 |console.log("Hello World!"); 98 |
hello.js
console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | console.log("Hello World!");
38 |
hello.js
39 | .
40 |
41 | :hello.js
42 | .
43 | ```:hello.js
44 | console.log("Hello World!");
45 | ```
46 | .
47 | console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | console.log("Hello World!");
98 |
hello.js
99 | .
--------------------------------------------------------------------------------
/test/fixture/hljs11/codeblock_highlightjs_full_override.txt:
--------------------------------------------------------------------------------
1 | none
2 | .
3 | ```
4 | console.log("Hello World!");
5 | ```
6 | .
7 | console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | console.log("Hello World!");
38 |
hello.js
39 | .
40 |
41 | :hello.js
42 | .
43 | ```:hello.js
44 | console.log("Hello World!");
45 | ```
46 | .
47 | console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | console.log("Hello World!");
98 |
hello.js
99 | .
--------------------------------------------------------------------------------
/test/fixture/hljs11/codeblock_inline_css.txt:
--------------------------------------------------------------------------------
1 | none
2 | .
3 | ```
4 | console.log("Hello World!");
5 | ```
6 | .
7 | console.log("Hello World!");
8 |
9 | .
10 |
11 | js
12 | .
13 | ```js
14 | console.log("Hello World!");
15 | ```
16 | .
17 | console.log("Hello World!");
18 |
19 | .
20 |
21 | js:
22 | .
23 | ```js:
24 | console.log("Hello World!");
25 | ```
26 | .
27 | console.log("Hello World!");
28 |
29 | .
30 |
31 | js:hello.js (named code blocks)
32 | .
33 | ```js:hello.js
34 | console.log("Hello World!");
35 | ```
36 | .
37 | 39 | . 40 | 41 | :hello.js 42 | . 43 | ```:hello.js 44 | console.log("Hello World!"); 45 | ``` 46 | . 47 |console.log("Hello World!"); 38 |
hello.js
console.log("Hello World!");
48 |
49 | .
50 |
51 | hello.js
52 | .
53 | ```hello.js
54 | console.log("Hello World!");
55 | ```
56 | .
57 | console.log("Hello World!");
58 |
59 | .
60 |
61 | js:hello.js:second.js
62 | .
63 | ```js:hello.js:second.js
64 | console.log("Hello World!");
65 | ```
66 | .
67 | console.log("Hello World!");
68 |
69 | .
70 |
71 | hello.js:second.js (named code blocks, but language is incorrect)
72 | .
73 | ```hello.js:second.js
74 | console.log("Hello World!");
75 | ```
76 | .
77 | 79 | . 80 | 81 | js langAttr 82 | . 83 | ```js langAttr 84 | console.log("Hello World!"); 85 | ``` 86 | . 87 |console.log("Hello World!"); 78 |
second.js
console.log("Hello World!");
88 |
89 | .
90 |
91 | js:hello.js langAttr
92 | .
93 | ```js:hello.js langAttr
94 | console.log("Hello World!");
95 | ```
96 | .
97 | 99 | . -------------------------------------------------------------------------------- /test/index.test.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import path from "path"; 4 | 5 | const generate = require("markdown-it-testgen"); // eslint-disable-line @typescript-eslint/no-var-requires 6 | import hljs from "highlight.js"; 7 | import MarkdownIt from "markdown-it"; 8 | import namedCodeBlocks from "../src"; 9 | 10 | const hljsVersion = require("highlight.js/package.json").version; 11 | const fixturePath = hljsVersion.startsWith("10") 12 | ? "fixture/hljs10" 13 | : "fixture/hljs11"; 14 | 15 | console.log(`Running tests with highlight.js version: ${hljsVersion}`); 16 | 17 | describe("markdown-it-named-code-blocks", () => { 18 | const md = new MarkdownIt().use(namedCodeBlocks); 19 | 20 | generate( 21 | path.join(__dirname, `./${fixturePath}/codeblock.txt`), 22 | { header: true }, 23 | md 24 | ); 25 | }); 26 | 27 | describe("markdown-it-named-code-blocks-default-highlight", () => { 28 | const md = new MarkdownIt({ 29 | highlight: function (str: string, lang: string) { 30 | if (lang && hljs.getLanguage(lang)) { 31 | return hljs.highlight(str, { language: lang }).value; 32 | } 33 | return ""; 34 | } 35 | }).use(namedCodeBlocks); 36 | 37 | generate( 38 | path.join(__dirname, `./${fixturePath}/codeblock_highlightjs.txt`), 39 | { header: true }, 40 | md 41 | ); 42 | }); 43 | 44 | describe("markdown-it-named-code-blocks-override-highlight", () => { 45 | const md: MarkdownIt = new MarkdownIt({ 46 | highlight: function (str: string, lang: string) { 47 | if (lang && hljs.getLanguage(lang)) { 48 | return ( 49 | 'console.log("Hello World!"); 98 |
hello.js
' +
50 | hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
51 | "
"
52 | );
53 | }
54 |
55 | return (
56 | '' + md.utils.escapeHtml(str) + "
"
57 | );
58 | }
59 | }).use(namedCodeBlocks);
60 |
61 | generate(
62 | path.join(
63 | __dirname,
64 | `./${fixturePath}/codeblock_highlightjs_full_override.txt`
65 | ),
66 | { header: true },
67 | md
68 | );
69 | });
70 |
71 | describe("markdown-it-named-code-blocks-inline-css", () => {
72 | const md = new MarkdownIt().use(namedCodeBlocks, {
73 | isEnableInlineCss: true
74 | });
75 |
76 | generate(
77 | path.join(__dirname, `./${fixturePath}/codeblock_inline_css.txt`),
78 | { header: true },
79 | md
80 | );
81 | });
82 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "outDir": "./dist",
6 | "rootDir": "./src",
7 | "strict": true,
8 | "esModuleInterop": true,
9 | "declaration": true
10 | },
11 | "include": ["src/**/*.ts"],
12 | "exclude": ["node_modules", "dist", "demo"]
13 | }
14 |
--------------------------------------------------------------------------------