@peaceroad/markdown-it-strong-ja 0.5.3 → 0.5.5
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/index.js +301 -185
- package/package.json +6 -4
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Token from 'markdown-it/lib/token.mjs'
|
|
2
2
|
import { parseLinkDestination, parseLinkTitle } from 'markdown-it/lib/helpers/index.mjs'
|
|
3
|
-
import { isSpace } from 'markdown-it/lib/common/utils.mjs'
|
|
3
|
+
import { isSpace, isWhiteSpace } from 'markdown-it/lib/common/utils.mjs'
|
|
4
4
|
|
|
5
5
|
const CHAR_ASTERISK = 0x2A // *
|
|
6
6
|
//const CHAR_UNDERSCORE = 0x5F // _
|
|
@@ -20,15 +20,19 @@ const CHAR_TAB = 0x09 // tab
|
|
|
20
20
|
//const CHAR_OPEN_CURLY = 0x7B // {
|
|
21
21
|
const CHAR_CLOSE_CURLY = 0x7D // }
|
|
22
22
|
|
|
23
|
-
const REG_ASTERISKS = /^\*+$/
|
|
24
23
|
const REG_ATTRS = /{[^{}\n!@#%^&*()]+?}$/
|
|
25
|
-
const
|
|
24
|
+
const REG_ASCII_PUNCT = /[!-/:-@[-`{-~]/g
|
|
26
25
|
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 // ひらがな|カタカナ|漢字|句読点|記号|フォーマット文字|絵文字
|
|
27
26
|
|
|
28
27
|
const REG_MARKDOWN_HTML = /^\[[^\[\]]+\]\([^)]+\)$|^<([a-zA-Z][a-zA-Z0-9]*)[^>]*>([^<]+<\/\1>)$|^`[^`]+`$|^\$[^$]+\$$/ // for mixed-language context detection
|
|
29
28
|
|
|
30
29
|
const hasBackslash = (state, start) => {
|
|
31
30
|
if (start <= 0) return false
|
|
31
|
+
if (state.__strongJaHasBackslash === false) return false
|
|
32
|
+
if (state.__strongJaHasBackslash === undefined) {
|
|
33
|
+
state.__strongJaHasBackslash = state.src.indexOf('\\') !== -1
|
|
34
|
+
if (!state.__strongJaHasBackslash) return false
|
|
35
|
+
}
|
|
32
36
|
const cache = state.__strongJaBackslashCache
|
|
33
37
|
if (cache && cache.has(start)) {
|
|
34
38
|
return cache.get(start)
|
|
@@ -173,12 +177,11 @@ const computeReferenceRanges = (state, start, max) => {
|
|
|
173
177
|
? referenceCount > 0
|
|
174
178
|
: Object.keys(references).length > 0)
|
|
175
179
|
if (!hasReferences) return []
|
|
176
|
-
|
|
177
|
-
if (
|
|
180
|
+
let pos = src.indexOf('[', start)
|
|
181
|
+
if (pos === -1 || pos >= max) return []
|
|
178
182
|
const ranges = []
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (src.charCodeAt(pos) === CHAR_OPEN_BRACKET && !hasBackslash(state, pos)) {
|
|
183
|
+
while (pos !== -1 && pos < max) {
|
|
184
|
+
if (!hasBackslash(state, pos)) {
|
|
182
185
|
const labelClose = findMatchingBracket(state, pos, max, CHAR_OPEN_BRACKET, CHAR_CLOSE_BRACKET)
|
|
183
186
|
if (labelClose !== -1) {
|
|
184
187
|
const nextPos = labelClose + 1
|
|
@@ -199,16 +202,13 @@ const computeReferenceRanges = (state, start, max) => {
|
|
|
199
202
|
ranges.push({ start: pos, end: labelClose, hasReference: true })
|
|
200
203
|
ranges.push({ start: nextPos, end: refClose, hasReference: true })
|
|
201
204
|
}
|
|
202
|
-
pos = refClose
|
|
205
|
+
pos = src.indexOf('[', refClose + 1)
|
|
203
206
|
continue
|
|
204
207
|
}
|
|
205
208
|
}
|
|
206
209
|
}
|
|
207
210
|
}
|
|
208
|
-
pos
|
|
209
|
-
}
|
|
210
|
-
if (ranges.length) {
|
|
211
|
-
ranges.__cache = new Map()
|
|
211
|
+
pos = src.indexOf('[', pos + 1)
|
|
212
212
|
}
|
|
213
213
|
return ranges
|
|
214
214
|
}
|
|
@@ -217,10 +217,11 @@ const computeInlineLinkRanges = (state, start, max) => {
|
|
|
217
217
|
const src = state.src
|
|
218
218
|
const ranges = []
|
|
219
219
|
const labelRanges = []
|
|
220
|
-
let pos = start
|
|
220
|
+
let pos = src.indexOf('[', start)
|
|
221
|
+
if (pos === -1 || pos >= max) return []
|
|
221
222
|
let rangeId = 0
|
|
222
|
-
while (pos < max) {
|
|
223
|
-
if (
|
|
223
|
+
while (pos !== -1 && pos < max) {
|
|
224
|
+
if (!hasBackslash(state, pos)) {
|
|
224
225
|
const labelClose = findMatchingBracket(state, pos, max, CHAR_OPEN_BRACKET, CHAR_CLOSE_BRACKET)
|
|
225
226
|
if (labelClose === -1) break
|
|
226
227
|
let destStart = labelClose + 1
|
|
@@ -237,14 +238,14 @@ const computeInlineLinkRanges = (state, start, max) => {
|
|
|
237
238
|
labelRanges.push(labelRange)
|
|
238
239
|
ranges.push({ start: destStart, end: destClose, kind: 'dest', id: rangeId })
|
|
239
240
|
rangeId++
|
|
240
|
-
pos = destClose + 1
|
|
241
|
+
pos = src.indexOf('[', destClose + 1)
|
|
241
242
|
continue
|
|
242
243
|
}
|
|
243
244
|
}
|
|
244
|
-
pos = labelClose + 1
|
|
245
|
+
pos = src.indexOf('[', labelClose + 1)
|
|
245
246
|
continue
|
|
246
247
|
}
|
|
247
|
-
pos
|
|
248
|
+
pos = src.indexOf('[', pos + 1)
|
|
248
249
|
}
|
|
249
250
|
if (ranges.length && labelRanges.length) {
|
|
250
251
|
ranges.__labelRanges = labelRanges
|
|
@@ -264,7 +265,8 @@ const getInlineRangeCacheMap = (ranges, kind, create) => {
|
|
|
264
265
|
|
|
265
266
|
const findInlineLinkRange = (pos, ranges, kind) => {
|
|
266
267
|
if (!ranges || ranges.length === 0) return null
|
|
267
|
-
const
|
|
268
|
+
const useCache = ranges.length > 32
|
|
269
|
+
const cache = useCache ? getInlineRangeCacheMap(ranges, kind, false) : null
|
|
268
270
|
if (cache && cache.has(pos)) return cache.get(pos)
|
|
269
271
|
let left = 0
|
|
270
272
|
let right = ranges.length - 1
|
|
@@ -283,8 +285,10 @@ const findInlineLinkRange = (pos, ranges, kind) => {
|
|
|
283
285
|
break
|
|
284
286
|
}
|
|
285
287
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
+
if (useCache) {
|
|
289
|
+
const storeCache = getInlineRangeCacheMap(ranges, kind, true)
|
|
290
|
+
storeCache.set(pos, found)
|
|
291
|
+
}
|
|
288
292
|
return found
|
|
289
293
|
}
|
|
290
294
|
|
|
@@ -318,24 +322,64 @@ const registerPostProcessTarget = (state) => {
|
|
|
318
322
|
targets.push(state.tokens)
|
|
319
323
|
}
|
|
320
324
|
|
|
321
|
-
const
|
|
325
|
+
const hasMditAttrs = (state) => {
|
|
326
|
+
if (state.__strongJaHasAttrs !== undefined) return state.__strongJaHasAttrs
|
|
327
|
+
const rules = state.md && state.md.core && state.md.core.ruler && state.md.core.ruler.__rules__
|
|
328
|
+
if (!rules || !Array.isArray(rules)) {
|
|
329
|
+
state.__strongJaHasAttrs = false
|
|
330
|
+
return false
|
|
331
|
+
}
|
|
332
|
+
for (let i = 0; i < rules.length; i++) {
|
|
333
|
+
if (rules[i].name === 'curly_attributes') {
|
|
334
|
+
state.__strongJaHasAttrs = true
|
|
335
|
+
return true
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
state.__strongJaHasAttrs = false
|
|
339
|
+
return false
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const isAllAsterisks = (content) => {
|
|
343
|
+
for (let i = 0; i < content.length; i++) {
|
|
344
|
+
if (content.charCodeAt(i) !== CHAR_ASTERISK) return false
|
|
345
|
+
}
|
|
346
|
+
return true
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function isPlainTextContent(content) {
|
|
350
|
+
for (let idx = 0; idx < content.length; idx++) {
|
|
351
|
+
const code = content.charCodeAt(idx)
|
|
352
|
+
if (code === CHAR_BACKSLASH || code === CHAR_NEWLINE || code === CHAR_TAB) {
|
|
353
|
+
return false
|
|
354
|
+
}
|
|
355
|
+
if (code < 128 && isAsciiPunctuationCode(code)) return false
|
|
356
|
+
}
|
|
357
|
+
return true
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const setToken = (state, inlines, opt, attrsEnabled) => {
|
|
322
361
|
const src = state.src
|
|
323
362
|
let i = 0
|
|
324
|
-
let attrsIsText =
|
|
325
|
-
|
|
326
|
-
tag: '',
|
|
327
|
-
}
|
|
363
|
+
let attrsIsText = false
|
|
364
|
+
let attrsIsTextTag = ''
|
|
328
365
|
while (i < inlines.length) {
|
|
329
366
|
let type = inlines[i].type
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
367
|
+
let tag = ''
|
|
368
|
+
let isOpen = false
|
|
369
|
+
let isClose = false
|
|
370
|
+
if (type.length > 5 && type.endsWith('_open')) {
|
|
371
|
+
isOpen = true
|
|
372
|
+
tag = type.slice(0, -5)
|
|
373
|
+
} else if (type.length > 6 && type.endsWith('_close')) {
|
|
374
|
+
isClose = true
|
|
375
|
+
tag = type.slice(0, -6)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (isOpen) {
|
|
333
379
|
const startToken = state.push(type, tag, 1)
|
|
334
380
|
startToken.markup = tag === 'strong' ? '**' : '*'
|
|
335
|
-
attrsIsText =
|
|
336
|
-
|
|
337
|
-
tag: tag,
|
|
338
|
-
}
|
|
381
|
+
attrsIsText = true
|
|
382
|
+
attrsIsTextTag = tag
|
|
339
383
|
}
|
|
340
384
|
|
|
341
385
|
if (type === 'html_inline') {
|
|
@@ -343,18 +387,23 @@ const setToken = (state, inlines, opt) => {
|
|
|
343
387
|
}
|
|
344
388
|
if (type === 'text') {
|
|
345
389
|
let content = src.slice(inlines[i].s, inlines[i].e + 1)
|
|
346
|
-
if (
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
390
|
+
if (content.length > 0 && content.charCodeAt(0) === CHAR_ASTERISK) {
|
|
391
|
+
if (isAllAsterisks(content)) {
|
|
392
|
+
const asteriskToken = state.push(type, '', 0)
|
|
393
|
+
asteriskToken.content = content
|
|
394
|
+
i++
|
|
395
|
+
continue
|
|
396
|
+
}
|
|
351
397
|
}
|
|
352
|
-
if (
|
|
353
|
-
const hasImmediatelyAfterAsteriskClose = inlines[i+1].type ===
|
|
354
|
-
|
|
398
|
+
if (attrsEnabled && attrsIsText && i + 1 < inlines.length) {
|
|
399
|
+
const hasImmediatelyAfterAsteriskClose = inlines[i+1].type === attrsIsTextTag + '_close'
|
|
400
|
+
const maybeAttrs = content.length > 0 && content.charCodeAt(content.length - 1) === CHAR_CLOSE_CURLY
|
|
401
|
+
if (hasImmediatelyAfterAsteriskClose && maybeAttrs && REG_ATTRS.test(content)) {
|
|
355
402
|
const attrsToken = state.push(type, '', 0)
|
|
356
|
-
|
|
357
|
-
|
|
403
|
+
let hasBackslashBeforeCurlyAttribute = null
|
|
404
|
+
if (content.indexOf('\\') !== -1) {
|
|
405
|
+
hasBackslashBeforeCurlyAttribute = content.match(/(\\+){/)
|
|
406
|
+
}
|
|
358
407
|
if (hasBackslashBeforeCurlyAttribute) {
|
|
359
408
|
if (hasBackslashBeforeCurlyAttribute[1].length === 1) {
|
|
360
409
|
attrsToken.content = content.replace(/\\{/, '{')
|
|
@@ -371,11 +420,18 @@ const setToken = (state, inlines, opt) => {
|
|
|
371
420
|
} else {
|
|
372
421
|
attrsToken.content = content
|
|
373
422
|
}
|
|
374
|
-
attrsIsText
|
|
423
|
+
attrsIsText = false
|
|
424
|
+
attrsIsTextTag = ''
|
|
375
425
|
i++
|
|
376
426
|
continue
|
|
377
427
|
}
|
|
378
428
|
}
|
|
429
|
+
if (isPlainTextContent(content)) {
|
|
430
|
+
const textToken = state.push(type, '', 0)
|
|
431
|
+
textToken.content = content
|
|
432
|
+
i++
|
|
433
|
+
continue
|
|
434
|
+
}
|
|
379
435
|
|
|
380
436
|
const childTokens = state.md.parseInline(content, state.env)
|
|
381
437
|
if (childTokens[0] && childTokens[0].children) {
|
|
@@ -387,7 +443,7 @@ const setToken = (state, inlines, opt) => {
|
|
|
387
443
|
t.tag = ''
|
|
388
444
|
t.content = '\n'
|
|
389
445
|
}
|
|
390
|
-
if (!
|
|
446
|
+
if (!attrsEnabled && t.tag === 'br') {
|
|
391
447
|
t.tag = ''
|
|
392
448
|
t.content = '\n'
|
|
393
449
|
}
|
|
@@ -398,13 +454,11 @@ const setToken = (state, inlines, opt) => {
|
|
|
398
454
|
}
|
|
399
455
|
}
|
|
400
456
|
|
|
401
|
-
if (
|
|
457
|
+
if (isClose) {
|
|
402
458
|
const closeToken = state.push(type, tag, -1)
|
|
403
459
|
closeToken.markup = tag === 'strong' ? '**' : '*'
|
|
404
|
-
attrsIsText =
|
|
405
|
-
|
|
406
|
-
tag: '',
|
|
407
|
-
}
|
|
460
|
+
attrsIsText = false
|
|
461
|
+
attrsIsTextTag = ''
|
|
408
462
|
}
|
|
409
463
|
|
|
410
464
|
i++
|
|
@@ -425,71 +479,81 @@ const pushInlines = (inlines, s, e, len, type, tag, tagType) => {
|
|
|
425
479
|
inlines.push(inline)
|
|
426
480
|
}
|
|
427
481
|
|
|
428
|
-
const
|
|
482
|
+
const isAsciiPunctuationCode = (code) => {
|
|
483
|
+
return (code >= 33 && code <= 47) || (code >= 58 && code <= 64) ||
|
|
484
|
+
(code >= 91 && code <= 96) || (code >= 123 && code <= 126)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const findNextAsciiPunctuation = (src, start, max) => {
|
|
488
|
+
REG_ASCII_PUNCT.lastIndex = start
|
|
489
|
+
const match = REG_ASCII_PUNCT.exec(src)
|
|
490
|
+
if (!match || match.index >= max) return -1
|
|
491
|
+
return match.index
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const findNextSymbolPos = (state, n, max, symbol, symbolChar) => {
|
|
429
495
|
const src = state.src
|
|
430
496
|
if (src.charCodeAt(n) !== symbol || hasBackslash(state, n)) return -1
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
497
|
+
let i = src.indexOf(symbolChar, n + 1)
|
|
498
|
+
while (i !== -1 && i < max) {
|
|
499
|
+
if (!hasBackslash(state, i)) return i
|
|
500
|
+
i = src.indexOf(symbolChar, i + 1)
|
|
435
501
|
}
|
|
436
502
|
return -1
|
|
437
503
|
}
|
|
438
504
|
|
|
439
|
-
const processSymbolPair = (state, n, srcLen, symbol,
|
|
440
|
-
const nextSymbolPos = findNextSymbolPos(state, n, srcLen, symbol)
|
|
505
|
+
const processSymbolPair = (state, n, srcLen, symbol, symbolChar, hasText, textStart, pushInlines) => {
|
|
506
|
+
const nextSymbolPos = findNextSymbolPos(state, n, srcLen, symbol, symbolChar)
|
|
441
507
|
if (nextSymbolPos === -1) {
|
|
442
|
-
return { shouldBreak: false, shouldContinue: false, newN: n,
|
|
508
|
+
return { shouldBreak: false, shouldContinue: false, newN: n, hasText: hasText }
|
|
443
509
|
}
|
|
444
|
-
const src = state.src
|
|
445
|
-
const innerText = src.slice(n + 1, nextSymbolPos)
|
|
446
|
-
const markup = src.slice(n, nextSymbolPos + 1)
|
|
447
|
-
const newNoMark = noMark + innerText + markup
|
|
448
510
|
if (nextSymbolPos === srcLen - 1) {
|
|
449
511
|
pushInlines(textStart, nextSymbolPos, nextSymbolPos - textStart + 1, 'text')
|
|
450
|
-
return { shouldBreak: true, newN: nextSymbolPos + 1,
|
|
512
|
+
return { shouldBreak: true, newN: nextSymbolPos + 1, hasText: true }
|
|
451
513
|
}
|
|
452
|
-
return { shouldBreak: false, shouldContinue: true, newN: nextSymbolPos + 1,
|
|
514
|
+
return { shouldBreak: false, shouldContinue: true, newN: nextSymbolPos + 1, hasText: true }
|
|
453
515
|
}
|
|
454
516
|
|
|
455
|
-
const processTextSegment = (inlines, textStart, n,
|
|
456
|
-
if (n !== 0 &&
|
|
517
|
+
const processTextSegment = (inlines, textStart, n, hasText) => {
|
|
518
|
+
if (n !== 0 && hasText) {
|
|
457
519
|
pushInlines(inlines, textStart, n - 1, n - textStart, 'text')
|
|
458
|
-
return
|
|
520
|
+
return false
|
|
459
521
|
}
|
|
460
|
-
return
|
|
522
|
+
return hasText
|
|
461
523
|
}
|
|
462
524
|
|
|
463
525
|
const createInlines = (state, start, max, opt) => {
|
|
464
526
|
const src = state.src
|
|
465
527
|
const srcLen = max
|
|
466
528
|
const htmlEnabled = state.md.options.html
|
|
529
|
+
const dollarMath = opt.dollarMath
|
|
467
530
|
let n = start
|
|
468
531
|
let inlines = []
|
|
469
|
-
let
|
|
532
|
+
let hasText = false
|
|
470
533
|
let textStart = n
|
|
471
534
|
|
|
472
|
-
// Infinite loop prevention
|
|
473
|
-
const maxIterations = srcLen * 2 // Safe upper bound
|
|
474
|
-
let iterations = 0
|
|
475
|
-
|
|
476
535
|
while (n < srcLen) {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
if (
|
|
480
|
-
|
|
481
|
-
if (
|
|
482
|
-
|
|
536
|
+
let currentChar = src.charCodeAt(n)
|
|
537
|
+
|
|
538
|
+
if (!isAsciiPunctuationCode(currentChar)) {
|
|
539
|
+
const nextPunc = findNextAsciiPunctuation(src, n, srcLen)
|
|
540
|
+
if (nextPunc === -1) {
|
|
541
|
+
if (textStart < srcLen) {
|
|
542
|
+
pushInlines(inlines, textStart, srcLen - 1, srcLen - textStart, 'text')
|
|
543
|
+
}
|
|
544
|
+
break
|
|
545
|
+
}
|
|
546
|
+
if (nextPunc > n) {
|
|
547
|
+
hasText = true
|
|
548
|
+
n = nextPunc
|
|
549
|
+
currentChar = src.charCodeAt(n)
|
|
483
550
|
}
|
|
484
|
-
break
|
|
485
551
|
}
|
|
486
552
|
|
|
487
|
-
const currentChar = src.charCodeAt(n)
|
|
488
|
-
|
|
489
553
|
// Unified escape check
|
|
490
554
|
let isEscaped = false
|
|
491
555
|
if (currentChar === CHAR_ASTERISK || currentChar === CHAR_BACKTICK ||
|
|
492
|
-
(
|
|
556
|
+
(dollarMath && currentChar === CHAR_DOLLAR) ||
|
|
493
557
|
(htmlEnabled && currentChar === CHAR_LT)) {
|
|
494
558
|
isEscaped = hasBackslash(state, n)
|
|
495
559
|
}
|
|
@@ -497,7 +561,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
497
561
|
// Asterisk handling
|
|
498
562
|
if (currentChar === CHAR_ASTERISK) {
|
|
499
563
|
if (!isEscaped) {
|
|
500
|
-
|
|
564
|
+
hasText = processTextSegment(inlines, textStart, n, hasText)
|
|
501
565
|
if (n === srcLen - 1) {
|
|
502
566
|
pushInlines(inlines, n, n, 1, '')
|
|
503
567
|
break
|
|
@@ -511,6 +575,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
511
575
|
} else {
|
|
512
576
|
pushInlines(inlines, n, i - 1, i - n, '')
|
|
513
577
|
textStart = i
|
|
578
|
+
hasText = false
|
|
514
579
|
}
|
|
515
580
|
n = i
|
|
516
581
|
continue
|
|
@@ -520,30 +585,30 @@ const createInlines = (state, start, max, opt) => {
|
|
|
520
585
|
// Inline code (backticks)
|
|
521
586
|
if (currentChar === CHAR_BACKTICK) {
|
|
522
587
|
if (!isEscaped) {
|
|
523
|
-
const result = processSymbolPair(state, n, srcLen, CHAR_BACKTICK,
|
|
588
|
+
const result = processSymbolPair(state, n, srcLen, CHAR_BACKTICK, '`', hasText, textStart,
|
|
524
589
|
(start, end, len, type) => pushInlines(inlines, start, end, len, type))
|
|
525
590
|
if (result.shouldBreak) break
|
|
526
591
|
if (result.shouldContinue) {
|
|
527
592
|
n = result.newN
|
|
528
|
-
|
|
593
|
+
hasText = result.hasText
|
|
529
594
|
continue
|
|
530
595
|
}
|
|
531
|
-
|
|
596
|
+
hasText = result.hasText
|
|
532
597
|
}
|
|
533
598
|
}
|
|
534
599
|
|
|
535
600
|
// Inline math ($...$)
|
|
536
|
-
if (
|
|
601
|
+
if (dollarMath && currentChar === CHAR_DOLLAR) {
|
|
537
602
|
if (!isEscaped) {
|
|
538
|
-
const result = processSymbolPair(state, n, srcLen, CHAR_DOLLAR,
|
|
603
|
+
const result = processSymbolPair(state, n, srcLen, CHAR_DOLLAR, '$', hasText, textStart,
|
|
539
604
|
(start, end, len, type) => pushInlines(inlines, start, end, len, type))
|
|
540
605
|
if (result.shouldBreak) break
|
|
541
606
|
if (result.shouldContinue) {
|
|
542
607
|
n = result.newN
|
|
543
|
-
|
|
608
|
+
hasText = result.hasText
|
|
544
609
|
continue
|
|
545
610
|
}
|
|
546
|
-
|
|
611
|
+
hasText = result.hasText
|
|
547
612
|
}
|
|
548
613
|
}
|
|
549
614
|
|
|
@@ -551,9 +616,12 @@ const createInlines = (state, start, max, opt) => {
|
|
|
551
616
|
if (htmlEnabled && currentChar === CHAR_LT) {
|
|
552
617
|
if (!isEscaped) {
|
|
553
618
|
let foundClosingTag = false
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
619
|
+
let i = n + 1
|
|
620
|
+
while (i < srcLen) {
|
|
621
|
+
i = src.indexOf('>', i)
|
|
622
|
+
if (i === -1 || i >= srcLen) break
|
|
623
|
+
if (!hasBackslash(state, i)) {
|
|
624
|
+
hasText = processTextSegment(inlines, textStart, n, hasText)
|
|
557
625
|
let tag = src.slice(n + 1, i)
|
|
558
626
|
let tagType
|
|
559
627
|
if (tag.charCodeAt(0) === CHAR_SLASH) {
|
|
@@ -564,10 +632,12 @@ const createInlines = (state, start, max, opt) => {
|
|
|
564
632
|
}
|
|
565
633
|
pushInlines(inlines, n, i, i - n + 1, 'html_inline', tag, tagType)
|
|
566
634
|
textStart = i + 1
|
|
635
|
+
hasText = false
|
|
567
636
|
n = i + 1
|
|
568
637
|
foundClosingTag = true
|
|
569
638
|
break
|
|
570
639
|
}
|
|
640
|
+
i += 1
|
|
571
641
|
}
|
|
572
642
|
if (foundClosingTag) {
|
|
573
643
|
continue
|
|
@@ -577,7 +647,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
577
647
|
}
|
|
578
648
|
|
|
579
649
|
// Regular character
|
|
580
|
-
|
|
650
|
+
hasText = true
|
|
581
651
|
if (n === srcLen - 1) {
|
|
582
652
|
pushInlines(inlines, textStart, n, n - textStart + 1, 'text')
|
|
583
653
|
break
|
|
@@ -597,6 +667,10 @@ const pushMark = (marks, opts) => {
|
|
|
597
667
|
oLen: opts.oLen,
|
|
598
668
|
type: opts.type
|
|
599
669
|
}
|
|
670
|
+
if (marks.length === 0 || marks[marks.length - 1].s <= newMark.s) {
|
|
671
|
+
marks.push(newMark)
|
|
672
|
+
return
|
|
673
|
+
}
|
|
600
674
|
// Binary search for insertion point to maintain sorted order
|
|
601
675
|
let left = 0
|
|
602
676
|
let right = marks.length
|
|
@@ -613,16 +687,17 @@ const pushMark = (marks, opts) => {
|
|
|
613
687
|
}
|
|
614
688
|
|
|
615
689
|
const setStrong = (state, inlines, marks, n, memo, opt, nestTracker, refRanges, inlineLinkRanges) => {
|
|
690
|
+
const hasInlineLinkRanges = inlineLinkRanges && inlineLinkRanges.length > 0
|
|
691
|
+
const hasRefRanges = refRanges && refRanges.length > 0
|
|
692
|
+
const inlinesLength = inlines.length
|
|
616
693
|
if (opt.disallowMixed === true) {
|
|
617
694
|
let i = n + 1
|
|
618
|
-
const inlinesLength = inlines.length
|
|
619
695
|
while (i < inlinesLength) {
|
|
620
696
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
621
697
|
if (inlines[i].type !== '') { i++; continue }
|
|
622
698
|
|
|
623
699
|
if (inlines[i].len > 1) {
|
|
624
|
-
|
|
625
|
-
if (mixedCheck.shouldBlock) {
|
|
700
|
+
if (shouldBlockMixedLanguage(state, inlines, n, i)) {
|
|
626
701
|
return [n, 0]
|
|
627
702
|
}
|
|
628
703
|
break
|
|
@@ -631,33 +706,25 @@ const setStrong = (state, inlines, marks, n, memo, opt, nestTracker, refRanges,
|
|
|
631
706
|
}
|
|
632
707
|
}
|
|
633
708
|
|
|
634
|
-
const strongOpenRange = findRefRangeIndex(inlines[n].s, refRanges)
|
|
635
|
-
const openLinkRange = findInlineLinkRange(inlines[n].s, inlineLinkRanges)
|
|
709
|
+
const strongOpenRange = hasRefRanges ? findRefRangeIndex(inlines[n].s, refRanges) : -1
|
|
710
|
+
const openLinkRange = hasInlineLinkRanges ? findInlineLinkRange(inlines[n].s, inlineLinkRanges) : null
|
|
636
711
|
let i = n + 1
|
|
637
712
|
let j = 0
|
|
638
713
|
let nest = 0
|
|
639
|
-
let insideTagsIsClose = 1
|
|
640
|
-
const inlinesLength = inlines.length
|
|
641
714
|
while (i < inlinesLength) {
|
|
642
715
|
if (inlines[i].type !== '') { i++; continue }
|
|
643
716
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
644
|
-
if (inlines[i].type === 'html_inline') {
|
|
645
|
-
inlines[i].check = true
|
|
646
|
-
insideTagsIsClose = checkInsideTags(inlines, i, memo)
|
|
647
|
-
if (insideTagsIsClose === -1) return [n, nest]
|
|
648
|
-
if (insideTagsIsClose === 0) { i++; continue }
|
|
649
|
-
}
|
|
650
717
|
|
|
651
|
-
if (
|
|
718
|
+
if (hasInlineLinkRanges &&
|
|
652
719
|
hasInlineLinkLabelCrossing(inlineLinkRanges, inlines[n].ep + 1, inlines[i].sp)) {
|
|
653
720
|
i++
|
|
654
721
|
continue
|
|
655
722
|
}
|
|
656
723
|
|
|
657
|
-
const closeRange = findRefRangeIndex(inlines[i].s, refRanges)
|
|
724
|
+
const closeRange = hasRefRanges ? findRefRangeIndex(inlines[i].s, refRanges) : -1
|
|
658
725
|
if (strongOpenRange !== closeRange) { i++; continue }
|
|
659
726
|
|
|
660
|
-
const closeLinkRange = findInlineLinkRange(inlines[i].s, inlineLinkRanges)
|
|
727
|
+
const closeLinkRange = hasInlineLinkRanges ? findInlineLinkRange(inlines[i].s, inlineLinkRanges) : null
|
|
661
728
|
if (openLinkRange || closeLinkRange) {
|
|
662
729
|
if (!openLinkRange || !closeLinkRange || openLinkRange.id !== closeLinkRange.id || openLinkRange.kind !== closeLinkRange.kind) {
|
|
663
730
|
i++
|
|
@@ -689,16 +756,14 @@ const setStrong = (state, inlines, marks, n, memo, opt, nestTracker, refRanges,
|
|
|
689
756
|
inlines[n].ep -= 1
|
|
690
757
|
inlines[i].len -= 1
|
|
691
758
|
if (inlines[i].len > 0) inlines[i].sp += 1
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
nest = newNest
|
|
696
|
-
}
|
|
759
|
+
const [newN, newNest] = setEm(state, inlines, marks, n, memo, opt, null, nestTracker, refRanges, inlineLinkRanges)
|
|
760
|
+
n = newN
|
|
761
|
+
nest = newNest
|
|
697
762
|
}
|
|
698
763
|
let strongNum = Math.trunc(Math.min(inlines[n].len, inlines[i].len) / 2)
|
|
699
764
|
|
|
700
765
|
if (inlines[i].len > 1) {
|
|
701
|
-
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges)) {
|
|
766
|
+
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges, hasRefRanges)) {
|
|
702
767
|
if (memo.inlineMarkEnd) {
|
|
703
768
|
marks.push(...createMarks(state, inlines, i, inlinesLength - 1, memo, opt, refRanges, inlineLinkRanges))
|
|
704
769
|
if (inlines[i].len === 0) { i++; continue }
|
|
@@ -756,21 +821,19 @@ const checkInsideTags = (inlines, i, memo) => {
|
|
|
756
821
|
if (memo.htmlTags[tagName] === undefined) {
|
|
757
822
|
memo.htmlTags[tagName] = 0
|
|
758
823
|
}
|
|
759
|
-
|
|
824
|
+
const tagType = inlines[i].tag[1]
|
|
825
|
+
if (tagType === 'open') {
|
|
760
826
|
memo.htmlTags[tagName] += 1
|
|
827
|
+
memo.htmlTagDepth += 1
|
|
761
828
|
}
|
|
762
|
-
if (
|
|
829
|
+
if (tagType === 'close') {
|
|
763
830
|
memo.htmlTags[tagName] -= 1
|
|
831
|
+
memo.htmlTagDepth -= 1
|
|
764
832
|
}
|
|
765
|
-
if (memo.htmlTags[tagName] < 0) {
|
|
833
|
+
if (memo.htmlTags[tagName] < 0 || memo.htmlTagDepth < 0) {
|
|
766
834
|
return -1
|
|
767
835
|
}
|
|
768
|
-
|
|
769
|
-
// Direct check instead of Object.values().every()
|
|
770
|
-
for (const count of Object.values(memo.htmlTags)) {
|
|
771
|
-
if (count !== 0) return 0
|
|
772
|
-
}
|
|
773
|
-
return 1
|
|
836
|
+
return memo.htmlTagDepth === 0 ? 1 : 0
|
|
774
837
|
}
|
|
775
838
|
|
|
776
839
|
// Check if character is ASCII punctuation or space
|
|
@@ -799,7 +862,7 @@ const isJapanese = (ch) => {
|
|
|
799
862
|
}
|
|
800
863
|
|
|
801
864
|
// Check if character is English (letters, numbers) or other non-Japanese characters
|
|
802
|
-
// Uses REG_JAPANESE
|
|
865
|
+
// Uses REG_JAPANESE to exclude Japanese characters
|
|
803
866
|
const isEnglish = (ch) => {
|
|
804
867
|
if (!ch) return false
|
|
805
868
|
const code = ch.charCodeAt(0)
|
|
@@ -809,10 +872,10 @@ const isEnglish = (ch) => {
|
|
|
809
872
|
if (code < 128) {
|
|
810
873
|
return code === CHAR_SPACE || (code > 126)
|
|
811
874
|
}
|
|
812
|
-
return !REG_JAPANESE.test(ch)
|
|
875
|
+
return !REG_JAPANESE.test(ch)
|
|
813
876
|
}
|
|
814
877
|
|
|
815
|
-
const
|
|
878
|
+
const shouldBlockMixedLanguage = (state, inlines, n, i) => {
|
|
816
879
|
const src = state.src
|
|
817
880
|
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
818
881
|
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
@@ -820,25 +883,17 @@ const checkMixedLanguagePattern = (state, inlines, n, i, opt) => {
|
|
|
820
883
|
const isEnglishPrefix = isEnglish(openPrevChar)
|
|
821
884
|
const isEnglishSuffix = isEnglish(closeNextChar)
|
|
822
885
|
if (!isEnglishPrefix && !isEnglishSuffix) {
|
|
823
|
-
return
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
const contentBetween = src.slice(inlines[n].e + 1, inlines[i].s)
|
|
827
|
-
const hasMarkdownOrHtml = REG_MARKDOWN_HTML.test(contentBetween)
|
|
828
|
-
|
|
829
|
-
return {
|
|
830
|
-
hasEnglishContext: true,
|
|
831
|
-
hasMarkdownOrHtml,
|
|
832
|
-
shouldBlock: hasMarkdownOrHtml
|
|
886
|
+
return false
|
|
833
887
|
}
|
|
888
|
+
return hasMarkdownHtmlPattern(src, inlines[n].e + 1, inlines[i].s)
|
|
834
889
|
}
|
|
835
890
|
|
|
836
|
-
const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges) => {
|
|
891
|
+
const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges, hasRefRanges) => {
|
|
837
892
|
const src = state.src
|
|
838
893
|
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
839
894
|
const openNextChar = src[inlines[n].e + 1] || ''
|
|
840
895
|
let checkOpenNextChar = isPunctuation(openNextChar)
|
|
841
|
-
if (checkOpenNextChar && (openNextChar === '[' || openNextChar === ']')) {
|
|
896
|
+
if (hasRefRanges && checkOpenNextChar && (openNextChar === '[' || openNextChar === ']')) {
|
|
842
897
|
const openNextRange = findRefRangeIndex(inlines[n].e + 1, refRanges)
|
|
843
898
|
if (openNextRange !== -1) {
|
|
844
899
|
checkOpenNextChar = false
|
|
@@ -846,19 +901,19 @@ const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges) => {
|
|
|
846
901
|
}
|
|
847
902
|
const closePrevChar = src[inlines[i].s - 1] || ''
|
|
848
903
|
let checkClosePrevChar = isPunctuation(closePrevChar)
|
|
849
|
-
if (checkClosePrevChar && (closePrevChar === '[' || closePrevChar === ']')) {
|
|
904
|
+
if (hasRefRanges && checkClosePrevChar && (closePrevChar === '[' || closePrevChar === ']')) {
|
|
850
905
|
const closePrevRange = findRefRangeIndex(inlines[i].s - 1, refRanges)
|
|
851
906
|
if (closePrevRange !== -1) {
|
|
852
907
|
checkClosePrevChar = false
|
|
853
908
|
}
|
|
854
909
|
}
|
|
855
910
|
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
856
|
-
const
|
|
911
|
+
const isLastInline = i === inlines.length - 1
|
|
912
|
+
const checkCloseNextChar = isLastInline || isPunctuation(closeNextChar) || closeNextChar === '\n'
|
|
857
913
|
|
|
858
914
|
if (opt.disallowMixed === false) {
|
|
859
915
|
if (isEnglish(openPrevChar) || isEnglish(closeNextChar)) {
|
|
860
|
-
|
|
861
|
-
if (REG_MARKDOWN_HTML.test(contentBetween)) {
|
|
916
|
+
if (hasMarkdownHtmlPattern(src, inlines[n].e + 1, inlines[i].s)) {
|
|
862
917
|
return false
|
|
863
918
|
}
|
|
864
919
|
}
|
|
@@ -869,18 +924,19 @@ const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges) => {
|
|
|
869
924
|
}
|
|
870
925
|
|
|
871
926
|
const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRanges, inlineLinkRanges) => {
|
|
872
|
-
const
|
|
873
|
-
const
|
|
927
|
+
const hasInlineLinkRanges = inlineLinkRanges && inlineLinkRanges.length > 0
|
|
928
|
+
const hasRefRanges = refRanges && refRanges.length > 0
|
|
929
|
+
const inlinesLength = inlines.length
|
|
930
|
+
const emOpenRange = hasRefRanges ? findRefRangeIndex(inlines[n].s, refRanges) : -1
|
|
931
|
+
const openLinkRange = hasInlineLinkRanges ? findInlineLinkRange(inlines[n].s, inlineLinkRanges) : null
|
|
874
932
|
if (opt.disallowMixed === true && !sNest) {
|
|
875
933
|
let i = n + 1
|
|
876
|
-
const inlinesLength = inlines.length
|
|
877
934
|
while (i < inlinesLength) {
|
|
878
935
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
879
936
|
if (inlines[i].type !== '') { i++; continue }
|
|
880
937
|
|
|
881
938
|
if (inlines[i].len > 0) {
|
|
882
|
-
|
|
883
|
-
if (mixedCheck.shouldBlock) {
|
|
939
|
+
if (shouldBlockMixedLanguage(state, inlines, n, i)) {
|
|
884
940
|
return [n, 0]
|
|
885
941
|
}
|
|
886
942
|
break
|
|
@@ -893,7 +949,6 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
893
949
|
let nest = 0
|
|
894
950
|
let strongPNum = 0
|
|
895
951
|
let insideTagsIsClose = 1
|
|
896
|
-
const inlinesLength = inlines.length
|
|
897
952
|
while (i < inlinesLength) {
|
|
898
953
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
899
954
|
if (!sNest && inlines[i].type === 'html_inline') {
|
|
@@ -904,19 +959,19 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
904
959
|
}
|
|
905
960
|
if (inlines[i].type !== '') { i++; continue }
|
|
906
961
|
|
|
907
|
-
if (
|
|
962
|
+
if (hasInlineLinkRanges &&
|
|
908
963
|
hasInlineLinkLabelCrossing(inlineLinkRanges, inlines[n].ep + 1, inlines[i].sp)) {
|
|
909
964
|
i++
|
|
910
965
|
continue
|
|
911
966
|
}
|
|
912
967
|
|
|
913
|
-
const closeRange = findRefRangeIndex(inlines[i].s, refRanges)
|
|
968
|
+
const closeRange = hasRefRanges ? findRefRangeIndex(inlines[i].s, refRanges) : -1
|
|
914
969
|
if (emOpenRange !== closeRange) {
|
|
915
970
|
i++
|
|
916
971
|
continue
|
|
917
972
|
}
|
|
918
973
|
|
|
919
|
-
const closeLinkRange = findInlineLinkRange(inlines[i].s, inlineLinkRanges)
|
|
974
|
+
const closeLinkRange = hasInlineLinkRanges ? findInlineLinkRange(inlines[i].s, inlineLinkRanges) : null
|
|
920
975
|
if (openLinkRange || closeLinkRange) {
|
|
921
976
|
if (!openLinkRange || !closeLinkRange || openLinkRange.id !== closeLinkRange.id || openLinkRange.kind !== closeLinkRange.kind) {
|
|
922
977
|
i++
|
|
@@ -928,15 +983,10 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
928
983
|
|
|
929
984
|
if (!sNest && emNum !== 1) return [n, sNest, memo]
|
|
930
985
|
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
if (!flag) return false
|
|
936
|
-
inlines[i].len > 1 ? flag = true : flag = false
|
|
937
|
-
return flag
|
|
938
|
-
}
|
|
939
|
-
if (!sNest && inlines[i].len === 2 && !hasMarkersAtStartAndEnd(i)) {
|
|
986
|
+
const isMarkerAtStartAndEnd = memo.inlineMarkStart &&
|
|
987
|
+
i === inlinesLength - 1 &&
|
|
988
|
+
inlines[i].len > 1
|
|
989
|
+
if (!sNest && inlines[i].len === 2 && !isMarkerAtStartAndEnd) {
|
|
940
990
|
strongPNum++
|
|
941
991
|
i++
|
|
942
992
|
continue
|
|
@@ -950,7 +1000,7 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
950
1000
|
if (nest === -1) return [n, nest]
|
|
951
1001
|
|
|
952
1002
|
if (emNum === 1) {
|
|
953
|
-
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges)) {
|
|
1003
|
+
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges, hasRefRanges)) {
|
|
954
1004
|
if (memo.inlineMarkEnd) {
|
|
955
1005
|
marks.push(...createMarks(state, inlines, i, inlinesLength - 1, memo, opt, refRanges, inlineLinkRanges))
|
|
956
1006
|
|
|
@@ -1102,7 +1152,33 @@ const mergeInlinesAndMarks = (inlines, marks) => {
|
|
|
1102
1152
|
return merged
|
|
1103
1153
|
}
|
|
1104
1154
|
|
|
1105
|
-
const isWhitespaceToken = (token) =>
|
|
1155
|
+
const isWhitespaceToken = (token) => {
|
|
1156
|
+
if (!token || token.type !== 'text') return false
|
|
1157
|
+
const content = token.content
|
|
1158
|
+
if (!content) return true
|
|
1159
|
+
for (let i = 0; i < content.length; i++) {
|
|
1160
|
+
if (!isWhiteSpace(content.charCodeAt(i))) return false
|
|
1161
|
+
}
|
|
1162
|
+
return true
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
const hasMarkdownHtmlPattern = (src, start, end) => {
|
|
1166
|
+
if (start >= end) return false
|
|
1167
|
+
const first = src.charCodeAt(start)
|
|
1168
|
+
const last = src.charCodeAt(end - 1)
|
|
1169
|
+
if (first === CHAR_OPEN_BRACKET) {
|
|
1170
|
+
if (last !== CHAR_CLOSE_PAREN) return false
|
|
1171
|
+
} else if (first === CHAR_LT) {
|
|
1172
|
+
if (last !== CHAR_GT) return false
|
|
1173
|
+
} else if (first === CHAR_BACKTICK) {
|
|
1174
|
+
if (last !== CHAR_BACKTICK) return false
|
|
1175
|
+
} else if (first === CHAR_DOLLAR) {
|
|
1176
|
+
if (last !== CHAR_DOLLAR) return false
|
|
1177
|
+
} else {
|
|
1178
|
+
return false
|
|
1179
|
+
}
|
|
1180
|
+
return REG_MARKDOWN_HTML.test(src.slice(start, end))
|
|
1181
|
+
}
|
|
1106
1182
|
|
|
1107
1183
|
const strongJa = (state, silent, opt) => {
|
|
1108
1184
|
if (silent) return false
|
|
@@ -1115,13 +1191,16 @@ const strongJa = (state, silent, opt) => {
|
|
|
1115
1191
|
if (src.charCodeAt(start) !== CHAR_ASTERISK) return false
|
|
1116
1192
|
if (hasBackslash(state, start)) return false
|
|
1117
1193
|
|
|
1194
|
+
const attrsEnabled = opt.mditAttrs && hasMditAttrs(state)
|
|
1195
|
+
|
|
1118
1196
|
if (start === 0) {
|
|
1119
1197
|
state.__strongJaRefRangeCache = null
|
|
1120
1198
|
state.__strongJaInlineLinkRangeCache = null
|
|
1121
1199
|
state.__strongJaBackslashCache = undefined
|
|
1200
|
+
state.__strongJaHasBackslash = undefined
|
|
1122
1201
|
}
|
|
1123
1202
|
|
|
1124
|
-
if (
|
|
1203
|
+
if (attrsEnabled) {
|
|
1125
1204
|
let attrCandidate = false
|
|
1126
1205
|
let probe = originalMax - 1
|
|
1127
1206
|
while (probe >= start) {
|
|
@@ -1158,7 +1237,8 @@ const strongJa = (state, silent, opt) => {
|
|
|
1158
1237
|
}
|
|
1159
1238
|
|
|
1160
1239
|
if (state.__strongJaHasCollapsedRefs === undefined) {
|
|
1161
|
-
state.__strongJaHasCollapsedRefs =
|
|
1240
|
+
state.__strongJaHasCollapsedRefs = src.indexOf('[') !== -1 &&
|
|
1241
|
+
/\[[^\]]*\]\s*\[[^\]]*\]/.test(src)
|
|
1162
1242
|
}
|
|
1163
1243
|
|
|
1164
1244
|
if (state.__strongJaReferenceCount === undefined) {
|
|
@@ -1201,6 +1281,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
1201
1281
|
const memo = {
|
|
1202
1282
|
html: state.md.options.html,
|
|
1203
1283
|
htmlTags: {},
|
|
1284
|
+
htmlTagDepth: 0,
|
|
1204
1285
|
inlineMarkStart: src.charCodeAt(0) === CHAR_ASTERISK,
|
|
1205
1286
|
inlineMarkEnd: src.charCodeAt(max - 1) === CHAR_ASTERISK,
|
|
1206
1287
|
}
|
|
@@ -1209,7 +1290,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
1209
1290
|
|
|
1210
1291
|
inlines = mergeInlinesAndMarks(inlines, marks)
|
|
1211
1292
|
|
|
1212
|
-
setToken(state, inlines, opt)
|
|
1293
|
+
setToken(state, inlines, opt, attrsEnabled)
|
|
1213
1294
|
|
|
1214
1295
|
if (inlineLinkRanges && inlineLinkRanges.length > 0) {
|
|
1215
1296
|
const labelSources = []
|
|
@@ -1231,7 +1312,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
1231
1312
|
state.__strongJaPostProcessRegistered = true
|
|
1232
1313
|
}
|
|
1233
1314
|
|
|
1234
|
-
if (
|
|
1315
|
+
if (attrsEnabled && max !== state.posMax) {
|
|
1235
1316
|
if (!attributesSrc) {
|
|
1236
1317
|
state.pos = max
|
|
1237
1318
|
return true
|
|
@@ -1244,9 +1325,12 @@ const strongJa = (state, silent, opt) => {
|
|
|
1244
1325
|
}
|
|
1245
1326
|
|
|
1246
1327
|
// Collapsed reference helpers
|
|
1247
|
-
const
|
|
1328
|
+
const buildReferenceLabelRange = (tokens, startIdx, endIdx) => {
|
|
1329
|
+
if (startIdx > endIdx) return ''
|
|
1248
1330
|
let label = ''
|
|
1249
|
-
for (
|
|
1331
|
+
for (let idx = startIdx; idx <= endIdx; idx++) {
|
|
1332
|
+
const token = tokens[idx]
|
|
1333
|
+
if (!token) continue
|
|
1250
1334
|
if (token.type === 'text' || token.type === 'code_inline') {
|
|
1251
1335
|
label += token.content
|
|
1252
1336
|
} else if (token.type === 'softbreak' || token.type === 'hardbreak') {
|
|
@@ -1261,11 +1345,12 @@ const buildReferenceLabel = (tokens) => {
|
|
|
1261
1345
|
}
|
|
1262
1346
|
|
|
1263
1347
|
const cleanLabelText = (label) => {
|
|
1348
|
+
if (label.indexOf('*') === -1 && label.indexOf('_') === -1) return label
|
|
1264
1349
|
return label.replace(/^[*_]+/, '').replace(/[*_]+$/, '')
|
|
1265
1350
|
}
|
|
1266
1351
|
|
|
1267
1352
|
const normalizeReferenceCandidate = (state, text, { useClean = false } = {}) => {
|
|
1268
|
-
const source = useClean ? cleanLabelText(text) : text
|
|
1353
|
+
const source = useClean ? cleanLabelText(text) : text
|
|
1269
1354
|
return normalizeRefKey(state, source)
|
|
1270
1355
|
}
|
|
1271
1356
|
|
|
@@ -1325,7 +1410,9 @@ const splitBracketToken = (tokens, index, options) => {
|
|
|
1325
1410
|
let buffer = ''
|
|
1326
1411
|
let pos = 0
|
|
1327
1412
|
while (pos < content.length) {
|
|
1328
|
-
if (!splitEmptyPair &&
|
|
1413
|
+
if (!splitEmptyPair &&
|
|
1414
|
+
content.charCodeAt(pos) === CHAR_OPEN_BRACKET &&
|
|
1415
|
+
content.charCodeAt(pos + 1) === CHAR_CLOSE_BRACKET) {
|
|
1329
1416
|
if (buffer) {
|
|
1330
1417
|
segments.push(buffer)
|
|
1331
1418
|
buffer = ''
|
|
@@ -1556,11 +1643,13 @@ const parseInlineLinkTail = (content, md) => {
|
|
|
1556
1643
|
|
|
1557
1644
|
const INLINE_LINK_BRACKET_SPLIT_OPTIONS = { splitEmptyPair: true }
|
|
1558
1645
|
|
|
1559
|
-
const removeGhostLabelText = (tokens,
|
|
1646
|
+
const removeGhostLabelText = (tokens, linkCloseIndex, labelText) => {
|
|
1560
1647
|
if (!labelText) return
|
|
1561
|
-
|
|
1562
|
-
if (
|
|
1563
|
-
|
|
1648
|
+
if (linkCloseIndex === null || linkCloseIndex === undefined) return
|
|
1649
|
+
if (linkCloseIndex < 0 || linkCloseIndex >= tokens.length) return
|
|
1650
|
+
const closeToken = tokens[linkCloseIndex]
|
|
1651
|
+
if (!closeToken || closeToken.type !== 'link_close') return
|
|
1652
|
+
let idx = linkCloseIndex + 1
|
|
1564
1653
|
while (idx < tokens.length) {
|
|
1565
1654
|
const token = tokens[idx]
|
|
1566
1655
|
if (!token) {
|
|
@@ -1627,6 +1716,7 @@ const convertInlineLinks = (tokens, state) => {
|
|
|
1627
1716
|
let tailIdx = closeIdx + 1
|
|
1628
1717
|
let tailContent = ''
|
|
1629
1718
|
let parsedTail = null
|
|
1719
|
+
let tailHasCloseParen = false
|
|
1630
1720
|
while (tailIdx < tokens.length) {
|
|
1631
1721
|
if (splitBracketToken(tokens, tailIdx, INLINE_LINK_BRACKET_SPLIT_OPTIONS)) {
|
|
1632
1722
|
continue
|
|
@@ -1636,6 +1726,13 @@ const convertInlineLinks = (tokens, state) => {
|
|
|
1636
1726
|
break
|
|
1637
1727
|
}
|
|
1638
1728
|
tailContent += tailToken.content
|
|
1729
|
+
if (!tailHasCloseParen) {
|
|
1730
|
+
if (tailToken.content.indexOf(')') === -1) {
|
|
1731
|
+
tailIdx++
|
|
1732
|
+
continue
|
|
1733
|
+
}
|
|
1734
|
+
tailHasCloseParen = true
|
|
1735
|
+
}
|
|
1639
1736
|
parsedTail = parseInlineLinkTail(tailContent, state.md)
|
|
1640
1737
|
if (parsedTail) break
|
|
1641
1738
|
tailIdx++
|
|
@@ -1669,7 +1766,7 @@ const convertInlineLinks = (tokens, state) => {
|
|
|
1669
1766
|
continue
|
|
1670
1767
|
}
|
|
1671
1768
|
if (needsPlaceholder && currentLabelSource) {
|
|
1672
|
-
removeGhostLabelText(tokens,
|
|
1769
|
+
removeGhostLabelText(tokens, nextIndex - 1, currentLabelSource)
|
|
1673
1770
|
}
|
|
1674
1771
|
|
|
1675
1772
|
if (labelSources && labelSources.length > 0) {
|
|
@@ -1724,8 +1821,10 @@ const convertCollapsedReferenceLinks = (tokens, state) => {
|
|
|
1724
1821
|
continue
|
|
1725
1822
|
}
|
|
1726
1823
|
|
|
1727
|
-
const
|
|
1728
|
-
const
|
|
1824
|
+
const labelStart = i + 1
|
|
1825
|
+
const labelEnd = closeIdx - 1
|
|
1826
|
+
const labelLength = closeIdx - i - 1
|
|
1827
|
+
const labelText = buildReferenceLabelRange(tokens, labelStart, labelEnd)
|
|
1729
1828
|
const cleanedLabel = cleanLabelText(labelText)
|
|
1730
1829
|
const whitespaceStart = closeIdx + 1
|
|
1731
1830
|
let refRemoveStart = whitespaceStart
|
|
@@ -1753,11 +1852,12 @@ const convertCollapsedReferenceLinks = (tokens, state) => {
|
|
|
1753
1852
|
i++
|
|
1754
1853
|
continue
|
|
1755
1854
|
}
|
|
1756
|
-
const
|
|
1757
|
-
|
|
1855
|
+
const refStart = refRemoveStart + 1
|
|
1856
|
+
const refEnd = refCloseIdx - 1
|
|
1857
|
+
if (refStart > refEnd) {
|
|
1758
1858
|
refKey = normalizeReferenceCandidate(state, cleanedLabel)
|
|
1759
1859
|
} else {
|
|
1760
|
-
const refLabelText =
|
|
1860
|
+
const refLabelText = buildReferenceLabelRange(tokens, refStart, refEnd)
|
|
1761
1861
|
refKey = normalizeReferenceCandidate(state, refLabelText)
|
|
1762
1862
|
}
|
|
1763
1863
|
refRemoveCount = refCloseIdx - refRemoveStart + 1
|
|
@@ -1815,7 +1915,7 @@ const convertCollapsedReferenceLinks = (tokens, state) => {
|
|
|
1815
1915
|
tokens.splice(closeIdx, 1)
|
|
1816
1916
|
tokens.splice(i, 1)
|
|
1817
1917
|
|
|
1818
|
-
const nextIndex = wrapLabelTokensWithLink(tokens, i, i +
|
|
1918
|
+
const nextIndex = wrapLabelTokensWithLink(tokens, i, i + labelLength - 1, linkOpenToken, linkCloseToken)
|
|
1819
1919
|
i = nextIndex
|
|
1820
1920
|
}
|
|
1821
1921
|
}
|
|
@@ -1889,6 +1989,22 @@ const mditStrongJa = (md, option) => {
|
|
|
1889
1989
|
if (!targets || targets.length === 0) return
|
|
1890
1990
|
for (const tokens of targets) {
|
|
1891
1991
|
if (!tokens || !tokens.length) continue
|
|
1992
|
+
let hasBracketText = false
|
|
1993
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
1994
|
+
const token = tokens[i]
|
|
1995
|
+
if (!token || token.type !== 'text') continue
|
|
1996
|
+
const content = token.content
|
|
1997
|
+
if (!content) continue
|
|
1998
|
+
if (content.indexOf('[') !== -1 || content.indexOf(']') !== -1) {
|
|
1999
|
+
hasBracketText = true
|
|
2000
|
+
break
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
if (!hasBracketText) {
|
|
2004
|
+
delete tokens.__strongJaInlineLabelSources
|
|
2005
|
+
delete tokens.__strongJaInlineLabelIndex
|
|
2006
|
+
continue
|
|
2007
|
+
}
|
|
1892
2008
|
convertInlineLinks(tokens, state)
|
|
1893
2009
|
convertCollapsedReferenceLinks(tokens, state)
|
|
1894
2010
|
mergeBrokenMarksAroundLinks(tokens)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-strong-ja",
|
|
3
3
|
"description": "This is a plugin for markdown-it. It is an alternative to the standard `**` (strong) and `*` (em) processing. It also processes strings that cannot be converted by the standard.",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.5",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
"markdown-it": "^14.1.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@peaceroad/markdown-it-
|
|
23
|
-
"@
|
|
24
|
-
"markdown-it-attrs": "^4.
|
|
22
|
+
"@peaceroad/markdown-it-cjk-breaks-mod": "^0.1.1",
|
|
23
|
+
"@peaceroad/markdown-it-hr-sandwiched-semantic-container": "^0.8.0",
|
|
24
|
+
"markdown-it-attrs": "^4.3.1",
|
|
25
|
+
"markdown-it-sub": "^2.0.0",
|
|
26
|
+
"markdown-it-sup": "^2.0.0"
|
|
25
27
|
}
|
|
26
28
|
}
|