UNPKG

@mdfriday/foundry

Version:

The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.

234 lines 6.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutoIDGenerator = exports.TOCBuilder = exports.ParagraphImpl = exports.LinkImpl = exports.HeaderImpl = exports.TableOfContentsImpl = void 0; /** * TableOfContentsImpl implements TocFragments */ class TableOfContentsImpl { constructor(fragments = []) { this.fragments = fragments; } toHTML(startLevel, stopLevel, ordered) { if (this.fragments.length === 0) { return ''; } const filtered = this.filterByLevel(this.fragments, startLevel, stopLevel); if (filtered.length === 0) { return ''; } const tag = ordered ? 'ol' : 'ul'; return `<${tag}>\n${this.renderFragments(filtered, ordered)}</${tag}>\n`; } filterByLevel(fragments, startLevel, stopLevel) { return fragments .filter(f => f.level >= startLevel && f.level <= stopLevel) .map(f => { const filtered = { id: f.id, text: f.text, level: f.level, }; if (f.children) { filtered.children = this.filterByLevel(f.children, startLevel, stopLevel); } return filtered; }); } renderFragments(fragments, ordered) { const tag = ordered ? 'ol' : 'ul'; return fragments .map(f => { let html = ` <li><a href="#${f.id}">${this.escapeHTML(f.text)}</a>`; if (f.children && f.children.length > 0) { html += `\n <${tag}>\n${this.renderFragments(f.children, ordered)} </${tag}>`; } html += '</li>'; return html; }) .join('\n'); } escapeHTML(text) { return text .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#x27;'); } addFragment(fragment) { this.fragments.push(fragment); } getFragments() { return [...this.fragments]; } } exports.TableOfContentsImpl = TableOfContentsImpl; /** * HeaderImpl implements Header interface */ class HeaderImpl { constructor(_name, _level, _links = [], _paragraphs = [], _listParagraphs = []) { this._name = _name; this._level = _level; this._links = _links; this._paragraphs = _paragraphs; this._listParagraphs = _listParagraphs; } name() { return this._name; } level() { return this._level; } links() { return [...this._links]; } paragraphs() { return [...this._paragraphs]; } listParagraphs() { return [...this._listParagraphs]; } addLink(link) { this._links.push(link); } addParagraph(paragraph) { this._paragraphs.push(paragraph); } addListParagraph(paragraph) { this._listParagraphs.push(paragraph); } } exports.HeaderImpl = HeaderImpl; /** * LinkImpl implements Link interface */ class LinkImpl { constructor(_text, _url) { this._text = _text; this._url = _url; } text() { return this._text; } url() { return this._url; } } exports.LinkImpl = LinkImpl; /** * ParagraphImpl implements Paragraph interface */ class ParagraphImpl { constructor(_text) { this._text = _text; } text() { return this._text; } } exports.ParagraphImpl = ParagraphImpl; /** * TOC Builder utility class */ class TOCBuilder { constructor() { this.fragments = []; this.stack = []; } addHeading(text, level, id) { // Remove any fragments from stack that are at same or deeper level while (this.stack.length > 0 && this.stack[this.stack.length - 1].level >= level) { this.stack.pop(); } const fragment = { id, text, level, children: [], }; if (this.stack.length === 0) { // Top level fragment this.fragments.push(fragment); } else { // Child fragment const parent = this.stack[this.stack.length - 1]; if (!parent.children) { parent.children = []; } parent.children.push(fragment); } this.stack.push(fragment); } build() { return new TableOfContentsImpl(this.fragments); } reset() { this.fragments = []; this.stack = []; } } exports.TOCBuilder = TOCBuilder; /** * Auto ID generation utilities */ class AutoIDGenerator { constructor() { this.usedIds = new Set(); } generateID(text, type = 'github') { let id; switch (type) { case 'github': id = this.githubStyle(text); break; case 'github-ascii': id = this.githubAsciiStyle(text); break; case 'blackfriday': id = this.blackfridayStyle(text); break; default: id = this.githubStyle(text); } // Ensure uniqueness if (this.usedIds.has(id)) { let counter = 1; let uniqueId = `${id}-${counter}`; while (this.usedIds.has(uniqueId)) { counter++; uniqueId = `${id}-${counter}`; } id = uniqueId; } this.usedIds.add(id); return id; } githubStyle(text) { return text .toLowerCase() .replace(/[^\w\u4e00-\u9fff\s-]/g, '') // Keep word chars, CJK, spaces, and hyphens .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens } githubAsciiStyle(text) { return text .toLowerCase() .replace(/[^\w\s-]/g, '') // Keep only ASCII word chars, spaces, and hyphens .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens } blackfridayStyle(text) { return text .toLowerCase() .replace(/[^a-z0-9\s-]/g, '') // Keep only lowercase letters, digits, spaces, and hyphens .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens } reset() { this.usedIds.clear(); } } exports.AutoIDGenerator = AutoIDGenerator; //# sourceMappingURL=tableofcontents.js.map