UNPKG

mdtocs

Version:

Markdown table of contents generator.

107 lines (98 loc) 3.43 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.mdtocs = {})); })(this, (function (exports) { 'use strict'; const CODE_BLOCK_REGEX = /^```.*\n[\s\S]*?```$/gm; const HEADINGS_REGEX = /^(#{1,6}[ \t].+)$|^(.+[\r\n][=-]{3,})$/gm; const HEADING_REGEX = /^(#+)[ \t](.+)$|^(.+)[\r\n]([=-])/; const INVALID_FRAGMENT_REGEX = /[^a-zA-Z0-9_-]/g; const WHITESPACE_REGEX = /\s/; const BLANK = ''; const HYPHEN = '-'; const NEWLINE = '\n'; const SPACE = ' '; const INDENT = SPACE.repeat(2); const BULLET = HYPHEN + SPACE; function clean(markdown) { return markdown.replace(CODE_BLOCK_REGEX, BLANK).trim(); } function parse(markdown) { const headings = markdown.match(HEADINGS_REGEX); if (headings === null) { return []; } const fragments = {}; const initialValue = []; return headings.reduce((accumulator, heading) => { const [level, text] = getHeadingLevelAndText(heading); if (level && text) { accumulator.push({ level, text, fragment: createFragment(text, fragments), }); } return accumulator; }, initialValue); } function getHeadingLevelAndText(heading) { const headingMatch = heading.match(HEADING_REGEX); if (headingMatch === null) { return []; } const [, headingLevel, headingText, headingTextAlternate, headingLevelAlternate,] = headingMatch; let text; let level; if (headingLevelAlternate) { level = headingLevelAlternate === HYPHEN ? 2 : 1; text = headingTextAlternate.trim(); } else { level = headingLevel.length; text = headingText.trim(); } if (!text) { return []; } return [level, text]; } function createFragment(text, fragments) { const fragment = text .toLowerCase() .split(WHITESPACE_REGEX) .join('-') .replace(INVALID_FRAGMENT_REGEX, ''); const count = fragments[fragment]; if (count) { fragments[fragment]++; return fragment + HYPHEN + count; } fragments[fragment] = 1; return fragment; } function transform(headings) { return headings.reduce((accumulator, heading) => { const { level, text, fragment } = heading; return (accumulator + INDENT.repeat(level - 1) + BULLET + createLink(text, fragment) + NEWLINE); }, ''); } function createLink(text, fragment) { return '[' + text + '](#' + fragment + ')'; } function validate(markdown) { if (typeof markdown !== 'string') { throw new TypeError('First argument must be a string'); } return markdown; } function mdtocs(markdown) { return transform(parse(clean(validate(markdown)))); } exports.mdtocs = mdtocs; })); //# sourceMappingURL=mdtocs.js.map