@peaceroad/markdown-it-renderer-fence 0.3.0 → 0.4.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/README.md +25 -1
- package/index.js +196 -27
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -92,6 +92,7 @@ CSS example: <https://codepen.io/peaceroad/pen/qBGpYGK>
|
|
|
92
92
|
## Add span elements to add background color to the row ranges.
|
|
93
93
|
|
|
94
94
|
Add `em-lines` or `emphasize-lines` attribute by by adding attributes used markdown-it-attrs.
|
|
95
|
+
Open-ended ranges are supported: `-5` (1..5), `3-` (3..last), `-` (all).
|
|
95
96
|
|
|
96
97
|
~~~md
|
|
97
98
|
``` {em-lines="2,4-5"}
|
|
@@ -132,6 +133,25 @@ const longLine = 'This line is long but wraps.'
|
|
|
132
133
|
|
|
133
134
|
When `setPreWrapStyle` is set to false, only `data-pre-wrap="true"` is added and the inline style is omitted.
|
|
134
135
|
|
|
136
|
+
## Mark comment lines in code blocks
|
|
137
|
+
|
|
138
|
+
Add `comment-line` attribute to mark comment lines. Lines that start with the given marker (after leading whitespace) are wrapped with `<span class="pre-comment-line">`.
|
|
139
|
+
|
|
140
|
+
~~~md
|
|
141
|
+
```samp {comment-line="#"}
|
|
142
|
+
# comment
|
|
143
|
+
echo 1
|
|
144
|
+
```
|
|
145
|
+
~~~
|
|
146
|
+
|
|
147
|
+
~~~html
|
|
148
|
+
<pre><samp data-pre-comment-line="#"><span class="pre-comment-line"># comment</span>
|
|
149
|
+
echo 1
|
|
150
|
+
</samp></pre>
|
|
151
|
+
~~~
|
|
152
|
+
|
|
153
|
+
Note: this feature relies on line splitting and is disabled when `useHighlightPre` is true and `<pre><code>` is provided by the highlighter.
|
|
154
|
+
|
|
135
155
|
|
|
136
156
|
## Options
|
|
137
157
|
|
|
@@ -141,8 +161,12 @@ The following options can be specified when initializing the plugin:
|
|
|
141
161
|
- setHighlight: default true — enable calling highlight function (e.g., highlight.js).
|
|
142
162
|
- setLineNumber: default true — wrap lines in spans for line numbers.
|
|
143
163
|
- setEmphasizeLines: default true — enable emphasis based on emphasize-lines attribute.
|
|
144
|
-
-
|
|
164
|
+
- lineEndSpanThreshold: default 0 — character count threshold to append end-of-line span (0 to disable).
|
|
165
|
+
- setLineEndSpan: alias for lineEndSpanThreshold.
|
|
145
166
|
- lineEndSpanClass: default 'pre-lineend-spacer' — CSS class for end-of-line span.
|
|
146
167
|
- setPreWrapStyle: default true — include inline pre-wrap styles on `<pre>` when wrap is enabled.
|
|
168
|
+
- useHighlightPre: default false — if highlight returns `<pre><code>`, keep that wrapper and skip line-splitting features; attributes are still merged.
|
|
169
|
+
|
|
170
|
+
When `useHighlightPre` is true and the highlight output contains `<pre><code>`, line-splitting features are disabled (setLineNumber, setEmphasizeLines, lineEndSpanThreshold, comment-line).
|
|
147
171
|
- sampLang: default 'shell,console' — comma-separated list of languages (in addition to 'samp') that will be rendered using `<samp>`.
|
|
148
172
|
- langPrefix: default md.options.langPrefix || 'language-' — prefix for language class on code blocks.
|
package/index.js
CHANGED
|
@@ -5,9 +5,13 @@ const interAttrsSpaceReg = / +/
|
|
|
5
5
|
const tagReg = /<\/?([A-Za-z][A-Za-z0-9-]*)(?:\s+[^>]*?)?\/?\s*>/g
|
|
6
6
|
const preLineTag = '<span class="pre-line">'
|
|
7
7
|
const emphOpenTag = '<span class="pre-lines-emphasis">'
|
|
8
|
+
const commentLineClass = 'pre-comment-line'
|
|
8
9
|
const closeTag = '</span>'
|
|
9
10
|
const closeTagLen = closeTag.length
|
|
10
11
|
const preWrapStyle = 'white-space: pre-wrap; overflow-wrap: anywhere;'
|
|
12
|
+
const preCodeWrapperReg = /^\s*<pre\b([^>]*)>\s*<code\b([^>]*)>([\s\S]*?)<\/code>\s*<\/pre>\s*$/i
|
|
13
|
+
const htmlAttrReg = /([^\s=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g
|
|
14
|
+
const voidTags = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'])
|
|
11
15
|
|
|
12
16
|
const appendStyleValue = (style, addition) => {
|
|
13
17
|
if (!addition) return style
|
|
@@ -20,27 +24,110 @@ const appendStyleValue = (style, addition) => {
|
|
|
20
24
|
return base + separator + next
|
|
21
25
|
}
|
|
22
26
|
|
|
27
|
+
const parseHtmlAttrs = (attrText) => {
|
|
28
|
+
const attrs = []
|
|
29
|
+
if (!attrText) return attrs
|
|
30
|
+
htmlAttrReg.lastIndex = 0
|
|
31
|
+
let match
|
|
32
|
+
while ((match = htmlAttrReg.exec(attrText)) !== null) {
|
|
33
|
+
const name = match[1]
|
|
34
|
+
const val = match[2] ?? match[3] ?? match[4] ?? ''
|
|
35
|
+
attrs.push([name, val])
|
|
36
|
+
}
|
|
37
|
+
return attrs
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const mergeAttrSets = (target, source) => {
|
|
41
|
+
if (!source || source.length === 0) return
|
|
42
|
+
const index = new Map()
|
|
43
|
+
for (let i = 0; i < target.length; i++) index.set(target[i][0], i)
|
|
44
|
+
for (const [name, val] of source) {
|
|
45
|
+
const idx = index.get(name)
|
|
46
|
+
if (name === 'class') {
|
|
47
|
+
if (idx === undefined) {
|
|
48
|
+
target.push([name, val])
|
|
49
|
+
index.set(name, target.length - 1)
|
|
50
|
+
} else if (val) {
|
|
51
|
+
const existing = target[idx][1]
|
|
52
|
+
target[idx][1] = existing ? existing + ' ' + val : val
|
|
53
|
+
}
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
if (name === 'style') {
|
|
57
|
+
if (idx === undefined) {
|
|
58
|
+
target.push([name, val])
|
|
59
|
+
index.set(name, target.length - 1)
|
|
60
|
+
} else {
|
|
61
|
+
target[idx][1] = appendStyleValue(target[idx][1], val)
|
|
62
|
+
}
|
|
63
|
+
continue
|
|
64
|
+
}
|
|
65
|
+
if (idx === undefined) {
|
|
66
|
+
target.push([name, val])
|
|
67
|
+
index.set(name, target.length - 1)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
23
72
|
const getEmphasizeLines = (attrVal) => {
|
|
24
73
|
const lines = []
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
74
|
+
for (const range of attrVal.split(',')) {
|
|
75
|
+
const part = range.trim()
|
|
76
|
+
if (!part) continue
|
|
77
|
+
const dash = part.indexOf('-')
|
|
78
|
+
if (dash > -1) {
|
|
79
|
+
const left = part.slice(0, dash).trim()
|
|
80
|
+
const right = part.slice(dash + 1).trim()
|
|
81
|
+
const s = left ? parseInt(left, 10) : null
|
|
82
|
+
const e = right ? parseInt(right, 10) : null
|
|
83
|
+
if (s !== null && (!Number.isFinite(s) || s <= 0)) continue
|
|
84
|
+
if (e !== null && (!Number.isFinite(e) || e <= 0)) continue
|
|
85
|
+
if (s === null && e === null) {
|
|
86
|
+
lines.push([null, null])
|
|
87
|
+
} else {
|
|
88
|
+
lines.push([s, e])
|
|
89
|
+
}
|
|
30
90
|
} else {
|
|
31
|
-
s = parseInt(
|
|
91
|
+
const s = parseInt(part, 10)
|
|
92
|
+
if (!Number.isFinite(s) || s <= 0) continue
|
|
32
93
|
lines.push([s, s])
|
|
33
94
|
}
|
|
34
|
-
}
|
|
95
|
+
}
|
|
35
96
|
return lines
|
|
36
97
|
}
|
|
37
98
|
|
|
38
|
-
const splitFenceBlockToLines = (content, emphasizeLines, needLineNumber, needEmphasis, needEndSpan, threshold, lineEndSpanClass, br) => {
|
|
99
|
+
const splitFenceBlockToLines = (content, emphasizeLines, needLineNumber, needEmphasis, needEndSpan, threshold, lineEndSpanClass, br, commentLines, commentClass) => {
|
|
39
100
|
const lines = content.split(br)
|
|
40
101
|
const len = lines.length
|
|
41
102
|
const endSpanTag = needEndSpan ? `<span class="${lineEndSpanClass}"></span>` : ''
|
|
103
|
+
const needComment = !!(commentLines && commentClass)
|
|
104
|
+
const maxLine = len - (lines[len - 1] === '' ? 1 : 0)
|
|
42
105
|
let emIdx = 0
|
|
43
|
-
let
|
|
106
|
+
let emStart
|
|
107
|
+
let emEnd
|
|
108
|
+
let doEmphasis = false
|
|
109
|
+
if (needEmphasis && maxLine > 0) {
|
|
110
|
+
const normalized = []
|
|
111
|
+
for (const range of emphasizeLines) {
|
|
112
|
+
let [s, e] = range
|
|
113
|
+
if (s == null) s = 1
|
|
114
|
+
if (e == null) e = maxLine
|
|
115
|
+
if (!Number.isFinite(s) || !Number.isFinite(e) || s <= 0 || e <= 0) continue
|
|
116
|
+
if (s > e) {
|
|
117
|
+
const tmp = s
|
|
118
|
+
s = e
|
|
119
|
+
e = tmp
|
|
120
|
+
}
|
|
121
|
+
if (s > maxLine || e < 1) continue
|
|
122
|
+
if (e > maxLine) e = maxLine
|
|
123
|
+
normalized.push([s, e])
|
|
124
|
+
}
|
|
125
|
+
if (normalized.length > 0) {
|
|
126
|
+
doEmphasis = true
|
|
127
|
+
emphasizeLines = normalized
|
|
128
|
+
;[emStart, emEnd] = emphasizeLines[0]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
44
131
|
for (let n = 0; n < len; n++) {
|
|
45
132
|
let line = lines[n]
|
|
46
133
|
|
|
@@ -69,10 +156,11 @@ const splitFenceBlockToLines = (content, emphasizeLines, needLineNumber, needEmp
|
|
|
69
156
|
let match
|
|
70
157
|
while ((match = tagReg.exec(line)) !== null) {
|
|
71
158
|
const [fullMatch, tagName] = match
|
|
159
|
+
const tagNameLower = tagName.toLowerCase()
|
|
72
160
|
if (fullMatch.startsWith('</')) {
|
|
73
|
-
if (tagStack[tagStack.length-1] ===
|
|
74
|
-
} else if (!fullMatch.endsWith('/>')) {
|
|
75
|
-
tagStack.push(
|
|
161
|
+
if (tagStack[tagStack.length-1] === tagNameLower) tagStack.pop()
|
|
162
|
+
} else if (!fullMatch.endsWith('/>') && !voidTags.has(tagNameLower)) {
|
|
163
|
+
tagStack.push(tagNameLower)
|
|
76
164
|
}
|
|
77
165
|
}
|
|
78
166
|
for (let i = tagStack.length-1; i >= 0; i--) {
|
|
@@ -81,10 +169,17 @@ const splitFenceBlockToLines = (content, emphasizeLines, needLineNumber, needEmp
|
|
|
81
169
|
lines[n+1] = `<${tagName}>` + (lines[n+1]||'')
|
|
82
170
|
}
|
|
83
171
|
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (needComment && commentLines[n]) {
|
|
175
|
+
line = `<span class="${commentClass}">` + line + closeTag
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (needLineNumber && n !== len - 1) {
|
|
84
179
|
line = preLineTag + line + closeTag
|
|
85
180
|
}
|
|
86
181
|
|
|
87
|
-
if (
|
|
182
|
+
if (doEmphasis) {
|
|
88
183
|
if (emStart === n + 1) line = emphOpenTag + line
|
|
89
184
|
if (emEnd === n) {
|
|
90
185
|
line = closeTag + line
|
|
@@ -156,15 +251,18 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
156
251
|
let emphasizeLines = []
|
|
157
252
|
let wrapEnabled = false
|
|
158
253
|
let preWrapValue
|
|
254
|
+
let commentLineValue
|
|
159
255
|
|
|
160
256
|
if (token.attrs) {
|
|
161
257
|
const newAttrs = []
|
|
162
258
|
let dataPreStartIndex = -1
|
|
163
259
|
let dataPreEmphasisIndex = -1
|
|
164
260
|
let styleIndex = -1
|
|
261
|
+
let dataPreCommentIndex = -1
|
|
165
262
|
let startValue
|
|
166
263
|
let emphasisValue
|
|
167
264
|
let styleValue
|
|
265
|
+
let sawCommentLine = false
|
|
168
266
|
let sawStartAttr = false
|
|
169
267
|
let sawEmphasisAttr = false
|
|
170
268
|
const appendOrder = []
|
|
@@ -206,6 +304,11 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
206
304
|
dataPreEmphasisIndex = newAttrs.length
|
|
207
305
|
newAttrs.push(attr)
|
|
208
306
|
break
|
|
307
|
+
case 'data-pre-comment-line':
|
|
308
|
+
dataPreCommentIndex = newAttrs.length
|
|
309
|
+
commentLineValue = val
|
|
310
|
+
newAttrs.push(attr)
|
|
311
|
+
break
|
|
209
312
|
case 'em-lines':
|
|
210
313
|
case 'emphasize-lines':
|
|
211
314
|
emphasizeLines = getEmphasizeLines(val)
|
|
@@ -215,6 +318,13 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
215
318
|
sawEmphasisAttr = true
|
|
216
319
|
}
|
|
217
320
|
break
|
|
321
|
+
case 'comment-line':
|
|
322
|
+
commentLineValue = val
|
|
323
|
+
if (!sawCommentLine) {
|
|
324
|
+
appendOrder.push('comment')
|
|
325
|
+
sawCommentLine = true
|
|
326
|
+
}
|
|
327
|
+
break
|
|
218
328
|
case 'data-pre-wrap':
|
|
219
329
|
preWrapValue = val
|
|
220
330
|
if (val === '' || val === 'true') wrapEnabled = true
|
|
@@ -236,6 +346,9 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
236
346
|
if (emphasisValue !== undefined && dataPreEmphasisIndex >= 0) {
|
|
237
347
|
newAttrs[dataPreEmphasisIndex][1] = emphasisValue
|
|
238
348
|
}
|
|
349
|
+
if (commentLineValue !== undefined && dataPreCommentIndex >= 0) {
|
|
350
|
+
newAttrs[dataPreCommentIndex][1] = commentLineValue
|
|
351
|
+
}
|
|
239
352
|
for (const kind of appendOrder) {
|
|
240
353
|
if (kind === 'start') {
|
|
241
354
|
if (dataPreStartIndex === -1 && startValue !== undefined) {
|
|
@@ -245,6 +358,10 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
245
358
|
if (dataPreEmphasisIndex === -1 && emphasisValue !== undefined) {
|
|
246
359
|
newAttrs.push(['data-pre-emphasis', emphasisValue])
|
|
247
360
|
}
|
|
361
|
+
} else if (kind === 'comment') {
|
|
362
|
+
if (dataPreCommentIndex === -1 && commentLineValue !== undefined) {
|
|
363
|
+
newAttrs.push(['data-pre-comment-line', commentLineValue])
|
|
364
|
+
}
|
|
248
365
|
}
|
|
249
366
|
}
|
|
250
367
|
if (startNumber !== -1) {
|
|
@@ -258,13 +375,17 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
258
375
|
if (wrapEnabled) preWrapValue = 'true'
|
|
259
376
|
token.attrs = newAttrs
|
|
260
377
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
378
|
+
|
|
379
|
+
const isSamp = opt._sampReg.test(lang)
|
|
380
|
+
let commentLines
|
|
381
|
+
let needComment = false
|
|
382
|
+
if (commentLineValue) {
|
|
383
|
+
const rawLines = token.content.split(/\r?\n/)
|
|
384
|
+
commentLines = new Array(rawLines.length)
|
|
385
|
+
for (let i = 0; i < rawLines.length; i++) {
|
|
386
|
+
const isComment = rawLines[i].trimStart().startsWith(commentLineValue)
|
|
387
|
+
commentLines[i] = isComment
|
|
388
|
+
if (isComment) needComment = true
|
|
268
389
|
}
|
|
269
390
|
}
|
|
270
391
|
|
|
@@ -278,17 +399,59 @@ const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
|
278
399
|
content = md.utils.escapeHtml(token.content)
|
|
279
400
|
}
|
|
280
401
|
|
|
402
|
+
let preAttrsFromHighlight
|
|
403
|
+
let hasHighlightPre = false
|
|
404
|
+
const hasPreTag = (content.indexOf('<pre') !== -1 || content.indexOf('<PRE') !== -1)
|
|
405
|
+
if (hasPreTag) {
|
|
406
|
+
const preMatch = content.match(preCodeWrapperReg)
|
|
407
|
+
if (preMatch) {
|
|
408
|
+
hasHighlightPre = true
|
|
409
|
+
preAttrsFromHighlight = parseHtmlAttrs(preMatch[1])
|
|
410
|
+
const codeAttrsFromHighlight = parseHtmlAttrs(preMatch[2])
|
|
411
|
+
content = preMatch[3]
|
|
412
|
+
if (codeAttrsFromHighlight.length) {
|
|
413
|
+
if (!token.attrs) token.attrs = []
|
|
414
|
+
mergeAttrSets(token.attrs, codeAttrsFromHighlight)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (opt.useHighlightPre && hasPreTag && !hasHighlightPre) {
|
|
419
|
+
return content.endsWith('\n') ? content : content + '\n'
|
|
420
|
+
}
|
|
421
|
+
orderTokenAttrs(token, opt)
|
|
422
|
+
|
|
423
|
+
let preAttrs = preAttrsFromHighlight ? preAttrsFromHighlight.slice() : []
|
|
424
|
+
if (preWrapValue !== undefined) {
|
|
425
|
+
const idx = preAttrs.findIndex(attr => attr[0] === 'data-pre-wrap')
|
|
426
|
+
if (idx === -1) {
|
|
427
|
+
preAttrs.push(['data-pre-wrap', preWrapValue])
|
|
428
|
+
} else {
|
|
429
|
+
preAttrs[idx][1] = preWrapValue
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (wrapEnabled && opt.setPreWrapStyle !== false) {
|
|
433
|
+
const idx = preAttrs.findIndex(attr => attr[0] === 'style')
|
|
434
|
+
if (idx === -1) {
|
|
435
|
+
preAttrs.push(['style', preWrapStyle])
|
|
436
|
+
} else {
|
|
437
|
+
preAttrs[idx][1] = appendStyleValue(preAttrs[idx][1], preWrapStyle)
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (preAttrs.length) orderTokenAttrs({ attrs: preAttrs }, opt)
|
|
441
|
+
const preAttrsText = preAttrs.length ? slf.renderAttrs({ attrs: preAttrs }) : ''
|
|
442
|
+
|
|
281
443
|
const needLineNumber = opt.setLineNumber && startNumber >= 0
|
|
282
444
|
const needEmphasis = opt.setEmphasizeLines && emphasizeLines.length > 0
|
|
283
|
-
const needEndSpan = opt.
|
|
284
|
-
|
|
445
|
+
const needEndSpan = opt.lineEndSpanThreshold > 0
|
|
446
|
+
const useHighlightPre = opt.useHighlightPre && hasHighlightPre
|
|
447
|
+
if (!useHighlightPre && (needLineNumber || needEmphasis || needEndSpan || needComment)) {
|
|
285
448
|
const nlIndex = content.indexOf('\n')
|
|
286
449
|
const br = nlIndex > 0 && content[nlIndex - 1] === '\r' ? '\r\n' : '\n'
|
|
287
|
-
content = splitFenceBlockToLines(content, emphasizeLines, needLineNumber, needEmphasis, needEndSpan, opt.
|
|
450
|
+
content = splitFenceBlockToLines(content, emphasizeLines, needLineNumber, needEmphasis, needEndSpan, opt.lineEndSpanThreshold, opt.lineEndSpanClass, br, commentLines, commentLineClass)
|
|
288
451
|
}
|
|
289
452
|
|
|
290
|
-
const tag =
|
|
291
|
-
return `<pre${
|
|
453
|
+
const tag = isSamp ? 'samp' : 'code'
|
|
454
|
+
return `<pre${preAttrsText}><${tag}${slf.renderAttrs(token)}>${content}</${tag}></pre>\n`
|
|
292
455
|
}
|
|
293
456
|
|
|
294
457
|
const mditRendererFence = (md, option) => {
|
|
@@ -297,13 +460,19 @@ const mditRendererFence = (md, option) => {
|
|
|
297
460
|
setHighlight: true,
|
|
298
461
|
setLineNumber: true,
|
|
299
462
|
setEmphasizeLines: true,
|
|
300
|
-
|
|
463
|
+
lineEndSpanThreshold: 0,
|
|
301
464
|
lineEndSpanClass: 'pre-lineend-spacer',
|
|
302
465
|
setPreWrapStyle: true,
|
|
466
|
+
useHighlightPre: false,
|
|
303
467
|
sampLang: 'shell,console',
|
|
304
468
|
langPrefix: md.options.langPrefix || 'language-',
|
|
305
469
|
}
|
|
306
|
-
if (option)
|
|
470
|
+
if (option) {
|
|
471
|
+
Object.assign(opt, option)
|
|
472
|
+
if (option.lineEndSpanThreshold == null && option.setLineEndSpan != null) {
|
|
473
|
+
opt.lineEndSpanThreshold = option.setLineEndSpan
|
|
474
|
+
}
|
|
475
|
+
}
|
|
307
476
|
|
|
308
477
|
opt._sampReg = new RegExp('^(?:samp|' + opt.sampLang.split(',').join('|') + ')$')
|
|
309
478
|
opt._langReg = new RegExp(opt.langPrefix + '([A-Za-z0-9-]+)')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-renderer-fence",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "In code blocks, the `<samp>` tag is used with the language keywords `samp`, `shell`, and `console`, and provides an option to display line numbers.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
"repository": "https://github.com/peaceroad/p7d-markdown-it-renderer-fence",
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@peaceroad/markdown-it-figure-with-p-caption": "^0.
|
|
19
|
+
"@peaceroad/markdown-it-figure-with-p-caption": "^0.15.2",
|
|
20
|
+
"highlight.js": "^11.11.1",
|
|
20
21
|
"markdown-it": "^14.1.0",
|
|
21
22
|
"markdown-it-attrs": "^4.3.1",
|
|
22
|
-
"
|
|
23
|
+
"shiki": "^3.21.0"
|
|
23
24
|
}
|
|
24
25
|
}
|