@peaceroad/markdown-it-renderer-fence 0.1.2 → 0.2.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 +15 -1
- package/index.js +144 -111
- package/package.json +1 -1
- package/test/example-line-end-span.txt +55 -0
- package/test/example-lines-emphasis.txt +5 -10
- package/test/examples.txt +1 -1
- package/test/test.js +4 -1
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ Add `em-lines` or `emphasize-lines` attribute by by adding attributes used markd
|
|
|
106
106
|
|
|
107
107
|
~~~html
|
|
108
108
|
[HTML]
|
|
109
|
-
<pre><code>1
|
|
109
|
+
<pre><code data-pre-emphasis="2,4-5">1
|
|
110
110
|
<span class="pre-lines-emphasis">2
|
|
111
111
|
</span>3
|
|
112
112
|
<span class="pre-lines-emphasis">4
|
|
@@ -114,3 +114,17 @@ Add `em-lines` or `emphasize-lines` attribute by by adding attributes used markd
|
|
|
114
114
|
</span>6
|
|
115
115
|
</code></pre>
|
|
116
116
|
~~~
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## Options
|
|
120
|
+
|
|
121
|
+
The following options can be specified when initializing the plugin:
|
|
122
|
+
|
|
123
|
+
- attrsOrder: default ['class','id','data-*','style'] — order of attributes in output; wildcards supported.
|
|
124
|
+
- setHighlight: default true — enable calling highlight function (e.g., highlight.js).
|
|
125
|
+
- setLineNumber: default true — wrap lines in spans for line numbers.
|
|
126
|
+
- setEmphasizeLines: default true — enable emphasis based on emphasize-lines attribute.
|
|
127
|
+
- setLineEndSpan: default 0 — character count threshold to append end-of-line span (0 to disable).
|
|
128
|
+
- lineEndSpanClass: default 'pre-lineend-spacer' — CSS class for end-of-line span.
|
|
129
|
+
- sampLang: default 'shell,console' — comma-separated list of languages (in addition to 'samp') that will be rendered using `<samp>`.
|
|
130
|
+
- langPrefix: default md.options.langPrefix || 'language-' — prefix for language class on code blocks.
|
package/index.js
CHANGED
|
@@ -1,68 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
const infoReg = /^([^{\s]*)(?:\s*\{(.*)\})?$/
|
|
2
|
+
const startReg = /^(?:(?:data-)?pre-)?start$/
|
|
3
|
+
const startFilterReg = /^(?:pre-)?start$/
|
|
4
|
+
const emphasisReg = /^em(?:phasize)?-lines$/
|
|
5
|
+
|
|
6
|
+
const attrReg = /^(?:([.#])(.+)|(.+?)(?:=(["'])?(.*?)\1)?)$/
|
|
7
|
+
const interAttrsSpaceReg = / +/
|
|
8
|
+
const tagReg = /<\/?([A-Za-z][A-Za-z0-9-]*)(?:\s+[^>]*?)?\/?\s*>/g
|
|
9
|
+
const preLineTag = '<span class="pre-line">'
|
|
10
|
+
const emphOpenTag = '<span class="pre-lines-emphasis">'
|
|
11
|
+
const closeTag = '</span>'
|
|
12
|
+
const closeTagLen = closeTag.length
|
|
12
13
|
|
|
13
|
-
const
|
|
14
|
+
const getEmphasizeLines = (attrVal) => {
|
|
14
15
|
const lines = []
|
|
15
16
|
let s, e
|
|
16
|
-
|
|
17
|
-
if (range.
|
|
18
|
-
[s, e] = range.split('-').map(n => parseInt(n.trim(), 10))
|
|
19
|
-
lines.push([s, e])
|
|
17
|
+
attrVal.split(',').forEach(range => {
|
|
18
|
+
if (range.indexOf('-') > -1) {
|
|
19
|
+
[s, e] = range.split('-').map(n => parseInt(n.trim(), 10))
|
|
20
|
+
lines.push([s, e])
|
|
20
21
|
} else {
|
|
21
22
|
s = parseInt(range.trim(), 10)
|
|
22
23
|
lines.push([s, s])
|
|
23
24
|
}
|
|
24
|
-
})
|
|
25
|
-
return lines
|
|
25
|
+
})
|
|
26
|
+
return lines
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
const splitFenceBlockToLines = (content, emphasizeLines,
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
const splitFenceBlockToLines = (content, emphasizeLines, needLineNumber, needEmphasis, needEndSpan, threshold, lineEndSpanClass, br) => {
|
|
30
|
+
const lines = content.split(br)
|
|
31
|
+
const len = lines.length
|
|
32
|
+
const endSpanTag = `<span class="${lineEndSpanClass}"></span>`
|
|
33
|
+
let emIdx = 0
|
|
34
|
+
let [emStart, emEnd] = emphasizeLines[0] || []
|
|
35
|
+
for (let n = 0; n < len; n++) {
|
|
36
|
+
let line = lines[n]
|
|
37
|
+
|
|
38
|
+
if (needEndSpan) {
|
|
39
|
+
let lineLen = 0
|
|
40
|
+
for (let i = 0, L = line.length; i < L; i++) {
|
|
41
|
+
lineLen += line.charCodeAt(i) > 255 ? 2 : 1
|
|
39
42
|
}
|
|
40
|
-
if (
|
|
41
|
-
|
|
43
|
+
if (lineLen >= threshold) {
|
|
44
|
+
if (line.slice(-closeTagLen) === closeTag) {
|
|
45
|
+
line = line.slice(0, -closeTagLen) + endSpanTag + closeTag
|
|
46
|
+
} else {
|
|
47
|
+
line = line + endSpanTag
|
|
48
|
+
}
|
|
42
49
|
}
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
if (needLineNumber && n !== len - 1) {
|
|
53
|
+
const tagStack = []
|
|
54
|
+
tagReg.lastIndex = 0
|
|
55
|
+
let match
|
|
56
|
+
while ((match = tagReg.exec(line)) !== null) {
|
|
57
|
+
const [fullMatch, tagName] = match
|
|
58
|
+
if (fullMatch.startsWith('</')) {
|
|
59
|
+
if (tagStack[tagStack.length-1] === tagName) tagStack.pop()
|
|
60
|
+
} else if (!fullMatch.endsWith('/>')) {
|
|
61
|
+
tagStack.push(tagName)
|
|
62
|
+
}
|
|
48
63
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
for (let i = tagStack.length-1; i >= 0; i--) {
|
|
65
|
+
const tagName = tagStack[i]
|
|
66
|
+
line += `</${tagName}>`
|
|
67
|
+
lines[n+1] = `<${tagName}>` + (lines[n+1]||'')
|
|
52
68
|
}
|
|
69
|
+
line = preLineTag + line + closeTag
|
|
53
70
|
}
|
|
54
71
|
|
|
55
|
-
|
|
72
|
+
if (needEmphasis) {
|
|
73
|
+
if (emStart === n + 1) line = emphOpenTag + line
|
|
74
|
+
if (emEnd === n) {
|
|
75
|
+
line = closeTag + line
|
|
76
|
+
emIdx++
|
|
77
|
+
[emStart, emEnd] = emphasizeLines[emIdx] || []
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
lines[n] = line
|
|
81
|
+
}
|
|
56
82
|
return lines.join(br)
|
|
57
83
|
}
|
|
58
84
|
|
|
59
|
-
const
|
|
85
|
+
const getInfoAttr = (infoAttr) => {
|
|
86
|
+
let attrSets = infoAttr.trim().split(interAttrsSpaceReg)
|
|
60
87
|
let arr = []
|
|
61
|
-
let attrSets = infoAttr.trim().split(/ +/)
|
|
62
88
|
for (let attrSet of attrSets) {
|
|
63
|
-
const str =
|
|
89
|
+
const str = attrReg.exec(attrSet)
|
|
64
90
|
if (str) {
|
|
65
|
-
//console.log(str)
|
|
66
91
|
if (str[1] === '.') str[1] = 'class'
|
|
67
92
|
if (str[1] === '#') str[1] = 'id'
|
|
68
93
|
if (str[3]) {
|
|
@@ -75,102 +100,110 @@ const setInfoAttr = (infoAttr) => {
|
|
|
75
100
|
return arr
|
|
76
101
|
}
|
|
77
102
|
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
103
|
+
const orderTokenAttrs = (token, opt) => {
|
|
104
|
+
if (!token.attrs) return
|
|
105
|
+
const order = opt.attrsOrder || []
|
|
106
|
+
token.attrs.sort((a, b) => {
|
|
107
|
+
const idx = (name) => {
|
|
108
|
+
for (let i = 0; i < order.length; i++) {
|
|
109
|
+
const key = order[i]
|
|
110
|
+
if (key.endsWith('*')) {
|
|
111
|
+
const prefix = key.slice(0, -1)
|
|
112
|
+
if (name.startsWith(prefix)) return i
|
|
113
|
+
} else if (name === key) {
|
|
114
|
+
return i
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return order.length
|
|
118
|
+
}
|
|
119
|
+
return idx(a[0]) - idx(b[0])
|
|
120
|
+
})
|
|
121
|
+
}
|
|
87
122
|
|
|
123
|
+
const getFenceHtml = (tokens, idx, md, opt, slf) => {
|
|
88
124
|
const token = tokens[idx]
|
|
89
125
|
let content = token.content
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
126
|
+
const match = token.info.trim().match(infoReg)
|
|
127
|
+
let lang = match ? match[1] : ''
|
|
128
|
+
|
|
129
|
+
if (match && match[2]) {
|
|
130
|
+
getInfoAttr(match[2]).forEach(([name, val]) => token.attrJoin(name, val))
|
|
131
|
+
}
|
|
132
|
+
let langClass = ''
|
|
133
|
+
if (lang && lang !== 'samp') {
|
|
134
|
+
langClass = opt.langPrefix + lang
|
|
135
|
+
token.attrSet('class', langClass + (token.attrGet('class') ? ' ' + token.attrGet('class') : ''))
|
|
93
136
|
}
|
|
94
137
|
|
|
95
|
-
let
|
|
96
|
-
const langClass = lang && token.info !== 'samp' ? opt.langPrefix + lang : ''
|
|
97
|
-
let sAttr = {id: [], clas: [], data: [], style: [], other: []}
|
|
98
|
-
let hasPreLineStart = false
|
|
99
|
-
let preLineStart = -1
|
|
138
|
+
let startNumber = -1
|
|
100
139
|
let emphasizeLines = []
|
|
140
|
+
|
|
101
141
|
if (token.attrs) {
|
|
102
|
-
//console.log('start: ' +token.attrs)
|
|
103
142
|
for (let attr of token.attrs) {
|
|
104
|
-
if (attr[0] === '
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
hasPreLineStart = true
|
|
114
|
-
preLineStart = attr[1]
|
|
115
|
-
attr[0] = 'data-pre-start'
|
|
143
|
+
if (attr[0] === 'class') {
|
|
144
|
+
const hasClassLang = attr[1].match(opt._langReg)
|
|
145
|
+
if (hasClassLang) lang = hasClassLang[1]
|
|
146
|
+
}
|
|
147
|
+
if (startReg.test(attr[0])) {
|
|
148
|
+
startNumber = +attr[1]
|
|
149
|
+
if (attr[0] !== 'data-pre-start') {
|
|
150
|
+
token.attrSet('data-pre-start', attr[1])
|
|
151
|
+
token.attrs = token.attrs.filter(attr => !startFilterReg.test(attr[0]))
|
|
116
152
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
emphasizeLines =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
} else {
|
|
123
|
-
sAttr.other.push(attr)
|
|
153
|
+
}
|
|
154
|
+
if (emphasisReg.test(attr[0])) {
|
|
155
|
+
emphasizeLines = getEmphasizeLines(attr[1])
|
|
156
|
+
token.attrSet('data-pre-emphasis', attr[1])
|
|
157
|
+
token.attrs = token.attrs.filter(attr => !emphasisReg.test(attr[0]))
|
|
124
158
|
}
|
|
125
159
|
}
|
|
126
160
|
}
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
if (sAttr.style.length === 0) {
|
|
130
|
-
sAttr.style.push(['style', 'counter-set:pre-line-number ' + preLineStart + ';'])
|
|
131
|
-
} else {
|
|
132
|
-
sAttr.style[0][1] = sAttr.style[0][1].replace(/;?$/, '; counter-set:pre-line-number ' + preLineStart + ';')
|
|
133
|
-
}
|
|
161
|
+
if (startNumber !== -1) {
|
|
162
|
+
token.attrJoin('style', 'counter-set:pre-line-number ' + startNumber + ';')
|
|
134
163
|
}
|
|
135
|
-
|
|
164
|
+
orderTokenAttrs(token, opt)
|
|
165
|
+
|
|
136
166
|
if (opt.setHighlight && md.options.highlight) {
|
|
137
167
|
if (lang && lang !== 'samp' ) {
|
|
138
168
|
content = md.options.highlight(content, lang)
|
|
139
|
-
/*
|
|
140
|
-
try {
|
|
141
|
-
content = highlightjs.highlight(token.content, {language: lang}).value
|
|
142
|
-
} catch (__) {}
|
|
143
|
-
*/
|
|
144
169
|
} else {
|
|
145
170
|
content = md.utils.escapeHtml(token.content)
|
|
146
171
|
}
|
|
147
172
|
} else {
|
|
148
173
|
content = md.utils.escapeHtml(token.content)
|
|
149
174
|
}
|
|
150
|
-
if (opt.setLineNumber || opt.setEmphasizeLines) {
|
|
151
|
-
content = splitFenceBlockToLines(content, emphasizeLines, opt, hasPreLineStart)
|
|
152
|
-
}
|
|
153
175
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
176
|
+
const needLineNumber = opt.setLineNumber && startNumber >= 0
|
|
177
|
+
const needEmphasis = opt.setEmphasizeLines && emphasizeLines.length > 0
|
|
178
|
+
const needEndSpan = opt.setLineEndSpan > 0
|
|
179
|
+
if (needLineNumber || needEmphasis || needEndSpan) {
|
|
180
|
+
const brMatch = content.match(/\r?\n/)
|
|
181
|
+
const br = brMatch ? brMatch[0] : '\n'
|
|
182
|
+
content = splitFenceBlockToLines(content, emphasizeLines, needLineNumber, needEmphasis, needEndSpan, opt.setLineEndSpan, opt.lineEndSpanClass, br)
|
|
160
183
|
}
|
|
161
184
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
fenceHtml += '</samp>'
|
|
165
|
-
} else {
|
|
166
|
-
fenceHtml += '</code>'
|
|
167
|
-
}
|
|
168
|
-
return fenceHtml + '</pre>\n'
|
|
185
|
+
const tag = opt._sampReg.test(lang) ? 'samp' : 'code'
|
|
186
|
+
return `<pre><${tag}${slf.renderAttrs(token)}>${content}</${tag}></pre>\n`
|
|
169
187
|
}
|
|
170
188
|
|
|
171
|
-
const mditRendererFence = (md,
|
|
172
|
-
|
|
173
|
-
|
|
189
|
+
const mditRendererFence = (md, option) => {
|
|
190
|
+
const opt = {
|
|
191
|
+
attrsOrder: ['class', 'id', 'data-*', 'style'],
|
|
192
|
+
setHighlight: true,
|
|
193
|
+
setLineNumber: true,
|
|
194
|
+
setEmphasizeLines: true,
|
|
195
|
+
setLineEndSpan: 0,
|
|
196
|
+
lineEndSpanClass: 'pre-lineend-spacer',
|
|
197
|
+
sampLang: 'shell,console',
|
|
198
|
+
langPrefix: md.options.langPrefix || 'language-',
|
|
199
|
+
}
|
|
200
|
+
if (option) Object.assign(opt, option)
|
|
201
|
+
|
|
202
|
+
opt._sampReg = new RegExp('^(?:samp|' + opt.sampLang.split(',').join('|') + ')$')
|
|
203
|
+
opt._langReg = new RegExp(opt.langPrefix + '([A-Za-z0-9-]+)')
|
|
204
|
+
|
|
205
|
+
md.renderer.rules['fence'] = (tokens, idx, options, env, slf) => {
|
|
206
|
+
return getFenceHtml(tokens, idx, md, opt, slf)
|
|
174
207
|
}
|
|
175
208
|
}
|
|
176
209
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-renderer-fence",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.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
|
"type": "module",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[Markdown]
|
|
2
|
+
```
|
|
3
|
+
1234567890
|
|
4
|
+
2
|
|
5
|
+
1234567890
|
|
6
|
+
4
|
|
7
|
+
1234567890
|
|
8
|
+
6
|
|
9
|
+
```
|
|
10
|
+
[HTML]
|
|
11
|
+
<pre><code>1234567890<span class="pre-lineend-spacer"></span>
|
|
12
|
+
2
|
|
13
|
+
1234567890<span class="pre-lineend-spacer"></span>
|
|
14
|
+
4
|
|
15
|
+
1234567890<span class="pre-lineend-spacer"></span>
|
|
16
|
+
6
|
|
17
|
+
</code></pre>
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
[Markdown]
|
|
21
|
+
``` {em-lines="3"}
|
|
22
|
+
1234567890
|
|
23
|
+
2
|
|
24
|
+
1234567890
|
|
25
|
+
4
|
|
26
|
+
1234567890
|
|
27
|
+
6
|
|
28
|
+
```
|
|
29
|
+
[HTML]
|
|
30
|
+
<pre><code data-pre-emphasis="3">1234567890<span class="pre-lineend-spacer"></span>
|
|
31
|
+
2
|
|
32
|
+
<span class="pre-lines-emphasis">1234567890<span class="pre-lineend-spacer"></span>
|
|
33
|
+
</span>4
|
|
34
|
+
1234567890<span class="pre-lineend-spacer"></span>
|
|
35
|
+
6
|
|
36
|
+
</code></pre>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
[Markdown]
|
|
40
|
+
``` {em-lines="3" start="4"}
|
|
41
|
+
1234567890
|
|
42
|
+
2
|
|
43
|
+
1234567890
|
|
44
|
+
4
|
|
45
|
+
1234567890
|
|
46
|
+
6
|
|
47
|
+
```
|
|
48
|
+
[HTML]
|
|
49
|
+
<pre><code data-pre-emphasis="3" data-pre-start="4" style="counter-set:pre-line-number 4;"><span class="pre-line">1234567890<span class="pre-lineend-spacer"></span></span>
|
|
50
|
+
<span class="pre-line">2</span>
|
|
51
|
+
<span class="pre-lines-emphasis"><span class="pre-line">1234567890<span class="pre-lineend-spacer"></span></span>
|
|
52
|
+
</span><span class="pre-line">4</span>
|
|
53
|
+
<span class="pre-line">1234567890<span class="pre-lineend-spacer"></span></span>
|
|
54
|
+
<span class="pre-line">6</span>
|
|
55
|
+
</code></pre>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
6
|
|
9
9
|
```
|
|
10
10
|
[HTML]
|
|
11
|
-
<pre><code>1
|
|
11
|
+
<pre><code data-pre-emphasis="3-5">1
|
|
12
12
|
2
|
|
13
13
|
<span class="pre-lines-emphasis">3
|
|
14
14
|
4
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
6
|
|
28
28
|
```
|
|
29
29
|
[HTML]
|
|
30
|
-
<pre><code><span class="pre-lines-emphasis">1
|
|
30
|
+
<pre><code data-pre-emphasis="1"><span class="pre-lines-emphasis">1
|
|
31
31
|
</span>2
|
|
32
32
|
3
|
|
33
33
|
4
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
6
|
|
47
47
|
```
|
|
48
48
|
[HTML]
|
|
49
|
-
<pre><code><span class="pre-lines-emphasis">1
|
|
49
|
+
<pre><code data-pre-emphasis="1-3,5-6"><span class="pre-lines-emphasis">1
|
|
50
50
|
2
|
|
51
51
|
3
|
|
52
52
|
</span>4
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
6
|
|
66
66
|
```
|
|
67
67
|
[HTML]
|
|
68
|
-
<pre><code data-pre-start="1" style="counter-set:pre-line-number 1;"><span class="pre-line">1</span>
|
|
68
|
+
<pre><code data-pre-emphasis="3-5" data-pre-start="1" style="counter-set:pre-line-number 1;"><span class="pre-line">1</span>
|
|
69
69
|
<span class="pre-line">2</span>
|
|
70
70
|
<span class="pre-lines-emphasis"><span class="pre-line">3</span>
|
|
71
71
|
<span class="pre-line">4</span>
|
|
@@ -84,15 +84,10 @@
|
|
|
84
84
|
6
|
|
85
85
|
```
|
|
86
86
|
[HTML]
|
|
87
|
-
<pre><code>1
|
|
87
|
+
<pre><code data-pre-emphasis="2,4-5">1
|
|
88
88
|
<span class="pre-lines-emphasis">2
|
|
89
89
|
</span>3
|
|
90
90
|
<span class="pre-lines-emphasis">4
|
|
91
91
|
5
|
|
92
92
|
</span>6
|
|
93
93
|
</code></pre>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
package/test/examples.txt
CHANGED
package/test/test.js
CHANGED
|
@@ -26,6 +26,7 @@ const mdHighlightJs = mdit({
|
|
|
26
26
|
}
|
|
27
27
|
}).use(mditRendererFence, opt).use(mditAttrs)
|
|
28
28
|
const mdLinesEmphasis = mdit({ html: true }).use(mditRendererFence).use(mditAttrs)
|
|
29
|
+
const mdLIneEndSpan = mdit({ html: true }).use(mditRendererFence, {setLineEndSpan: 8}).use(mditAttrs)
|
|
29
30
|
|
|
30
31
|
let __dirname = path.dirname(new URL(import.meta.url).pathname)
|
|
31
32
|
const isWindows = (process.platform === 'win32')
|
|
@@ -37,6 +38,7 @@ const testData = {
|
|
|
37
38
|
noOption: __dirname + path.sep + 'examples.txt',
|
|
38
39
|
highlightjs: __dirname + path.sep + 'examples-highlightjs.txt',
|
|
39
40
|
linesEmphasis: __dirname + path.sep + 'example-lines-emphasis.txt',
|
|
41
|
+
lineEndSpan: __dirname + path.sep + 'example-line-end-span.txt',
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
const getTestData = (pat) => {
|
|
@@ -88,7 +90,7 @@ const runTest = (process, pat, pass, testId) => {
|
|
|
88
90
|
|
|
89
91
|
while(n <= end) {
|
|
90
92
|
if (!ms[n]
|
|
91
|
-
//|| n !=
|
|
93
|
+
//|| n != 14
|
|
92
94
|
) {
|
|
93
95
|
n++
|
|
94
96
|
continue
|
|
@@ -116,5 +118,6 @@ let pass = true
|
|
|
116
118
|
pass = runTest(md, testData.noOption, pass)
|
|
117
119
|
pass = runTest(mdHighlightJs, testData.highlightjs, pass)
|
|
118
120
|
pass = runTest(mdLinesEmphasis, testData.linesEmphasis, pass)
|
|
121
|
+
pass = runTest(mdLIneEndSpan, testData.lineEndSpan, pass)
|
|
119
122
|
|
|
120
123
|
if (pass) console.log('Passed all test.')
|