@peaceroad/markdown-it-renderer-fence 0.4.1 → 0.6.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.
@@ -0,0 +1,114 @@
1
+ const isSpaceCode = (code) => {
2
+ return code === 9 || code === 10 || code === 12 || code === 13 || code === 32
3
+ }
4
+
5
+ const isTagNameCharCode = (code) => {
6
+ return (
7
+ (code >= 48 && code <= 57) || // 0-9
8
+ (code >= 65 && code <= 90) || // A-Z
9
+ (code >= 97 && code <= 122) || // a-z
10
+ code === 45 || // -
11
+ code === 58 // :
12
+ )
13
+ }
14
+
15
+ const skipSpace = (source, start) => {
16
+ let i = start
17
+ const len = source.length
18
+ while (i < len && isSpaceCode(source.charCodeAt(i))) i++
19
+ return i
20
+ }
21
+
22
+ const parseOpenTag = (source, start) => {
23
+ if (source.charCodeAt(start) !== 60) return null // <
24
+ let i = start + 1
25
+ if (i >= source.length || source.charCodeAt(i) === 47) return null // /
26
+
27
+ const nameStart = i
28
+ while (i < source.length && isTagNameCharCode(source.charCodeAt(i))) i++
29
+ if (i === nameStart) return null
30
+ const name = source.slice(nameStart, i).toLowerCase()
31
+
32
+ const attrStart = i
33
+ let quote = 0
34
+ while (i < source.length) {
35
+ const ch = source.charCodeAt(i)
36
+ if (quote !== 0) {
37
+ if (ch === quote) quote = 0
38
+ i++
39
+ continue
40
+ }
41
+ if (ch === 34 || ch === 39) { // " or '
42
+ quote = ch
43
+ i++
44
+ continue
45
+ }
46
+ if (ch === 62) break // >
47
+ i++
48
+ }
49
+ if (i >= source.length) return null
50
+
51
+ let tail = i - 1
52
+ while (tail >= attrStart && isSpaceCode(source.charCodeAt(tail))) tail--
53
+ const selfClosing = tail >= attrStart && source.charCodeAt(tail) === 47 // /
54
+ const attrsText = source.slice(attrStart, i).trim()
55
+ return { name, attrsText, selfClosing, start, end: i + 1 }
56
+ }
57
+
58
+ const parseCloseTag = (source, start) => {
59
+ if (source.charCodeAt(start) !== 60) return null // <
60
+ let i = start + 1
61
+ if (i >= source.length || source.charCodeAt(i) !== 47) return null // /
62
+ i++
63
+ i = skipSpace(source, i)
64
+ const nameStart = i
65
+ while (i < source.length && isTagNameCharCode(source.charCodeAt(i))) i++
66
+ if (i === nameStart) return null
67
+ const name = source.slice(nameStart, i).toLowerCase()
68
+ i = skipSpace(source, i)
69
+ if (i >= source.length || source.charCodeAt(i) !== 62) return null // >
70
+ return { name, start, end: i + 1 }
71
+ }
72
+
73
+ const findCloseTag = (source, start, targetName) => {
74
+ const len = source.length
75
+ for (let i = start; i < len; i++) {
76
+ if (source.charCodeAt(i) !== 60) continue
77
+ const close = parseCloseTag(source, i)
78
+ if (!close) continue
79
+ if (close.name === targetName) return close
80
+ }
81
+ return null
82
+ }
83
+
84
+ const parsePreCodeWrapper = (html) => {
85
+ const source = String(html || '')
86
+ if (!source) return null
87
+ let i = skipSpace(source, 0)
88
+ const preOpen = parseOpenTag(source, i)
89
+ if (!preOpen || preOpen.selfClosing || preOpen.name !== 'pre') return null
90
+ i = skipSpace(source, preOpen.end)
91
+ const codeOpen = parseOpenTag(source, i)
92
+ if (!codeOpen || codeOpen.selfClosing || codeOpen.name !== 'code') return null
93
+
94
+ const codeClose = findCloseTag(source, codeOpen.end, 'code')
95
+ if (!codeClose) return null
96
+ const content = source.slice(codeOpen.end, codeClose.start)
97
+
98
+ i = skipSpace(source, codeClose.end)
99
+ const preClose = parseCloseTag(source, i)
100
+ if (!preClose || preClose.name !== 'pre') return null
101
+
102
+ i = skipSpace(source, preClose.end)
103
+ if (i !== source.length) return null
104
+
105
+ return {
106
+ preAttrsText: preOpen.attrsText,
107
+ codeAttrsText: codeOpen.attrsText,
108
+ content,
109
+ }
110
+ }
111
+
112
+ export {
113
+ parsePreCodeWrapper,
114
+ }