container-flow.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /**
  2. * @typedef {import('../types.js').FlowParents} FlowParents
  3. * @typedef {import('../types.js').FlowChildren} FlowChildren
  4. * @typedef {import('../types.js').State} State
  5. * @typedef {import('../types.js').TrackFields} TrackFields
  6. */
  7. /**
  8. * @param {FlowParents} parent
  9. * Parent of flow nodes.
  10. * @param {State} state
  11. * Info passed around about the current state.
  12. * @param {TrackFields} info
  13. * Info on where we are in the document we are generating.
  14. * @returns {string}
  15. * Serialized children, joined by (blank) lines.
  16. */
  17. export function containerFlow(parent, state, info) {
  18. const indexStack = state.indexStack
  19. const children = parent.children || []
  20. const tracker = state.createTracker(info)
  21. /** @type {Array<string>} */
  22. const results = []
  23. let index = -1
  24. indexStack.push(-1)
  25. while (++index < children.length) {
  26. const child = children[index]
  27. indexStack[indexStack.length - 1] = index
  28. results.push(
  29. tracker.move(
  30. state.handle(child, parent, state, {
  31. before: '\n',
  32. after: '\n',
  33. ...tracker.current()
  34. })
  35. )
  36. )
  37. if (child.type !== 'list') {
  38. state.bulletLastUsed = undefined
  39. }
  40. if (index < children.length - 1) {
  41. results.push(
  42. tracker.move(between(child, children[index + 1], parent, state))
  43. )
  44. }
  45. }
  46. indexStack.pop()
  47. return results.join('')
  48. }
  49. /**
  50. * @param {FlowChildren} left
  51. * @param {FlowChildren} right
  52. * @param {FlowParents} parent
  53. * @param {State} state
  54. * @returns {string}
  55. */
  56. function between(left, right, parent, state) {
  57. let index = state.join.length
  58. while (index--) {
  59. const result = state.join[index](left, right, parent, state)
  60. if (result === true || result === 1) {
  61. break
  62. }
  63. if (typeof result === 'number') {
  64. return '\n'.repeat(1 + result)
  65. }
  66. if (result === false) {
  67. return '\n\n<!---->\n\n'
  68. }
  69. }
  70. return '\n\n'
  71. }