ts-markdown
Version:
An extensible TypeScript markdown generator that takes JSON and creates a markdown document.
119 lines (118 loc) • 4.27 kB
JavaScript
;
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);
}