/** | |
* @typedef {import('mdast').Root|import('mdast').Content} Node | |
* | |
* @typedef Options | |
* Configuration (optional). | |
* @property {boolean | null | undefined} [includeImageAlt=true] | |
* Whether to use `alt` for `image`s. | |
* @property {boolean | null | undefined} [includeHtml=true] | |
* Whether to use `value` of HTML. | |
*/ | |
/** @type {Options} */ | |
const emptyOptions = {} | |
/** | |
* Get the text content of a node or list of nodes. | |
* | |
* Prefers the node’s plain-text fields, otherwise serializes its children, | |
* and if the given value is an array, serialize the nodes in it. | |
* | |
* @param {unknown} value | |
* Thing to serialize, typically `Node`. | |
* @param {Options | null | undefined} [options] | |
* Configuration (optional). | |
* @returns {string} | |
* Serialized `value`. | |
*/ | |
export function toString(value, options) { | |
const settings = options || emptyOptions | |
const includeImageAlt = | |
typeof settings.includeImageAlt === 'boolean' | |
? settings.includeImageAlt | |
: true | |
const includeHtml = | |
typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true | |
return one(value, includeImageAlt, includeHtml) | |
} | |
/** | |
* One node or several nodes. | |
* | |
* @param {unknown} value | |
* Thing to serialize. | |
* @param {boolean} includeImageAlt | |
* Include image `alt`s. | |
* @param {boolean} includeHtml | |
* Include HTML. | |
* @returns {string} | |
* Serialized node. | |
*/ | |
function one(value, includeImageAlt, includeHtml) { | |
if (node(value)) { | |
if ('value' in value) { | |
return value.type === 'html' && !includeHtml ? '' : value.value | |
} | |
if (includeImageAlt && 'alt' in value && value.alt) { | |
return value.alt | |
} | |
if ('children' in value) { | |
return all(value.children, includeImageAlt, includeHtml) | |
} | |
} | |
if (Array.isArray(value)) { | |
return all(value, includeImageAlt, includeHtml) | |
} | |
return '' | |
} | |
/** | |
* Serialize a list of nodes. | |
* | |
* @param {Array<unknown>} values | |
* Thing to serialize. | |
* @param {boolean} includeImageAlt | |
* Include image `alt`s. | |
* @param {boolean} includeHtml | |
* Include HTML. | |
* @returns {string} | |
* Serialized nodes. | |
*/ | |
function all(values, includeImageAlt, includeHtml) { | |
/** @type {Array<string>} */ | |
const result = [] | |
let index = -1 | |
while (++index < values.length) { | |
result[index] = one(values[index], includeImageAlt, includeHtml) | |
} | |
return result.join('') | |
} | |
/** | |
* Check if `value` looks like a node. | |
* | |
* @param {unknown} value | |
* Thing. | |
* @returns {value is Node} | |
* Whether `value` is a node. | |
*/ | |
function node(value) { | |
return Boolean(value && typeof value === 'object') | |
} | |