hackmd-to-html-cli
Version:
A node.js CLI tool for converting HackMD markdown to HTML.
138 lines • 6.06 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.MarkdownItExternal = MarkdownItExternal;
const webMap = new Map([
['youtube', 'iframe'],
['vimeo', 'iframe'],
['gist', 'script'],
['slideshare', 'iframe'],
['speakerdeck', 'iframe'],
['pdf', 'embed'],
['figma', 'iframe'],
]);
// modified from
// https://github.com/markdown-it/markdown-it-container
function MarkdownItExternal(md) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function renderer(tokens, idx, _options, _env, slf) {
// add a class to the opening tag
if (tokens[idx].nesting === 1) {
const meta = tokens[idx].meta;
tokens[idx].attrJoin('class', 'embed-' + meta.website);
if (meta.website === 'youtube') {
tokens[idx].attrJoin('src', 'https://www.youtube.com/embed/' + meta.url);
tokens[idx].attrJoin('allowfullscreen', 'true');
tokens[idx].attrJoin('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share');
tokens[idx].attrJoin('frameborder', '0');
}
else if (meta.website === 'vimeo') {
tokens[idx].attrJoin('src', 'https://player.vimeo.com/video/' + meta.url);
tokens[idx].attrJoin('allowfullscreen', 'true');
tokens[idx].attrJoin('frameborder', '0');
tokens[idx].attrJoin('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share');
}
else if (meta.website === 'gist') {
tokens[idx].attrJoin('src', 'https://gist.github.com/' + meta.url + '.js');
}
else if (meta.website === 'slideshare') {
tokens[idx].attrJoin('src', 'https://www.slideshare.net/' + meta.url);
tokens[idx].attrJoin('frameborder', '0');
tokens[idx].attrJoin('marginwidth', '0');
tokens[idx].attrJoin('marginheight', '0');
tokens[idx].attrJoin('scrolling', 'no');
tokens[idx].attrJoin('allowfullscreen', 'true');
}
else if (meta.website === 'speakerdeck') {
tokens[idx].attrJoin('src', 'https://speakerdeck.com/' + meta.url);
}
else if (meta.website === 'pdf') {
tokens[idx].attrJoin('src', meta.url);
tokens[idx].attrJoin('type', 'application/pdf');
}
else if (meta.website === 'figma') {
tokens[idx].attrJoin('src', 'https://www.figma.com/embed?embed_host=hackmd&url=' + meta.url);
tokens[idx].attrJoin('allowfullscreen', 'true');
}
}
return slf.renderToken(tokens, idx, _options);
}
const markerStart = '{%';
const markerEnd = '%}';
const markerStartChar = markerStart.charCodeAt(0);
const markerLen = markerStart.length;
function rule(state, startLine, endLine, silent) {
var _a, _b;
let pos, nextLine, token;
const start = state.bMarks[startLine] + state.tShift[startLine];
const max = state.eMarks[startLine];
// Check out the first character quickly,
// this should filter out most of non-containers
if (markerStartChar !== state.src.charCodeAt(start)) {
return false;
}
// Check out the rest of the marker string
for (pos = start + 1; pos <= max; pos++) {
if (markerStart[(pos - start) % markerLen] !== state.src[pos]) {
break;
}
}
pos -= (pos - start) % markerLen;
const params = state.src.slice(pos, max);
const parse = params.trim().split(' ');
const website = (parse === null || parse === void 0 ? void 0 : parse.length) > 0 ? (parse[0] || '') : '';
let content = (parse === null || parse === void 0 ? void 0 : parse.length) > 1 ? parse[1] : '';
if (!webMap.has(website)) {
return false;
}
// Since start is found, we can report success here in validation mode
if (silent) {
return true;
}
// Search for the end of the block i.e., %}
// from the current start line to the end of file
let nextPos = 0;
for (nextLine = startLine; nextLine < endLine; nextLine++) {
// fetch `nextLine`
const a = state.bMarks[nextLine] + state.tShift[nextLine];
const b = state.eMarks[nextLine];
const line = state.src.slice(a, b);
// search from right to left
nextPos = line.lastIndexOf(markerEnd);
if (nextPos === -1) {
if (nextLine !== startLine) {
content += line;
}
continue;
}
break;
}
token = state.push('external_open', (_a = webMap.get(website)) !== null && _a !== void 0 ? _a : "", 1);
token.meta = {
website: website,
url: content.trim(),
};
token.markup = markerStart;
token.block = true;
token.map = [startLine, nextLine];
token = state.push('external_close', (_b = webMap.get(website)) !== null && _b !== void 0 ? _b : "", -1);
token.markup = markerEnd;
token.block = true;
// {% -- startLine
// URL
// %} -- nextLine
// ^
// move state.bMarks[nextLine]
if (nextPos !== -1) {
state.bMarks[nextLine] += nextPos + 2;
}
// state.line should be increased after parsing
state.line = nextLine + 1;
return true;
}
md.block.ruler.after('blockquote', 'external', rule, {
alt: ['paragraph', 'reference', 'blockquote', 'list']
});
md.renderer.rules.external_open = renderer;
md.renderer.rules.external_close = renderer;
}
//# sourceMappingURL=external.js.map
;