metalsmith-prism 4.3.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -36
- package/lib/index.js +40 -48
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,45 +1,69 @@
|
|
|
1
1
|
# metalsmith-prism
|
|
2
2
|
|
|
3
|
-
A Metalsmith plugin that **adds Prism specific HTML markup** to code sections for syntax coloring.
|
|
3
|
+
A Metalsmith plugin that **adds Prism specific HTML markup** to code sections for syntax coloring.
|
|
4
4
|
|
|
5
5
|
[](http://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://npmjs.org/package/metalsmith-prism)
|
|
7
7
|
[](https://travis-ci.org/Availity/metalsmith-prism)
|
|
8
8
|
[](https://ci.appveyor.com/project/robmcguinness/metalsmith-prism)
|
|
9
9
|
|
|
10
|
-
While this plugin adds all the required Prism HTML markup, **prism.css** must be included on the page to provide the syntax coloring.
|
|
10
|
+
While this plugin adds all the required Prism HTML markup, **prism.css** must be included on the page to provide the syntax coloring. The plugin:
|
|
11
|
+
|
|
12
|
+
- Automatically handles language dependencies
|
|
13
|
+
- Supports HTML entity decoding
|
|
14
|
+
- Can add line numbers
|
|
15
|
+
- Works seamlessly with Markdown code blocks
|
|
16
|
+
- Supports all Prism.js languages
|
|
11
17
|
|
|
12
18
|
## Requirements
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
- Node `>= 18.x.x`
|
|
21
|
+
- NPM `>= 9.x.x`
|
|
22
|
+
- Metalsmith `>= v2.6.x`
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
17
25
|
|
|
26
|
+
1. Install the plugin
|
|
27
|
+
2. Add Prism CSS to your page
|
|
28
|
+
3. Add language classes to your code blocks
|
|
29
|
+
4. Configure the plugin in your Metalsmith build
|
|
18
30
|
|
|
31
|
+
Example using all features:
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
metalsmith(__dirname).use(
|
|
35
|
+
prism({
|
|
36
|
+
decode: true, // Decode HTML entities
|
|
37
|
+
lineNumbers: true, // Show line numbers
|
|
38
|
+
preLoad: ['java'], // Pre-load language dependencies
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
```
|
|
19
42
|
|
|
20
43
|
## Installation
|
|
21
44
|
|
|
22
45
|
NPM:
|
|
46
|
+
|
|
23
47
|
```bash
|
|
24
48
|
npm install metalsmith-prism --save-dev
|
|
25
49
|
```
|
|
26
50
|
|
|
27
51
|
Yarn:
|
|
52
|
+
|
|
28
53
|
```bash
|
|
29
54
|
yarn add metalsmith-prism
|
|
30
55
|
```
|
|
31
56
|
|
|
32
57
|
## Usage
|
|
33
58
|
|
|
34
|
-
### Add Prism styles to page header.
|
|
59
|
+
### Add Prism styles to page header.
|
|
35
60
|
|
|
36
|
-
If the `linenumbers` option is set to `true`, `prism-line-numbers.css` must be added to the page.
|
|
61
|
+
If the `linenumbers` option is set to `true`, `prism-line-numbers.css` must be added to the page.
|
|
37
62
|
|
|
38
63
|
The css files can be downloaded from the [Prism website](https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript) or [use a CDN](https://prismjs.com/#basic-usage-cdn). Please refer to the [Prism documentation](https://prismjs.com/index.html) for details.
|
|
39
64
|
|
|
40
65
|
```html
|
|
41
|
-
<link href="/assets/prism.css" rel="stylesheet" />
|
|
42
|
-
<link href="/assets/prism-line-numbers.css" rel="stylesheet" />
|
|
66
|
+
<link href="/assets/prism.css" rel="stylesheet" /> <link href="/assets/prism-line-numbers.css" rel="stylesheet" />
|
|
43
67
|
```
|
|
44
68
|
|
|
45
69
|
### Add language definition to code block
|
|
@@ -54,9 +78,7 @@ The css files can be downloaded from the [Prism website](https://prismjs.com/dow
|
|
|
54
78
|
const metalsmith = require('metalsmith');
|
|
55
79
|
const prism = require('metalsmith-prism');
|
|
56
80
|
|
|
57
|
-
metalsmith(__dirname)
|
|
58
|
-
.use(prism())
|
|
59
|
-
.build();
|
|
81
|
+
metalsmith(__dirname).use(prism()).build();
|
|
60
82
|
```
|
|
61
83
|
|
|
62
84
|
### To use with Markdown code blocks rendered by [@metalsmith/markdown](https://github.com/metalsmith/markdown)
|
|
@@ -66,14 +88,13 @@ const metalsmith = require('metalsmith');
|
|
|
66
88
|
const markdown = require('@metalsmith/markdown');
|
|
67
89
|
const prism = require('metalsmith-prism');
|
|
68
90
|
|
|
69
|
-
metalsmith(__dirname)
|
|
70
|
-
.use(markdown())
|
|
71
|
-
.use(prism())
|
|
72
|
-
.build();
|
|
91
|
+
metalsmith(__dirname).use(markdown()).use(prism()).build();
|
|
73
92
|
```
|
|
74
93
|
|
|
75
94
|
## Language support
|
|
76
95
|
|
|
96
|
+
The plugin default language support includes: markup, css, clike, javascript and php.
|
|
97
|
+
|
|
77
98
|
Supports all programming languages that have a corresponding Prism.js component file. Component files are found in the [Prism.js `components` directory](https://github.com/PrismJS/prism/tree/master/components).
|
|
78
99
|
|
|
79
100
|
## Options
|
|
@@ -83,21 +104,23 @@ Supports all programming languages that have a corresponding Prism.js component
|
|
|
83
104
|
Always decode the html entities when processing language of type `markup`
|
|
84
105
|
|
|
85
106
|
```js
|
|
86
|
-
Metalsmith(__dirname)
|
|
87
|
-
|
|
88
|
-
decode: true
|
|
89
|
-
})
|
|
107
|
+
Metalsmith(__dirname).use(
|
|
108
|
+
prism({
|
|
109
|
+
decode: true,
|
|
110
|
+
})
|
|
111
|
+
);
|
|
90
112
|
```
|
|
91
113
|
|
|
92
114
|
**lineNumbers (optional)**
|
|
93
115
|
|
|
94
|
-
Adds the additional HTML markup so line numbers can be added via the line-numbers CSS.
|
|
116
|
+
Adds the additional HTML markup so line numbers can be added via the line-numbers CSS.
|
|
95
117
|
|
|
96
118
|
```javascript
|
|
97
|
-
Metalsmith(__dirname)
|
|
98
|
-
|
|
99
|
-
lineNumbers: true
|
|
100
|
-
})
|
|
119
|
+
Metalsmith(__dirname).use(
|
|
120
|
+
metalsmithPrism({
|
|
121
|
+
lineNumbers: true,
|
|
122
|
+
})
|
|
123
|
+
);
|
|
101
124
|
```
|
|
102
125
|
|
|
103
126
|
**preLoad (optional)**
|
|
@@ -107,11 +130,13 @@ Pre-loads language component(s), such that each language component registers its
|
|
|
107
130
|
Useful for loading syntax that extends other language components that are not automatically registered by Prism
|
|
108
131
|
|
|
109
132
|
```javascript
|
|
110
|
-
Metalsmith(__dirname)
|
|
111
|
-
|
|
112
|
-
preLoad: [
|
|
113
|
-
})
|
|
133
|
+
Metalsmith(__dirname).use(
|
|
134
|
+
prism({
|
|
135
|
+
preLoad: ['java', 'scala'],
|
|
136
|
+
})
|
|
137
|
+
);
|
|
114
138
|
```
|
|
139
|
+
|
|
115
140
|
## Debug
|
|
116
141
|
|
|
117
142
|
To enable debug logs, set the `DEBUG` environment variable to `metalsmith-prism`:
|
|
@@ -142,16 +167,11 @@ Add `metalsmith-prism` key to your `metalsmith.json` plugins key
|
|
|
142
167
|
}
|
|
143
168
|
}
|
|
144
169
|
```
|
|
145
|
-
## Credits
|
|
146
|
-
|
|
147
|
-
[Robert McGuinness]( https://github.com/robmcguinness) - for the initial implementation of the plugin.
|
|
148
|
-
|
|
149
170
|
|
|
171
|
+
## Credits
|
|
150
172
|
|
|
173
|
+
[Robert McGuinness](https://github.com/robmcguinness) - for the initial implementation of the plugin.
|
|
151
174
|
|
|
152
175
|
## License
|
|
153
176
|
|
|
154
177
|
Code released under [the MIT license](https://github.com/wernerglinka/metalsmith-prism/blob/main/LICENSE).
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
package/lib/index.js
CHANGED
|
@@ -1,71 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
import { load } from 'cheerio';
|
|
2
|
+
import { extname } from 'path';
|
|
3
|
+
import Prism from 'prismjs';
|
|
4
|
+
import loadLanguages from 'prismjs/components/index.js';
|
|
5
|
+
import he from 'he';
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const extname = require( 'path' ).extname;
|
|
6
|
-
const languages = require( 'prismjs' ).languages;
|
|
7
|
-
const Prism = require( 'prismjs' );
|
|
7
|
+
// Import languages from Prism's default export
|
|
8
|
+
const { languages } = Prism;
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
// Preload PHP
|
|
10
11
|
loadLanguages( [ 'php' ] );
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Check if a file is HTML
|
|
15
|
+
* @param {string} filePath
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
14
18
|
const isHTMLFile = ( filePath ) => {
|
|
15
19
|
return /\.html|\.htm/.test( extname( filePath ) );
|
|
16
20
|
};
|
|
17
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @typedef Options
|
|
24
|
+
* @property {boolean} [decode=false] - Whether to decode HTML entities
|
|
25
|
+
* @property {boolean} [lineNumbers=false] - Whether to add line numbers
|
|
26
|
+
* @property {string[]} [preLoad=[]] - Languages to preload
|
|
27
|
+
*/
|
|
18
28
|
|
|
19
29
|
/**
|
|
20
30
|
* Metalsmith plugin to highlight code syntax with PrismJS
|
|
21
31
|
*
|
|
22
|
-
* @param {
|
|
23
|
-
* @returns
|
|
32
|
+
* @param {Options} [options]
|
|
33
|
+
* @returns {import('metalsmith').Plugin}
|
|
24
34
|
*/
|
|
25
|
-
|
|
26
|
-
module.exports = ( options ) => {
|
|
27
|
-
|
|
28
|
-
options = options || {};
|
|
29
|
-
|
|
35
|
+
function metalsmithPrism( options = {} ) {
|
|
30
36
|
if ( options.preLoad ) {
|
|
31
|
-
//list of available languages: https://github.com/PrismJS/prism/tree/master/components
|
|
32
37
|
options.preLoad.forEach( ( language ) => {
|
|
33
38
|
try {
|
|
34
|
-
|
|
39
|
+
loadLanguages( [ language ] );
|
|
35
40
|
} catch ( e ) {
|
|
36
|
-
|
|
37
|
-
console.warn( `Failed to preload prism syntax: ${ language } !` );
|
|
41
|
+
console.warn( `Failed to preload prism syntax: ${ language }!` );
|
|
38
42
|
}
|
|
39
43
|
} );
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
/**
|
|
43
|
-
* requireLanguage
|
|
44
47
|
* Require optional language package
|
|
45
|
-
*
|
|
46
|
-
* @param {*} language
|
|
48
|
+
* @param {string} language
|
|
47
49
|
*/
|
|
48
50
|
function requireLanguage( language ) {
|
|
49
51
|
if ( !languages[ language ] ) {
|
|
50
52
|
try {
|
|
51
|
-
|
|
53
|
+
loadLanguages( [ language ] );
|
|
52
54
|
} catch ( e ) {
|
|
53
|
-
|
|
54
|
-
console.warn( `Failed to load prism syntax: ${ language } !` );
|
|
55
|
+
console.warn( `Failed to load prism syntax: ${ language }!` );
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Prism hook "after-tokenize" used to add html for line numbers
|
|
62
|
-
* Neccessary as we don't have a browser
|
|
63
|
-
*
|
|
64
|
-
* Sources:
|
|
65
|
-
* https://github.com/PrismJS/prism/blob/master/plugins/line-numbers/prism-line-numbers.js#L109
|
|
66
|
-
* https://stackoverflow.com/questions/59508413/static-html-generation-with-prismjs-how-to-enable-line-numbers
|
|
67
|
-
*
|
|
68
|
-
*/
|
|
60
|
+
// Set up line numbers
|
|
69
61
|
const NEW_LINE_EXP = /\n(?!$)/g;
|
|
70
62
|
let lineNumbersWrapper;
|
|
71
63
|
|
|
@@ -73,22 +65,19 @@ module.exports = ( options ) => {
|
|
|
73
65
|
const match = env.code.match( NEW_LINE_EXP );
|
|
74
66
|
const linesNum = match ? match.length + 1 : 1;
|
|
75
67
|
const lines = new Array( linesNum + 1 ).join( '<span></span>' );
|
|
76
|
-
|
|
77
68
|
lineNumbersWrapper = `<span aria-hidden="true" class="line-numbers-rows">${ lines }</span>`;
|
|
78
69
|
} );
|
|
79
70
|
|
|
80
71
|
return function( files, metalsmith, done ) {
|
|
81
|
-
|
|
82
72
|
setImmediate( done );
|
|
83
73
|
|
|
84
74
|
Object.keys( files ).forEach( file => {
|
|
85
|
-
|
|
86
75
|
if ( !isHTMLFile( file ) ) {
|
|
87
76
|
return;
|
|
88
77
|
}
|
|
89
78
|
|
|
90
79
|
const contents = files[ file ].contents.toString();
|
|
91
|
-
const $ =
|
|
80
|
+
const $ = load( contents, { decodeEntities: false } );
|
|
92
81
|
let highlighted = false;
|
|
93
82
|
const code = $( 'code' );
|
|
94
83
|
|
|
@@ -99,10 +88,9 @@ module.exports = ( options ) => {
|
|
|
99
88
|
|
|
100
89
|
const className = $this.attr( 'class' ) || '';
|
|
101
90
|
const targets = className.split( 'language-' );
|
|
102
|
-
let
|
|
91
|
+
let addLineNumbers = false;
|
|
103
92
|
|
|
104
93
|
if ( targets.length > 1 ) {
|
|
105
|
-
|
|
106
94
|
const $pre = $this.parent( 'pre' );
|
|
107
95
|
|
|
108
96
|
if ( $pre ) {
|
|
@@ -110,9 +98,8 @@ module.exports = ( options ) => {
|
|
|
110
98
|
$pre.addClass( className );
|
|
111
99
|
|
|
112
100
|
if ( options.lineNumbers ) {
|
|
113
|
-
debug( 'adding line numbers' );
|
|
114
101
|
$pre.addClass( 'line-numbers' );
|
|
115
|
-
|
|
102
|
+
addLineNumbers = true;
|
|
116
103
|
}
|
|
117
104
|
}
|
|
118
105
|
|
|
@@ -123,10 +110,13 @@ module.exports = ( options ) => {
|
|
|
123
110
|
if ( !languages[ language ] ) {
|
|
124
111
|
language = 'markup';
|
|
125
112
|
}
|
|
126
|
-
const html = ( language === 'markup' && !options.decode ) ? $this.html() : he.decode( $this.html() );
|
|
127
|
-
const highlightedCode = Prism.highlight( html, Prism.languages[ language ] );
|
|
128
|
-
$this.html( addLineNmbers ? highlightedCode + lineNumbersWrapper : highlightedCode );
|
|
129
113
|
|
|
114
|
+
const html = ( language === 'markup' && !options.decode )
|
|
115
|
+
? $this.html()
|
|
116
|
+
: he.decode( $this.html() );
|
|
117
|
+
|
|
118
|
+
const highlightedCode = Prism.highlight( html, languages[ language ] );
|
|
119
|
+
$this.html( addLineNumbers ? highlightedCode + lineNumbersWrapper : highlightedCode );
|
|
130
120
|
}
|
|
131
121
|
} );
|
|
132
122
|
|
|
@@ -135,4 +125,6 @@ module.exports = ( options ) => {
|
|
|
135
125
|
}
|
|
136
126
|
} );
|
|
137
127
|
};
|
|
138
|
-
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export default metalsmithPrism;
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metalsmith-prism",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "Syntax highlighting for Metalsmith HTML templates using Prism.js",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "lib/index.js",
|
|
7
|
+
"exports": "./lib/index.js",
|
|
6
8
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
9
|
+
"node": ">= 18.0.0"
|
|
8
10
|
},
|
|
9
11
|
"scripts": {
|
|
10
12
|
"preversion": "npm run test",
|
|
@@ -39,9 +41,8 @@
|
|
|
39
41
|
"prismjs": "^1.29.0"
|
|
40
42
|
},
|
|
41
43
|
"devDependencies": {
|
|
42
|
-
"babel-eslint": "^7.2.3",
|
|
43
44
|
"chai": "^5.1.2",
|
|
44
|
-
"eslint": "^9.
|
|
45
|
+
"eslint": "^9.15.0",
|
|
45
46
|
"eslint-config-prettier": "^9.1.0",
|
|
46
47
|
"eslint-plugin-prettier": "^5.2.1",
|
|
47
48
|
"mocha": "^10.8.2",
|