@peaceroad/markdown-it-strong-ja 0.4.1 → 0.4.3
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 +19 -0
- package/index.js +204 -155
- package/package.json +6 -1
- package/test/example-complex.txt +0 -506
- package/test/example-em.txt +0 -205
- package/test/example-strong.txt +0 -219
- package/test/example-with-linebreak.txt +0 -282
- package/test/mditNoAttrs/example-complex.txt +0 -512
- package/test/mditNoAttrs/example-em.txt +0 -205
- package/test/mditNoAttrs/example-strong.txt +0 -219
- package/test/mditNoAttrs/example-with-linebreak.txt +0 -289
- package/test/test.js +0 -109
package/index.js
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
// Character code constants
|
|
2
|
+
const CHAR_ASTERISK = 0x2A // *
|
|
3
|
+
const CHAR_UNDERSCORE = 0x5F // _
|
|
4
|
+
const CHAR_BACKSLASH = 0x5C // \
|
|
5
|
+
const CHAR_BACKTICK = 0x60 // `
|
|
6
|
+
const CHAR_DOLLAR = 0x24 // $
|
|
7
|
+
const CHAR_LT = 0x3C // <
|
|
8
|
+
const CHAR_GT = 0x3E // >
|
|
9
|
+
const CHAR_SLASH = 0x2F // /
|
|
10
|
+
const CHAR_SPACE = 0x20 // ' ' (space)
|
|
11
|
+
|
|
1
12
|
const REG_ASTERISKS = /^\*+$/
|
|
2
13
|
const REG_ATTRS = /{[^{}\n!@#%^&*()]+?}$/
|
|
3
14
|
const REG_PUNCTUATION = /[!-/:-@[-`{-~ ]/
|
|
4
|
-
const REG_JAPANESE =
|
|
15
|
+
const REG_JAPANESE = /\p{Script=Hiragana}|\p{Script=Katakana}|\p{Script=Han}|\p{General_Category=Punctuation}|\p{General_Category=Symbol}|\p{General_Category=Format}|\p{Emoji}/u // ひらがな|カタカナ|漢字|句読点|記号|フォーマット文字|絵文字
|
|
16
|
+
|
|
17
|
+
const REG_MARKDOWN_HTML = /^\[[^\[\]]+\]\([^)]+\)$|^<([a-zA-Z][a-zA-Z0-9]*)[^>]*>([^<]+<\/\1>)$|^`[^`]+`$|^\$[^$]+\$$/ // for mixed-language context detection
|
|
5
18
|
|
|
6
19
|
const hasBackslash = (state, start) => {
|
|
7
20
|
let slashNum = 0
|
|
8
21
|
let i = start - 1
|
|
9
22
|
const src = state.src
|
|
10
23
|
while(i >= 0) {
|
|
11
|
-
if (src.charCodeAt(i) ===
|
|
24
|
+
if (src.charCodeAt(i) === CHAR_BACKSLASH) { slashNum++; i--; continue }
|
|
12
25
|
break
|
|
13
26
|
}
|
|
14
27
|
return slashNum % 2 === 1
|
|
@@ -23,7 +36,6 @@ const setToken = (state, inlines, opt) => {
|
|
|
23
36
|
}
|
|
24
37
|
while (i < inlines.length) {
|
|
25
38
|
let type = inlines[i].type
|
|
26
|
-
//console.log(i, type)
|
|
27
39
|
const tag = type.replace(/(?:_open|_close)$/, '')
|
|
28
40
|
|
|
29
41
|
if (/_open$/.test(type)) {
|
|
@@ -40,9 +52,7 @@ const setToken = (state, inlines, opt) => {
|
|
|
40
52
|
}
|
|
41
53
|
if (type === 'text') {
|
|
42
54
|
let content = src.slice(inlines[i].s, inlines[i].e + 1)
|
|
43
|
-
//console.log('content: ' + content)
|
|
44
55
|
if (REG_ASTERISKS.test(content)) {
|
|
45
|
-
//console.log('asterisk process::')
|
|
46
56
|
const asteriskToken = state.push(type, '', 0)
|
|
47
57
|
asteriskToken.content = content
|
|
48
58
|
i++
|
|
@@ -50,7 +60,6 @@ const setToken = (state, inlines, opt) => {
|
|
|
50
60
|
}
|
|
51
61
|
if (opt.mditAttrs && attrsIsText.val && i + 1 < inlines.length) {
|
|
52
62
|
const hasImmediatelyAfterAsteriskClose = inlines[i+1].type === attrsIsText.tag + '_close'
|
|
53
|
-
//console.log(hasImmediatelyAfterAsteriskClose, inlines[i+1].type, /^[\s\S]*{[^{}\n!@#%^&*()]+?}$/.test(content))
|
|
54
63
|
if (hasImmediatelyAfterAsteriskClose && REG_ATTRS.test(content)) {
|
|
55
64
|
const attrsToken = state.push(type, '', 0)
|
|
56
65
|
|
|
@@ -66,7 +75,6 @@ const setToken = (state, inlines, opt) => {
|
|
|
66
75
|
backSlash += '\\'
|
|
67
76
|
k++
|
|
68
77
|
}
|
|
69
|
-
//console.log(backSlashNum, backSlash)
|
|
70
78
|
attrsToken.content = content.replace(/\\+{/, backSlash + '{')
|
|
71
79
|
}
|
|
72
80
|
} else {
|
|
@@ -79,13 +87,11 @@ const setToken = (state, inlines, opt) => {
|
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
const childTokens = state.md.parseInline(content, state.env)
|
|
82
|
-
//console.log(childTokens)
|
|
83
|
-
//console.log(childTokens[0].children)
|
|
84
90
|
if (childTokens[0] && childTokens[0].children) {
|
|
85
91
|
let j = 0
|
|
86
92
|
while (j < childTokens[0].children.length) {
|
|
87
93
|
const t = childTokens[0].children[j]
|
|
88
|
-
if (t.type === 'softbreak') {
|
|
94
|
+
if (t.type === 'softbreak' && !opt.mdBreaks) {
|
|
89
95
|
t.type = 'text'
|
|
90
96
|
t.tag = ''
|
|
91
97
|
t.content = '\n'
|
|
@@ -131,7 +137,7 @@ const pushInlines = (inlines, s, e, len, type, tag, tagType) => {
|
|
|
131
137
|
ep: e,
|
|
132
138
|
len: len,
|
|
133
139
|
type: type,
|
|
134
|
-
check: type === 'text'
|
|
140
|
+
check: type === 'text',
|
|
135
141
|
}
|
|
136
142
|
if (tag) inline.tag = [tag, tagType]
|
|
137
143
|
inlines.push(inline)
|
|
@@ -141,16 +147,13 @@ const hasNextSymbol = (state, n, max, symbol, noMark) => {
|
|
|
141
147
|
let nextSymbolPos = -1
|
|
142
148
|
const src = state.src
|
|
143
149
|
if (src.charCodeAt(n) === symbol && !hasBackslash(state, n)) {
|
|
144
|
-
let i = n + 1
|
|
145
|
-
|
|
146
|
-
while (i < max) {
|
|
147
|
-
tempNoMark += src[i]
|
|
150
|
+
for (let i = n + 1; i < max; i++) {
|
|
151
|
+
noMark += src[i]
|
|
148
152
|
if (src.charCodeAt(i) === symbol && !hasBackslash(state, i)) {
|
|
149
153
|
noMark += src.substring(n, i + 1)
|
|
150
154
|
nextSymbolPos = i
|
|
151
155
|
break
|
|
152
156
|
}
|
|
153
|
-
i++
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
159
|
return [nextSymbolPos, noMark]
|
|
@@ -158,25 +161,33 @@ const hasNextSymbol = (state, n, max, symbol, noMark) => {
|
|
|
158
161
|
|
|
159
162
|
const createInlines = (state, start, max, opt) => {
|
|
160
163
|
const src = state.src
|
|
161
|
-
const srcLen = max
|
|
164
|
+
const srcLen = max
|
|
165
|
+
const htmlEnabled = state.md.options.html
|
|
162
166
|
let n = start
|
|
163
167
|
let inlines = []
|
|
164
168
|
let noMark = ''
|
|
165
169
|
let textStart = n
|
|
170
|
+
|
|
166
171
|
while (n < srcLen) {
|
|
167
|
-
|
|
168
|
-
let nextSymbolPos = -1
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
const currentChar = src.charCodeAt(n)
|
|
173
|
+
let nextSymbolPos = -1
|
|
174
|
+
|
|
175
|
+
// Inline code (backticks)
|
|
176
|
+
if (currentChar === CHAR_BACKTICK && !hasBackslash(state, n)) {
|
|
177
|
+
[nextSymbolPos, noMark] = hasNextSymbol(state, n, srcLen, CHAR_BACKTICK, noMark)
|
|
178
|
+
if (nextSymbolPos !== -1) {
|
|
179
|
+
if (nextSymbolPos === srcLen - 1) {
|
|
180
|
+
pushInlines(inlines, textStart, nextSymbolPos, nextSymbolPos - textStart + 1, 'text')
|
|
181
|
+
break
|
|
182
|
+
}
|
|
183
|
+
n = nextSymbolPos + 1
|
|
184
|
+
continue
|
|
174
185
|
}
|
|
175
|
-
n = nextSymbolPos + 1
|
|
176
|
-
continue
|
|
177
186
|
}
|
|
178
|
-
|
|
179
|
-
|
|
187
|
+
|
|
188
|
+
// Inline math ($...$)
|
|
189
|
+
if (opt.dollarMath && currentChar === CHAR_DOLLAR && !hasBackslash(state, n)) {
|
|
190
|
+
[nextSymbolPos, noMark] = hasNextSymbol(state, n, srcLen, CHAR_DOLLAR, noMark)
|
|
180
191
|
if (nextSymbolPos !== -1) {
|
|
181
192
|
if (nextSymbolPos === srcLen - 1) {
|
|
182
193
|
pushInlines(inlines, textStart, nextSymbolPos, nextSymbolPos - textStart + 1, 'text')
|
|
@@ -187,58 +198,56 @@ const createInlines = (state, start, max, opt) => {
|
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
noMark = ''
|
|
198
|
-
}
|
|
199
|
-
let tag = src.slice(n + 1, i)
|
|
200
|
-
let tagType = ''
|
|
201
|
-
if (/^\//.test(tag)) {
|
|
202
|
-
tag = tag.slice(1)
|
|
203
|
-
tagType = 'close'
|
|
204
|
-
} else {
|
|
205
|
-
tagType = 'open'
|
|
206
|
-
}
|
|
207
|
-
pushInlines(inlines, n, i, i - n + 1, 'html_inline', tag, tagType)
|
|
208
|
-
textStart = i + 1
|
|
209
|
-
break
|
|
201
|
+
// HTML tags
|
|
202
|
+
if (htmlEnabled && currentChar === CHAR_LT && !hasBackslash(state, n)) {
|
|
203
|
+
for (let i = n + 1; i < srcLen; i++) {
|
|
204
|
+
if (src.charCodeAt(i) === CHAR_GT && !hasBackslash(state, i)) {
|
|
205
|
+
if (noMark.length !== 0) {
|
|
206
|
+
pushInlines(inlines, textStart, n - 1, n - textStart, 'text')
|
|
207
|
+
noMark = ''
|
|
210
208
|
}
|
|
211
|
-
i
|
|
209
|
+
let tag = src.slice(n + 1, i)
|
|
210
|
+
let tagType
|
|
211
|
+
if (tag.charCodeAt(0) === CHAR_SLASH) {
|
|
212
|
+
tag = tag.slice(1)
|
|
213
|
+
tagType = 'close'
|
|
214
|
+
} else {
|
|
215
|
+
tagType = 'open'
|
|
216
|
+
}
|
|
217
|
+
pushInlines(inlines, n, i, i - n + 1, 'html_inline', tag, tagType)
|
|
218
|
+
textStart = i + 1
|
|
219
|
+
n = i + 1
|
|
220
|
+
break
|
|
212
221
|
}
|
|
213
|
-
n = i + 1
|
|
214
|
-
continue
|
|
215
222
|
}
|
|
223
|
+
continue
|
|
216
224
|
}
|
|
217
225
|
|
|
218
|
-
|
|
226
|
+
// Asterisk handling
|
|
227
|
+
if (currentChar === CHAR_ASTERISK && !hasBackslash(state, n)) {
|
|
219
228
|
if (n !== 0 && noMark.length !== 0) {
|
|
220
229
|
pushInlines(inlines, textStart, n - 1, n - textStart, 'text')
|
|
221
230
|
noMark = ''
|
|
222
231
|
}
|
|
223
232
|
if (n === srcLen - 1) {
|
|
224
|
-
pushInlines(inlines, n,
|
|
233
|
+
pushInlines(inlines, n, n, 1, '')
|
|
225
234
|
break
|
|
226
235
|
}
|
|
227
236
|
let i = n + 1
|
|
228
|
-
while (i < srcLen) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
pushInlines(inlines, n,
|
|
237
|
+
while (i < srcLen && src.charCodeAt(i) === CHAR_ASTERISK) {
|
|
238
|
+
i++
|
|
239
|
+
}
|
|
240
|
+
if (i === srcLen) {
|
|
241
|
+
pushInlines(inlines, n, i - 1, i - n, '')
|
|
242
|
+
} else {
|
|
243
|
+
pushInlines(inlines, n, i - 1, i - n, '')
|
|
235
244
|
textStart = i
|
|
236
|
-
break
|
|
237
245
|
}
|
|
238
246
|
n = i
|
|
239
247
|
continue
|
|
240
248
|
}
|
|
241
249
|
|
|
250
|
+
// Regular character
|
|
242
251
|
noMark += src[n]
|
|
243
252
|
if (n === srcLen - 1) {
|
|
244
253
|
pushInlines(inlines, textStart, n, n - textStart + 1, 'text')
|
|
@@ -250,7 +259,6 @@ const createInlines = (state, start, max, opt) => {
|
|
|
250
259
|
}
|
|
251
260
|
|
|
252
261
|
const pushMark = (marks, opts) => {
|
|
253
|
-
//binary search
|
|
254
262
|
let left = 0, right = marks.length
|
|
255
263
|
while (left < right) {
|
|
256
264
|
const mid = (left + right) >> 1
|
|
@@ -264,28 +272,43 @@ const pushMark = (marks, opts) => {
|
|
|
264
272
|
}
|
|
265
273
|
|
|
266
274
|
const setStrong = (state, inlines, marks, n, memo, opt) => {
|
|
275
|
+
if (opt.disallowMixed === true) {
|
|
276
|
+
let i = n + 1
|
|
277
|
+
const inlinesLength = inlines.length
|
|
278
|
+
while (i < inlinesLength) {
|
|
279
|
+
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
280
|
+
if (inlines[i].type !== '') { i++; continue }
|
|
281
|
+
|
|
282
|
+
if (inlines[i].len > 1) {
|
|
283
|
+
const mixedCheck = checkMixedLanguagePattern(state, inlines, n, i, opt)
|
|
284
|
+
if (mixedCheck.shouldBlock) {
|
|
285
|
+
return [n, 0]
|
|
286
|
+
}
|
|
287
|
+
break
|
|
288
|
+
}
|
|
289
|
+
i++
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
267
293
|
let i = n + 1
|
|
268
294
|
let j = 0
|
|
269
295
|
let nest = 0
|
|
270
|
-
let insideTagsIsClose = 1
|
|
271
|
-
|
|
272
|
-
|
|
296
|
+
let insideTagsIsClose = 1
|
|
297
|
+
const inlinesLength = inlines.length
|
|
298
|
+
while (i < inlinesLength) {
|
|
299
|
+
if (inlines[i].type !== '') { i++; continue }
|
|
273
300
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
274
301
|
if (inlines[i].type === 'html_inline') {
|
|
275
302
|
inlines[i].check = true
|
|
276
303
|
insideTagsIsClose = checkInsideTags(inlines, i, memo)
|
|
277
|
-
|
|
278
|
-
if (insideTagsIsClose === -1) return n, nest
|
|
304
|
+
if (insideTagsIsClose === -1) return [n, nest]
|
|
279
305
|
if (insideTagsIsClose === 0) { i++; continue }
|
|
280
306
|
}
|
|
281
|
-
if (inlines[i].type !== '') { i++; continue }
|
|
282
307
|
|
|
283
308
|
nest = checkNest(inlines, marks, n, i)
|
|
284
|
-
|
|
285
|
-
if (nest === -1) return n, nest
|
|
309
|
+
if (nest === -1) return [n, nest]
|
|
286
310
|
|
|
287
311
|
if (inlines[i].len === 1 && inlines[n].len > 2) {
|
|
288
|
-
//console.log(' check em inside strong:: i: ' + i)
|
|
289
312
|
pushMark(marks, {
|
|
290
313
|
nest: nest,
|
|
291
314
|
s: inlines[n].ep,
|
|
@@ -307,32 +330,25 @@ const setStrong = (state, inlines, marks, n, memo, opt) => {
|
|
|
307
330
|
inlines[i].len -= 1
|
|
308
331
|
if (inlines[i].len > 0) inlines[i].sp += 1
|
|
309
332
|
if (insideTagsIsClose === 1) {
|
|
310
|
-
|
|
333
|
+
const [newN, newNest] = setEm(state, inlines, marks, n, memo, opt)
|
|
334
|
+
n = newN
|
|
335
|
+
nest = newNest
|
|
311
336
|
}
|
|
312
|
-
//console.log(marks)
|
|
313
337
|
}
|
|
314
|
-
//console.log(' check len:: inlines[n].len: ' + inlines[n].len + ', inlines[i].len: ' + inlines[i].len)
|
|
315
338
|
let strongNum = Math.trunc(Math.min(inlines[n].len, inlines[i].len) / 2)
|
|
316
339
|
|
|
317
340
|
if (inlines[i].len > 1) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if (hasPunctuationOrNonJapanese(state, inlines, n, i)) {
|
|
341
|
+
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt)) {
|
|
321
342
|
if (memo.inlineMarkEnd) {
|
|
322
|
-
|
|
323
|
-
//console.log('~~~~~~~~~~~~~~~~~')
|
|
324
|
-
marks.push(...createMarks(state, inlines, i, inlines.length - 1, memo, opt))
|
|
325
|
-
//console.log('~~~~~~~~~~~~~~~~~')
|
|
343
|
+
marks.push(...createMarks(state, inlines, i, inlinesLength - 1, memo, opt))
|
|
326
344
|
if (inlines[i].len === 0) { i++; continue }
|
|
327
345
|
} else {
|
|
328
|
-
return n, nest
|
|
346
|
+
return [n, nest]
|
|
329
347
|
}
|
|
330
348
|
}
|
|
331
|
-
//console.log(' ===> strong normal push. n: ' + n + ', i: ' + i + ' , nest: ' + nest + ',strongNum: ' + strongNum)
|
|
332
349
|
|
|
333
350
|
j = 0
|
|
334
351
|
while (j < strongNum) {
|
|
335
|
-
//console.log(' - j: ' + j + ', inlines[i].sp: ' + inlines[i].sp)
|
|
336
352
|
pushMark(marks, {
|
|
337
353
|
nest: nest + strongNum - 1 - j,
|
|
338
354
|
s: inlines[n].ep - 1,
|
|
@@ -355,47 +371,40 @@ const setStrong = (state, inlines, marks, n, memo, opt) => {
|
|
|
355
371
|
inlines[i].len -= 2
|
|
356
372
|
j++
|
|
357
373
|
}
|
|
358
|
-
if (inlines[n].len === 0) return n, nest
|
|
374
|
+
if (inlines[n].len === 0) return [n, nest]
|
|
359
375
|
}
|
|
360
376
|
|
|
361
377
|
if (inlines[n].len === 1 && inlines[i].len > 0) {
|
|
362
|
-
//console.log(' check em that warp strong.')
|
|
363
378
|
nest++
|
|
364
|
-
|
|
379
|
+
const [newN, newNest] = setEm(state, inlines, marks, n, memo, opt, nest)
|
|
380
|
+
n = newN
|
|
381
|
+
nest = newNest
|
|
365
382
|
}
|
|
366
383
|
|
|
367
384
|
i++
|
|
368
385
|
}
|
|
369
386
|
|
|
370
387
|
if (n == 0 && memo.inlineMarkEnd) {
|
|
371
|
-
|
|
372
|
-
//console.log('===============================')
|
|
373
|
-
marks.push(...createMarks(state, inlines, n + 1 , inlines.length - 1, memo, opt))
|
|
374
|
-
//console.log(marks)
|
|
375
|
-
//console.log('===============================')
|
|
388
|
+
marks.push(...createMarks(state, inlines, n + 1, inlinesLength - 1, memo, opt))
|
|
376
389
|
}
|
|
377
|
-
return n, nest
|
|
390
|
+
return [n, nest]
|
|
378
391
|
}
|
|
379
392
|
|
|
380
393
|
const checkInsideTags = (inlines, i, memo) => {
|
|
381
|
-
//console.log('isJumTag before::memo.htmlTags: ' + JSON.stringify(memo.htmlTags))
|
|
382
394
|
if (inlines[i].tag === undefined) return 0
|
|
383
395
|
const tagName = inlines[i].tag[0].toLowerCase()
|
|
384
396
|
if (memo.htmlTags[tagName] === undefined) {
|
|
385
397
|
memo.htmlTags[tagName] = 0
|
|
386
398
|
}
|
|
387
|
-
//console.log('memo.htmlTags: ' + JSON.stringify(memo.htmlTags) + ', inlines[i]: ' + JSON.stringify(inlines[i]) + ', inlines[i]')
|
|
388
399
|
if (inlines[i].tag[1] === 'open') {
|
|
389
400
|
memo.htmlTags[tagName] += 1
|
|
390
401
|
}
|
|
391
402
|
if (inlines[i].tag[1] === 'close') {
|
|
392
403
|
memo.htmlTags[tagName] -= 1
|
|
393
404
|
}
|
|
394
|
-
//console.log(' i: ' + i + ', tagName: ' + tagName + ', memo.htmlTags[tagName]: ' + memo.htmlTags[tagName] + ', prevHtmlTags[tagName]: ' + prevHtmlTags[tagName])
|
|
395
405
|
if (memo.htmlTags[tagName] < 0) {
|
|
396
406
|
return -1
|
|
397
407
|
}
|
|
398
|
-
//console.log('isJumTag after::memo.htmlTags: ' + JSON.stringify(memo.htmlTags))
|
|
399
408
|
const closeAllTags = Object.values(memo.htmlTags).every(val => val === 0)
|
|
400
409
|
if (closeAllTags) return 1
|
|
401
410
|
return 0
|
|
@@ -408,47 +417,107 @@ const isJapanese = (ch) => {
|
|
|
408
417
|
return REG_JAPANESE.test(ch)
|
|
409
418
|
}
|
|
410
419
|
|
|
411
|
-
const
|
|
420
|
+
const isEnglish = (ch) => {
|
|
421
|
+
if (!ch) return false
|
|
422
|
+
const code = ch.charCodeAt(0)
|
|
423
|
+
if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122) || (code >= 48 && code <= 57)) {
|
|
424
|
+
return true
|
|
425
|
+
}
|
|
426
|
+
if (code < 128) {
|
|
427
|
+
return code === CHAR_SPACE || (code > 126)
|
|
428
|
+
}
|
|
429
|
+
return !REG_JAPANESE.test(ch) && !REG_PUNCTUATION.test(ch)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const checkMixedLanguagePattern = (state, inlines, n, i, opt) => {
|
|
433
|
+
const src = state.src
|
|
434
|
+
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
435
|
+
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
436
|
+
|
|
437
|
+
const isEnglishPrefix = isEnglish(openPrevChar)
|
|
438
|
+
const isEnglishSuffix = isEnglish(closeNextChar)
|
|
439
|
+
if (!isEnglishPrefix && !isEnglishSuffix) {
|
|
440
|
+
return { hasEnglishContext: false, hasMarkdownOrHtml: false, shouldBlock: false }
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const contentBetween = src.slice(inlines[n].e + 1, inlines[i].s)
|
|
444
|
+
const hasMarkdownOrHtml = REG_MARKDOWN_HTML.test(contentBetween)
|
|
445
|
+
|
|
446
|
+
return {
|
|
447
|
+
hasEnglishContext: true,
|
|
448
|
+
hasMarkdownOrHtml,
|
|
449
|
+
shouldBlock: hasMarkdownOrHtml
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt) => {
|
|
412
454
|
const src = state.src
|
|
413
455
|
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
414
|
-
//const checkOpenPrevChar =
|
|
415
456
|
const openNextChar = src[inlines[n].e + 1] || ''
|
|
416
457
|
const checkOpenNextChar = isPunctuation(openNextChar)
|
|
417
458
|
const closePrevChar = src[inlines[i].s - 1] || ''
|
|
418
459
|
const checkClosePrevChar = isPunctuation(closePrevChar)
|
|
419
460
|
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
420
|
-
const checkCloseNextChar = (isPunctuation(closeNextChar) || i === inlines.length - 1)
|
|
421
|
-
|
|
422
|
-
|
|
461
|
+
const checkCloseNextChar = (isPunctuation(closeNextChar) || i === inlines.length - 1)
|
|
462
|
+
|
|
463
|
+
if (opt.disallowMixed === false) {
|
|
464
|
+
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
465
|
+
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
466
|
+
|
|
467
|
+
if (isEnglish(openPrevChar) || isEnglish(closeNextChar)) {
|
|
468
|
+
const contentBetween = src.slice(inlines[n].e + 1, inlines[i].s)
|
|
469
|
+
if (REG_MARKDOWN_HTML.test(contentBetween)) {
|
|
470
|
+
return false
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const result = (checkOpenNextChar || checkClosePrevChar) && !checkCloseNextChar && !(isJapanese(openPrevChar) || isJapanese(closeNextChar))
|
|
476
|
+
return result
|
|
423
477
|
}
|
|
424
478
|
|
|
425
479
|
const setEm = (state, inlines, marks, n, memo, opt, sNest) => {
|
|
480
|
+
if (opt.disallowMixed === true && !sNest) {
|
|
481
|
+
let i = n + 1
|
|
482
|
+
const inlinesLength = inlines.length
|
|
483
|
+
while (i < inlinesLength) {
|
|
484
|
+
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
485
|
+
if (inlines[i].type !== '') { i++; continue }
|
|
486
|
+
|
|
487
|
+
if (inlines[i].len > 0) {
|
|
488
|
+
const mixedCheck = checkMixedLanguagePattern(state, inlines, n, i, opt)
|
|
489
|
+
if (mixedCheck.shouldBlock) {
|
|
490
|
+
return [n, 0]
|
|
491
|
+
}
|
|
492
|
+
break
|
|
493
|
+
}
|
|
494
|
+
i++
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
426
498
|
let i = n + 1
|
|
427
499
|
let nest = 0
|
|
428
500
|
let strongPNum = 0
|
|
429
501
|
let insideTagsIsClose = 1
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
//console.log(inlines[i].type, JSON.stringify(memo.htmlTags))
|
|
502
|
+
const inlinesLength = inlines.length
|
|
503
|
+
while (i < inlinesLength) {
|
|
433
504
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
434
505
|
if (!sNest && inlines[i].type === 'html_inline') {
|
|
435
506
|
inlines.check = true
|
|
436
507
|
insideTagsIsClose = checkInsideTags(inlines, i, memo)
|
|
437
|
-
|
|
438
|
-
if (insideTagsIsClose === -1) return n, nest
|
|
508
|
+
if (insideTagsIsClose === -1) return [n, nest]
|
|
439
509
|
if (insideTagsIsClose === 0) { i++; continue }
|
|
440
510
|
}
|
|
441
511
|
if (inlines[i].type !== '') { i++; continue }
|
|
442
512
|
|
|
443
513
|
const emNum = Math.min(inlines[n].len, inlines[i].len)
|
|
444
514
|
|
|
445
|
-
|
|
446
|
-
if (!sNest && emNum !== 1) return n, sNest, memo
|
|
515
|
+
if (!sNest && emNum !== 1) return [n, sNest, memo]
|
|
447
516
|
|
|
448
517
|
const hasMarkersAtStartAndEnd = (i) => {
|
|
449
518
|
let flag = memo.inlineMarkStart
|
|
450
519
|
if (!flag) return false
|
|
451
|
-
|
|
520
|
+
inlinesLength - 1 === i ? flag = true : flag = false
|
|
452
521
|
if (!flag) return false
|
|
453
522
|
inlines[i].len > 1 ? flag = true : flag = false
|
|
454
523
|
return flag
|
|
@@ -464,30 +533,22 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest) => {
|
|
|
464
533
|
} else {
|
|
465
534
|
nest = checkNest(inlines, marks, n, i)
|
|
466
535
|
}
|
|
467
|
-
|
|
468
|
-
if (nest === -1) return n, nest
|
|
536
|
+
if (nest === -1) return [n, nest]
|
|
469
537
|
|
|
470
538
|
if (emNum === 1) {
|
|
471
|
-
|
|
472
|
-
if (hasPunctuationOrNonJapanese(state, inlines, n, i)) {
|
|
539
|
+
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt)) {
|
|
473
540
|
if (memo.inlineMarkEnd) {
|
|
474
|
-
|
|
475
|
-
//console.log('~~~~~~~~~~~~~~~~~')
|
|
476
|
-
marks.push(...createMarks(state, inlines, i, inlines.length - 1, memo, opt))
|
|
477
|
-
//console.log('~~~~~~~~~~~~~~~~~')
|
|
541
|
+
marks.push(...createMarks(state, inlines, i, inlinesLength - 1, memo, opt))
|
|
478
542
|
|
|
479
543
|
if (inlines[i].len === 0) { i++; continue }
|
|
480
544
|
} else {
|
|
481
|
-
return n, nest
|
|
545
|
+
return [n, nest]
|
|
482
546
|
}
|
|
483
547
|
}
|
|
484
|
-
|
|
485
|
-
if (inlines[i].len < 1) { // memo.html
|
|
548
|
+
if (inlines[i].len < 1) {
|
|
486
549
|
i++; continue;
|
|
487
550
|
}
|
|
488
551
|
|
|
489
|
-
//console.log(' ===> em Normal push. n: ' + n + ', i: ' + i + ', nest: ' + nest, ', strongPNum: ' + strongPNum)
|
|
490
|
-
//console.log(inlines[n].ep, inlines[n].sp, inlines[n].s)
|
|
491
552
|
pushMark(marks, {
|
|
492
553
|
nest: nest,
|
|
493
554
|
s: inlines[n].ep,
|
|
@@ -522,17 +583,15 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest) => {
|
|
|
522
583
|
inlines[i].ep -= 1
|
|
523
584
|
}
|
|
524
585
|
inlines[i].len -= 1
|
|
525
|
-
|
|
526
|
-
if (inlines[n].len === 0) return n, nest
|
|
586
|
+
if (inlines[n].len === 0) return [n, nest]
|
|
527
587
|
}
|
|
528
588
|
|
|
529
589
|
i++
|
|
530
590
|
}
|
|
531
|
-
return n, nest
|
|
591
|
+
return [n, nest]
|
|
532
592
|
}
|
|
533
593
|
|
|
534
594
|
const setText = (inlines, marks, n, nest) => {
|
|
535
|
-
//console.log('n: ' + n + ' [text]: inlines[n].len: ' + inlines[n].len)
|
|
536
595
|
pushMark(marks, {
|
|
537
596
|
nest: nest,
|
|
538
597
|
s: inlines[n].sp,
|
|
@@ -551,10 +610,8 @@ const checkNest = (inlines, marks, n, i) => {
|
|
|
551
610
|
let strongNest = 0
|
|
552
611
|
let emNest = 0
|
|
553
612
|
let j = 0
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
//console.log('n: ' + n + ', i: ' + i + ', inlines[n].s: ' + inlines[n].s + ', inlines[i].s: ' + inlines[i].s)
|
|
557
|
-
while (j < marks.length) {
|
|
613
|
+
const marksLength = marks.length
|
|
614
|
+
while (j < marksLength) {
|
|
558
615
|
if (marks[j].s <= inlines[n].s) {
|
|
559
616
|
if (marks[j].type === 'strong_open') strongNest++
|
|
560
617
|
if (marks[j].type === 'strong_close') strongNest--
|
|
@@ -565,21 +622,17 @@ const checkNest = (inlines, marks, n, i) => {
|
|
|
565
622
|
}
|
|
566
623
|
let parentNest = strongNest + emNest
|
|
567
624
|
let parentCloseN = j
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
while (parentCloseN < marks.length) {
|
|
625
|
+
if (parentCloseN < marksLength) {
|
|
626
|
+
while (parentCloseN < marksLength) {
|
|
571
627
|
if (marks[parentCloseN].nest === parentNest) break
|
|
572
628
|
parentCloseN++
|
|
573
629
|
}
|
|
574
|
-
|
|
575
|
-
if (parentCloseN > marks.length - 1) {
|
|
630
|
+
if (parentCloseN > marksLength - 1) {
|
|
576
631
|
isRange = true
|
|
577
632
|
} else {
|
|
578
|
-
//console.log(marks[parentCloseN].s, i, inlines[i].s)
|
|
579
633
|
if (marks[parentCloseN].s < inlines[i].s) isRange = false
|
|
580
634
|
}
|
|
581
635
|
}
|
|
582
|
-
//console.log('isRange: ' + isRange)
|
|
583
636
|
|
|
584
637
|
if (isRange) {
|
|
585
638
|
nest = parentNest + 1
|
|
@@ -592,15 +645,20 @@ const checkNest = (inlines, marks, n, i) => {
|
|
|
592
645
|
const createMarks = (state, inlines, start, end, memo, opt) => {
|
|
593
646
|
let marks = []
|
|
594
647
|
let n = start
|
|
648
|
+
|
|
595
649
|
while (n < end) {
|
|
596
650
|
if (inlines[n].type !== '') { n++; continue }
|
|
597
651
|
let nest = 0
|
|
598
|
-
|
|
652
|
+
|
|
599
653
|
if (inlines[n].len > 1) {
|
|
600
|
-
|
|
654
|
+
const [newN, newNest] = setStrong(state, inlines, marks, n, memo, opt)
|
|
655
|
+
n = newN
|
|
656
|
+
nest = newNest
|
|
601
657
|
}
|
|
602
658
|
if (inlines[n].len !== 0) {
|
|
603
|
-
|
|
659
|
+
const [newN2, newNest2] = setEm(state, inlines, marks, n, memo, opt)
|
|
660
|
+
n = newN2
|
|
661
|
+
nest = newNest2
|
|
604
662
|
}
|
|
605
663
|
if (inlines[n].len !== 0) {
|
|
606
664
|
setText(inlines, marks, n, nest)
|
|
@@ -638,7 +696,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
638
696
|
const src = state.src
|
|
639
697
|
let attributesSrc
|
|
640
698
|
if (start > max) return false
|
|
641
|
-
if (src.charCodeAt(start) !==
|
|
699
|
+
if (src.charCodeAt(start) !== CHAR_ASTERISK) return false
|
|
642
700
|
if (hasBackslash(state, start)) return false
|
|
643
701
|
|
|
644
702
|
if (opt.mditAttrs) {
|
|
@@ -659,36 +717,26 @@ const strongJa = (state, silent, opt) => {
|
|
|
659
717
|
}
|
|
660
718
|
}
|
|
661
719
|
|
|
662
|
-
//console.log('state.src.length(max): ' + state.src.length + (state.src.length === max ? '' : '(' + max + ')') + ', start: ' + start + ', state.src: ' + state.src)
|
|
663
720
|
let inlines = createInlines(state, start, max, opt)
|
|
664
|
-
//console.log('inlines: ')
|
|
665
|
-
//console.log(inlines)
|
|
666
721
|
|
|
667
722
|
const memo = {
|
|
668
723
|
html: state.md.options.html,
|
|
669
724
|
htmlTags: {},
|
|
670
|
-
inlineMarkStart: src.charCodeAt(0) ===
|
|
671
|
-
inlineMarkEnd: src.charCodeAt(max - 1) ===
|
|
725
|
+
inlineMarkStart: src.charCodeAt(0) === CHAR_ASTERISK,
|
|
726
|
+
inlineMarkEnd: src.charCodeAt(max - 1) === CHAR_ASTERISK,
|
|
672
727
|
}
|
|
673
728
|
|
|
674
729
|
let marks = createMarks(state, inlines, 0, inlines.length, memo, opt)
|
|
675
|
-
//console.log('marks: ')
|
|
676
|
-
//console.log(marks)
|
|
677
730
|
|
|
678
731
|
inlines = mergeInlinesAndMarks(inlines, marks)
|
|
679
|
-
//console.log('fix inlines:')
|
|
680
|
-
//console.log(inlines)
|
|
681
732
|
|
|
682
733
|
setToken(state, inlines, opt)
|
|
683
734
|
|
|
684
|
-
//console.log ('End process:: max:' + max + ', state.posMax: ' + state.posMax + ', opt.mditAttrs: ' + opt.mditAttrs)
|
|
685
|
-
|
|
686
735
|
if (opt.mditAttrs && max !== state.posMax) {
|
|
687
736
|
if (!attributesSrc) {
|
|
688
737
|
state.pos = max
|
|
689
738
|
return true
|
|
690
739
|
}
|
|
691
|
-
//console.log('start: ' + start + ', attributesSrc[0]::' + attributesSrc[0] + ', attributesSrc[1].length: ' + attributesSrc[1].length)
|
|
692
740
|
if (attributesSrc[1].length > 1) {
|
|
693
741
|
state.pos = max + attributesSrc[1].length
|
|
694
742
|
} else {
|
|
@@ -697,7 +745,6 @@ const strongJa = (state, silent, opt) => {
|
|
|
697
745
|
} else {
|
|
698
746
|
state.pos = max
|
|
699
747
|
}
|
|
700
|
-
//console.log(state.tokens)
|
|
701
748
|
return true
|
|
702
749
|
}
|
|
703
750
|
|
|
@@ -705,6 +752,8 @@ const mditStrongJa = (md, option) => {
|
|
|
705
752
|
const opt = {
|
|
706
753
|
dollarMath: true, //inline math $...$
|
|
707
754
|
mditAttrs: true, //markdown-it-attrs
|
|
755
|
+
mdBreaks: md.options.breaks,
|
|
756
|
+
disallowMixed: false, //Non-Japanese text handling
|
|
708
757
|
}
|
|
709
758
|
if (option) Object.assign(opt, option)
|
|
710
759
|
|