mirror of
https://github.com/Sevichecc/Urara-Blog.git
synced 2025-05-02 13:59:30 +08:00
109 lines
3.2 KiB
Text
109 lines
3.2 KiB
Text
/**
|
||
* @typedef {import('mdast').List} List
|
||
* @typedef {import('../types.js').Handle} Handle
|
||
*/
|
||
|
||
import {containerFlow} from '../util/container-flow.js'
|
||
import {checkBullet} from '../util/check-bullet.js'
|
||
import {checkBulletOther} from '../util/check-bullet-other.js'
|
||
import {checkBulletOrdered} from '../util/check-bullet-ordered.js'
|
||
import {checkBulletOrderedOther} from '../util/check-bullet-ordered-other.js'
|
||
import {checkRule} from '../util/check-rule.js'
|
||
|
||
/**
|
||
* @type {Handle}
|
||
* @param {List} node
|
||
*/
|
||
export function list(node, parent, context, safeOptions) {
|
||
const exit = context.enter('list')
|
||
const bulletCurrent = context.bulletCurrent
|
||
/** @type {string} */
|
||
let bullet = node.ordered ? checkBulletOrdered(context) : checkBullet(context)
|
||
/** @type {string} */
|
||
const bulletOther = node.ordered
|
||
? checkBulletOrderedOther(context)
|
||
: checkBulletOther(context)
|
||
const bulletLastUsed = context.bulletLastUsed
|
||
let useDifferentMarker = false
|
||
|
||
if (
|
||
parent &&
|
||
// Explicit `other` set.
|
||
(node.ordered
|
||
? context.options.bulletOrderedOther
|
||
: context.options.bulletOther) &&
|
||
bulletLastUsed &&
|
||
bullet === bulletLastUsed
|
||
) {
|
||
useDifferentMarker = true
|
||
}
|
||
|
||
if (!node.ordered) {
|
||
const firstListItem = node.children ? node.children[0] : undefined
|
||
|
||
// If there’s an empty first list item directly in two list items,
|
||
// we have to use a different bullet:
|
||
//
|
||
// ```markdown
|
||
// * - *
|
||
// ```
|
||
//
|
||
// …because otherwise it would become one big thematic break.
|
||
if (
|
||
// Bullet could be used as a thematic break marker:
|
||
(bullet === '*' || bullet === '-') &&
|
||
// Empty first list item:
|
||
firstListItem &&
|
||
(!firstListItem.children || !firstListItem.children[0]) &&
|
||
// Directly in two other list items:
|
||
context.stack[context.stack.length - 1] === 'list' &&
|
||
context.stack[context.stack.length - 2] === 'listItem' &&
|
||
context.stack[context.stack.length - 3] === 'list' &&
|
||
context.stack[context.stack.length - 4] === 'listItem' &&
|
||
// That are each the first child.
|
||
context.indexStack[context.indexStack.length - 1] === 0 &&
|
||
context.indexStack[context.indexStack.length - 2] === 0 &&
|
||
context.indexStack[context.indexStack.length - 3] === 0
|
||
) {
|
||
useDifferentMarker = true
|
||
}
|
||
|
||
// If there’s a thematic break at the start of the first list item,
|
||
// we have to use a different bullet:
|
||
//
|
||
// ```markdown
|
||
// * ---
|
||
// ```
|
||
//
|
||
// …because otherwise it would become one big thematic break.
|
||
if (checkRule(context) === bullet && firstListItem) {
|
||
let index = -1
|
||
|
||
while (++index < node.children.length) {
|
||
const item = node.children[index]
|
||
|
||
if (
|
||
item &&
|
||
item.type === 'listItem' &&
|
||
item.children &&
|
||
item.children[0] &&
|
||
item.children[0].type === 'thematicBreak'
|
||
) {
|
||
useDifferentMarker = true
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (useDifferentMarker) {
|
||
bullet = bulletOther
|
||
}
|
||
|
||
context.bulletCurrent = bullet
|
||
const value = containerFlow(node, context, safeOptions)
|
||
context.bulletLastUsed = bullet
|
||
context.bulletCurrent = bulletCurrent
|
||
exit()
|
||
return value
|
||
}
|