52 lines
1.3 KiB
JavaScript
52 lines
1.3 KiB
JavaScript
|
/**
|
|||
|
* @typedef {import('hast').Parents} Parents
|
|||
|
* @typedef {import('hast').RootContent} RootContent
|
|||
|
*/
|
|||
|
|
|||
|
import {whitespace} from 'hast-util-whitespace'
|
|||
|
|
|||
|
export const siblingAfter = siblings(1)
|
|||
|
export const siblingBefore = siblings(-1)
|
|||
|
|
|||
|
/** @type {Array<RootContent>} */
|
|||
|
const emptyChildren = []
|
|||
|
|
|||
|
/**
|
|||
|
* Factory to check siblings in a direction.
|
|||
|
*
|
|||
|
* @param {number} increment
|
|||
|
*/
|
|||
|
function siblings(increment) {
|
|||
|
return sibling
|
|||
|
|
|||
|
/**
|
|||
|
* Find applicable siblings in a direction.
|
|||
|
*
|
|||
|
* @template {Parents} Parent
|
|||
|
* Parent type.
|
|||
|
* @param {Parent | undefined} parent
|
|||
|
* Parent.
|
|||
|
* @param {number | undefined} index
|
|||
|
* Index of child in `parent`.
|
|||
|
* @param {boolean | undefined} [includeWhitespace=false]
|
|||
|
* Whether to include whitespace (default: `false`).
|
|||
|
* @returns {Parent extends {children: Array<infer Child>} ? Child | undefined : never}
|
|||
|
* Child of parent.
|
|||
|
*/
|
|||
|
function sibling(parent, index, includeWhitespace) {
|
|||
|
const siblings = parent ? parent.children : emptyChildren
|
|||
|
let offset = (index || 0) + increment
|
|||
|
let next = siblings[offset]
|
|||
|
|
|||
|
if (!includeWhitespace) {
|
|||
|
while (next && whitespace(next)) {
|
|||
|
offset += increment
|
|||
|
next = siblings[offset]
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// @ts-expect-error: it’s a correct child.
|
|||
|
return next
|
|||
|
}
|
|||
|
}
|