@peaceroad/markdown-it-strong-ja 0.4.1 → 0.4.3

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