123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /**
- * @typedef {import('micromark-util-types').Extension} Extension
- * @typedef {import('micromark-util-types').Handles} Handles
- * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension
- * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension
- */
- import {splice} from 'micromark-util-chunked'
- const hasOwnProperty = {}.hasOwnProperty
- /**
- * Combine multiple syntax extensions into one.
- *
- * @param {Array<Extension>} extensions
- * List of syntax extensions.
- * @returns {NormalizedExtension}
- * A single combined extension.
- */
- export function combineExtensions(extensions) {
- /** @type {NormalizedExtension} */
- const all = {}
- let index = -1
- while (++index < extensions.length) {
- syntaxExtension(all, extensions[index])
- }
- return all
- }
- /**
- * Merge `extension` into `all`.
- *
- * @param {NormalizedExtension} all
- * Extension to merge into.
- * @param {Extension} extension
- * Extension to merge.
- * @returns {undefined}
- */
- function syntaxExtension(all, extension) {
- /** @type {keyof Extension} */
- let hook
- for (hook in extension) {
- const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined
- /** @type {Record<string, unknown>} */
- const left = maybe || (all[hook] = {})
- /** @type {Record<string, unknown> | undefined} */
- const right = extension[hook]
- /** @type {string} */
- let code
- if (right) {
- for (code in right) {
- if (!hasOwnProperty.call(left, code)) left[code] = []
- const value = right[code]
- constructs(
- // @ts-expect-error Looks like a list.
- left[code],
- Array.isArray(value) ? value : value ? [value] : []
- )
- }
- }
- }
- }
- /**
- * Merge `list` into `existing` (both lists of constructs).
- * Mutates `existing`.
- *
- * @param {Array<unknown>} existing
- * @param {Array<unknown>} list
- * @returns {undefined}
- */
- function constructs(existing, list) {
- let index = -1
- /** @type {Array<unknown>} */
- const before = []
- while (++index < list.length) {
- // @ts-expect-error Looks like an object.
- ;(list[index].add === 'after' ? existing : before).push(list[index])
- }
- splice(existing, 0, 0, before)
- }
- /**
- * Combine multiple HTML extensions into one.
- *
- * @param {Array<HtmlExtension>} htmlExtensions
- * List of HTML extensions.
- * @returns {HtmlExtension}
- * A single combined HTML extension.
- */
- export function combineHtmlExtensions(htmlExtensions) {
- /** @type {HtmlExtension} */
- const handlers = {}
- let index = -1
- while (++index < htmlExtensions.length) {
- htmlExtension(handlers, htmlExtensions[index])
- }
- return handlers
- }
- /**
- * Merge `extension` into `all`.
- *
- * @param {HtmlExtension} all
- * Extension to merge into.
- * @param {HtmlExtension} extension
- * Extension to merge.
- * @returns {undefined}
- */
- function htmlExtension(all, extension) {
- /** @type {keyof HtmlExtension} */
- let hook
- for (hook in extension) {
- const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined
- const left = maybe || (all[hook] = {})
- const right = extension[hook]
- /** @type {keyof Handles} */
- let type
- if (right) {
- for (type in right) {
- // @ts-expect-error assume document vs regular handler are managed correctly.
- left[type] = right[type]
- }
- }
- }
- }
|