metalsmith-prism 4.2.4 → 5.0.0

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.
Files changed (2) hide show
  1. package/lib/index.js +41 -48
  2. package/package.json +4 -3
package/lib/index.js CHANGED
@@ -1,71 +1,63 @@
1
- 'use strict';
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
- const cheerio = require( 'cheerio' );
4
- const debug = require( 'debug' )( 'metalsmith-prism' );
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
- const loadLanguages = require( 'prismjs/components/' );
10
+ // Preload PHP
10
11
  loadLanguages( [ 'php' ] );
11
12
 
12
- const he = require( 'he' );
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 {Object} options
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
- require( `prismjs/components/prism-${ language }.js` );
39
+ loadLanguages( [ language ] );
35
40
  } catch ( e ) {
36
- /* eslint no-console: 0 */
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
- require( `prismjs/components/prism-${ language }.js` );
53
+ loadLanguages( [ language ] );
52
54
  } catch ( e ) {
53
- /* eslint no-console: 0 */
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 $ = cheerio.load( contents, { decodeEntities: false }, true );
80
+ const $ = load( contents, { decodeEntities: false } );
92
81
  let highlighted = false;
93
82
  const code = $( 'code' );
94
83
 
@@ -96,12 +85,12 @@ module.exports = ( options ) => {
96
85
 
97
86
  code.each( function() {
98
87
  const $this = $( this );
88
+
99
89
  const className = $this.attr( 'class' ) || '';
100
90
  const targets = className.split( 'language-' );
101
- let addLineNmbers = false;
91
+ let addLineNumbers = false;
102
92
 
103
93
  if ( targets.length > 1 ) {
104
-
105
94
  const $pre = $this.parent( 'pre' );
106
95
 
107
96
  if ( $pre ) {
@@ -109,9 +98,8 @@ module.exports = ( options ) => {
109
98
  $pre.addClass( className );
110
99
 
111
100
  if ( options.lineNumbers ) {
112
- debug( 'adding line numbers' );
113
101
  $pre.addClass( 'line-numbers' );
114
- addLineNmbers = true;
102
+ addLineNumbers = true;
115
103
  }
116
104
  }
117
105
 
@@ -122,10 +110,13 @@ module.exports = ( options ) => {
122
110
  if ( !languages[ language ] ) {
123
111
  language = 'markup';
124
112
  }
125
- const html = ( language === 'markup' && !options.decode ) ? $this.html() : he.decode( $this.html() );
126
- const highlightedCode = Prism.highlight( html, Prism.languages[ language ] );
127
- $this.html( addLineNmbers ? highlightedCode + lineNumbersWrapper : highlightedCode );
128
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 );
129
120
  }
130
121
  } );
131
122
 
@@ -134,4 +125,6 @@ module.exports = ( options ) => {
134
125
  }
135
126
  } );
136
127
  };
137
- };
128
+ }
129
+
130
+ export default metalsmithPrism;
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "metalsmith-prism",
3
- "version": "4.2.4",
3
+ "version": "5.0.0",
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": ">= 14.0.0"
9
+ "node": ">= 18.0.0"
8
10
  },
9
11
  "scripts": {
10
12
  "preversion": "npm run test",
@@ -39,7 +41,6 @@
39
41
  "prismjs": "^1.29.0"
40
42
  },
41
43
  "devDependencies": {
42
- "babel-eslint": "^7.2.3",
43
44
  "chai": "^5.1.2",
44
45
  "eslint": "^9.14.0",
45
46
  "eslint-config-prettier": "^9.1.0",