remark-heading-anchor
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -1,391 +0,21 @@ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.index = global.index || {}, global.index.js = factory())); | ||
})(this, (function () { 'use strict'; | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Parent} Parent | ||
* | ||
* @typedef {string} Type | ||
* @typedef {Object<string, unknown>} Props | ||
* | ||
* @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test | ||
*/ | ||
const convert = | ||
/** | ||
* @type {( | ||
* (<T extends Node>(test: T['type']|Partial<T>|TestFunctionPredicate<T>) => AssertPredicate<T>) & | ||
* ((test?: Test) => AssertAnything) | ||
* )} | ||
*/ | ||
( | ||
/** | ||
* Generate an assertion from a check. | ||
* @param {Test} [test] | ||
* When nullish, checks if `node` is a `Node`. | ||
* When `string`, works like passing `function (node) {return node.type === test}`. | ||
* When `function` checks if function passed the node is true. | ||
* When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. | ||
* When `array`, checks any one of the subtests pass. | ||
* @returns {AssertAnything} | ||
*/ | ||
function (test) { | ||
if (test === undefined || test === null) { | ||
return ok | ||
} | ||
if (typeof test === 'string') { | ||
return typeFactory(test) | ||
} | ||
if (typeof test === 'object') { | ||
return Array.isArray(test) ? anyFactory(test) : propsFactory(test) | ||
} | ||
if (typeof test === 'function') { | ||
return castFactory(test) | ||
} | ||
throw new Error('Expected function, string, or object as test') | ||
} | ||
); | ||
/** | ||
* @param {Array.<Type|Props|TestFunctionAnything>} tests | ||
* @returns {AssertAnything} | ||
*/ | ||
function anyFactory(tests) { | ||
/** @type {Array.<AssertAnything>} */ | ||
const checks = []; | ||
let index = -1; | ||
while (++index < tests.length) { | ||
checks[index] = convert(tests[index]); | ||
} | ||
return castFactory(any) | ||
/** | ||
* @this {unknown} | ||
* @param {unknown[]} parameters | ||
* @returns {boolean} | ||
*/ | ||
function any(...parameters) { | ||
let index = -1; | ||
while (++index < checks.length) { | ||
if (checks[index].call(this, ...parameters)) return true | ||
} | ||
return false | ||
} | ||
} | ||
/** | ||
* Utility to assert each property in `test` is represented in `node`, and each | ||
* values are strictly equal. | ||
* | ||
* @param {Props} check | ||
* @returns {AssertAnything} | ||
*/ | ||
function propsFactory(check) { | ||
return castFactory(all) | ||
/** | ||
* @param {Node} node | ||
* @returns {boolean} | ||
*/ | ||
function all(node) { | ||
/** @type {string} */ | ||
let key; | ||
for (key in check) { | ||
// @ts-expect-error: hush, it sure works as an index. | ||
if (node[key] !== check[key]) return false | ||
} | ||
return true | ||
} | ||
} | ||
/** | ||
* Utility to convert a string into a function which checks a given node’s type | ||
* for said string. | ||
* | ||
* @param {Type} check | ||
* @returns {AssertAnything} | ||
*/ | ||
function typeFactory(check) { | ||
return castFactory(type) | ||
/** | ||
* @param {Node} node | ||
*/ | ||
function type(node) { | ||
return node && node.type === check | ||
} | ||
} | ||
/** | ||
* Utility to convert a string into a function which checks a given node’s type | ||
* for said string. | ||
* @param {TestFunctionAnything} check | ||
* @returns {AssertAnything} | ||
*/ | ||
function castFactory(check) { | ||
return assertion | ||
/** | ||
* @this {unknown} | ||
* @param {Array.<unknown>} parameters | ||
* @returns {boolean} | ||
*/ | ||
function assertion(...parameters) { | ||
// @ts-expect-error: spreading is fine. | ||
return Boolean(check.call(this, ...parameters)) | ||
} | ||
} | ||
// Utility to return true. | ||
function ok() { | ||
return true | ||
} | ||
/** | ||
* @param {string} d | ||
* @returns {string} | ||
*/ | ||
function color(d) { | ||
return '\u001B[33m' + d + '\u001B[39m' | ||
} | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Parent} Parent | ||
* @typedef {import('unist-util-is').Test} Test | ||
* @typedef {import('./complex-types').Action} Action | ||
* @typedef {import('./complex-types').Index} Index | ||
* @typedef {import('./complex-types').ActionTuple} ActionTuple | ||
* @typedef {import('./complex-types').VisitorResult} VisitorResult | ||
* @typedef {import('./complex-types').Visitor} Visitor | ||
*/ | ||
/** | ||
* Continue traversing as normal | ||
*/ | ||
const CONTINUE = true; | ||
/** | ||
* Do not traverse this node’s children | ||
*/ | ||
const SKIP = 'skip'; | ||
/** | ||
* Stop traversing immediately | ||
*/ | ||
const EXIT = false; | ||
/** | ||
* Visit children of tree which pass a test | ||
* | ||
* @param tree Abstract syntax tree to walk | ||
* @param test Test node, optional | ||
* @param visitor Function to run for each node | ||
* @param reverse Visit the tree in reverse order, defaults to false | ||
*/ | ||
const visitParents = | ||
/** | ||
* @type {( | ||
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types').BuildVisitor<Tree, Check>, reverse?: boolean) => void) & | ||
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types').BuildVisitor<Tree>, reverse?: boolean) => void) | ||
* )} | ||
*/ | ||
( | ||
/** | ||
* @param {Node} tree | ||
* @param {Test} test | ||
* @param {import('./complex-types').Visitor<Node>} visitor | ||
* @param {boolean} [reverse] | ||
*/ | ||
function (tree, test, visitor, reverse) { | ||
if (typeof test === 'function' && typeof visitor !== 'function') { | ||
reverse = visitor; | ||
// @ts-expect-error no visitor given, so `visitor` is test. | ||
visitor = test; | ||
test = null; | ||
} | ||
const is = convert(test); | ||
const step = reverse ? -1 : 1; | ||
factory(tree, null, [])(); | ||
/** | ||
* @param {Node} node | ||
* @param {number?} index | ||
* @param {Array.<Parent>} parents | ||
*/ | ||
function factory(node, index, parents) { | ||
/** @type {Object.<string, unknown>} */ | ||
// @ts-expect-error: hush | ||
const value = typeof node === 'object' && node !== null ? node : {}; | ||
/** @type {string|undefined} */ | ||
let name; | ||
if (typeof value.type === 'string') { | ||
name = | ||
typeof value.tagName === 'string' | ||
? value.tagName | ||
: typeof value.name === 'string' | ||
? value.name | ||
: undefined; | ||
Object.defineProperty(visit, 'name', { | ||
value: | ||
'node (' + | ||
color(value.type + (name ? '<' + name + '>' : '')) + | ||
')' | ||
import { visit } from 'unist-util-visit'; | ||
function getFileList(root, options) { | ||
const headList = []; | ||
visit(root, (node, index) => { | ||
if (node.type === 'heading') { | ||
const id = (options === null || options === void 0 ? void 0 : options.idPrefix) ? `${options.idPrefix}${index}` : index + ''; | ||
headList.push({ | ||
title: node.children[0].value, | ||
index, | ||
id, | ||
level: node.depth | ||
}); | ||
} | ||
return visit | ||
function visit() { | ||
/** @type {ActionTuple} */ | ||
let result = []; | ||
/** @type {ActionTuple} */ | ||
let subresult; | ||
/** @type {number} */ | ||
let offset; | ||
/** @type {Array.<Parent>} */ | ||
let grandparents; | ||
if (!test || is(node, index, parents[parents.length - 1] || null)) { | ||
result = toResult(visitor(node, parents)); | ||
if (result[0] === EXIT) { | ||
return result | ||
} | ||
} | ||
// @ts-expect-error looks like a parent. | ||
if (node.children && result[0] !== SKIP) { | ||
// @ts-expect-error looks like a parent. | ||
offset = (reverse ? node.children.length : -1) + step; | ||
// @ts-expect-error looks like a parent. | ||
grandparents = parents.concat(node); | ||
// @ts-expect-error looks like a parent. | ||
while (offset > -1 && offset < node.children.length) { | ||
// @ts-expect-error looks like a parent. | ||
subresult = factory(node.children[offset], offset, grandparents)(); | ||
if (subresult[0] === EXIT) { | ||
return subresult | ||
} | ||
offset = | ||
typeof subresult[1] === 'number' ? subresult[1] : offset + step; | ||
} | ||
} | ||
return result | ||
} | ||
} | ||
} | ||
); | ||
/** | ||
* @param {VisitorResult} value | ||
* @returns {ActionTuple} | ||
*/ | ||
function toResult(value) { | ||
if (Array.isArray(value)) { | ||
return value | ||
} | ||
if (typeof value === 'number') { | ||
return [CONTINUE, value] | ||
} | ||
return [value] | ||
} | ||
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Parent} Parent | ||
* @typedef {import('unist-util-is').Test} Test | ||
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult | ||
* @typedef {import('./complex-types').Visitor} Visitor | ||
*/ | ||
/** | ||
* Visit children of tree which pass a test | ||
* | ||
* @param tree Abstract syntax tree to walk | ||
* @param test Test, optional | ||
* @param visitor Function to run for each node | ||
* @param reverse Fisit the tree in reverse, defaults to false | ||
*/ | ||
const visit = | ||
/** | ||
* @type {( | ||
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types').BuildVisitor<Tree, Check>, reverse?: boolean) => void) & | ||
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types').BuildVisitor<Tree>, reverse?: boolean) => void) | ||
* )} | ||
*/ | ||
( | ||
/** | ||
* @param {Node} tree | ||
* @param {Test} test | ||
* @param {import('./complex-types').Visitor} visitor | ||
* @param {boolean} [reverse] | ||
*/ | ||
function (tree, test, visitor, reverse) { | ||
if (typeof test === 'function' && typeof visitor !== 'function') { | ||
reverse = visitor; | ||
visitor = test; | ||
test = null; | ||
} | ||
visitParents(tree, test, overload, reverse); | ||
/** | ||
* @param {Node} node | ||
* @param {Array.<Parent>} parents | ||
*/ | ||
function overload(node, parents) { | ||
const parent = parents[parents.length - 1]; | ||
return visitor( | ||
node, | ||
parent ? parent.children.indexOf(node) : null, | ||
parent | ||
) | ||
} | ||
} | ||
); | ||
function getFileList(root, options) { | ||
const headList = []; | ||
visit(root, (node, index) => { | ||
if (node.type === 'heading') { | ||
const id = options?.idPrefix ? `${options.idPrefix}${index}` : index + ''; | ||
headList.push({ | ||
title: node.children[0].value, | ||
index, | ||
id, | ||
level: node.depth | ||
}); | ||
} | ||
}); | ||
return headList; | ||
} | ||
function remarkHeadingAnchor(options) { | ||
return (root, file) => { | ||
file.result = getFileList(root, options); | ||
}; | ||
} | ||
return remarkHeadingAnchor; | ||
})); | ||
}); | ||
return headList; | ||
} | ||
export default function remarkHeadingAnchor(options) { | ||
return (root, file) => { | ||
file.result = getFileList(root, options); | ||
}; | ||
} |
{ | ||
"name": "remark-heading-anchor", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "", | ||
"type": "module", | ||
"main": "dist/index.js", | ||
"main": "dist/index.cjs.js", | ||
"module": "dist/index.esm.js", | ||
"browser": "dist/index.umd.js", | ||
"scripts": { | ||
@@ -13,3 +15,4 @@ "dev": "ts-node example/index.ts", | ||
"dist/*", | ||
"*.json" | ||
"package.json", | ||
"README.md" | ||
], | ||
@@ -33,2 +36,5 @@ "repository": { | ||
"devDependencies": { | ||
"@babel/core": "^7.17.8", | ||
"@babel/preset-env": "^7.16.11", | ||
"@rollup/plugin-commonjs": "^21.0.3", | ||
"@rollup/plugin-node-resolve": "^13.1.3", | ||
@@ -38,2 +44,3 @@ "@rollup/plugin-typescript": "^8.3.1", | ||
"rollup": "^2.70.1", | ||
"rollup-plugin-babel": "^4.4.0", | ||
"ts-node": "^10.7.0", | ||
@@ -40,0 +47,0 @@ "tslib": "^2.3.1", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
7
34340
11
1055
1