@peaceroad/markdown-it-strong-ja 0.3.5 → 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 +6 -4
- package/index.js +387 -224
- package/package.json +2 -1
- package/test/example-complex.txt +125 -10
- package/test/example-with-linebreak.txt +282 -0
- package/test/mditNoAttrs/example-complex.txt +480 -0
- package/test/mditNoAttrs/example-em.txt +205 -0
- package/test/mditNoAttrs/example-strong.txt +219 -0
- package/test/mditNoAttrs/example-with-linebreak.txt +289 -0
- package/test/test.js +71 -33
package/index.js
CHANGED
|
@@ -1,45 +1,98 @@
|
|
|
1
|
+
const REG_ASTERISKS = /^\*+$/
|
|
2
|
+
const REG_ATTRS = /{[^{}\n!@#%^&*()]+?}$/
|
|
3
|
+
const REG_PUNCTUATION = /[!-/:-@[-`{-~ ]/
|
|
4
|
+
|
|
1
5
|
const hasBackslash = (state, start) => {
|
|
2
6
|
let slashNum = 0
|
|
3
7
|
let i = start - 1
|
|
8
|
+
const src = state.src
|
|
4
9
|
while(i >= 0) {
|
|
5
|
-
|
|
6
|
-
if (state.src.charCodeAt(i) === 0x5C) { slashNum++; i--; continue }
|
|
10
|
+
if (src.charCodeAt(i) === 0x5C) { slashNum++; i--; continue }
|
|
7
11
|
break
|
|
8
12
|
}
|
|
9
|
-
return slashNum % 2 === 1
|
|
13
|
+
return slashNum % 2 === 1
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
const setToken = (state, inlines) => {
|
|
16
|
+
const setToken = (state, inlines, opt) => {
|
|
17
|
+
const src = state.src
|
|
13
18
|
let i = 0
|
|
19
|
+
let attrsIsText = {
|
|
20
|
+
val: false,
|
|
21
|
+
tag: '',
|
|
22
|
+
}
|
|
14
23
|
while (i < inlines.length) {
|
|
15
24
|
let type = inlines[i].type
|
|
25
|
+
//console.log(i, type)
|
|
16
26
|
const tag = type.replace(/(?:_open|_close)$/, '')
|
|
17
27
|
|
|
18
28
|
if (/_open$/.test(type)) {
|
|
19
29
|
const startToken = state.push(type, tag, 1)
|
|
20
30
|
startToken.markup = tag === 'strong' ? '**' : '*'
|
|
31
|
+
attrsIsText = {
|
|
32
|
+
val: true,
|
|
33
|
+
tag: tag,
|
|
34
|
+
}
|
|
21
35
|
}
|
|
22
36
|
|
|
23
37
|
if (type === 'html_inline') {
|
|
24
38
|
type = 'text'
|
|
25
39
|
}
|
|
26
40
|
if (type === 'text') {
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
let content = src.slice(inlines[i].s, inlines[i].e + 1)
|
|
42
|
+
//console.log('content: ' + content)
|
|
43
|
+
if (REG_ASTERISKS.test(content)) {
|
|
29
44
|
//console.log('asterisk process::')
|
|
30
45
|
const asteriskToken = state.push(type, '', 0)
|
|
31
46
|
asteriskToken.content = content
|
|
32
47
|
i++
|
|
33
48
|
continue
|
|
34
49
|
}
|
|
50
|
+
if (opt.mditAttrs && attrsIsText.val && i + 1 < inlines.length) {
|
|
51
|
+
const hasImmediatelyAfterAsteriskClose = inlines[i+1].type === attrsIsText.tag + '_close'
|
|
52
|
+
//console.log(hasImmediatelyAfterAsteriskClose, inlines[i+1].type, /^[\s\S]*{[^{}\n!@#%^&*()]+?}$/.test(content))
|
|
53
|
+
if (hasImmediatelyAfterAsteriskClose && REG_ATTRS.test(content)) {
|
|
54
|
+
const attrsToken = state.push(type, '', 0)
|
|
55
|
+
|
|
56
|
+
const hasBackslashBeforeCurlyAttribute = content.match(/(\\+){/)
|
|
57
|
+
if (hasBackslashBeforeCurlyAttribute) {
|
|
58
|
+
if (hasBackslashBeforeCurlyAttribute[1].length === 1) {
|
|
59
|
+
attrsToken.content = content.replace(/\\{/, '{')
|
|
60
|
+
} else {
|
|
61
|
+
let backSlashNum = Math.floor(hasBackslashBeforeCurlyAttribute[1].length / 2)
|
|
62
|
+
let k = 0
|
|
63
|
+
let backSlash = ''
|
|
64
|
+
while (k < backSlashNum) {
|
|
65
|
+
backSlash += '\\'
|
|
66
|
+
k++
|
|
67
|
+
}
|
|
68
|
+
//console.log(backSlashNum, backSlash)
|
|
69
|
+
attrsToken.content = content.replace(/\\+{/, backSlash + '{')
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
attrsToken.content = content
|
|
73
|
+
}
|
|
74
|
+
attrsIsText.val = false
|
|
75
|
+
i++
|
|
76
|
+
continue
|
|
77
|
+
}
|
|
78
|
+
}
|
|
35
79
|
|
|
36
80
|
const childTokens = state.md.parseInline(content, state.env)
|
|
81
|
+
//console.log(childTokens)
|
|
82
|
+
//console.log(childTokens[0].children)
|
|
37
83
|
if (childTokens[0] && childTokens[0].children) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
84
|
+
let j = 0
|
|
85
|
+
while (j < childTokens[0].children.length) {
|
|
86
|
+
const t = childTokens[0].children[j]
|
|
87
|
+
if (t.type === 'softbreak') {
|
|
88
|
+
t.type = 'text'
|
|
89
|
+
t.tag = ''
|
|
90
|
+
t.content = '\n'
|
|
91
|
+
}
|
|
92
|
+
if (!opt.mditAttrs && t.tag === 'br') {
|
|
93
|
+
t.tag = ''
|
|
94
|
+
t.content = '\n'
|
|
95
|
+
}
|
|
43
96
|
const token = state.push(t.type, t.tag, t.nesting)
|
|
44
97
|
token.attrs = t.attrs
|
|
45
98
|
token.map = t.map
|
|
@@ -51,20 +104,25 @@ const setToken = (state, inlines) => {
|
|
|
51
104
|
token.meta = t.meta
|
|
52
105
|
token.block = t.block
|
|
53
106
|
token.hidden = t.hidden
|
|
54
|
-
|
|
107
|
+
j++
|
|
108
|
+
}
|
|
55
109
|
}
|
|
56
110
|
}
|
|
57
111
|
|
|
58
112
|
if (/_close$/.test(type)) {
|
|
59
113
|
const closeToken = state.push(type, tag, -1)
|
|
60
114
|
closeToken.markup = tag === 'strong' ? '**' : '*'
|
|
115
|
+
attrsIsText = {
|
|
116
|
+
val: false,
|
|
117
|
+
tag: '',
|
|
118
|
+
}
|
|
61
119
|
}
|
|
62
120
|
|
|
63
121
|
i++
|
|
64
122
|
}
|
|
65
123
|
}
|
|
66
124
|
|
|
67
|
-
const
|
|
125
|
+
const pushInlines = (inlines, s, e, len, type, tag, tagType) => {
|
|
68
126
|
const inline = {
|
|
69
127
|
s: s,
|
|
70
128
|
sp: s,
|
|
@@ -72,6 +130,7 @@ const inlinesPush = (inlines, s, e, len, type, tag, tagType) => {
|
|
|
72
130
|
ep: e,
|
|
73
131
|
len: len,
|
|
74
132
|
type: type,
|
|
133
|
+
check: type === 'text' ? true : false,
|
|
75
134
|
}
|
|
76
135
|
if (tag) inline.tag = [tag, tagType]
|
|
77
136
|
inlines.push(inline)
|
|
@@ -79,13 +138,14 @@ const inlinesPush = (inlines, s, e, len, type, tag, tagType) => {
|
|
|
79
138
|
|
|
80
139
|
const hasNextSymbol = (state, n, max, symbol, noMark) => {
|
|
81
140
|
let nextSymbolPos = -1
|
|
82
|
-
|
|
141
|
+
const src = state.src
|
|
142
|
+
if (src.charCodeAt(n) === symbol && !hasBackslash(state, n)) {
|
|
83
143
|
let i = n + 1
|
|
84
144
|
let tempNoMark = noMark
|
|
85
145
|
while (i < max) {
|
|
86
|
-
tempNoMark +=
|
|
87
|
-
if (
|
|
88
|
-
noMark +=
|
|
146
|
+
tempNoMark += src[i]
|
|
147
|
+
if (src.charCodeAt(i) === symbol && !hasBackslash(state, i)) {
|
|
148
|
+
noMark += src.substring(n, i + 1)
|
|
89
149
|
nextSymbolPos = i
|
|
90
150
|
break
|
|
91
151
|
}
|
|
@@ -96,26 +156,29 @@ const hasNextSymbol = (state, n, max, symbol, noMark) => {
|
|
|
96
156
|
}
|
|
97
157
|
|
|
98
158
|
const createInlines = (state, start, max, opt) => {
|
|
159
|
+
const src = state.src
|
|
160
|
+
const srcLen = max;
|
|
99
161
|
let n = start
|
|
100
162
|
let inlines = []
|
|
101
163
|
let noMark = ''
|
|
102
164
|
let textStart = n
|
|
103
|
-
while (n <
|
|
165
|
+
while (n < srcLen) {
|
|
166
|
+
//console.log('n: ' + n + ', state.src[n]: ' + state.src[n] + ', noMark: ' + noMark)
|
|
104
167
|
let nextSymbolPos = -1;
|
|
105
|
-
[nextSymbolPos, noMark] = hasNextSymbol(state, n,
|
|
168
|
+
[nextSymbolPos, noMark] = hasNextSymbol(state, n, srcLen, 0x60, noMark) // '`'
|
|
106
169
|
if (nextSymbolPos !== -1) {
|
|
107
|
-
if (nextSymbolPos ===
|
|
108
|
-
|
|
170
|
+
if (nextSymbolPos === srcLen - 1) {
|
|
171
|
+
pushInlines(inlines, textStart, nextSymbolPos, nextSymbolPos - textStart + 1, 'text')
|
|
109
172
|
break
|
|
110
173
|
}
|
|
111
174
|
n = nextSymbolPos + 1
|
|
112
175
|
continue
|
|
113
176
|
}
|
|
114
177
|
if (opt.dollarMath) {
|
|
115
|
-
[nextSymbolPos, noMark] = hasNextSymbol(state, n,
|
|
178
|
+
[nextSymbolPos, noMark] = hasNextSymbol(state, n, srcLen, 0x24, noMark) // '$'
|
|
116
179
|
if (nextSymbolPos !== -1) {
|
|
117
|
-
if (nextSymbolPos ===
|
|
118
|
-
|
|
180
|
+
if (nextSymbolPos === srcLen - 1) {
|
|
181
|
+
pushInlines(inlines, textStart, nextSymbolPos, nextSymbolPos - textStart + 1, 'text')
|
|
119
182
|
break
|
|
120
183
|
}
|
|
121
184
|
n = nextSymbolPos + 1
|
|
@@ -124,14 +187,15 @@ const createInlines = (state, start, max, opt) => {
|
|
|
124
187
|
}
|
|
125
188
|
|
|
126
189
|
if (state.md.options.html) {
|
|
127
|
-
if (
|
|
190
|
+
if (src.charCodeAt(n) === 0x3C && !hasBackslash(state, n)) { // '<'
|
|
128
191
|
let i = n + 1
|
|
129
|
-
while (i <
|
|
130
|
-
if (
|
|
192
|
+
while (i < srcLen) {
|
|
193
|
+
if (src.charCodeAt(i) === 0x3E && !hasBackslash(state, i)) { // '>'
|
|
131
194
|
if (noMark.length !== 0) {
|
|
132
|
-
|
|
195
|
+
pushInlines(inlines, textStart, n - 1, n - textStart, 'text')
|
|
196
|
+
noMark = ''
|
|
133
197
|
}
|
|
134
|
-
let tag =
|
|
198
|
+
let tag = src.slice(n + 1, i)
|
|
135
199
|
let tagType = ''
|
|
136
200
|
if (/^\//.test(tag)) {
|
|
137
201
|
tag = tag.slice(1)
|
|
@@ -139,7 +203,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
139
203
|
} else {
|
|
140
204
|
tagType = 'open'
|
|
141
205
|
}
|
|
142
|
-
|
|
206
|
+
pushInlines(inlines, n, i, i - n + 1, 'html_inline', tag, tagType)
|
|
143
207
|
textStart = i + 1
|
|
144
208
|
break
|
|
145
209
|
}
|
|
@@ -149,31 +213,34 @@ const createInlines = (state, start, max, opt) => {
|
|
|
149
213
|
continue
|
|
150
214
|
}
|
|
151
215
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
216
|
+
|
|
217
|
+
if (src.charCodeAt(n) === 0x2A && !hasBackslash(state, n)) { // '*'
|
|
218
|
+
if (n !== 0 && noMark.length !== 0) {
|
|
219
|
+
pushInlines(inlines, textStart, n - 1, n - textStart, 'text')
|
|
220
|
+
noMark = ''
|
|
155
221
|
}
|
|
156
|
-
if (n ===
|
|
157
|
-
|
|
222
|
+
if (n === srcLen - 1) {
|
|
223
|
+
pushInlines(inlines, n, n, 1 , '')
|
|
158
224
|
break
|
|
159
225
|
}
|
|
160
226
|
let i = n + 1
|
|
161
|
-
while (i <
|
|
162
|
-
if (
|
|
163
|
-
if (i ===
|
|
227
|
+
while (i < srcLen) {
|
|
228
|
+
if (src.charCodeAt(i) === 0x2A) {
|
|
229
|
+
if (i === srcLen - 1) pushInlines(inlines, n, i, i - n + 1 , '')
|
|
164
230
|
i++
|
|
165
231
|
continue
|
|
166
232
|
}
|
|
167
|
-
|
|
233
|
+
pushInlines(inlines, n, i - 1, i - n, '')
|
|
168
234
|
textStart = i
|
|
169
235
|
break
|
|
170
236
|
}
|
|
171
237
|
n = i
|
|
172
238
|
continue
|
|
173
239
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
240
|
+
|
|
241
|
+
noMark += src[n]
|
|
242
|
+
if (n === srcLen - 1) {
|
|
243
|
+
pushInlines(inlines, textStart, n, n - textStart + 1, 'text')
|
|
177
244
|
break
|
|
178
245
|
}
|
|
179
246
|
n++
|
|
@@ -181,159 +248,214 @@ const createInlines = (state, start, max, opt) => {
|
|
|
181
248
|
return inlines
|
|
182
249
|
}
|
|
183
250
|
|
|
184
|
-
const
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
s
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
let i = marks.findIndex(o => o.s > s)
|
|
196
|
-
if (i === -1) {
|
|
197
|
-
marks.push(np)
|
|
198
|
-
} else {
|
|
199
|
-
marks.splice(i, 0, np)
|
|
251
|
+
const pushMark = (marks, opts) => {
|
|
252
|
+
//binary search
|
|
253
|
+
let left = 0, right = marks.length
|
|
254
|
+
while (left < right) {
|
|
255
|
+
const mid = (left + right) >> 1
|
|
256
|
+
if (marks[mid].s > opts.s) {
|
|
257
|
+
right = mid
|
|
258
|
+
} else {
|
|
259
|
+
left = mid + 1
|
|
260
|
+
}
|
|
200
261
|
}
|
|
262
|
+
marks.splice(left, 0, { ...opts });
|
|
201
263
|
}
|
|
202
264
|
|
|
203
|
-
const setStrong = (inlines, marks, n, memo) => {
|
|
265
|
+
const setStrong = (state, inlines, marks, n, memo, opt) => {
|
|
204
266
|
let i = n + 1
|
|
205
267
|
let j = 0
|
|
206
268
|
let nest = 0
|
|
207
|
-
let insideTagsIsClose = 1
|
|
269
|
+
let insideTagsIsClose = 1 // 1: closed, 0: open still, -1: error
|
|
208
270
|
while (i < inlines.length) {
|
|
209
|
-
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
271
|
+
//console.log('[strong] i: ' + i + ', inlines[i].len: ' + inlines[i].len + ', inlines[i].type: ' + inlines[i].type)
|
|
272
|
+
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
273
|
+
if (inlines[i].type === 'html_inline') {
|
|
274
|
+
inlines[i].check = true
|
|
275
|
+
insideTagsIsClose = checkInsideTags(inlines, i, memo)
|
|
276
|
+
//console.log(' nest: ' + nest + ', insideTagsIsClose: ' + insideTagsIsClose )
|
|
277
|
+
if (insideTagsIsClose === -1) return n, nest
|
|
278
|
+
if (insideTagsIsClose === 0) { i++; continue }
|
|
217
279
|
}
|
|
218
280
|
if (inlines[i].type !== '') { i++; continue }
|
|
219
281
|
|
|
220
|
-
//console.log('n: ' + n + ' [strong]: inlines[n].len: ' + inlines[n].len + ', i: ' + i + ', inlines[i].len: ' + inlines[i].len)
|
|
221
|
-
|
|
222
282
|
nest = checkNest(inlines, marks, n, i)
|
|
223
|
-
//console.log('
|
|
224
|
-
if (nest === -1) return n, nest
|
|
283
|
+
//console.log(' check nest: ' + nest)
|
|
284
|
+
if (nest === -1) return n, nest
|
|
285
|
+
|
|
225
286
|
if (inlines[i].len === 1 && inlines[n].len > 2) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
287
|
+
//console.log(' check em inside strong:: i: ' + i)
|
|
288
|
+
pushMark(marks, {
|
|
289
|
+
nest: nest,
|
|
290
|
+
s: inlines[n].ep,
|
|
291
|
+
e: inlines[n].ep,
|
|
292
|
+
len: 1,
|
|
293
|
+
oLen: inlines[n].len - 1,
|
|
294
|
+
type: 'em_open'
|
|
295
|
+
})
|
|
296
|
+
pushMark(marks, {
|
|
297
|
+
nest: nest,
|
|
298
|
+
s: inlines[i].sp,
|
|
299
|
+
e: inlines[i].ep,
|
|
300
|
+
len: 1,
|
|
301
|
+
oLen: inlines[i].len - 1,
|
|
302
|
+
type: 'em_close'
|
|
303
|
+
})
|
|
229
304
|
inlines[n].len -= 1
|
|
230
305
|
inlines[n].ep -= 1
|
|
231
|
-
inlines[i].len
|
|
232
|
-
inlines[i].sp += 1
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
nest++
|
|
236
|
-
} else {
|
|
237
|
-
return n, nest, memo
|
|
306
|
+
inlines[i].len -= 1
|
|
307
|
+
if (inlines[i].len > 0) inlines[i].sp += 1
|
|
308
|
+
if (insideTagsIsClose === 1) {
|
|
309
|
+
n, nest = setEm(state, inlines, marks, n, memo, opt)
|
|
238
310
|
}
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
//console.log('memo.html: ' + memo.html + 'insideTagsIsClose: ' + insideTagsIsClose + 'inlines[i].len: ' + inlines[i].len)
|
|
243
|
-
if (memo.html && !insideTagsIsClose && inlines[i].len !== 1) {
|
|
244
|
-
i++; continue
|
|
311
|
+
//console.log(marks)
|
|
245
312
|
}
|
|
313
|
+
//console.log(' check len:: inlines[n].len: ' + inlines[n].len + ', inlines[i].len: ' + inlines[i].len)
|
|
246
314
|
let strongNum = Math.trunc(Math.min(inlines[n].len, inlines[i].len) / 2)
|
|
247
315
|
|
|
248
316
|
if (inlines[i].len > 1) {
|
|
249
|
-
|
|
317
|
+
//console.log(' hasPunctuation: ' + hasPunctuation(state, inlines, n, i) + ', memo.inlineMarkEnd: ' + memo.inlineMarkEnd)
|
|
318
|
+
if (hasPunctuation(state, inlines, n, i)) {
|
|
319
|
+
if (memo.inlineMarkEnd) {
|
|
320
|
+
//console.log('check nest em.')
|
|
321
|
+
//console.log('~~~~~~~~~~~~~~~~~')
|
|
322
|
+
marks.push(...createMarks(state, inlines, i, inlines.length - 1, memo, opt))
|
|
323
|
+
//console.log('~~~~~~~~~~~~~~~~~')
|
|
324
|
+
if (inlines[i].len === 0) { i++; continue }
|
|
325
|
+
} else {
|
|
326
|
+
return n, nest
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
//console.log(' ===> strong normal push. n: ' + n + ', i: ' + i + ' , nest: ' + nest + ',strongNum: ' + strongNum)
|
|
330
|
+
|
|
250
331
|
j = 0
|
|
251
332
|
while (j < strongNum) {
|
|
252
|
-
//console.log('j: ' + j + ', inlines[i].sp: ' + inlines[i].sp)
|
|
253
|
-
|
|
333
|
+
//console.log(' - j: ' + j + ', inlines[i].sp: ' + inlines[i].sp)
|
|
334
|
+
pushMark(marks, {
|
|
335
|
+
nest: nest + strongNum - 1 - j,
|
|
336
|
+
s: inlines[n].ep - 1,
|
|
337
|
+
e: inlines[n].ep,
|
|
338
|
+
len: 2,
|
|
339
|
+
oLen: inlines[n].len - 2,
|
|
340
|
+
type: 'strong_open'
|
|
341
|
+
})
|
|
254
342
|
inlines[n].ep -= 2
|
|
255
343
|
inlines[n].len -= 2
|
|
256
|
-
|
|
344
|
+
pushMark(marks, {
|
|
345
|
+
nest: nest + strongNum - 1 - j,
|
|
346
|
+
s: inlines[i].sp,
|
|
347
|
+
e: inlines[i].sp + 1,
|
|
348
|
+
len: 2,
|
|
349
|
+
oLen: inlines[i].len - 2,
|
|
350
|
+
type: 'strong_close'
|
|
351
|
+
})
|
|
257
352
|
inlines[i].sp += 2
|
|
258
353
|
inlines[i].len -= 2
|
|
259
|
-
//console.log(marks)
|
|
260
354
|
j++
|
|
261
355
|
}
|
|
262
|
-
if (inlines[n].len === 0) return n, nest
|
|
356
|
+
if (inlines[n].len === 0) return n, nest
|
|
263
357
|
}
|
|
264
358
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
//console.log('check em that warp strong.')
|
|
359
|
+
if (inlines[n].len === 1 && inlines[i].len > 0) {
|
|
360
|
+
//console.log(' check em that warp strong.')
|
|
268
361
|
nest++
|
|
269
|
-
n, nest
|
|
270
|
-
if (memo.hasEmThatWrapStrong) {
|
|
271
|
-
//console.log('set em that wrap strong.')
|
|
272
|
-
let k = 0
|
|
273
|
-
while (k < strongNum) {
|
|
274
|
-
marks[marks.length - 2 - k * 2 - 1].nest += 1
|
|
275
|
-
marks[marks.length - 2 - k * 2].nest += 1
|
|
276
|
-
k++
|
|
277
|
-
}
|
|
278
|
-
}
|
|
362
|
+
n, nest = setEm(state, inlines, marks, n, memo, opt, nest)
|
|
279
363
|
}
|
|
280
|
-
|
|
364
|
+
|
|
281
365
|
i++
|
|
282
366
|
}
|
|
283
|
-
|
|
367
|
+
|
|
368
|
+
if (n == 0 && memo.inlineMarkEnd) {
|
|
369
|
+
//console.log('check nest em(inlineMarkEnd).')
|
|
370
|
+
//console.log('===============================')
|
|
371
|
+
marks.push(...createMarks(state, inlines, n + 1 , inlines.length - 1, memo, opt))
|
|
372
|
+
//console.log(marks)
|
|
373
|
+
//console.log('===============================')
|
|
374
|
+
}
|
|
375
|
+
return n, nest
|
|
284
376
|
}
|
|
285
377
|
|
|
286
|
-
const
|
|
287
|
-
//console.log(
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
else {
|
|
293
|
-
memo.htmlTags[tag]--
|
|
294
|
-
}
|
|
295
|
-
return true
|
|
296
|
-
}
|
|
297
|
-
return false
|
|
298
|
-
})
|
|
299
|
-
if (!hasSet && !memo.htmlTags[inlines[n].tag[0]]) {
|
|
300
|
-
if (inlines[n].tag[1] === 'close') {
|
|
301
|
-
memo.htmlTags = {}
|
|
302
|
-
return -1
|
|
303
|
-
}
|
|
304
|
-
memo.htmlTags[inlines[n].tag[0]] = 1
|
|
378
|
+
const checkInsideTags = (inlines, i, memo) => {
|
|
379
|
+
//console.log('isJumTag before::memo.htmlTags: ' + JSON.stringify(memo.htmlTags))
|
|
380
|
+
if (inlines[i].tag === undefined) return 0
|
|
381
|
+
const tagName = inlines[i].tag[0].toLowerCase()
|
|
382
|
+
if (memo.htmlTags[tagName] === undefined) {
|
|
383
|
+
memo.htmlTags[tagName] = 0
|
|
305
384
|
}
|
|
306
|
-
|
|
385
|
+
//console.log('memo.htmlTags: ' + JSON.stringify(memo.htmlTags) + ', inlines[i]: ' + JSON.stringify(inlines[i]) + ', inlines[i]')
|
|
386
|
+
if (inlines[i].tag[1] === 'open') {
|
|
387
|
+
memo.htmlTags[tagName] += 1
|
|
388
|
+
}
|
|
389
|
+
if (inlines[i].tag[1] === 'close') {
|
|
390
|
+
memo.htmlTags[tagName] -= 1
|
|
391
|
+
}
|
|
392
|
+
//console.log(' i: ' + i + ', tagName: ' + tagName + ', memo.htmlTags[tagName]: ' + memo.htmlTags[tagName] + ', prevHtmlTags[tagName]: ' + prevHtmlTags[tagName])
|
|
393
|
+
if (memo.htmlTags[tagName] < 0) {
|
|
394
|
+
return -1
|
|
395
|
+
}
|
|
396
|
+
//console.log('isJumTag after::memo.htmlTags: ' + JSON.stringify(memo.htmlTags))
|
|
307
397
|
const closeAllTags = Object.values(memo.htmlTags).every(val => val === 0)
|
|
308
|
-
//console.log('closeAllTags: ' + closeAllTags)
|
|
309
398
|
if (closeAllTags) return 1
|
|
310
|
-
//memo.htmlTags = {}
|
|
311
399
|
return 0
|
|
312
400
|
}
|
|
313
401
|
|
|
314
|
-
const
|
|
402
|
+
const isPunctuation = (ch) => {
|
|
403
|
+
return REG_PUNCTUATION.test(ch)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const hasPunctuation = (state, inlines, n, i) => {
|
|
407
|
+
const src = state.src
|
|
408
|
+
const openNextChar = isPunctuation(src[inlines[n].e + 1] || '')
|
|
409
|
+
//const openPrevChar = isPunctuation(src[inlines[n].s - 1] || '') || n === 0
|
|
410
|
+
let closePrevChar = isPunctuation(src[inlines[i].s - 1] || '')
|
|
411
|
+
if (i + 1 < inlines.length) {
|
|
412
|
+
//closePrevChar = closePrevChar && inlines[i+1] !== 'html_inline'
|
|
413
|
+
}
|
|
414
|
+
let closeNextChar = isPunctuation(src[inlines[i].e + 1] || '') || i === inlines.length - 1
|
|
415
|
+
//const lastCharIsAsterisk = memo.inlineMarkEnd
|
|
416
|
+
//const firstCharIsAsterisk = memo.inlineMarkStart
|
|
417
|
+
|
|
418
|
+
//console.log('openPrevChar: ' + openPrevChar + ', openNextChar: ' + openNextChar + ', closePrevChar: ' + closePrevChar + ', closeNextChar: ' + closeNextChar + ', lastCharIsAsterisk: ' + lastCharIsAsterisk + ', firstCharIsAsterisk: ' + firstCharIsAsterisk + ', next condition: ' + ((openNextChar || closePrevChar) && !closeNextChar))
|
|
419
|
+
//if ((openNextChar || closePrevChar) && !closeNextChar) {
|
|
420
|
+
if ((openNextChar || closePrevChar) && !closeNextChar) {
|
|
421
|
+
return true
|
|
422
|
+
} else {
|
|
423
|
+
return false
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const setEm = (state, inlines, marks, n, memo, opt, sNest) => {
|
|
315
428
|
let i = n + 1
|
|
316
429
|
let nest = 0
|
|
317
430
|
let strongPNum = 0
|
|
318
431
|
let insideTagsIsClose = 1
|
|
319
432
|
while (i < inlines.length) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
433
|
+
//console.log('[em] i: ' + i + ', src: ' + state.src.slice(inlines[i].sp, inlines[i].ep + 1) + ', inlines[i]: ' + JSON.stringify(inlines[i]))
|
|
434
|
+
//console.log(inlines[i].type, JSON.stringify(memo.htmlTags))
|
|
435
|
+
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
436
|
+
if (!sNest && inlines[i].type === 'html_inline') {
|
|
437
|
+
inlines.check = true
|
|
438
|
+
insideTagsIsClose = checkInsideTags(inlines, i, memo)
|
|
439
|
+
//console.log(' i: ' + i + ', insideTagsIsClose: ' + insideTagsIsClose)
|
|
440
|
+
if (insideTagsIsClose === -1) return n, nest
|
|
441
|
+
if (insideTagsIsClose === 0) { i++; continue }
|
|
328
442
|
}
|
|
329
443
|
if (inlines[i].type !== '') { i++; continue }
|
|
330
444
|
|
|
331
445
|
const emNum = Math.min(inlines[n].len, inlines[i].len)
|
|
332
|
-
if (memo.isEm && emNum !== 1) return n, sNest, memo
|
|
333
|
-
//console.log('n: ' + n + ' [em]: inlines[n].len: ' + inlines[n].len + ', i: ' + i, ', inlines[i].len: ' + inlines[i].len + ', isEm: ' + memo.isEm)
|
|
334
|
-
//console.log(marks)
|
|
335
446
|
|
|
336
|
-
|
|
447
|
+
//console.log('sNest: ' + sNest + ', emNum: ' + emNum)
|
|
448
|
+
if (!sNest && emNum !== 1) return n, sNest, memo
|
|
449
|
+
|
|
450
|
+
const hasMarkersAtStartAndEnd = (i) => {
|
|
451
|
+
let flag = memo.inlineMarkStart
|
|
452
|
+
if (!flag) return false
|
|
453
|
+
inlines.length - 1 === i ? flag = true : flag = false
|
|
454
|
+
if (!flag) return false
|
|
455
|
+
inlines[i].len > 1 ? flag = true : flag = false
|
|
456
|
+
return flag
|
|
457
|
+
}
|
|
458
|
+
if (!sNest && inlines[i].len === 2 && !hasMarkersAtStartAndEnd(i)) {
|
|
337
459
|
strongPNum++
|
|
338
460
|
i++
|
|
339
461
|
continue
|
|
@@ -344,47 +466,83 @@ const setEm = (inlines, marks, n, memo, sNest) => {
|
|
|
344
466
|
} else {
|
|
345
467
|
nest = checkNest(inlines, marks, n, i)
|
|
346
468
|
}
|
|
347
|
-
//console.log('
|
|
348
|
-
if (nest === -1) return n, nest
|
|
469
|
+
//console.log(' nest: ' + nest + ', emNum: ' + emNum)
|
|
470
|
+
if (nest === -1) return n, nest
|
|
349
471
|
|
|
350
472
|
if (emNum === 1) {
|
|
351
|
-
//console.log(n, i,
|
|
352
|
-
if (
|
|
473
|
+
//console.log(' hasPunctuation: ' + hasPunctuation(state, inlines, n, i) + ', memo.inlineMarkEnd: ' + memo.inlineMarkEnd)
|
|
474
|
+
if (hasPunctuation(state, inlines, n, i)) {
|
|
475
|
+
if (memo.inlineMarkEnd) {
|
|
476
|
+
//console.log('check nest em.')
|
|
477
|
+
//console.log('~~~~~~~~~~~~~~~~~')
|
|
478
|
+
marks.push(...createMarks(state, inlines, i, inlines.length - 1, memo, opt))
|
|
479
|
+
//console.log('~~~~~~~~~~~~~~~~~')
|
|
480
|
+
|
|
481
|
+
if (inlines[i].len === 0) { i++; continue }
|
|
482
|
+
} else {
|
|
483
|
+
return n, nest
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
//console.log('inlines[i].len: ' + inlines[i].len)
|
|
487
|
+
if (inlines[i].len < 1) { // memo.html
|
|
353
488
|
i++; continue;
|
|
354
489
|
}
|
|
355
|
-
//console.log('n: ' + n + ' [em]: normal push, nest: ' + nest)
|
|
356
|
-
//console.log('strongPNum: ' + strongPNum)
|
|
357
|
-
//console.log(inlines[n].ep, inlines[n].sp, inlines[n].s)
|
|
358
490
|
|
|
359
|
-
|
|
491
|
+
//console.log(' ===> em Normal push. n: ' + n + ', i: ' + i + ', nest: ' + nest, ', strongPNum: ' + strongPNum)
|
|
492
|
+
//console.log(inlines[n].ep, inlines[n].sp, inlines[n].s)
|
|
493
|
+
pushMark(marks, {
|
|
494
|
+
nest: nest,
|
|
495
|
+
s: inlines[n].ep,
|
|
496
|
+
e: inlines[n].ep,
|
|
497
|
+
len: 1,
|
|
498
|
+
oLen: inlines[n].len - 1,
|
|
499
|
+
type: 'em_open'
|
|
500
|
+
})
|
|
360
501
|
inlines[n].ep -= 1
|
|
361
502
|
inlines[n].len -= 1
|
|
362
503
|
|
|
363
504
|
if (strongPNum % 2 === 0 || inlines[i].len < 2) {
|
|
364
|
-
|
|
505
|
+
pushMark(marks, {
|
|
506
|
+
nest: nest,
|
|
507
|
+
s: inlines[i].sp,
|
|
508
|
+
e: inlines[i].sp,
|
|
509
|
+
len: 1,
|
|
510
|
+
oLen: inlines[i].len - 1,
|
|
511
|
+
type: 'em_close'
|
|
512
|
+
})
|
|
365
513
|
inlines[i].sp += 1
|
|
366
514
|
} else {
|
|
367
|
-
|
|
515
|
+
pushMark(marks, {
|
|
516
|
+
nest: nest,
|
|
517
|
+
s: inlines[i].ep,
|
|
518
|
+
e: inlines[i].ep,
|
|
519
|
+
len: 1,
|
|
520
|
+
oLen: inlines[i].len - 1,
|
|
521
|
+
type: 'em_close'
|
|
522
|
+
})
|
|
368
523
|
inlines[i].sp = inlines[i].ep - 1
|
|
369
524
|
inlines[i].ep -= 1
|
|
370
|
-
|
|
371
525
|
}
|
|
372
526
|
inlines[i].len -= 1
|
|
373
527
|
//console.log(marks)
|
|
374
|
-
if (
|
|
375
|
-
if (inlines[n].len === 0) return n, nest, memo
|
|
528
|
+
if (inlines[n].len === 0) return n, nest
|
|
376
529
|
}
|
|
377
530
|
|
|
378
531
|
i++
|
|
379
532
|
}
|
|
380
|
-
return n, nest
|
|
533
|
+
return n, nest
|
|
381
534
|
}
|
|
382
535
|
|
|
383
536
|
const setText = (inlines, marks, n, nest) => {
|
|
384
537
|
//console.log('n: ' + n + ' [text]: inlines[n].len: ' + inlines[n].len)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
538
|
+
pushMark(marks, {
|
|
539
|
+
nest: nest,
|
|
540
|
+
s: inlines[n].sp,
|
|
541
|
+
e: inlines[n].ep,
|
|
542
|
+
len: inlines[n].len,
|
|
543
|
+
oLen: -1,
|
|
544
|
+
type: 'text'
|
|
545
|
+
})
|
|
388
546
|
inlines[n].len = 0
|
|
389
547
|
}
|
|
390
548
|
|
|
@@ -413,7 +571,6 @@ const checkNest = (inlines, marks, n, i) => {
|
|
|
413
571
|
if (parentCloseN < marks.length) {
|
|
414
572
|
while (parentCloseN < marks.length) {
|
|
415
573
|
if (marks[parentCloseN].nest === parentNest) break
|
|
416
|
-
//if (marks.length - 1 == parentCloseN) break
|
|
417
574
|
parentCloseN++
|
|
418
575
|
}
|
|
419
576
|
//console.log('parentCloseN: ' + parentCloseN)
|
|
@@ -434,121 +591,127 @@ const checkNest = (inlines, marks, n, i) => {
|
|
|
434
591
|
return nest
|
|
435
592
|
}
|
|
436
593
|
|
|
437
|
-
const createMarks = (inlines, start, end, memo) => {
|
|
594
|
+
const createMarks = (state, inlines, start, end, memo, opt) => {
|
|
438
595
|
let marks = []
|
|
439
596
|
let n = start
|
|
440
597
|
while (n < end) {
|
|
441
|
-
if (inlines[n].type !== ''
|
|
442
|
-
memo.isEm = inlines[n].len === 1 ? true : false
|
|
443
|
-
memo.wrapEm = 0
|
|
598
|
+
if (inlines[n].type !== '') { n++; continue }
|
|
444
599
|
let nest = 0
|
|
445
|
-
|
|
446
|
-
if (
|
|
447
|
-
n, nest
|
|
600
|
+
//console.log('n: ' + n + ' ----- inlines:: src: ' + state.src.slice(inlines[n].sp, inlines[n].ep + 1) + ', inlines[n].sp: ' + inlines[n].sp + ', inlines[n].len: ' + inlines[n].len + ', memo.isEm: ' + memo.isEm)
|
|
601
|
+
if (inlines[n].len > 1) {
|
|
602
|
+
n, nest = setStrong(state, inlines, marks, n, memo, opt)
|
|
603
|
+
}
|
|
604
|
+
if (inlines[n].len !== 0) {
|
|
605
|
+
n, nest = setEm(state, inlines, marks, n, memo, opt)
|
|
606
|
+
}
|
|
607
|
+
if (inlines[n].len !== 0) {
|
|
608
|
+
setText(inlines, marks, n, nest)
|
|
448
609
|
}
|
|
449
|
-
n, nest, memo = setEm(inlines, marks, n, memo)
|
|
450
|
-
if (inlines[n].len !== 0) setText(inlines, marks, n, nest)
|
|
451
|
-
//console.log(marks)
|
|
452
610
|
n++
|
|
453
611
|
}
|
|
454
612
|
return marks
|
|
455
613
|
}
|
|
456
614
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
//console.log('n: ' + n + ', i: ' + i + ', marks[i].type: ' + marks[i].type)
|
|
468
|
-
inlines.splice(n + i + 1, 0, marks[i])
|
|
469
|
-
i++
|
|
470
|
-
continue
|
|
615
|
+
|
|
616
|
+
const mergeInlinesAndMarks = (inlines, marks) => {
|
|
617
|
+
marks.sort((a, b) => a.s - b.s)
|
|
618
|
+
const merged = []
|
|
619
|
+
let markIndex = 0
|
|
620
|
+
for (const token of inlines) {
|
|
621
|
+
if (token.type === '') {
|
|
622
|
+
while (markIndex < marks.length && marks[markIndex].s >= token.s && marks[markIndex].e <= token.e) {
|
|
623
|
+
merged.push(marks[markIndex])
|
|
624
|
+
markIndex++
|
|
471
625
|
}
|
|
472
|
-
break
|
|
473
|
-
}
|
|
474
|
-
if (marks.length) {
|
|
475
|
-
marks.splice(0, i)
|
|
476
|
-
inlines.splice(n, 1)
|
|
477
|
-
n += i
|
|
478
626
|
} else {
|
|
479
|
-
|
|
480
|
-
n++
|
|
627
|
+
merged.push(token)
|
|
481
628
|
}
|
|
482
629
|
}
|
|
630
|
+
while (markIndex < marks.length) {
|
|
631
|
+
merged.push(marks[markIndex++])
|
|
632
|
+
}
|
|
633
|
+
return merged
|
|
483
634
|
}
|
|
484
635
|
|
|
485
636
|
const strongJa = (state, silent, opt) => {
|
|
486
637
|
if (silent) return false
|
|
487
638
|
const start = state.pos
|
|
488
639
|
let max = state.posMax
|
|
640
|
+
const src = state.src
|
|
489
641
|
let attributesSrc
|
|
490
|
-
if (
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
642
|
+
if (start > max) return false
|
|
643
|
+
if (src.charCodeAt(start) !== 0x2A) return false
|
|
644
|
+
if (hasBackslash(state, start)) return false
|
|
645
|
+
|
|
646
|
+
if (opt.mditAttrs) {
|
|
647
|
+
attributesSrc = src.match(/((\n)? *){([^{}\n!@#%^&*()]+?)} *$/)
|
|
648
|
+
if (attributesSrc && attributesSrc[3] !== '.') {
|
|
649
|
+
max = src.slice(0, attributesSrc.index).length
|
|
650
|
+
if (attributesSrc[2] === '\n') {
|
|
651
|
+
max = src.slice(0, attributesSrc.index - 1).length
|
|
652
|
+
}
|
|
653
|
+
if(hasBackslash(state, attributesSrc.index) && attributesSrc[2] === '' && attributesSrc[1].length === 0) {
|
|
654
|
+
max = state.posMax
|
|
655
|
+
}
|
|
656
|
+
} else {
|
|
657
|
+
let endCurlyKet = src.match(/(\n *){([^{}\n!@#%^&*()]*?)}.*(} *?)$/)
|
|
658
|
+
if (endCurlyKet) {
|
|
659
|
+
max -= endCurlyKet[3].length
|
|
660
|
+
}
|
|
494
661
|
}
|
|
495
662
|
}
|
|
496
|
-
if (start > max) return false
|
|
497
|
-
if (state.src.charCodeAt(start) !== 0x2A) return false
|
|
498
663
|
|
|
499
|
-
|
|
500
|
-
//console.log('state.src.length: ' + state.src.length + ', start: ' + start + ', state.src: ' + state.src)
|
|
664
|
+
//console.log('state.src.length(max): ' + state.src.length + (state.src.length === max ? '' : '(' + max + ')') + ', start: ' + start + ', state.src: ' + state.src)
|
|
501
665
|
let inlines = createInlines(state, start, max, opt)
|
|
502
666
|
//console.log('inlines: ')
|
|
503
667
|
//console.log(inlines)
|
|
504
668
|
|
|
505
669
|
const memo = {
|
|
506
|
-
isEm: false,
|
|
507
|
-
hasEmThatWrapStrong: false,
|
|
508
|
-
noSetStrongEnd: false,
|
|
509
670
|
html: state.md.options.html,
|
|
510
671
|
htmlTags: {},
|
|
511
|
-
inlineMarkStart:
|
|
512
|
-
inlineMarkEnd:
|
|
672
|
+
inlineMarkStart: src.charCodeAt(0) === 0x2A ? true : false,
|
|
673
|
+
inlineMarkEnd: src.charCodeAt(max - 1) === 0x2A ? true : false,
|
|
513
674
|
}
|
|
514
|
-
|
|
675
|
+
|
|
676
|
+
let marks = createMarks(state, inlines, 0, inlines.length, memo, opt)
|
|
515
677
|
//console.log('marks: ')
|
|
516
678
|
//console.log(marks)
|
|
517
679
|
|
|
518
|
-
|
|
680
|
+
inlines = mergeInlinesAndMarks(inlines, marks)
|
|
519
681
|
//console.log('fix inlines:')
|
|
520
682
|
//console.log(inlines)
|
|
521
683
|
|
|
522
|
-
setToken(state, inlines)
|
|
684
|
+
setToken(state, inlines, opt)
|
|
685
|
+
|
|
686
|
+
//console.log ('End process:: max:' + max + ', state.posMax: ' + state.posMax + ', opt.mditAttrs: ' + opt.mditAttrs)
|
|
523
687
|
|
|
524
|
-
if (
|
|
525
|
-
|
|
688
|
+
if (opt.mditAttrs && max !== state.posMax) {
|
|
689
|
+
if (!attributesSrc) {
|
|
690
|
+
state.pos = max
|
|
691
|
+
return true
|
|
692
|
+
}
|
|
693
|
+
//console.log('start: ' + start + ', attributesSrc[0]::' + attributesSrc[0] + ', attributesSrc[1].length: ' + attributesSrc[1].length)
|
|
526
694
|
if (attributesSrc[1].length > 1) {
|
|
527
695
|
state.pos = max + attributesSrc[1].length
|
|
528
696
|
} else {
|
|
529
697
|
state.pos = max
|
|
530
698
|
}
|
|
531
699
|
} else {
|
|
532
|
-
state.pos = max
|
|
700
|
+
state.pos = max
|
|
533
701
|
}
|
|
702
|
+
//console.log(state.tokens)
|
|
534
703
|
return true
|
|
535
704
|
}
|
|
536
705
|
|
|
537
706
|
const mditStrongJa = (md, option) => {
|
|
538
707
|
const opt = {
|
|
539
|
-
dollarMath: true,
|
|
540
|
-
|
|
541
|
-
}
|
|
542
|
-
opt.hasCurlyAttributes = md.core.ruler.__rules__.filter(rule => {
|
|
543
|
-
rule.name === 'curly_attributes' // markdown-it-attrs
|
|
544
|
-
})
|
|
545
|
-
if (option !== undefined) {
|
|
546
|
-
for (let o in option) {
|
|
547
|
-
opt[o] = option[o]
|
|
548
|
-
}
|
|
708
|
+
dollarMath: true, //inline math $...$
|
|
709
|
+
mditAttrs: true, //markdown-it-attrs
|
|
549
710
|
}
|
|
711
|
+
if (option) Object.assign(opt, option)
|
|
712
|
+
|
|
550
713
|
md.inline.ruler.before('emphasis', 'strong_ja', (state, silent) => {
|
|
551
714
|
return strongJa(state, silent, opt)
|
|
552
715
|
})
|
|
553
716
|
}
|
|
554
|
-
export default mditStrongJa
|
|
717
|
+
export default mditStrongJa
|