123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- /**
- * @typedef {import('../types.js').Handle} Handle
- * @typedef {import('../types.js').Info} Info
- * @typedef {import('../types.js').PhrasingParents} PhrasingParents
- * @typedef {import('../types.js').State} State
- */
- /**
- * Serialize the children of a parent that contains phrasing children.
- *
- * These children will be joined flush together.
- *
- * @param {PhrasingParents} parent
- * Parent of flow nodes.
- * @param {State} state
- * Info passed around about the current state.
- * @param {Info} info
- * Info on where we are in the document we are generating.
- * @returns {string}
- * Serialized children, joined together.
- */
- export function containerPhrasing(parent, state, info) {
- const indexStack = state.indexStack
- const children = parent.children || []
- /** @type {Array<string>} */
- const results = []
- let index = -1
- let before = info.before
- indexStack.push(-1)
- let tracker = state.createTracker(info)
- while (++index < children.length) {
- const child = children[index]
- /** @type {string} */
- let after
- indexStack[indexStack.length - 1] = index
- if (index + 1 < children.length) {
- /** @type {Handle} */
- // @ts-expect-error: hush, it’s actually a `zwitch`.
- let handle = state.handle.handlers[children[index + 1].type]
- /** @type {Handle} */
- // @ts-expect-error: hush, it’s actually a `zwitch`.
- if (handle && handle.peek) handle = handle.peek
- after = handle
- ? handle(children[index + 1], parent, state, {
- before: '',
- after: '',
- ...tracker.current()
- }).charAt(0)
- : ''
- } else {
- after = info.after
- }
- // In some cases, html (text) can be found in phrasing right after an eol.
- // When we’d serialize that, in most cases that would be seen as html
- // (flow).
- // As we can’t escape or so to prevent it from happening, we take a somewhat
- // reasonable approach: replace that eol with a space.
- // See: <https://github.com/syntax-tree/mdast-util-to-markdown/issues/15>
- if (
- results.length > 0 &&
- (before === '\r' || before === '\n') &&
- child.type === 'html'
- ) {
- results[results.length - 1] = results[results.length - 1].replace(
- /(\r?\n|\r)$/,
- ' '
- )
- before = ' '
- // To do: does this work to reset tracker?
- tracker = state.createTracker(info)
- tracker.move(results.join(''))
- }
- results.push(
- tracker.move(
- state.handle(child, parent, state, {
- ...tracker.current(),
- before,
- after
- })
- )
- )
- before = results[results.length - 1].slice(-1)
- }
- indexStack.pop()
- return results.join('')
- }
|