/** * @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 }