UNPKG

remark-sort-definitions

Version:

remark plugin that reorders reference-style link definitions by id at the end of a document

33 lines 1.32 kB
import assert from 'node:assert'; import { SKIP, visit } from 'unist-util-visit'; const compareNaturally = new Intl.Collator(undefined, { numeric: true }).compare; const remarkSortDefinitions = function ({ algorithm = 'alphanumeric-first' } = {}, ..._ignored) { const definitionMap = new Map(); return tree => { visit(tree, 'definition', (node, index, parent) => { assert(node.type === 'definition', `unexpected node type ${node.type}`); assert(index !== undefined, 'index is missing'); assert(parent !== undefined, 'parent is missing'); definitionMap.set(node.identifier.toUpperCase(), node); parent.children.splice(index, 1); return [SKIP, index]; }); tree.children.push(...getSortedDefinitions()); function getSortedDefinitions() { return Array.from(definitionMap.entries()).sort(([a], [b]) => { const aIsNumeric = isNumeric(a); const bIsNumeric = isNumeric(b); const result = algorithm === 'numeric-first' ? -1 : 1; return aIsNumeric && !bIsNumeric ? result : !aIsNumeric && bIsNumeric ? -1 * result : compareNaturally(a, b); }).map(([, definition]) => definition); } function isNumeric(identifier) { return /^\p{Decimal_Number}+$/u.test(identifier); } }; }; export default remarkSortDefinitions;