nodebb-plugin-markdown 11.0.3 → 12.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.
package/index.js CHANGED
@@ -44,11 +44,18 @@ const Markdown = {
44
44
  },
45
45
 
46
46
  getConfig: async (config) => {
47
- const { defaultHighlightLanguage, highlightTheme } = await meta.settings.get('markdown');
47
+ let { defaultHighlightLanguage, highlightTheme, hljsLanguages, highlightLinesLanguageList } = await meta.settings.get('markdown');
48
+
49
+ try {
50
+ hljsLanguages = JSON.parse(hljsLanguages);
51
+ } catch (e) {
52
+ hljsLanguages = ['common'];
53
+ }
48
54
 
49
55
  config.markdown = {
50
56
  highlight: Markdown.highlight ? 1 : 0,
51
- highlightLinesLanguageList: Markdown.config.highlightLinesLanguageList,
57
+ highlightLinesLanguageList,
58
+ hljsLanguages,
52
59
  theme: highlightTheme || 'default.css',
53
60
  defaultHighlightLanguage: defaultHighlightLanguage || '',
54
61
  };
@@ -79,7 +86,6 @@ const Markdown = {
79
86
 
80
87
  langPrefix: 'language-',
81
88
  highlight: true,
82
- highlightLinesLanguageList: [],
83
89
  highlightTheme: 'default.css',
84
90
 
85
91
  probe: true,
@@ -95,7 +101,7 @@ const Markdown = {
95
101
  checkboxes: true,
96
102
  multimdTables: true,
97
103
  };
98
- const notCheckboxes = ['langPrefix', 'highlightTheme', 'highlightLinesLanguageList', 'probeCacheSize'];
104
+ const notCheckboxes = ['langPrefix', 'highlightTheme', 'probeCacheSize'];
99
105
 
100
106
  meta.settings.get('markdown', (err, options) => {
101
107
  if (err) {
@@ -116,17 +122,6 @@ const Markdown = {
116
122
  _self.highlight = _self.config.highlight;
117
123
  delete _self.config.highlight;
118
124
 
119
- if (typeof _self.config.highlightLinesLanguageList === 'string') {
120
- try {
121
- _self.config.highlightLinesLanguageList = JSON.parse(_self.config.highlightLinesLanguageList);
122
- } catch (e) {
123
- winston.warn('[plugins/markdown] Invalid config for highlightLinesLanguageList, blanking.');
124
- _self.config.highlightLinesLanguageList = [];
125
- }
126
-
127
- _self.config.highlightLinesLanguageList = _self.config.highlightLinesLanguageList.join(',').split(',');
128
- }
129
-
130
125
  parser = new MarkdownIt(_self.config);
131
126
 
132
127
  Markdown.updateParserRules(parser);
@@ -1,12 +1,19 @@
1
1
  'use strict';
2
2
 
3
+ const path = require('path');
4
+
3
5
  const parent = module.parent.exports;
4
6
  const posts = require.main.require('./src/posts');
7
+ const file = require.main.require('./src/file');
5
8
  const Controllers = {};
6
9
 
7
- Controllers.renderAdmin = function renderAdmin(req, res) {
10
+ Controllers.renderAdmin = async function renderAdmin(req, res) {
11
+ let hljsLanguages = await file.walk(path.resolve(require.main.path, 'node_modules/highlight.js/lib/languages'));
12
+ hljsLanguages = hljsLanguages.map(language => path.basename(language, '.js')).filter(language => !language.endsWith('.js'));
13
+
8
14
  res.render('admin/plugins/markdown', {
9
15
  themes: parent.themes,
16
+ hljsLanguages,
10
17
  });
11
18
  };
12
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-markdown",
3
- "version": "11.0.3",
3
+ "version": "12.0.0",
4
4
  "description": "A Markdown parser for NodeBB",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -16,7 +16,6 @@ define('admin/plugins/markdown', ['settings', 'alerts'], function (Settings, ale
16
16
 
17
17
  langPrefix: 'language-',
18
18
  highlight: true,
19
- highlightLinesLanguageList: [],
20
19
  highlightTheme: 'default.css',
21
20
 
22
21
  probe: true,
@@ -240,7 +240,55 @@
240
240
 
241
241
  async function highlight(elements) {
242
242
  if (parseInt(config.markdown.highlight, 10)) {
243
- const { default: hljs } = await import('highlight.js/lib/common');
243
+ console.debug('[plugin/markdown] Initializing highlight.js');
244
+ let hljs;
245
+ let list;
246
+ let aliasMap = new Map();
247
+ switch(true) {
248
+ case config.markdown.hljsLanguages.includes('common'): {
249
+ ({ default: hljs} = await import(`highlight.js/lib/common`));
250
+ list = 'common';
251
+ break;
252
+ }
253
+
254
+ case config.markdown.hljsLanguages.includes('all'): {
255
+ ({ default: hljs} = await import(`highlight.js`));
256
+ list = 'all';
257
+ break;
258
+ }
259
+
260
+ default: {
261
+ ({ default: hljs} = await import(`highlight.js/lib/core`));
262
+ list = 'core';
263
+ }
264
+ }
265
+ console.debug(`[plugins/markdown] Loaded ${list} hljs library`);
266
+
267
+ if (list !== 'all') {
268
+ await Promise.all(config.markdown.hljsLanguages.map(async (language) => {
269
+ if (['common', 'all'].includes(language)) {
270
+ return;
271
+ }
272
+
273
+ console.debug(`[plugins/markdown] Loading ${language} support`);
274
+ const { default: lang } = await import('../../node_modules/highlight.js/lib/languages/' + language + '.js');
275
+ hljs.registerLanguage(language, lang);
276
+ }));
277
+ }
278
+
279
+ // Build alias set
280
+ hljs.listLanguages().forEach((language) => {
281
+ const { aliases } = hljs.getLanguage(language);
282
+ if (aliases && Array.isArray(aliases)) {
283
+ aliases.forEach((alias) => {
284
+ aliasMap.set(alias, language);
285
+ });
286
+ }
287
+
288
+ aliasMap.set(language, language);
289
+ });
290
+
291
+ console.debug(`[plugins/markdown] Loading support for line numbers`);
244
292
  window.hljs = hljs;
245
293
  require('highlightjs-line-numbers.js');
246
294
 
@@ -255,14 +303,16 @@
255
303
  window.hljs.highlightElement(block);
256
304
 
257
305
  // Check detected language against whitelist and add lines if enabled
258
- if (block.className.split(' ').map(function (className) {
259
- if (className.indexOf('language-') === 0) {
260
- className = className.slice(9);
306
+ const classIterator = block.classList.values();
307
+ for(className of classIterator) {
308
+ if (className.startsWith('language-')) {
309
+ const language = className.split('-')[1];
310
+ if (aliasMap.has(language) && config.markdown.highlightLinesLanguageList.includes(aliasMap.get(language))) {
311
+ $(block).attr('data-lines', 1);
312
+ window.hljs.lineNumbersBlock(block);
313
+ }
314
+ break;
261
315
  }
262
- return config.markdown.highlightLinesLanguageList.includes(className) || config.markdown.highlightLinesLanguageList.includes(className);
263
- }).some(Boolean)) {
264
- $(block).attr('data-lines', 1);
265
- window.hljs.lineNumbersBlock(block);
266
316
  }
267
317
  });
268
318
  }
@@ -103,34 +103,37 @@
103
103
  <input class="form-control" placeholder="language-" type="text" name="langPrefix" id="langPrefix" />
104
104
  </div>
105
105
 
106
+ <div class="mb-3">
107
+ <label class="form-label" for="hljsLanguages">Apply syntax highlighting to the following languages</label>
108
+ <select class="form-select" multiple="true" name="hljsLanguages" id="hljsLanguages" size="20">
109
+ <optgroup label="Pre-defined lists">
110
+ <option value="all">All supported languages (greatest file size)</option>
111
+ <option value="common" selected>Common languages (a good compromise)</option>
112
+ </optgroup>
113
+ <optgroup label="Individual languages">
114
+ {{{ each hljsLanguages }}}
115
+ <option value="{@value}">{@value}</option>
116
+ {{{ end }}}
117
+ </optgroup>
118
+ </select>
119
+ <p class="form-text">
120
+ You can use <code>ctrl</code> and <code>shift</code> to select/deselect multiple
121
+ items and select/deselect items in ranges. <em>(Default: "Common languages".)</em>
122
+ </p>
123
+ <p class="form-text">
124
+ You are able to mix and match any of the items above, although "All" will include
125
+ everything anyway.
126
+ </p>
127
+ </div>
128
+
106
129
  <div class="mb-3">
107
130
  <label class="form-label" for="highlightLinesLanguageList">
108
131
  Enable line numbers for the following languages
109
132
  </label>
110
- <select class="form-control" multiple="true" name="highlightLinesLanguageList" id="highlightLinesLanguageList" size="20">
111
- <option value="apache,apacheconf">Apache</option>
112
- <option value="bash,sh,zsh">Bash</option>
113
- <option value="cs,csharp">C#</option>
114
- <option value="cpp,c,cc,h,c++,h++,hpp">C++</option>
115
- <option value="css">CSS</option>
116
- <option value="coffeescript,coffee,cson,iced">CoffeeScript</option>
117
- <option value="diff,patch">Diff</option>
118
- <option value="xml,html,xhtml,rss,atom,xjb,xsd,xsl,plist">HTML</option>
119
- <option value="http,https">HTTP</option>
120
- <option value="ini,toml">Ini</option>
121
- <option value="json">JSON</option>
122
- <option value="java">Java</option>
123
- <option value="javascript,js,jsx">Javascript</option>
124
- <option value="makefile,mk,mak">Makefile</option>
125
- <option value="markdown,md,mkdown,mkd">Markdown</option>
126
- <option value="nginx,nginxconf">Nginx</option>
127
- <option value="objectivec,objc,obj-c">Objective C</option>
128
- <option value="php,php3,php4,php5,php6">PHP</option>
129
- <option value="perl,pl,pm">Perl</option>
130
- <option value="python,py,gyp">Python</option>
131
- <option value="ruby,rb,gemspec,podspec,thor,irb">Ruby</option>
132
- <option value="sql">SQL</option>
133
- <option value="shell,console">Shell</option>
133
+ <select class="form-select" multiple="true" name="highlightLinesLanguageList" id="highlightLinesLanguageList" size="20">
134
+ {{{ each hljsLanguages }}}
135
+ <option value="{@value}">{@value}</option>
136
+ {{{ end }}}
134
137
  </select>
135
138
  <p class="form-text">
136
139
  You can use <code>ctrl</code> and <code>shift</code> to select/deselect multiple