UNPKG

ts-markdown

Version:

An extensible TypeScript markdown generator that takes JSON and creates a markdown document.

119 lines (118 loc) 4.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMarkdownString = exports.renderEntries = exports.tsMarkdown = void 0; const defaults_1 = require("./defaults"); const footnote_1 = require("./renderers/footnote"); /** * The main entrypoint into rendering documents in **ts-markdown**. * * @param data The markdown entries which should be rendered into a markdown document. * @param options Document-level options which can affect broad aspects of the rendering process. * @returns A string of markdown. */ function tsMarkdown(data, options) { options ??= { prefix: '', }; options.renderers ??= (0, defaults_1.getRenderers)(); let document = renderEntries(data, options); document = options.onDocumentFootnoteAppending ? options.onDocumentFootnoteAppending(data, document, options) : document; document = (0, footnote_1.appendFootnotes)(data, document, options); document = options.onDocumentFootnoteAppended ? options.onDocumentFootnoteAppended(data, document, options) : document; return document; } exports.tsMarkdown = tsMarkdown; /** * Reduces an array of markdown entries to a single string. * * @param data the markdown entries to process. * @param options Document-level options which can affect broad aspects of the rendering process. * @returns a string of markdown content. */ function renderEntries(data, options) { let prefix = options.prefix ?? ''; let textStack = ''; for (const [index, entry] of data.entries()) { let entryPrefix = renderPrefix(prefix, index, entry); const result = getMarkdownString(entry, options); let { markdown, blockLevel } = typeof result === 'string' ? { markdown: result, blockLevel: false } : result; textStack += markdown .split('\n') .map((text) => entryPrefix + text) .join('\n'); if (isAppendable(entry)) { let appendable = entry; let appendContent = getMarkdownString(appendable.append, options); if (appendContent !== '') { textStack += '\n' + appendContent; } } if (index < data.length - 1) { textStack += '\n'; } if (index < data.length - 1 && blockLevel) { textStack += entryPrefix; textStack += '\n'; } } return textStack; } exports.renderEntries = renderEntries; function isAppendable(entry) { return (!!entry && typeof entry === 'object' && 'append' in entry && typeof 'append' === 'string'); } /** * Reduces a single markdown entry to a string of markdown content. * * @param entry the target markdown entry or string of text. * @param options Document-level options which can affect broad aspects of the rendering process. * @returns */ function getMarkdownString(entry, options) { if (entry === null && options.renderers?.null) { return options.renderers.null(entry, options); } if (entry === undefined && options.renderers?.null) { return options.renderers.undefined(entry, options); } if (typeof entry === 'string' && options.renderers?.string) { return options.renderers.string(entry, options); } if (typeof entry === 'boolean' && options.renderers?.boolean) { return options.renderers.boolean(entry, options); } if (typeof entry === 'number' && options.renderers?.number) { return options.renderers.number(entry, options); } if (typeof entry === 'bigint' && options.renderers?.bigint) { return options.renderers.bigint(entry, options); } if (entry instanceof Date && options.renderers?.date) { return options.renderers.date(entry, options); } if (typeof entry === 'object') { for (let key in entry) { let renderer = options.renderers?.[key]; if (renderer) { return renderer(entry, options); } } } return ''; } exports.getMarkdownString = getMarkdownString; function renderPrefix(prefix, index, entry) { if (typeof prefix === 'string') { return prefix; } return prefix(index, entry); }