@peaceroad/markdown-it-strong-ja 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/index.js +461 -207
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -172,3 +172,18 @@ md.render('string**[text](url)**')
|
|
|
172
172
|
// <p>string**<a href="url">text</a>**</p>
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
### coreRulesBeforePostprocess
|
|
176
|
+
|
|
177
|
+
`strong_ja_postprocess` runs inside the markdown-it core pipeline. When other plugins register core rules, you can keep their rules ahead of `strong_ja_postprocess` by listing them in `coreRulesBeforePostprocess`. Each name is normalized, deduplicated, and re-ordered once during plugin setup.
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
const md = mdit()
|
|
181
|
+
.use(cjkBreaks)
|
|
182
|
+
.use(mditStrongJa, {
|
|
183
|
+
coreRulesBeforePostprocess: ['cjk_breaks', 'my_custom_rule']
|
|
184
|
+
})
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- Default: `[]`
|
|
188
|
+
- Specify `['cjk_breaks']` (or other rule names) when you rely on plugins such as `@peaceroad/markdown-it-cjk-breaks-mod` and need them to run first.
|
|
189
|
+
- Pass an empty array if you do not want `mditStrongJa` to reorder any core rules.
|
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 // _
|
|
@@ -15,16 +15,24 @@ const CHAR_OPEN_BRACKET = 0x5B // [
|
|
|
15
15
|
const CHAR_CLOSE_BRACKET = 0x5D // ]
|
|
16
16
|
const CHAR_OPEN_PAREN = 0x28 // (
|
|
17
17
|
const CHAR_CLOSE_PAREN = 0x29 // )
|
|
18
|
+
const CHAR_NEWLINE = 0x0A // \n
|
|
19
|
+
const CHAR_TAB = 0x09 // tab
|
|
20
|
+
//const CHAR_OPEN_CURLY = 0x7B // {
|
|
21
|
+
const CHAR_CLOSE_CURLY = 0x7D // }
|
|
18
22
|
|
|
19
|
-
const REG_ASTERISKS = /^\*+$/
|
|
20
23
|
const REG_ATTRS = /{[^{}\n!@#%^&*()]+?}$/
|
|
21
|
-
const
|
|
24
|
+
const REG_ASCII_PUNCT = /[!-/:-@[-`{-~]/g
|
|
22
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 // ひらがな|カタカナ|漢字|句読点|記号|フォーマット文字|絵文字
|
|
23
26
|
|
|
24
27
|
const REG_MARKDOWN_HTML = /^\[[^\[\]]+\]\([^)]+\)$|^<([a-zA-Z][a-zA-Z0-9]*)[^>]*>([^<]+<\/\1>)$|^`[^`]+`$|^\$[^$]+\$$/ // for mixed-language context detection
|
|
25
28
|
|
|
26
29
|
const hasBackslash = (state, start) => {
|
|
27
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
|
+
}
|
|
28
36
|
const cache = state.__strongJaBackslashCache
|
|
29
37
|
if (cache && cache.has(start)) {
|
|
30
38
|
return cache.get(start)
|
|
@@ -169,12 +177,11 @@ const computeReferenceRanges = (state, start, max) => {
|
|
|
169
177
|
? referenceCount > 0
|
|
170
178
|
: Object.keys(references).length > 0)
|
|
171
179
|
if (!hasReferences) return []
|
|
172
|
-
|
|
173
|
-
if (
|
|
180
|
+
let pos = src.indexOf('[', start)
|
|
181
|
+
if (pos === -1 || pos >= max) return []
|
|
174
182
|
const ranges = []
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (src.charCodeAt(pos) === CHAR_OPEN_BRACKET && !hasBackslash(state, pos)) {
|
|
183
|
+
while (pos !== -1 && pos < max) {
|
|
184
|
+
if (!hasBackslash(state, pos)) {
|
|
178
185
|
const labelClose = findMatchingBracket(state, pos, max, CHAR_OPEN_BRACKET, CHAR_CLOSE_BRACKET)
|
|
179
186
|
if (labelClose !== -1) {
|
|
180
187
|
const nextPos = labelClose + 1
|
|
@@ -195,16 +202,13 @@ const computeReferenceRanges = (state, start, max) => {
|
|
|
195
202
|
ranges.push({ start: pos, end: labelClose, hasReference: true })
|
|
196
203
|
ranges.push({ start: nextPos, end: refClose, hasReference: true })
|
|
197
204
|
}
|
|
198
|
-
pos = refClose
|
|
205
|
+
pos = src.indexOf('[', refClose + 1)
|
|
199
206
|
continue
|
|
200
207
|
}
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
210
|
}
|
|
204
|
-
pos
|
|
205
|
-
}
|
|
206
|
-
if (ranges.length) {
|
|
207
|
-
ranges.__cache = new Map()
|
|
211
|
+
pos = src.indexOf('[', pos + 1)
|
|
208
212
|
}
|
|
209
213
|
return ranges
|
|
210
214
|
}
|
|
@@ -213,10 +217,11 @@ const computeInlineLinkRanges = (state, start, max) => {
|
|
|
213
217
|
const src = state.src
|
|
214
218
|
const ranges = []
|
|
215
219
|
const labelRanges = []
|
|
216
|
-
let pos = start
|
|
220
|
+
let pos = src.indexOf('[', start)
|
|
221
|
+
if (pos === -1 || pos >= max) return []
|
|
217
222
|
let rangeId = 0
|
|
218
|
-
while (pos < max) {
|
|
219
|
-
if (
|
|
223
|
+
while (pos !== -1 && pos < max) {
|
|
224
|
+
if (!hasBackslash(state, pos)) {
|
|
220
225
|
const labelClose = findMatchingBracket(state, pos, max, CHAR_OPEN_BRACKET, CHAR_CLOSE_BRACKET)
|
|
221
226
|
if (labelClose === -1) break
|
|
222
227
|
let destStart = labelClose + 1
|
|
@@ -233,14 +238,14 @@ const computeInlineLinkRanges = (state, start, max) => {
|
|
|
233
238
|
labelRanges.push(labelRange)
|
|
234
239
|
ranges.push({ start: destStart, end: destClose, kind: 'dest', id: rangeId })
|
|
235
240
|
rangeId++
|
|
236
|
-
pos = destClose + 1
|
|
241
|
+
pos = src.indexOf('[', destClose + 1)
|
|
237
242
|
continue
|
|
238
243
|
}
|
|
239
244
|
}
|
|
240
|
-
pos = labelClose + 1
|
|
245
|
+
pos = src.indexOf('[', labelClose + 1)
|
|
241
246
|
continue
|
|
242
247
|
}
|
|
243
|
-
pos
|
|
248
|
+
pos = src.indexOf('[', pos + 1)
|
|
244
249
|
}
|
|
245
250
|
if (ranges.length && labelRanges.length) {
|
|
246
251
|
ranges.__labelRanges = labelRanges
|
|
@@ -260,7 +265,8 @@ const getInlineRangeCacheMap = (ranges, kind, create) => {
|
|
|
260
265
|
|
|
261
266
|
const findInlineLinkRange = (pos, ranges, kind) => {
|
|
262
267
|
if (!ranges || ranges.length === 0) return null
|
|
263
|
-
const
|
|
268
|
+
const useCache = ranges.length > 32
|
|
269
|
+
const cache = useCache ? getInlineRangeCacheMap(ranges, kind, false) : null
|
|
264
270
|
if (cache && cache.has(pos)) return cache.get(pos)
|
|
265
271
|
let left = 0
|
|
266
272
|
let right = ranges.length - 1
|
|
@@ -279,8 +285,10 @@ const findInlineLinkRange = (pos, ranges, kind) => {
|
|
|
279
285
|
break
|
|
280
286
|
}
|
|
281
287
|
}
|
|
282
|
-
|
|
283
|
-
|
|
288
|
+
if (useCache) {
|
|
289
|
+
const storeCache = getInlineRangeCacheMap(ranges, kind, true)
|
|
290
|
+
storeCache.set(pos, found)
|
|
291
|
+
}
|
|
284
292
|
return found
|
|
285
293
|
}
|
|
286
294
|
|
|
@@ -314,24 +322,64 @@ const registerPostProcessTarget = (state) => {
|
|
|
314
322
|
targets.push(state.tokens)
|
|
315
323
|
}
|
|
316
324
|
|
|
317
|
-
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 || code === 0x0D) {
|
|
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) => {
|
|
318
361
|
const src = state.src
|
|
319
362
|
let i = 0
|
|
320
|
-
let attrsIsText =
|
|
321
|
-
|
|
322
|
-
tag: '',
|
|
323
|
-
}
|
|
363
|
+
let attrsIsText = false
|
|
364
|
+
let attrsIsTextTag = ''
|
|
324
365
|
while (i < inlines.length) {
|
|
325
366
|
let type = inlines[i].type
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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) {
|
|
329
379
|
const startToken = state.push(type, tag, 1)
|
|
330
380
|
startToken.markup = tag === 'strong' ? '**' : '*'
|
|
331
|
-
attrsIsText =
|
|
332
|
-
|
|
333
|
-
tag: tag,
|
|
334
|
-
}
|
|
381
|
+
attrsIsText = true
|
|
382
|
+
attrsIsTextTag = tag
|
|
335
383
|
}
|
|
336
384
|
|
|
337
385
|
if (type === 'html_inline') {
|
|
@@ -339,18 +387,23 @@ const setToken = (state, inlines, opt) => {
|
|
|
339
387
|
}
|
|
340
388
|
if (type === 'text') {
|
|
341
389
|
let content = src.slice(inlines[i].s, inlines[i].e + 1)
|
|
342
|
-
if (
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
+
}
|
|
347
397
|
}
|
|
348
|
-
if (
|
|
349
|
-
const hasImmediatelyAfterAsteriskClose = inlines[i+1].type ===
|
|
350
|
-
|
|
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)) {
|
|
351
402
|
const attrsToken = state.push(type, '', 0)
|
|
352
|
-
|
|
353
|
-
|
|
403
|
+
let hasBackslashBeforeCurlyAttribute = null
|
|
404
|
+
if (content.indexOf('\\') !== -1) {
|
|
405
|
+
hasBackslashBeforeCurlyAttribute = content.match(/(\\+){/)
|
|
406
|
+
}
|
|
354
407
|
if (hasBackslashBeforeCurlyAttribute) {
|
|
355
408
|
if (hasBackslashBeforeCurlyAttribute[1].length === 1) {
|
|
356
409
|
attrsToken.content = content.replace(/\\{/, '{')
|
|
@@ -367,11 +420,18 @@ const setToken = (state, inlines, opt) => {
|
|
|
367
420
|
} else {
|
|
368
421
|
attrsToken.content = content
|
|
369
422
|
}
|
|
370
|
-
attrsIsText
|
|
423
|
+
attrsIsText = false
|
|
424
|
+
attrsIsTextTag = ''
|
|
371
425
|
i++
|
|
372
426
|
continue
|
|
373
427
|
}
|
|
374
428
|
}
|
|
429
|
+
if (isPlainTextContent(content)) {
|
|
430
|
+
const textToken = state.push(type, '', 0)
|
|
431
|
+
textToken.content = content
|
|
432
|
+
i++
|
|
433
|
+
continue
|
|
434
|
+
}
|
|
375
435
|
|
|
376
436
|
const childTokens = state.md.parseInline(content, state.env)
|
|
377
437
|
if (childTokens[0] && childTokens[0].children) {
|
|
@@ -383,7 +443,7 @@ const setToken = (state, inlines, opt) => {
|
|
|
383
443
|
t.tag = ''
|
|
384
444
|
t.content = '\n'
|
|
385
445
|
}
|
|
386
|
-
if (!
|
|
446
|
+
if (!attrsEnabled && t.tag === 'br') {
|
|
387
447
|
t.tag = ''
|
|
388
448
|
t.content = '\n'
|
|
389
449
|
}
|
|
@@ -394,13 +454,11 @@ const setToken = (state, inlines, opt) => {
|
|
|
394
454
|
}
|
|
395
455
|
}
|
|
396
456
|
|
|
397
|
-
if (
|
|
457
|
+
if (isClose) {
|
|
398
458
|
const closeToken = state.push(type, tag, -1)
|
|
399
459
|
closeToken.markup = tag === 'strong' ? '**' : '*'
|
|
400
|
-
attrsIsText =
|
|
401
|
-
|
|
402
|
-
tag: '',
|
|
403
|
-
}
|
|
460
|
+
attrsIsText = false
|
|
461
|
+
attrsIsTextTag = ''
|
|
404
462
|
}
|
|
405
463
|
|
|
406
464
|
i++
|
|
@@ -421,71 +479,81 @@ const pushInlines = (inlines, s, e, len, type, tag, tagType) => {
|
|
|
421
479
|
inlines.push(inline)
|
|
422
480
|
}
|
|
423
481
|
|
|
424
|
-
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) => {
|
|
425
495
|
const src = state.src
|
|
426
496
|
if (src.charCodeAt(n) !== symbol || hasBackslash(state, n)) return -1
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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)
|
|
431
501
|
}
|
|
432
502
|
return -1
|
|
433
503
|
}
|
|
434
504
|
|
|
435
|
-
const processSymbolPair = (state, n, srcLen, symbol,
|
|
436
|
-
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)
|
|
437
507
|
if (nextSymbolPos === -1) {
|
|
438
|
-
return { shouldBreak: false, shouldContinue: false, newN: n,
|
|
508
|
+
return { shouldBreak: false, shouldContinue: false, newN: n, hasText: hasText }
|
|
439
509
|
}
|
|
440
|
-
const src = state.src
|
|
441
|
-
const innerText = src.slice(n + 1, nextSymbolPos)
|
|
442
|
-
const markup = src.slice(n, nextSymbolPos + 1)
|
|
443
|
-
const newNoMark = noMark + innerText + markup
|
|
444
510
|
if (nextSymbolPos === srcLen - 1) {
|
|
445
511
|
pushInlines(textStart, nextSymbolPos, nextSymbolPos - textStart + 1, 'text')
|
|
446
|
-
return { shouldBreak: true, newN: nextSymbolPos + 1,
|
|
512
|
+
return { shouldBreak: true, newN: nextSymbolPos + 1, hasText: true }
|
|
447
513
|
}
|
|
448
|
-
return { shouldBreak: false, shouldContinue: true, newN: nextSymbolPos + 1,
|
|
514
|
+
return { shouldBreak: false, shouldContinue: true, newN: nextSymbolPos + 1, hasText: true }
|
|
449
515
|
}
|
|
450
516
|
|
|
451
|
-
const processTextSegment = (inlines, textStart, n,
|
|
452
|
-
if (n !== 0 &&
|
|
517
|
+
const processTextSegment = (inlines, textStart, n, hasText) => {
|
|
518
|
+
if (n !== 0 && hasText) {
|
|
453
519
|
pushInlines(inlines, textStart, n - 1, n - textStart, 'text')
|
|
454
|
-
return
|
|
520
|
+
return false
|
|
455
521
|
}
|
|
456
|
-
return
|
|
522
|
+
return hasText
|
|
457
523
|
}
|
|
458
524
|
|
|
459
525
|
const createInlines = (state, start, max, opt) => {
|
|
460
526
|
const src = state.src
|
|
461
527
|
const srcLen = max
|
|
462
528
|
const htmlEnabled = state.md.options.html
|
|
529
|
+
const dollarMath = opt.dollarMath
|
|
463
530
|
let n = start
|
|
464
531
|
let inlines = []
|
|
465
|
-
let
|
|
532
|
+
let hasText = false
|
|
466
533
|
let textStart = n
|
|
467
534
|
|
|
468
|
-
// Infinite loop prevention
|
|
469
|
-
const maxIterations = srcLen * 2 // Safe upper bound
|
|
470
|
-
let iterations = 0
|
|
471
|
-
|
|
472
535
|
while (n < srcLen) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
if (
|
|
476
|
-
|
|
477
|
-
if (
|
|
478
|
-
|
|
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)
|
|
479
550
|
}
|
|
480
|
-
break
|
|
481
551
|
}
|
|
482
552
|
|
|
483
|
-
const currentChar = src.charCodeAt(n)
|
|
484
|
-
|
|
485
553
|
// Unified escape check
|
|
486
554
|
let isEscaped = false
|
|
487
555
|
if (currentChar === CHAR_ASTERISK || currentChar === CHAR_BACKTICK ||
|
|
488
|
-
(
|
|
556
|
+
(dollarMath && currentChar === CHAR_DOLLAR) ||
|
|
489
557
|
(htmlEnabled && currentChar === CHAR_LT)) {
|
|
490
558
|
isEscaped = hasBackslash(state, n)
|
|
491
559
|
}
|
|
@@ -493,7 +561,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
493
561
|
// Asterisk handling
|
|
494
562
|
if (currentChar === CHAR_ASTERISK) {
|
|
495
563
|
if (!isEscaped) {
|
|
496
|
-
|
|
564
|
+
hasText = processTextSegment(inlines, textStart, n, hasText)
|
|
497
565
|
if (n === srcLen - 1) {
|
|
498
566
|
pushInlines(inlines, n, n, 1, '')
|
|
499
567
|
break
|
|
@@ -507,6 +575,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
507
575
|
} else {
|
|
508
576
|
pushInlines(inlines, n, i - 1, i - n, '')
|
|
509
577
|
textStart = i
|
|
578
|
+
hasText = false
|
|
510
579
|
}
|
|
511
580
|
n = i
|
|
512
581
|
continue
|
|
@@ -516,30 +585,30 @@ const createInlines = (state, start, max, opt) => {
|
|
|
516
585
|
// Inline code (backticks)
|
|
517
586
|
if (currentChar === CHAR_BACKTICK) {
|
|
518
587
|
if (!isEscaped) {
|
|
519
|
-
const result = processSymbolPair(state, n, srcLen, CHAR_BACKTICK,
|
|
588
|
+
const result = processSymbolPair(state, n, srcLen, CHAR_BACKTICK, '`', hasText, textStart,
|
|
520
589
|
(start, end, len, type) => pushInlines(inlines, start, end, len, type))
|
|
521
590
|
if (result.shouldBreak) break
|
|
522
591
|
if (result.shouldContinue) {
|
|
523
592
|
n = result.newN
|
|
524
|
-
|
|
593
|
+
hasText = result.hasText
|
|
525
594
|
continue
|
|
526
595
|
}
|
|
527
|
-
|
|
596
|
+
hasText = result.hasText
|
|
528
597
|
}
|
|
529
598
|
}
|
|
530
599
|
|
|
531
600
|
// Inline math ($...$)
|
|
532
|
-
if (
|
|
601
|
+
if (dollarMath && currentChar === CHAR_DOLLAR) {
|
|
533
602
|
if (!isEscaped) {
|
|
534
|
-
const result = processSymbolPair(state, n, srcLen, CHAR_DOLLAR,
|
|
603
|
+
const result = processSymbolPair(state, n, srcLen, CHAR_DOLLAR, '$', hasText, textStart,
|
|
535
604
|
(start, end, len, type) => pushInlines(inlines, start, end, len, type))
|
|
536
605
|
if (result.shouldBreak) break
|
|
537
606
|
if (result.shouldContinue) {
|
|
538
607
|
n = result.newN
|
|
539
|
-
|
|
608
|
+
hasText = result.hasText
|
|
540
609
|
continue
|
|
541
610
|
}
|
|
542
|
-
|
|
611
|
+
hasText = result.hasText
|
|
543
612
|
}
|
|
544
613
|
}
|
|
545
614
|
|
|
@@ -547,9 +616,12 @@ const createInlines = (state, start, max, opt) => {
|
|
|
547
616
|
if (htmlEnabled && currentChar === CHAR_LT) {
|
|
548
617
|
if (!isEscaped) {
|
|
549
618
|
let foundClosingTag = false
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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)
|
|
553
625
|
let tag = src.slice(n + 1, i)
|
|
554
626
|
let tagType
|
|
555
627
|
if (tag.charCodeAt(0) === CHAR_SLASH) {
|
|
@@ -560,10 +632,12 @@ const createInlines = (state, start, max, opt) => {
|
|
|
560
632
|
}
|
|
561
633
|
pushInlines(inlines, n, i, i - n + 1, 'html_inline', tag, tagType)
|
|
562
634
|
textStart = i + 1
|
|
635
|
+
hasText = false
|
|
563
636
|
n = i + 1
|
|
564
637
|
foundClosingTag = true
|
|
565
638
|
break
|
|
566
639
|
}
|
|
640
|
+
i += 1
|
|
567
641
|
}
|
|
568
642
|
if (foundClosingTag) {
|
|
569
643
|
continue
|
|
@@ -573,7 +647,7 @@ const createInlines = (state, start, max, opt) => {
|
|
|
573
647
|
}
|
|
574
648
|
|
|
575
649
|
// Regular character
|
|
576
|
-
|
|
650
|
+
hasText = true
|
|
577
651
|
if (n === srcLen - 1) {
|
|
578
652
|
pushInlines(inlines, textStart, n, n - textStart + 1, 'text')
|
|
579
653
|
break
|
|
@@ -593,6 +667,10 @@ const pushMark = (marks, opts) => {
|
|
|
593
667
|
oLen: opts.oLen,
|
|
594
668
|
type: opts.type
|
|
595
669
|
}
|
|
670
|
+
if (marks.length === 0 || marks[marks.length - 1].s <= newMark.s) {
|
|
671
|
+
marks.push(newMark)
|
|
672
|
+
return
|
|
673
|
+
}
|
|
596
674
|
// Binary search for insertion point to maintain sorted order
|
|
597
675
|
let left = 0
|
|
598
676
|
let right = marks.length
|
|
@@ -609,16 +687,17 @@ const pushMark = (marks, opts) => {
|
|
|
609
687
|
}
|
|
610
688
|
|
|
611
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
|
|
612
693
|
if (opt.disallowMixed === true) {
|
|
613
694
|
let i = n + 1
|
|
614
|
-
const inlinesLength = inlines.length
|
|
615
695
|
while (i < inlinesLength) {
|
|
616
696
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
617
697
|
if (inlines[i].type !== '') { i++; continue }
|
|
618
698
|
|
|
619
699
|
if (inlines[i].len > 1) {
|
|
620
|
-
|
|
621
|
-
if (mixedCheck.shouldBlock) {
|
|
700
|
+
if (shouldBlockMixedLanguage(state, inlines, n, i)) {
|
|
622
701
|
return [n, 0]
|
|
623
702
|
}
|
|
624
703
|
break
|
|
@@ -627,33 +706,25 @@ const setStrong = (state, inlines, marks, n, memo, opt, nestTracker, refRanges,
|
|
|
627
706
|
}
|
|
628
707
|
}
|
|
629
708
|
|
|
630
|
-
const strongOpenRange = findRefRangeIndex(inlines[n].s, refRanges)
|
|
631
|
-
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
|
|
632
711
|
let i = n + 1
|
|
633
712
|
let j = 0
|
|
634
713
|
let nest = 0
|
|
635
|
-
let insideTagsIsClose = 1
|
|
636
|
-
const inlinesLength = inlines.length
|
|
637
714
|
while (i < inlinesLength) {
|
|
638
715
|
if (inlines[i].type !== '') { i++; continue }
|
|
639
716
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
640
|
-
if (inlines[i].type === 'html_inline') {
|
|
641
|
-
inlines[i].check = true
|
|
642
|
-
insideTagsIsClose = checkInsideTags(inlines, i, memo)
|
|
643
|
-
if (insideTagsIsClose === -1) return [n, nest]
|
|
644
|
-
if (insideTagsIsClose === 0) { i++; continue }
|
|
645
|
-
}
|
|
646
717
|
|
|
647
|
-
if (
|
|
718
|
+
if (hasInlineLinkRanges &&
|
|
648
719
|
hasInlineLinkLabelCrossing(inlineLinkRanges, inlines[n].ep + 1, inlines[i].sp)) {
|
|
649
720
|
i++
|
|
650
721
|
continue
|
|
651
722
|
}
|
|
652
723
|
|
|
653
|
-
const closeRange = findRefRangeIndex(inlines[i].s, refRanges)
|
|
724
|
+
const closeRange = hasRefRanges ? findRefRangeIndex(inlines[i].s, refRanges) : -1
|
|
654
725
|
if (strongOpenRange !== closeRange) { i++; continue }
|
|
655
726
|
|
|
656
|
-
const closeLinkRange = findInlineLinkRange(inlines[i].s, inlineLinkRanges)
|
|
727
|
+
const closeLinkRange = hasInlineLinkRanges ? findInlineLinkRange(inlines[i].s, inlineLinkRanges) : null
|
|
657
728
|
if (openLinkRange || closeLinkRange) {
|
|
658
729
|
if (!openLinkRange || !closeLinkRange || openLinkRange.id !== closeLinkRange.id || openLinkRange.kind !== closeLinkRange.kind) {
|
|
659
730
|
i++
|
|
@@ -685,16 +756,14 @@ const setStrong = (state, inlines, marks, n, memo, opt, nestTracker, refRanges,
|
|
|
685
756
|
inlines[n].ep -= 1
|
|
686
757
|
inlines[i].len -= 1
|
|
687
758
|
if (inlines[i].len > 0) inlines[i].sp += 1
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
nest = newNest
|
|
692
|
-
}
|
|
759
|
+
const [newN, newNest] = setEm(state, inlines, marks, n, memo, opt, null, nestTracker, refRanges, inlineLinkRanges)
|
|
760
|
+
n = newN
|
|
761
|
+
nest = newNest
|
|
693
762
|
}
|
|
694
763
|
let strongNum = Math.trunc(Math.min(inlines[n].len, inlines[i].len) / 2)
|
|
695
764
|
|
|
696
765
|
if (inlines[i].len > 1) {
|
|
697
|
-
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges)) {
|
|
766
|
+
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges, hasRefRanges)) {
|
|
698
767
|
if (memo.inlineMarkEnd) {
|
|
699
768
|
marks.push(...createMarks(state, inlines, i, inlinesLength - 1, memo, opt, refRanges, inlineLinkRanges))
|
|
700
769
|
if (inlines[i].len === 0) { i++; continue }
|
|
@@ -752,21 +821,19 @@ const checkInsideTags = (inlines, i, memo) => {
|
|
|
752
821
|
if (memo.htmlTags[tagName] === undefined) {
|
|
753
822
|
memo.htmlTags[tagName] = 0
|
|
754
823
|
}
|
|
755
|
-
|
|
824
|
+
const tagType = inlines[i].tag[1]
|
|
825
|
+
if (tagType === 'open') {
|
|
756
826
|
memo.htmlTags[tagName] += 1
|
|
827
|
+
memo.htmlTagDepth += 1
|
|
757
828
|
}
|
|
758
|
-
if (
|
|
829
|
+
if (tagType === 'close') {
|
|
759
830
|
memo.htmlTags[tagName] -= 1
|
|
831
|
+
memo.htmlTagDepth -= 1
|
|
760
832
|
}
|
|
761
|
-
if (memo.htmlTags[tagName] < 0) {
|
|
833
|
+
if (memo.htmlTags[tagName] < 0 || memo.htmlTagDepth < 0) {
|
|
762
834
|
return -1
|
|
763
835
|
}
|
|
764
|
-
|
|
765
|
-
// Direct check instead of Object.values().every()
|
|
766
|
-
for (const count of Object.values(memo.htmlTags)) {
|
|
767
|
-
if (count !== 0) return 0
|
|
768
|
-
}
|
|
769
|
-
return 1
|
|
836
|
+
return memo.htmlTagDepth === 0 ? 1 : 0
|
|
770
837
|
}
|
|
771
838
|
|
|
772
839
|
// Check if character is ASCII punctuation or space
|
|
@@ -795,7 +862,7 @@ const isJapanese = (ch) => {
|
|
|
795
862
|
}
|
|
796
863
|
|
|
797
864
|
// Check if character is English (letters, numbers) or other non-Japanese characters
|
|
798
|
-
// Uses REG_JAPANESE
|
|
865
|
+
// Uses REG_JAPANESE to exclude Japanese characters
|
|
799
866
|
const isEnglish = (ch) => {
|
|
800
867
|
if (!ch) return false
|
|
801
868
|
const code = ch.charCodeAt(0)
|
|
@@ -805,10 +872,10 @@ const isEnglish = (ch) => {
|
|
|
805
872
|
if (code < 128) {
|
|
806
873
|
return code === CHAR_SPACE || (code > 126)
|
|
807
874
|
}
|
|
808
|
-
return !REG_JAPANESE.test(ch)
|
|
875
|
+
return !REG_JAPANESE.test(ch)
|
|
809
876
|
}
|
|
810
877
|
|
|
811
|
-
const
|
|
878
|
+
const shouldBlockMixedLanguage = (state, inlines, n, i) => {
|
|
812
879
|
const src = state.src
|
|
813
880
|
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
814
881
|
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
@@ -816,25 +883,17 @@ const checkMixedLanguagePattern = (state, inlines, n, i, opt) => {
|
|
|
816
883
|
const isEnglishPrefix = isEnglish(openPrevChar)
|
|
817
884
|
const isEnglishSuffix = isEnglish(closeNextChar)
|
|
818
885
|
if (!isEnglishPrefix && !isEnglishSuffix) {
|
|
819
|
-
return
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
const contentBetween = src.slice(inlines[n].e + 1, inlines[i].s)
|
|
823
|
-
const hasMarkdownOrHtml = REG_MARKDOWN_HTML.test(contentBetween)
|
|
824
|
-
|
|
825
|
-
return {
|
|
826
|
-
hasEnglishContext: true,
|
|
827
|
-
hasMarkdownOrHtml,
|
|
828
|
-
shouldBlock: hasMarkdownOrHtml
|
|
886
|
+
return false
|
|
829
887
|
}
|
|
888
|
+
return hasMarkdownHtmlPattern(src, inlines[n].e + 1, inlines[i].s)
|
|
830
889
|
}
|
|
831
890
|
|
|
832
|
-
const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges) => {
|
|
891
|
+
const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges, hasRefRanges) => {
|
|
833
892
|
const src = state.src
|
|
834
893
|
const openPrevChar = src[inlines[n].s - 1] || ''
|
|
835
894
|
const openNextChar = src[inlines[n].e + 1] || ''
|
|
836
895
|
let checkOpenNextChar = isPunctuation(openNextChar)
|
|
837
|
-
if (checkOpenNextChar && (openNextChar === '[' || openNextChar === ']')) {
|
|
896
|
+
if (hasRefRanges && checkOpenNextChar && (openNextChar === '[' || openNextChar === ']')) {
|
|
838
897
|
const openNextRange = findRefRangeIndex(inlines[n].e + 1, refRanges)
|
|
839
898
|
if (openNextRange !== -1) {
|
|
840
899
|
checkOpenNextChar = false
|
|
@@ -842,19 +901,19 @@ const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges) => {
|
|
|
842
901
|
}
|
|
843
902
|
const closePrevChar = src[inlines[i].s - 1] || ''
|
|
844
903
|
let checkClosePrevChar = isPunctuation(closePrevChar)
|
|
845
|
-
if (checkClosePrevChar && (closePrevChar === '[' || closePrevChar === ']')) {
|
|
904
|
+
if (hasRefRanges && checkClosePrevChar && (closePrevChar === '[' || closePrevChar === ']')) {
|
|
846
905
|
const closePrevRange = findRefRangeIndex(inlines[i].s - 1, refRanges)
|
|
847
906
|
if (closePrevRange !== -1) {
|
|
848
907
|
checkClosePrevChar = false
|
|
849
908
|
}
|
|
850
909
|
}
|
|
851
910
|
const closeNextChar = src[inlines[i].e + 1] || ''
|
|
852
|
-
const
|
|
911
|
+
const isLastInline = i === inlines.length - 1
|
|
912
|
+
const checkCloseNextChar = isLastInline || isPunctuation(closeNextChar)
|
|
853
913
|
|
|
854
914
|
if (opt.disallowMixed === false) {
|
|
855
915
|
if (isEnglish(openPrevChar) || isEnglish(closeNextChar)) {
|
|
856
|
-
|
|
857
|
-
if (REG_MARKDOWN_HTML.test(contentBetween)) {
|
|
916
|
+
if (hasMarkdownHtmlPattern(src, inlines[n].e + 1, inlines[i].s)) {
|
|
858
917
|
return false
|
|
859
918
|
}
|
|
860
919
|
}
|
|
@@ -865,18 +924,19 @@ const hasPunctuationOrNonJapanese = (state, inlines, n, i, opt, refRanges) => {
|
|
|
865
924
|
}
|
|
866
925
|
|
|
867
926
|
const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRanges, inlineLinkRanges) => {
|
|
868
|
-
const
|
|
869
|
-
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
|
|
870
932
|
if (opt.disallowMixed === true && !sNest) {
|
|
871
933
|
let i = n + 1
|
|
872
|
-
const inlinesLength = inlines.length
|
|
873
934
|
while (i < inlinesLength) {
|
|
874
935
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
875
936
|
if (inlines[i].type !== '') { i++; continue }
|
|
876
937
|
|
|
877
938
|
if (inlines[i].len > 0) {
|
|
878
|
-
|
|
879
|
-
if (mixedCheck.shouldBlock) {
|
|
939
|
+
if (shouldBlockMixedLanguage(state, inlines, n, i)) {
|
|
880
940
|
return [n, 0]
|
|
881
941
|
}
|
|
882
942
|
break
|
|
@@ -889,7 +949,6 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
889
949
|
let nest = 0
|
|
890
950
|
let strongPNum = 0
|
|
891
951
|
let insideTagsIsClose = 1
|
|
892
|
-
const inlinesLength = inlines.length
|
|
893
952
|
while (i < inlinesLength) {
|
|
894
953
|
if (inlines[i].len === 0 || inlines[i].check) { i++; continue }
|
|
895
954
|
if (!sNest && inlines[i].type === 'html_inline') {
|
|
@@ -900,19 +959,19 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
900
959
|
}
|
|
901
960
|
if (inlines[i].type !== '') { i++; continue }
|
|
902
961
|
|
|
903
|
-
if (
|
|
962
|
+
if (hasInlineLinkRanges &&
|
|
904
963
|
hasInlineLinkLabelCrossing(inlineLinkRanges, inlines[n].ep + 1, inlines[i].sp)) {
|
|
905
964
|
i++
|
|
906
965
|
continue
|
|
907
966
|
}
|
|
908
967
|
|
|
909
|
-
const closeRange = findRefRangeIndex(inlines[i].s, refRanges)
|
|
968
|
+
const closeRange = hasRefRanges ? findRefRangeIndex(inlines[i].s, refRanges) : -1
|
|
910
969
|
if (emOpenRange !== closeRange) {
|
|
911
970
|
i++
|
|
912
971
|
continue
|
|
913
972
|
}
|
|
914
973
|
|
|
915
|
-
const closeLinkRange = findInlineLinkRange(inlines[i].s, inlineLinkRanges)
|
|
974
|
+
const closeLinkRange = hasInlineLinkRanges ? findInlineLinkRange(inlines[i].s, inlineLinkRanges) : null
|
|
916
975
|
if (openLinkRange || closeLinkRange) {
|
|
917
976
|
if (!openLinkRange || !closeLinkRange || openLinkRange.id !== closeLinkRange.id || openLinkRange.kind !== closeLinkRange.kind) {
|
|
918
977
|
i++
|
|
@@ -924,15 +983,10 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
924
983
|
|
|
925
984
|
if (!sNest && emNum !== 1) return [n, sNest, memo]
|
|
926
985
|
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
if (!flag) return false
|
|
932
|
-
inlines[i].len > 1 ? flag = true : flag = false
|
|
933
|
-
return flag
|
|
934
|
-
}
|
|
935
|
-
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) {
|
|
936
990
|
strongPNum++
|
|
937
991
|
i++
|
|
938
992
|
continue
|
|
@@ -946,7 +1000,7 @@ const setEm = (state, inlines, marks, n, memo, opt, sNest, nestTracker, refRange
|
|
|
946
1000
|
if (nest === -1) return [n, nest]
|
|
947
1001
|
|
|
948
1002
|
if (emNum === 1) {
|
|
949
|
-
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges)) {
|
|
1003
|
+
if (hasPunctuationOrNonJapanese(state, inlines, n, i, opt, refRanges, hasRefRanges)) {
|
|
950
1004
|
if (memo.inlineMarkEnd) {
|
|
951
1005
|
marks.push(...createMarks(state, inlines, i, inlinesLength - 1, memo, opt, refRanges, inlineLinkRanges))
|
|
952
1006
|
|
|
@@ -1098,44 +1152,93 @@ const mergeInlinesAndMarks = (inlines, marks) => {
|
|
|
1098
1152
|
return merged
|
|
1099
1153
|
}
|
|
1100
1154
|
|
|
1101
|
-
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
|
+
}
|
|
1102
1182
|
|
|
1103
1183
|
const strongJa = (state, silent, opt) => {
|
|
1104
1184
|
if (silent) return false
|
|
1105
1185
|
const start = state.pos
|
|
1106
1186
|
let max = state.posMax
|
|
1187
|
+
const originalMax = max
|
|
1107
1188
|
const src = state.src
|
|
1108
1189
|
let attributesSrc
|
|
1109
1190
|
if (start > max) return false
|
|
1110
1191
|
if (src.charCodeAt(start) !== CHAR_ASTERISK) return false
|
|
1111
1192
|
if (hasBackslash(state, start)) return false
|
|
1112
1193
|
|
|
1194
|
+
const attrsEnabled = opt.mditAttrs && hasMditAttrs(state)
|
|
1195
|
+
|
|
1113
1196
|
if (start === 0) {
|
|
1114
1197
|
state.__strongJaRefRangeCache = null
|
|
1115
1198
|
state.__strongJaInlineLinkRangeCache = null
|
|
1116
1199
|
state.__strongJaBackslashCache = undefined
|
|
1200
|
+
state.__strongJaHasBackslash = undefined
|
|
1117
1201
|
}
|
|
1118
1202
|
|
|
1119
|
-
if (
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1203
|
+
if (attrsEnabled) {
|
|
1204
|
+
let attrCandidate = false
|
|
1205
|
+
let probe = originalMax - 1
|
|
1206
|
+
while (probe >= start) {
|
|
1207
|
+
const code = src.charCodeAt(probe)
|
|
1208
|
+
if (code === CHAR_CLOSE_CURLY) {
|
|
1209
|
+
attrCandidate = true
|
|
1210
|
+
break
|
|
1125
1211
|
}
|
|
1126
|
-
if(
|
|
1127
|
-
|
|
1212
|
+
if (code === CHAR_SPACE || code === CHAR_TAB || code === CHAR_NEWLINE) {
|
|
1213
|
+
probe--
|
|
1214
|
+
continue
|
|
1128
1215
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1216
|
+
break
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
if (attrCandidate) {
|
|
1220
|
+
const attrScanTarget = originalMax === src.length ? src : src.slice(0, originalMax)
|
|
1221
|
+
attributesSrc = attrScanTarget.match(/((\n)? *){([^{}\n!@#%^&*()]+?)} *$/)
|
|
1222
|
+
if (attributesSrc && attributesSrc[3] !== '.') {
|
|
1223
|
+
max = attrScanTarget.slice(0, attributesSrc.index).length
|
|
1224
|
+
if (attributesSrc[2] === '\n') {
|
|
1225
|
+
max = attrScanTarget.slice(0, attributesSrc.index - 1).length
|
|
1226
|
+
}
|
|
1227
|
+
if (hasBackslash(state, attributesSrc.index) && attributesSrc[2] === '' && attributesSrc[1].length === 0) {
|
|
1228
|
+
max = state.posMax
|
|
1229
|
+
}
|
|
1230
|
+
} else {
|
|
1231
|
+
const endCurlyKet = attrScanTarget.match(/(\n *){([^{}\n!@#%^&*()]*?)}.*(} *?)$/)
|
|
1232
|
+
if (endCurlyKet) {
|
|
1233
|
+
max -= endCurlyKet[3].length
|
|
1234
|
+
}
|
|
1133
1235
|
}
|
|
1134
1236
|
}
|
|
1135
1237
|
}
|
|
1136
1238
|
|
|
1137
1239
|
if (state.__strongJaHasCollapsedRefs === undefined) {
|
|
1138
|
-
state.__strongJaHasCollapsedRefs =
|
|
1240
|
+
state.__strongJaHasCollapsedRefs = src.indexOf('[') !== -1 &&
|
|
1241
|
+
/\[[^\]]*\]\s*\[[^\]]*\]/.test(src)
|
|
1139
1242
|
}
|
|
1140
1243
|
|
|
1141
1244
|
if (state.__strongJaReferenceCount === undefined) {
|
|
@@ -1143,13 +1246,16 @@ const strongJa = (state, silent, opt) => {
|
|
|
1143
1246
|
state.__strongJaReferenceCount = references ? Object.keys(references).length : 0
|
|
1144
1247
|
}
|
|
1145
1248
|
|
|
1146
|
-
let refRanges
|
|
1147
|
-
const
|
|
1148
|
-
if (
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1249
|
+
let refRanges = []
|
|
1250
|
+
const hasReferenceDefinitions = state.__strongJaReferenceCount > 0
|
|
1251
|
+
if (hasReferenceDefinitions) {
|
|
1252
|
+
const refCache = state.__strongJaRefRangeCache
|
|
1253
|
+
if (refCache && refCache.max === max && refCache.start <= start) {
|
|
1254
|
+
refRanges = refCache.ranges
|
|
1255
|
+
} else {
|
|
1256
|
+
refRanges = computeReferenceRanges(state, start, max)
|
|
1257
|
+
state.__strongJaRefRangeCache = { start, max, ranges: refRanges }
|
|
1258
|
+
}
|
|
1153
1259
|
}
|
|
1154
1260
|
if (refRanges.length > 0) {
|
|
1155
1261
|
state.__strongJaHasCollapsedRefs = true
|
|
@@ -1175,6 +1281,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
1175
1281
|
const memo = {
|
|
1176
1282
|
html: state.md.options.html,
|
|
1177
1283
|
htmlTags: {},
|
|
1284
|
+
htmlTagDepth: 0,
|
|
1178
1285
|
inlineMarkStart: src.charCodeAt(0) === CHAR_ASTERISK,
|
|
1179
1286
|
inlineMarkEnd: src.charCodeAt(max - 1) === CHAR_ASTERISK,
|
|
1180
1287
|
}
|
|
@@ -1183,7 +1290,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
1183
1290
|
|
|
1184
1291
|
inlines = mergeInlinesAndMarks(inlines, marks)
|
|
1185
1292
|
|
|
1186
|
-
setToken(state, inlines, opt)
|
|
1293
|
+
setToken(state, inlines, opt, attrsEnabled)
|
|
1187
1294
|
|
|
1188
1295
|
if (inlineLinkRanges && inlineLinkRanges.length > 0) {
|
|
1189
1296
|
const labelSources = []
|
|
@@ -1205,7 +1312,7 @@ const strongJa = (state, silent, opt) => {
|
|
|
1205
1312
|
state.__strongJaPostProcessRegistered = true
|
|
1206
1313
|
}
|
|
1207
1314
|
|
|
1208
|
-
if (
|
|
1315
|
+
if (attrsEnabled && max !== state.posMax) {
|
|
1209
1316
|
if (!attributesSrc) {
|
|
1210
1317
|
state.pos = max
|
|
1211
1318
|
return true
|
|
@@ -1218,9 +1325,12 @@ const strongJa = (state, silent, opt) => {
|
|
|
1218
1325
|
}
|
|
1219
1326
|
|
|
1220
1327
|
// Collapsed reference helpers
|
|
1221
|
-
const
|
|
1328
|
+
const buildReferenceLabelRange = (tokens, startIdx, endIdx) => {
|
|
1329
|
+
if (startIdx > endIdx) return ''
|
|
1222
1330
|
let label = ''
|
|
1223
|
-
for (
|
|
1331
|
+
for (let idx = startIdx; idx <= endIdx; idx++) {
|
|
1332
|
+
const token = tokens[idx]
|
|
1333
|
+
if (!token) continue
|
|
1224
1334
|
if (token.type === 'text' || token.type === 'code_inline') {
|
|
1225
1335
|
label += token.content
|
|
1226
1336
|
} else if (token.type === 'softbreak' || token.type === 'hardbreak') {
|
|
@@ -1235,19 +1345,26 @@ const buildReferenceLabel = (tokens) => {
|
|
|
1235
1345
|
}
|
|
1236
1346
|
|
|
1237
1347
|
const cleanLabelText = (label) => {
|
|
1348
|
+
if (label.indexOf('*') === -1 && label.indexOf('_') === -1) return label
|
|
1238
1349
|
return label.replace(/^[*_]+/, '').replace(/[*_]+$/, '')
|
|
1239
1350
|
}
|
|
1240
1351
|
|
|
1241
1352
|
const normalizeReferenceCandidate = (state, text, { useClean = false } = {}) => {
|
|
1242
|
-
const source = useClean ? cleanLabelText(text) : text
|
|
1353
|
+
const source = useClean ? cleanLabelText(text) : text
|
|
1243
1354
|
return normalizeRefKey(state, source)
|
|
1244
1355
|
}
|
|
1245
1356
|
|
|
1246
|
-
const
|
|
1357
|
+
const getNormalizeRef = (state) => {
|
|
1358
|
+
if (state.__strongJaNormalizeRef) return state.__strongJaNormalizeRef
|
|
1247
1359
|
const normalize = state.md && state.md.utils && state.md.utils.normalizeReference
|
|
1248
1360
|
? state.md.utils.normalizeReference
|
|
1249
1361
|
: (str) => str.trim().replace(/\s+/g, ' ').toUpperCase()
|
|
1250
|
-
|
|
1362
|
+
state.__strongJaNormalizeRef = normalize
|
|
1363
|
+
return normalize
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
const normalizeRefKey = (state, label) => {
|
|
1367
|
+
return getNormalizeRef(state)(label)
|
|
1251
1368
|
}
|
|
1252
1369
|
|
|
1253
1370
|
const adjustTokenLevels = (tokens, startIdx, endIdx, delta) => {
|
|
@@ -1272,16 +1389,30 @@ const cloneTextToken = (source, content) => {
|
|
|
1272
1389
|
const splitBracketToken = (tokens, index, options) => {
|
|
1273
1390
|
const token = tokens[index]
|
|
1274
1391
|
if (!token || token.type !== 'text') return false
|
|
1392
|
+
if (token.__strongJaBracketAtomic) return false
|
|
1393
|
+
if (token.__strongJaHasBracket === false) return false
|
|
1275
1394
|
const content = token.content
|
|
1276
|
-
if (!content
|
|
1395
|
+
if (!content) {
|
|
1396
|
+
token.__strongJaHasBracket = false
|
|
1397
|
+
token.__strongJaBracketAtomic = false
|
|
1277
1398
|
return false
|
|
1278
1399
|
}
|
|
1400
|
+
if (token.__strongJaHasBracket !== true) {
|
|
1401
|
+
if (content.indexOf('[') === -1 && content.indexOf(']') === -1) {
|
|
1402
|
+
token.__strongJaHasBracket = false
|
|
1403
|
+
token.__strongJaBracketAtomic = false
|
|
1404
|
+
return false
|
|
1405
|
+
}
|
|
1406
|
+
token.__strongJaHasBracket = true
|
|
1407
|
+
}
|
|
1279
1408
|
const splitEmptyPair = options && options.splitEmptyPair
|
|
1280
1409
|
const segments = []
|
|
1281
1410
|
let buffer = ''
|
|
1282
1411
|
let pos = 0
|
|
1283
1412
|
while (pos < content.length) {
|
|
1284
|
-
if (!splitEmptyPair &&
|
|
1413
|
+
if (!splitEmptyPair &&
|
|
1414
|
+
content.charCodeAt(pos) === CHAR_OPEN_BRACKET &&
|
|
1415
|
+
content.charCodeAt(pos + 1) === CHAR_CLOSE_BRACKET) {
|
|
1285
1416
|
if (buffer) {
|
|
1286
1417
|
segments.push(buffer)
|
|
1287
1418
|
buffer = ''
|
|
@@ -1304,11 +1435,49 @@ const splitBracketToken = (tokens, index, options) => {
|
|
|
1304
1435
|
pos++
|
|
1305
1436
|
}
|
|
1306
1437
|
if (buffer) segments.push(buffer)
|
|
1307
|
-
if (segments.length <= 1)
|
|
1438
|
+
if (segments.length <= 1) {
|
|
1439
|
+
if (segments.length === 0) {
|
|
1440
|
+
token.__strongJaHasBracket = false
|
|
1441
|
+
token.__strongJaBracketAtomic = false
|
|
1442
|
+
} else {
|
|
1443
|
+
const seg = segments[0]
|
|
1444
|
+
if (seg === '[' || seg === ']') {
|
|
1445
|
+
token.__strongJaHasBracket = true
|
|
1446
|
+
token.__strongJaBracketAtomic = true
|
|
1447
|
+
} else if (seg === '[]') {
|
|
1448
|
+
token.__strongJaHasBracket = true
|
|
1449
|
+
token.__strongJaBracketAtomic = false
|
|
1450
|
+
} else {
|
|
1451
|
+
token.__strongJaHasBracket = false
|
|
1452
|
+
token.__strongJaBracketAtomic = false
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
return false
|
|
1456
|
+
}
|
|
1308
1457
|
token.content = segments[0]
|
|
1458
|
+
if (token.content === '[' || token.content === ']') {
|
|
1459
|
+
token.__strongJaHasBracket = true
|
|
1460
|
+
token.__strongJaBracketAtomic = true
|
|
1461
|
+
} else if (token.content === '[]') {
|
|
1462
|
+
token.__strongJaHasBracket = true
|
|
1463
|
+
token.__strongJaBracketAtomic = false
|
|
1464
|
+
} else {
|
|
1465
|
+
token.__strongJaHasBracket = false
|
|
1466
|
+
token.__strongJaBracketAtomic = false
|
|
1467
|
+
}
|
|
1309
1468
|
let insertIdx = index + 1
|
|
1310
1469
|
for (let s = 1; s < segments.length; s++) {
|
|
1311
1470
|
const newToken = cloneTextToken(token, segments[s])
|
|
1471
|
+
if (segments[s] === '[' || segments[s] === ']') {
|
|
1472
|
+
newToken.__strongJaHasBracket = true
|
|
1473
|
+
newToken.__strongJaBracketAtomic = true
|
|
1474
|
+
} else if (segments[s] === '[]') {
|
|
1475
|
+
newToken.__strongJaHasBracket = true
|
|
1476
|
+
newToken.__strongJaBracketAtomic = false
|
|
1477
|
+
} else {
|
|
1478
|
+
newToken.__strongJaHasBracket = false
|
|
1479
|
+
newToken.__strongJaBracketAtomic = false
|
|
1480
|
+
}
|
|
1312
1481
|
tokens.splice(insertIdx, 0, newToken)
|
|
1313
1482
|
insertIdx++
|
|
1314
1483
|
}
|
|
@@ -1474,11 +1643,13 @@ const parseInlineLinkTail = (content, md) => {
|
|
|
1474
1643
|
|
|
1475
1644
|
const INLINE_LINK_BRACKET_SPLIT_OPTIONS = { splitEmptyPair: true }
|
|
1476
1645
|
|
|
1477
|
-
const removeGhostLabelText = (tokens,
|
|
1646
|
+
const removeGhostLabelText = (tokens, linkCloseIndex, labelText) => {
|
|
1478
1647
|
if (!labelText) return
|
|
1479
|
-
|
|
1480
|
-
if (
|
|
1481
|
-
|
|
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
|
|
1482
1653
|
while (idx < tokens.length) {
|
|
1483
1654
|
const token = tokens[idx]
|
|
1484
1655
|
if (!token) {
|
|
@@ -1545,6 +1716,7 @@ const convertInlineLinks = (tokens, state) => {
|
|
|
1545
1716
|
let tailIdx = closeIdx + 1
|
|
1546
1717
|
let tailContent = ''
|
|
1547
1718
|
let parsedTail = null
|
|
1719
|
+
let tailHasCloseParen = false
|
|
1548
1720
|
while (tailIdx < tokens.length) {
|
|
1549
1721
|
if (splitBracketToken(tokens, tailIdx, INLINE_LINK_BRACKET_SPLIT_OPTIONS)) {
|
|
1550
1722
|
continue
|
|
@@ -1554,6 +1726,13 @@ const convertInlineLinks = (tokens, state) => {
|
|
|
1554
1726
|
break
|
|
1555
1727
|
}
|
|
1556
1728
|
tailContent += tailToken.content
|
|
1729
|
+
if (!tailHasCloseParen) {
|
|
1730
|
+
if (tailToken.content.indexOf(')') === -1) {
|
|
1731
|
+
tailIdx++
|
|
1732
|
+
continue
|
|
1733
|
+
}
|
|
1734
|
+
tailHasCloseParen = true
|
|
1735
|
+
}
|
|
1557
1736
|
parsedTail = parseInlineLinkTail(tailContent, state.md)
|
|
1558
1737
|
if (parsedTail) break
|
|
1559
1738
|
tailIdx++
|
|
@@ -1587,7 +1766,7 @@ const convertInlineLinks = (tokens, state) => {
|
|
|
1587
1766
|
continue
|
|
1588
1767
|
}
|
|
1589
1768
|
if (needsPlaceholder && currentLabelSource) {
|
|
1590
|
-
removeGhostLabelText(tokens,
|
|
1769
|
+
removeGhostLabelText(tokens, nextIndex - 1, currentLabelSource)
|
|
1591
1770
|
}
|
|
1592
1771
|
|
|
1593
1772
|
if (labelSources && labelSources.length > 0) {
|
|
@@ -1642,8 +1821,10 @@ const convertCollapsedReferenceLinks = (tokens, state) => {
|
|
|
1642
1821
|
continue
|
|
1643
1822
|
}
|
|
1644
1823
|
|
|
1645
|
-
const
|
|
1646
|
-
const
|
|
1824
|
+
const labelStart = i + 1
|
|
1825
|
+
const labelEnd = closeIdx - 1
|
|
1826
|
+
const labelLength = closeIdx - i - 1
|
|
1827
|
+
const labelText = buildReferenceLabelRange(tokens, labelStart, labelEnd)
|
|
1647
1828
|
const cleanedLabel = cleanLabelText(labelText)
|
|
1648
1829
|
const whitespaceStart = closeIdx + 1
|
|
1649
1830
|
let refRemoveStart = whitespaceStart
|
|
@@ -1671,11 +1852,12 @@ const convertCollapsedReferenceLinks = (tokens, state) => {
|
|
|
1671
1852
|
i++
|
|
1672
1853
|
continue
|
|
1673
1854
|
}
|
|
1674
|
-
const
|
|
1675
|
-
|
|
1855
|
+
const refStart = refRemoveStart + 1
|
|
1856
|
+
const refEnd = refCloseIdx - 1
|
|
1857
|
+
if (refStart > refEnd) {
|
|
1676
1858
|
refKey = normalizeReferenceCandidate(state, cleanedLabel)
|
|
1677
1859
|
} else {
|
|
1678
|
-
const refLabelText =
|
|
1860
|
+
const refLabelText = buildReferenceLabelRange(tokens, refStart, refEnd)
|
|
1679
1861
|
refKey = normalizeReferenceCandidate(state, refLabelText)
|
|
1680
1862
|
}
|
|
1681
1863
|
refRemoveCount = refCloseIdx - refRemoveStart + 1
|
|
@@ -1733,7 +1915,7 @@ const convertCollapsedReferenceLinks = (tokens, state) => {
|
|
|
1733
1915
|
tokens.splice(closeIdx, 1)
|
|
1734
1916
|
tokens.splice(i, 1)
|
|
1735
1917
|
|
|
1736
|
-
const nextIndex = wrapLabelTokensWithLink(tokens, i, i +
|
|
1918
|
+
const nextIndex = wrapLabelTokensWithLink(tokens, i, i + labelLength - 1, linkOpenToken, linkCloseToken)
|
|
1737
1919
|
i = nextIndex
|
|
1738
1920
|
}
|
|
1739
1921
|
}
|
|
@@ -1787,8 +1969,16 @@ const mditStrongJa = (md, option) => {
|
|
|
1787
1969
|
mditAttrs: true, //markdown-it-attrs
|
|
1788
1970
|
mdBreaks: md.options.breaks,
|
|
1789
1971
|
disallowMixed: false, //Non-Japanese text handling
|
|
1972
|
+
coreRulesBeforePostprocess: [] // e.g. ['cjk_breaks'] when CJK line-break plugins are active
|
|
1790
1973
|
}
|
|
1791
1974
|
if (option) Object.assign(opt, option)
|
|
1975
|
+
const rawCoreRules = opt.coreRulesBeforePostprocess
|
|
1976
|
+
const hasCoreRuleConfig = Array.isArray(rawCoreRules)
|
|
1977
|
+
? rawCoreRules.length > 0
|
|
1978
|
+
: !!rawCoreRules
|
|
1979
|
+
const coreRulesBeforePostprocess = hasCoreRuleConfig
|
|
1980
|
+
? normalizeCoreRulesBeforePostprocess(rawCoreRules)
|
|
1981
|
+
: []
|
|
1792
1982
|
|
|
1793
1983
|
md.inline.ruler.before('emphasis', 'strong_ja', (state, silent) => {
|
|
1794
1984
|
return strongJa(state, silent, opt)
|
|
@@ -1799,6 +1989,22 @@ const mditStrongJa = (md, option) => {
|
|
|
1799
1989
|
if (!targets || targets.length === 0) return
|
|
1800
1990
|
for (const tokens of targets) {
|
|
1801
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
|
+
}
|
|
1802
2008
|
convertInlineLinks(tokens, state)
|
|
1803
2009
|
convertCollapsedReferenceLinks(tokens, state)
|
|
1804
2010
|
mergeBrokenMarksAroundLinks(tokens)
|
|
@@ -1808,6 +2014,54 @@ const mditStrongJa = (md, option) => {
|
|
|
1808
2014
|
delete state.env.__strongJaPostProcessTargets
|
|
1809
2015
|
delete state.env.__strongJaPostProcessTargetSet
|
|
1810
2016
|
})
|
|
2017
|
+
|
|
2018
|
+
if (coreRulesBeforePostprocess.length > 0) {
|
|
2019
|
+
ensureCoreRuleOrder(md, coreRulesBeforePostprocess)
|
|
2020
|
+
}
|
|
1811
2021
|
}
|
|
1812
2022
|
|
|
1813
2023
|
export default mditStrongJa
|
|
2024
|
+
|
|
2025
|
+
|
|
2026
|
+
function normalizeCoreRulesBeforePostprocess(value) {
|
|
2027
|
+
if (!value) return []
|
|
2028
|
+
const list = Array.isArray(value) ? value : [value]
|
|
2029
|
+
const normalized = []
|
|
2030
|
+
const seen = new Set()
|
|
2031
|
+
for (let idx = 0; idx < list.length; idx++) {
|
|
2032
|
+
const raw = list[idx]
|
|
2033
|
+
if (typeof raw !== 'string') continue
|
|
2034
|
+
const trimmed = raw.trim()
|
|
2035
|
+
if (!trimmed || seen.has(trimmed)) continue
|
|
2036
|
+
seen.add(trimmed)
|
|
2037
|
+
normalized.push(trimmed)
|
|
2038
|
+
}
|
|
2039
|
+
return normalized
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
|
|
2043
|
+
function ensureCoreRuleOrder(md, ruleNames) {
|
|
2044
|
+
if (!md || !md.core || !md.core.ruler) return
|
|
2045
|
+
if (!ruleNames || ruleNames.length === 0) return
|
|
2046
|
+
for (let idx = 0; idx < ruleNames.length; idx++) {
|
|
2047
|
+
moveRuleBefore(md.core.ruler, ruleNames[idx], 'strong_ja_postprocess')
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
function moveRuleBefore(ruler, ruleName, beforeName) {
|
|
2053
|
+
if (!ruler || !ruler.__rules__) return
|
|
2054
|
+
const rules = ruler.__rules__
|
|
2055
|
+
let fromIdx = -1
|
|
2056
|
+
let beforeIdx = -1
|
|
2057
|
+
for (let idx = 0; idx < rules.length; idx++) {
|
|
2058
|
+
if (rules[idx].name === ruleName) fromIdx = idx
|
|
2059
|
+
if (rules[idx].name === beforeName) beforeIdx = idx
|
|
2060
|
+
if (fromIdx !== -1 && beforeIdx !== -1) break
|
|
2061
|
+
}
|
|
2062
|
+
if (fromIdx === -1 || beforeIdx === -1 || fromIdx < beforeIdx) return
|
|
2063
|
+
|
|
2064
|
+
const rule = rules.splice(fromIdx, 1)[0]
|
|
2065
|
+
rules.splice(beforeIdx, 0, rule)
|
|
2066
|
+
ruler.__cache__ = null
|
|
2067
|
+
}
|
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.4",
|
|
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
|
}
|