@axway/api-builder-runtime
Version:
API Builder Runtime
91 lines (83 loc) • 2.58 kB
JavaScript
/**
* @class MarkdownRendererEngine
* Renderer engine for Markdown templates.
* @extends APIBuilderRendererEngine
* @pseudo
*/
/**
* @property skipread
* @hide
*/
var { marked } = require('marked'),
fs = require('fs'),
renderer = new marked.Renderer(),
highlight = require('highlight.js'),
util = require('./util'),
langJS = /^(javascript|js|node|node\.js|nodejs|node-js|js|web|titanium|ti)$/i,
looksLikeJS = /(var|function|require|undefined|typeof)/,
options = {
renderer: renderer,
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
};
exports.extension = 'md';
/**
* @property {Object} marked
* marked module instance to access its APIs.
*/
exports.marked = marked;
/**
* @property {Object} renderer
* renderer module instance to access its APIs.
*/
exports.renderer = renderer;
// special code handler that does highlight.js automatically
renderer.code = function (value, lang) {
if (!lang) {
if (looksLikeJS.test(value)) {
// if it sort of loosely looks like JS code, let's be a little more lenient and pass it
// in since devs will often forget to use the language on ```
lang = 'javascript';
} else {
return '<blockquote class="unformat">\n' + marked.parse(value) + '\n</blockquote>';
}
}
lang = lang.replace(/\./g, '-');
var html = '<pre class="highlight ' + lang + ' code"><code>',
result;
if (langJS.test(lang)) {
result = highlight.highlight('javascript', value).value;
} else if (lang && highlight.getLanguage(lang)) {
// see if we can look up the language by the name
// and if found, don't auto-detect since it's too slow
result = highlight.highlight(lang, value).value;
} else {
// worse case, we can fall back to auto detection
result = highlight.highlightAuto(value).value;
}
html += result;
html += '</code></pre>';
return html;
};
function makeAnchor(text) {
return text.toLowerCase().replace(/[^\w]+/g, '-');
}
renderer.heading = function (text, level) {
var escapedText = makeAnchor(text);
return '<h' + level + ' id="heading-' + escapedText + '"><a name="heading-' + escapedText + '">' + text + '</a></h' + level + '>';
};
function render(app, filename) {
filename = util.resolveLayoutFilename(app, filename);
return marked.parse(fs.readFileSync(filename).toString(), options);
}
exports.createRenderer = function (content, filename, app) {
var tpl = marked.parse(content, options);
return function (filePath, opts, callback) {
util.render(app, tpl, opts, exports.extension, render, callback);
};
};