| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /**
- * @import {Handle, Info, State} from 'mdast-util-to-markdown'
- * @import {PhrasingParents} from '../types.js'
- */
- import {encodeCharacterReference} from './encode-character-reference.js'
- /**
- * 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
- /** @type {string | undefined} */
- let encodeAfter
- 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(''))
- }
- let value = state.handle(child, parent, state, {
- ...tracker.current(),
- after,
- before
- })
- // If we had to encode the first character after the previous node and it’s
- // still the same character,
- // encode it.
- if (encodeAfter && encodeAfter === value.slice(0, 1)) {
- value =
- encodeCharacterReference(encodeAfter.charCodeAt(0)) + value.slice(1)
- }
- const encodingInfo = state.attentionEncodeSurroundingInfo
- state.attentionEncodeSurroundingInfo = undefined
- encodeAfter = undefined
- // If we have to encode the first character before the current node and
- // it’s still the same character,
- // encode it.
- if (encodingInfo) {
- if (
- results.length > 0 &&
- encodingInfo.before &&
- before === results[results.length - 1].slice(-1)
- ) {
- results[results.length - 1] =
- results[results.length - 1].slice(0, -1) +
- encodeCharacterReference(before.charCodeAt(0))
- }
- if (encodingInfo.after) encodeAfter = after
- }
- tracker.move(value)
- results.push(value)
- before = value.slice(-1)
- }
- indexStack.pop()
- return results.join('')
- }
|