@peaceroad/markdown-it-numbering-ul-regarded-as-ol 0.2.0 → 0.2.1

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.
@@ -154,7 +154,10 @@ function analyzeList(tokens, startIndex, opt) {
154
154
  const level = listToken.level || 0
155
155
  const originalType = listToken.type
156
156
  const items = analyzeListItems(tokens, startIndex, endIndex, opt)
157
- const isLoose = detectLooseList(tokens, startIndex, endIndex)
157
+ const isLoose = detectLooseList(tokens, startIndex, endIndex, items)
158
+ if (!isLoose) {
159
+ hideFirstParagraphsForTightList(tokens, items, level)
160
+ }
158
161
 
159
162
  // Extract marker info (for both bullet_list and ordered_list)
160
163
  const markerInfo = extractMarkerInfo(tokens, startIndex, endIndex, opt)
@@ -229,9 +232,11 @@ function analyzeListItem(tokens, startIndex, endIndex, opt) {
229
232
  // When child list starts, check if blank line exists right after first paragraph
230
233
  if (foundParagraph && firstParagraphIndex !== -1) {
231
234
  const paragraphToken = tokens[firstParagraphIndex]
232
- if (paragraphToken.map && token.map) {
233
- const paragraphEndLine = paragraphToken.map[1]
234
- const nestedListStartLine = token.map[0]
235
+ const paragraphEndLine = paragraphToken.map ? paragraphToken.map[1] : undefined
236
+ const nestedListStartLine = token.map
237
+ ? token.map[0]
238
+ : (typeof token._literalStartLine === 'number' ? token._literalStartLine : undefined)
239
+ if (typeof paragraphEndLine === 'number' && typeof nestedListStartLine === 'number') {
235
240
  // Check if blank line exists between paragraph end and child list start
236
241
  if (nestedListStartLine > paragraphEndLine) {
237
242
  firstParagraphIsLoose = true
@@ -297,6 +302,7 @@ function extractMarkerInfo(tokens, startIndex, endIndex, opt) {
297
302
 
298
303
  markers.push({
299
304
  number: itemNumber,
305
+ originalNumber: itemNumber,
300
306
  prefix: '',
301
307
  suffix: markup,
302
308
  type: 'decimal' // Default (can be extended to detect from markup)
@@ -329,6 +335,7 @@ function extractMarkerInfo(tokens, startIndex, endIndex, opt) {
329
335
  // Use sequential numbers when same marker continues
330
336
  // (e.g., "イ. イ. イ." → interpreted as "イ、ロ、ハ")
331
337
  const adjustedMarkerInfo = { ...markerInfo }
338
+ adjustedMarkerInfo.originalNumber = markerInfo.number
332
339
 
333
340
  // Assign sequential numbers based on first marker's number
334
341
  if (markers.length === 0) {
@@ -361,12 +368,22 @@ function extractMarkerInfo(tokens, startIndex, endIndex, opt) {
361
368
 
362
369
  const firstType = markers[0].type
363
370
  const allSameType = markers.every(m => m.type === firstType)
371
+ const literalNumbers = markers.map(m => (typeof m.originalNumber === 'number' ? m.originalNumber : undefined))
372
+ const hasLiteralNumbers = literalNumbers.length === markers.length && literalNumbers.every(n => typeof n === 'number')
373
+ let allNumbersIdentical = false
374
+ if (hasLiteralNumbers) {
375
+ const firstLiteral = literalNumbers[0]
376
+ if (literalNumbers.every(n => n === firstLiteral) && firstLiteral === 1) {
377
+ allNumbersIdentical = true
378
+ }
379
+ }
364
380
 
365
381
  return {
366
382
  markers,
367
383
  type: firstType,
368
384
  isConsistent: allSameType,
369
- count: markers.length
385
+ count: markers.length,
386
+ allNumbersIdentical
370
387
  }
371
388
  }
372
389
 
@@ -397,17 +414,83 @@ function shouldConvertToOrdered(originalType, markerInfo, opt) {
397
414
  * In markdown-it, lists separated by blank lines have paragraphs in each list_item
398
415
  * For tight lists, paragraph_open.hidden === true
399
416
  */
400
- function detectLooseList(tokens, startIndex, endIndex) {
417
+ function detectLooseList(tokens, startIndex, endIndex, items = null) {
418
+ const listLevel = tokens[startIndex]?.level || 0
419
+ const paragraphLevel = listLevel + 2
401
420
  for (let i = startIndex + 1; i < endIndex; i++) {
402
421
  const token = tokens[i]
403
422
  // Loose list if paragraph_open exists and is not hidden
404
- if (token.type === 'paragraph_open' && !token.hidden) {
423
+ if (token.type === 'paragraph_open' && token.level === paragraphLevel && !token.hidden) {
424
+ if (items && items.length === 1 && isTightSingleItem(tokens, items[0])) {
425
+ continue
426
+ }
405
427
  return true
406
428
  }
407
429
  }
408
430
  return false
409
431
  }
410
432
 
433
+ function isTightSingleItem(tokens, item) {
434
+ if (!item || item.firstParagraphIsLoose) {
435
+ return false
436
+ }
437
+ const itemOpenToken = tokens[item.startIndex]
438
+ const childLevel = (itemOpenToken.level || 0) + 1
439
+ let paragraphCount = 0
440
+ for (let i = item.startIndex + 1; i < item.endIndex; i++) {
441
+ const token = tokens[i]
442
+ if (token.level !== childLevel) {
443
+ continue
444
+ }
445
+ if (token.type === 'paragraph_open') {
446
+ paragraphCount++
447
+ if (paragraphCount > 1) {
448
+ return false
449
+ }
450
+ } else if (token.type === 'ordered_list_open' || token.type === 'bullet_list_open') {
451
+ continue
452
+ } else if (token.type.endsWith('_open') || token.type === 'html_block' || token.type === 'code_block' || token.type === 'fence') {
453
+ return false
454
+ }
455
+ }
456
+ return true
457
+ }
458
+
459
+ function hideFirstParagraphsForTightList(tokens, items, level) {
460
+ if (!Array.isArray(items) || level !== 0) {
461
+ return
462
+ }
463
+ for (const item of items) {
464
+ if (!item || item.firstParagraphIsLoose) {
465
+ continue
466
+ }
467
+ const itemToken = tokens[item.startIndex]
468
+ if (!itemToken) {
469
+ continue
470
+ }
471
+ const paragraphLevel = (itemToken.level || 0) + 1
472
+ for (let i = item.startIndex + 1; i < item.endIndex; i++) {
473
+ const token = tokens[i]
474
+ if (!token) {
475
+ continue
476
+ }
477
+ if (token.type === 'paragraph_open' && token.level === paragraphLevel) {
478
+ if (!token._literalTight) {
479
+ break
480
+ }
481
+ token.hidden = true
482
+ const closeIdx = findMatchingClose(tokens, i, 'paragraph_open', 'paragraph_close')
483
+ if (closeIdx !== -1) {
484
+ tokens[closeIdx].hidden = true
485
+ }
486
+ break
487
+ } else if (token.type === 'bullet_list_open' || token.type === 'ordered_list_open') {
488
+ break
489
+ }
490
+ }
491
+ }
492
+ }
493
+
411
494
  /**
412
495
  * Find list end position
413
496
  */